#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdlib.h>
#include <errno.h>
#include <soundcard.h>
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/callerid.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/endian.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h"
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"
Go to the source code of this file.
Data Structures | |
struct | chan_oss_pvt |
struct | sound |
Defines | |
#define | BOOST_MAX 40 |
#define | BOOST_SCALE (1<<9) |
#define | DEV_DSP "/dev/dsp" |
#define | FRAGS ( ( (6 * 5) << 16 ) | 0x6 ) |
#define | FRAME_SIZE 160 |
#define | M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) ) |
#define | M_END(x) x; |
#define | M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else |
#define | M_START(var, val) char *__s = var; char *__val = val; |
#define | M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) |
#define | M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) ) |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MIN(a, b) ((a) < (b) ? (a) : (b)) |
#define | O_CLOSE 0x444 |
#define | QUEUE_SIZE 10 |
#define | TEXT_SIZE 256 |
#define | WARN_frag 4 |
#define | WARN_speed 2 |
#define | WARN_used_blocks 1 |
Functions | |
static int | __console_mute_unmute (int mute) |
static char * | ast_ext_ctx (const char *src, char **ext, char **ctx) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"OSS Console Channel Driver") | |
static char * | autoanswer_complete (const char *line, const char *word, int pos, int state) |
static char * | autoanswer_complete_deprecated (const char *line, const char *word, int pos, int state) |
static int | console_active (int fd, int argc, char *argv[]) |
static int | console_active_deprecated (int fd, int argc, char *argv[]) |
static int | console_answer (int fd, int argc, char *argv[]) |
static int | console_answer_deprecated (int fd, int argc, char *argv[]) |
static int | console_autoanswer (int fd, int argc, char *argv[]) |
static int | console_autoanswer_deprecated (int fd, int argc, char *argv[]) |
static int | console_dial (int fd, int argc, char *argv[]) |
static int | console_dial_deprecated (int fd, int argc, char *argv[]) |
static int | console_flash (int fd, int argc, char *argv[]) |
static int | console_flash_deprecated (int fd, int argc, char *argv[]) |
static int | console_hangup (int fd, int argc, char *argv[]) |
static int | console_hangup_deprecated (int fd, int argc, char *argv[]) |
static int | console_mute (int fd, int argc, char *argv[]) |
static int | console_mute_deprecated (int fd, int argc, char *argv[]) |
static int | console_sendtext (int fd, int argc, char *argv[]) |
static int | console_sendtext_deprecated (int fd, int argc, char *argv[]) |
static int | console_transfer (int fd, int argc, char *argv[]) |
static int | console_transfer_deprecated (int fd, int argc, char *argv[]) |
static int | console_unmute (int fd, int argc, char *argv[]) |
static int | console_unmute_deprecated (int fd, int argc, char *argv[]) |
static int | do_boost (int fd, int argc, char *argv[]) |
static struct chan_oss_pvt * | find_desc (char *dev) |
static int | load_module (void) |
static int | oss_answer (struct ast_channel *c) |
static int | oss_call (struct ast_channel *c, char *dest, int timeout) |
static int | oss_digit_begin (struct ast_channel *c, char digit) |
static int | oss_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | oss_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static int | oss_hangup (struct ast_channel *c) |
static int | oss_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen) |
static struct ast_channel * | oss_new (struct chan_oss_pvt *o, char *ext, char *ctx, int state) |
static struct ast_frame * | oss_read (struct ast_channel *chan) |
static struct ast_channel * | oss_request (const char *type, int format, void *data, int *cause) |
static int | oss_text (struct ast_channel *c, const char *text) |
static int | oss_write (struct ast_channel *chan, struct ast_frame *f) |
static void | ring (struct chan_oss_pvt *o, int x) |
static void | send_sound (struct chan_oss_pvt *o) |
static int | setformat (struct chan_oss_pvt *o, int mode) |
static void * | sound_thread (void *arg) |
static int | soundcard_writeframe (struct chan_oss_pvt *o, short *data) |
static void | store_boost (struct chan_oss_pvt *o, char *s) |
static void | store_callerid (struct chan_oss_pvt *o, char *s) |
static struct chan_oss_pvt * | store_config (struct ast_config *cfg, char *ctg) |
static void | store_mixer (struct chan_oss_pvt *o, char *s) |
static int | unload_module (void) |
static int | used_blocks (struct chan_oss_pvt *o) |
Variables | |
static char | active_usage [] |
static char | answer_usage [] |
static char | autoanswer_usage [] |
static struct ast_cli_entry | cli_oss [] |
static struct ast_cli_entry | cli_oss_active_deprecated |
static struct ast_cli_entry | cli_oss_answer_deprecated |
static struct ast_cli_entry | cli_oss_autoanswer_deprecated |
static struct ast_cli_entry | cli_oss_boost_deprecated |
static struct ast_cli_entry | cli_oss_dial_deprecated |
static struct ast_cli_entry | cli_oss_flash_deprecated |
static struct ast_cli_entry | cli_oss_hangup_deprecated |
static struct ast_cli_entry | cli_oss_mute_deprecated |
static struct ast_cli_entry | cli_oss_send_text_deprecated |
static struct ast_cli_entry | cli_oss_transfer_deprecated |
static struct ast_cli_entry | cli_oss_unmute_deprecated |
static char * | config = "oss.conf" |
static struct ast_jb_conf | default_jbconf |
static char | dial_usage [] |
static char | flash_usage [] |
static struct ast_jb_conf | global_jbconf |
static char | hangup_usage [] |
static char | mute_usage [] |
static char * | oss_active |
static int | oss_debug |
static struct chan_oss_pvt | oss_default |
static struct ast_channel_tech | oss_tech |
static char | sendtext_usage [] |
static struct sound | sounds [] |
static char | tdesc [] = "OSS Console Channel Driver" |
static char | transfer_usage [] |
static char | unmute_usage [] |
Definition in file chan_oss.c.
#define BOOST_MAX 40 |
#define BOOST_SCALE (1<<9) |
#define DEV_DSP "/dev/dsp" |
#define FRAGS ( ( (6 * 5) << 16 ) | 0x6 ) |
Definition at line 257 of file chan_oss.c.
#define FRAME_SIZE 160 |
Definition at line 251 of file chan_oss.c.
#define M_BOOL | ( | tag, | |||
dst | ) | M_F(tag, (dst) = ast_true(__val) ) |
#define M_END | ( | x | ) | x; |
#define M_STR | ( | tag, | |||
dst | ) | M_F(tag, ast_copy_string(dst, __val, sizeof(dst))) |
#define M_UINT | ( | tag, | |||
dst | ) | M_F(tag, (dst) = strtoul(__val, NULL, 0) ) |
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 281 of file chan_oss.c.
#define MIN | ( | a, | |||
b | ) | ((a) < (b) ? (a) : (b)) |
Definition at line 278 of file chan_oss.c.
#define O_CLOSE 0x444 |
Definition at line 269 of file chan_oss.c.
Referenced by console_hangup(), console_hangup_deprecated(), oss_hangup(), setformat(), and sound_thread().
#define QUEUE_SIZE 10 |
Definition at line 252 of file chan_oss.c.
#define TEXT_SIZE 256 |
Definition at line 264 of file chan_oss.c.
Referenced by console_sendtext(), and console_sendtext_deprecated().
#define WARN_frag 4 |
#define WARN_speed 2 |
#define WARN_used_blocks 1 |
static int __console_mute_unmute | ( | int | mute | ) | [static] |
Definition at line 1407 of file chan_oss.c.
References find_desc(), chan_oss_pvt::mute, and RESULT_SUCCESS.
Referenced by console_mute(), console_mute_deprecated(), console_unmute(), and console_unmute_deprecated().
01408 { 01409 struct chan_oss_pvt *o = find_desc(oss_active); 01410 01411 o->mute = mute; 01412 return RESULT_SUCCESS; 01413 }
static char* ast_ext_ctx | ( | const char * | src, | |
char ** | ext, | |||
char ** | ctx | |||
) | [static] |
Definition at line 462 of file chan_oss.c.
References ast_strdup, find_desc(), and chan_oss_pvt::overridecontext.
Referenced by console_dial(), console_dial_deprecated(), console_transfer(), and console_transfer_deprecated().
00463 { 00464 struct chan_oss_pvt *o = find_desc(oss_active); 00465 00466 if (ext == NULL || ctx == NULL) 00467 return NULL; /* error */ 00468 00469 *ext = *ctx = NULL; 00470 00471 if (src && *src != '\0') 00472 *ext = ast_strdup(src); 00473 00474 if (*ext == NULL) 00475 return NULL; 00476 00477 if (!o->overridecontext) { 00478 /* parse from the right */ 00479 *ctx = strrchr(*ext, '@'); 00480 if (*ctx) 00481 *(*ctx)++ = '\0'; 00482 } 00483 00484 return *ext; 00485 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"OSS Console Channel Driver" | ||||
) |
static char* autoanswer_complete | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1115 of file chan_oss.c.
References ast_cli_complete().
01116 { 01117 static char *choices[] = { "on", "off", NULL }; 01118 01119 return (pos != 3) ? NULL : ast_cli_complete(word, choices, state); 01120 }
static char* autoanswer_complete_deprecated | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 1108 of file chan_oss.c.
References ast_cli_complete().
01109 { 01110 static char *choices[] = { "on", "off", NULL }; 01111 01112 return (pos != 2) ? NULL : ast_cli_complete(word, choices, state); 01113 }
static int console_active | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1541 of file chan_oss.c.
References ast_cli(), find_desc(), chan_oss_pvt::name, chan_oss_pvt::next, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01542 { 01543 if (argc == 2) 01544 ast_cli(fd, "active console is [%s]\n", oss_active); 01545 else if (argc != 3) 01546 return RESULT_SHOWUSAGE; 01547 else { 01548 struct chan_oss_pvt *o; 01549 if (strcmp(argv[2], "show") == 0) { 01550 for (o = oss_default.next; o; o = o->next) 01551 ast_cli(fd, "device [%s] exists\n", o->name); 01552 return RESULT_SUCCESS; 01553 } 01554 o = find_desc(argv[2]); 01555 if (o == NULL) 01556 ast_cli(fd, "No device [%s] exists\n", argv[2]); 01557 else 01558 oss_active = o->name; 01559 } 01560 return RESULT_SUCCESS; 01561 }
static int console_active_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1519 of file chan_oss.c.
References ast_cli(), find_desc(), chan_oss_pvt::name, chan_oss_pvt::next, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01520 { 01521 if (argc == 1) 01522 ast_cli(fd, "active console is [%s]\n", oss_active); 01523 else if (argc != 2) 01524 return RESULT_SHOWUSAGE; 01525 else { 01526 struct chan_oss_pvt *o; 01527 if (strcmp(argv[1], "show") == 0) { 01528 for (o = oss_default.next; o; o = o->next) 01529 ast_cli(fd, "device [%s] exists\n", o->name); 01530 return RESULT_SUCCESS; 01531 } 01532 o = find_desc(argv[1]); 01533 if (o == NULL) 01534 ast_cli(fd, "No device [%s] exists\n", argv[1]); 01535 else 01536 oss_active = o->name; 01537 } 01538 return RESULT_SUCCESS; 01539 }
static int console_answer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1153 of file chan_oss.c.
References ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ring().
01154 { 01155 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 01156 struct chan_oss_pvt *o = find_desc(oss_active); 01157 01158 if (argc != 2) 01159 return RESULT_SHOWUSAGE; 01160 if (!o->owner) { 01161 ast_cli(fd, "No one is calling us\n"); 01162 return RESULT_FAILURE; 01163 } 01164 o->hookstate = 1; 01165 o->cursound = -1; 01166 o->nosound = 0; 01167 ast_queue_frame(o->owner, &f); 01168 #if 0 01169 /* XXX do we really need it ? considering we shut down immediately... */ 01170 ring(o, AST_CONTROL_ANSWER); 01171 #endif 01172 return RESULT_SUCCESS; 01173 }
static int console_answer_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1131 of file chan_oss.c.
References ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ring().
01132 { 01133 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 01134 struct chan_oss_pvt *o = find_desc(oss_active); 01135 01136 if (argc != 1) 01137 return RESULT_SHOWUSAGE; 01138 if (!o->owner) { 01139 ast_cli(fd, "No one is calling us\n"); 01140 return RESULT_FAILURE; 01141 } 01142 o->hookstate = 1; 01143 o->cursound = -1; 01144 o->nosound = 0; 01145 ast_queue_frame(o->owner, &f); 01146 #if 0 01147 /* XXX do we really need it ? considering we shut down immediately... */ 01148 ring(o, AST_CONTROL_ANSWER); 01149 #endif 01150 return RESULT_SUCCESS; 01151 }
static int console_autoanswer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1084 of file chan_oss.c.
References ast_cli(), ast_log(), chan_oss_pvt::autoanswer, find_desc(), LOG_WARNING, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01085 { 01086 struct chan_oss_pvt *o = find_desc(oss_active); 01087 01088 if (argc == 2) { 01089 ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off"); 01090 return RESULT_SUCCESS; 01091 } 01092 if (argc != 3) 01093 return RESULT_SHOWUSAGE; 01094 if (o == NULL) { 01095 ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", 01096 oss_active); 01097 return RESULT_FAILURE; 01098 } 01099 if (!strcasecmp(argv[2], "on")) 01100 o->autoanswer = -1; 01101 else if (!strcasecmp(argv[2], "off")) 01102 o->autoanswer = 0; 01103 else 01104 return RESULT_SHOWUSAGE; 01105 return RESULT_SUCCESS; 01106 }
static int console_autoanswer_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1061 of file chan_oss.c.
References ast_cli(), ast_log(), chan_oss_pvt::autoanswer, find_desc(), LOG_WARNING, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01062 { 01063 struct chan_oss_pvt *o = find_desc(oss_active); 01064 01065 if (argc == 1) { 01066 ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off"); 01067 return RESULT_SUCCESS; 01068 } 01069 if (argc != 2) 01070 return RESULT_SHOWUSAGE; 01071 if (o == NULL) { 01072 ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", oss_active); 01073 return RESULT_FAILURE; 01074 } 01075 if (!strcasecmp(argv[1], "on")) 01076 o->autoanswer = -1; 01077 else if (!strcasecmp(argv[1], "off")) 01078 o->autoanswer = 0; 01079 else 01080 return RESULT_SHOWUSAGE; 01081 return RESULT_SUCCESS; 01082 }
static int console_dial | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1362 of file chan_oss.c.
References ast_cli(), ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, ast_queue_frame(), AST_STATE_RINGING, chan_oss_pvt::ctx, chan_oss_pvt::ext, find_desc(), free, chan_oss_pvt::hookstate, oss_new(), chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and ast_frame::subclass.
01363 { 01364 char *s = NULL, *mye = NULL, *myc = NULL; 01365 struct chan_oss_pvt *o = find_desc(oss_active); 01366 01367 if (argc != 2 && argc != 3) 01368 return RESULT_SHOWUSAGE; 01369 if (o->owner) { /* already in a call */ 01370 int i; 01371 struct ast_frame f = { AST_FRAME_DTMF, 0 }; 01372 01373 if (argc == 2) { /* argument is mandatory here */ 01374 ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n"); 01375 return RESULT_FAILURE; 01376 } 01377 s = argv[2]; 01378 /* send the string one char at a time */ 01379 for (i = 0; i < strlen(s); i++) { 01380 f.subclass = s[i]; 01381 ast_queue_frame(o->owner, &f); 01382 } 01383 return RESULT_SUCCESS; 01384 } 01385 /* if we have an argument split it into extension and context */ 01386 if (argc == 3) 01387 s = ast_ext_ctx(argv[2], &mye, &myc); 01388 /* supply default values if needed */ 01389 if (mye == NULL) 01390 mye = o->ext; 01391 if (myc == NULL) 01392 myc = o->ctx; 01393 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 01394 o->hookstate = 1; 01395 oss_new(o, mye, myc, AST_STATE_RINGING); 01396 } else 01397 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); 01398 if (s) 01399 free(s); 01400 return RESULT_SUCCESS; 01401 }
static int console_dial_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1321 of file chan_oss.c.
References ast_cli(), ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, ast_queue_frame(), AST_STATE_RINGING, chan_oss_pvt::ctx, chan_oss_pvt::ext, find_desc(), free, chan_oss_pvt::hookstate, oss_new(), chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and ast_frame::subclass.
01322 { 01323 char *s = NULL, *mye = NULL, *myc = NULL; 01324 struct chan_oss_pvt *o = find_desc(oss_active); 01325 01326 if (argc != 1 && argc != 2) 01327 return RESULT_SHOWUSAGE; 01328 if (o->owner) { /* already in a call */ 01329 int i; 01330 struct ast_frame f = { AST_FRAME_DTMF, 0 }; 01331 01332 if (argc == 1) { /* argument is mandatory here */ 01333 ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n"); 01334 return RESULT_FAILURE; 01335 } 01336 s = argv[1]; 01337 /* send the string one char at a time */ 01338 for (i = 0; i < strlen(s); i++) { 01339 f.subclass = s[i]; 01340 ast_queue_frame(o->owner, &f); 01341 } 01342 return RESULT_SUCCESS; 01343 } 01344 /* if we have an argument split it into extension and context */ 01345 if (argc == 2) 01346 s = ast_ext_ctx(argv[1], &mye, &myc); 01347 /* supply default values if needed */ 01348 if (mye == NULL) 01349 mye = o->ext; 01350 if (myc == NULL) 01351 myc = o->ctx; 01352 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 01353 o->hookstate = 1; 01354 oss_new(o, mye, myc, AST_STATE_RINGING); 01355 } else 01356 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc); 01357 if (s) 01358 free(s); 01359 return RESULT_SUCCESS; 01360 }
static int console_flash | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1298 of file chan_oss.c.
References ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01299 { 01300 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; 01301 struct chan_oss_pvt *o = find_desc(oss_active); 01302 01303 if (argc != 2) 01304 return RESULT_SHOWUSAGE; 01305 o->cursound = -1; 01306 o->nosound = 0; /* when cursound is -1 nosound must be 0 */ 01307 if (!o->owner) { /* XXX maybe !o->hookstate too ? */ 01308 ast_cli(fd, "No call to flash\n"); 01309 return RESULT_FAILURE; 01310 } 01311 o->hookstate = 0; 01312 if (o->owner) /* XXX must be true, right ? */ 01313 ast_queue_frame(o->owner, &f); 01314 return RESULT_SUCCESS; 01315 }
static int console_flash_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1279 of file chan_oss.c.
References ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01280 { 01281 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; 01282 struct chan_oss_pvt *o = find_desc(oss_active); 01283 01284 if (argc != 1) 01285 return RESULT_SHOWUSAGE; 01286 o->cursound = -1; 01287 o->nosound = 0; /* when cursound is -1 nosound must be 0 */ 01288 if (!o->owner) { /* XXX maybe !o->hookstate too ? */ 01289 ast_cli(fd, "No call to flash\n"); 01290 return RESULT_FAILURE; 01291 } 01292 o->hookstate = 0; 01293 if (o->owner) /* XXX must be true, right ? */ 01294 ast_queue_frame(o->owner, &f); 01295 return RESULT_SUCCESS; 01296 }
static int console_hangup | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1256 of file chan_oss.c.
References ast_cli(), ast_queue_hangup(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and setformat().
01257 { 01258 struct chan_oss_pvt *o = find_desc(oss_active); 01259 01260 if (argc != 2) 01261 return RESULT_SHOWUSAGE; 01262 o->cursound = -1; 01263 o->nosound = 0; 01264 if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */ 01265 ast_cli(fd, "No call to hang up\n"); 01266 return RESULT_FAILURE; 01267 } 01268 o->hookstate = 0; 01269 if (o->owner) 01270 ast_queue_hangup(o->owner); 01271 setformat(o, O_CLOSE); 01272 return RESULT_SUCCESS; 01273 }
static int console_hangup_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1237 of file chan_oss.c.
References ast_cli(), ast_queue_hangup(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and setformat().
01238 { 01239 struct chan_oss_pvt *o = find_desc(oss_active); 01240 01241 if (argc != 1) 01242 return RESULT_SHOWUSAGE; 01243 o->cursound = -1; 01244 o->nosound = 0; 01245 if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */ 01246 ast_cli(fd, "No call to hang up\n"); 01247 return RESULT_FAILURE; 01248 } 01249 o->hookstate = 0; 01250 if (o->owner) 01251 ast_queue_hangup(o->owner); 01252 setformat(o, O_CLOSE); 01253 return RESULT_SUCCESS; 01254 }
static int console_mute | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1423 of file chan_oss.c.
References __console_mute_unmute(), and RESULT_SHOWUSAGE.
01424 { 01425 if (argc != 2) 01426 return RESULT_SHOWUSAGE; 01427 01428 return __console_mute_unmute(1); 01429 }
static int console_mute_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1415 of file chan_oss.c.
References __console_mute_unmute(), and RESULT_SHOWUSAGE.
01416 { 01417 if (argc != 1) 01418 return RESULT_SHOWUSAGE; 01419 01420 return __console_mute_unmute(1); 01421 }
static int console_sendtext | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1208 of file chan_oss.c.
References ast_cli(), AST_FRAME_TEXT, ast_join(), ast_queue_frame(), ast_strlen_zero(), ast_frame::data, ast_frame::datalen, find_desc(), ast_frame::frametype, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_frame::subclass, and TEXT_SIZE.
01209 { 01210 struct chan_oss_pvt *o = find_desc(oss_active); 01211 char buf[TEXT_SIZE]; 01212 01213 if (argc < 3) 01214 return RESULT_SHOWUSAGE; 01215 if (!o->owner) { 01216 ast_cli(fd, "Not in a call\n"); 01217 return RESULT_FAILURE; 01218 } 01219 ast_join(buf, sizeof(buf) - 1, argv + 3); 01220 if (!ast_strlen_zero(buf)) { 01221 struct ast_frame f = { 0, }; 01222 int i = strlen(buf); 01223 buf[i] = '\n'; 01224 f.frametype = AST_FRAME_TEXT; 01225 f.subclass = 0; 01226 f.data = buf; 01227 f.datalen = i + 1; 01228 ast_queue_frame(o->owner, &f); 01229 } 01230 return RESULT_SUCCESS; 01231 }
static int console_sendtext_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1183 of file chan_oss.c.
References ast_cli(), AST_FRAME_TEXT, ast_join(), ast_queue_frame(), ast_strlen_zero(), ast_frame::data, ast_frame::datalen, find_desc(), ast_frame::frametype, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_frame::subclass, and TEXT_SIZE.
01184 { 01185 struct chan_oss_pvt *o = find_desc(oss_active); 01186 char buf[TEXT_SIZE]; 01187 01188 if (argc < 2) 01189 return RESULT_SHOWUSAGE; 01190 if (!o->owner) { 01191 ast_cli(fd, "Not in a call\n"); 01192 return RESULT_FAILURE; 01193 } 01194 ast_join(buf, sizeof(buf) - 1, argv + 2); 01195 if (!ast_strlen_zero(buf)) { 01196 struct ast_frame f = { 0, }; 01197 int i = strlen(buf); 01198 buf[i] = '\n'; 01199 f.frametype = AST_FRAME_TEXT; 01200 f.subclass = 0; 01201 f.data = buf; 01202 f.datalen = i + 1; 01203 ast_queue_frame(o->owner, &f); 01204 } 01205 return RESULT_SUCCESS; 01206 }
static int console_transfer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1484 of file chan_oss.c.
References ast_async_goto(), ast_bridged_channel(), ast_cli(), ast_exists_extension(), ast_ext_ctx(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ext, find_desc(), free, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01485 { 01486 struct chan_oss_pvt *o = find_desc(oss_active); 01487 struct ast_channel *b = NULL; 01488 char *tmp, *ext, *ctx; 01489 01490 if (argc != 3) 01491 return RESULT_SHOWUSAGE; 01492 if (o == NULL) 01493 return RESULT_FAILURE; 01494 if (o->owner == NULL || (b = ast_bridged_channel(o->owner)) == NULL) { 01495 ast_cli(fd, "There is no call to transfer\n"); 01496 return RESULT_SUCCESS; 01497 } 01498 01499 tmp = ast_ext_ctx(argv[2], &ext, &ctx); 01500 if (ctx == NULL) /* supply default context if needed */ 01501 ctx = o->owner->context; 01502 if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num)) 01503 ast_cli(fd, "No such extension exists\n"); 01504 else { 01505 ast_cli(fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx); 01506 if (ast_async_goto(b, ctx, ext, 1)) 01507 ast_cli(fd, "Failed to transfer :(\n"); 01508 } 01509 if (tmp) 01510 free(tmp); 01511 return RESULT_SUCCESS; 01512 }
static int console_transfer_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1453 of file chan_oss.c.
References ast_async_goto(), ast_bridged_channel(), ast_cli(), ast_exists_extension(), ast_ext_ctx(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ext, find_desc(), free, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01454 { 01455 struct chan_oss_pvt *o = find_desc(oss_active); 01456 struct ast_channel *b = NULL; 01457 char *tmp, *ext, *ctx; 01458 01459 if (argc != 2) 01460 return RESULT_SHOWUSAGE; 01461 if (o == NULL) 01462 return RESULT_FAILURE; 01463 if (o->owner ==NULL || (b = ast_bridged_channel(o->owner)) == NULL) { 01464 ast_cli(fd, "There is no call to transfer\n"); 01465 return RESULT_SUCCESS; 01466 } 01467 01468 tmp = ast_ext_ctx(argv[1], &ext, &ctx); 01469 if (ctx == NULL) /* supply default context if needed */ 01470 ctx = o->owner->context; 01471 if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num)) 01472 ast_cli(fd, "No such extension exists\n"); 01473 else { 01474 ast_cli(fd, "Whee, transferring %s to %s@%s.\n", 01475 b->name, ext, ctx); 01476 if (ast_async_goto(b, ctx, ext, 1)) 01477 ast_cli(fd, "Failed to transfer :(\n"); 01478 } 01479 if (tmp) 01480 free(tmp); 01481 return RESULT_SUCCESS; 01482 }
static int console_unmute | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1442 of file chan_oss.c.
References __console_mute_unmute(), and RESULT_SHOWUSAGE.
01443 { 01444 if (argc != 2) 01445 return RESULT_SHOWUSAGE; 01446 01447 return __console_mute_unmute(0); 01448 }
static int console_unmute_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1434 of file chan_oss.c.
References __console_mute_unmute(), and RESULT_SHOWUSAGE.
01435 { 01436 if (argc != 1) 01437 return RESULT_SHOWUSAGE; 01438 01439 return __console_mute_unmute(0); 01440 }
static int do_boost | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1591 of file chan_oss.c.
References ast_cli(), chan_oss_pvt::boost, BOOST_SCALE, find_desc(), RESULT_SUCCESS, and store_boost().
01592 { 01593 struct chan_oss_pvt *o = find_desc(oss_active); 01594 01595 if (argc == 2) 01596 ast_cli(fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE))); 01597 else if (argc == 3) 01598 store_boost(o, argv[2]); 01599 return RESULT_SUCCESS; 01600 }
static struct chan_oss_pvt* find_desc | ( | char * | dev | ) | [static, read] |
Definition at line 438 of file chan_oss.c.
References ast_log(), LOG_WARNING, chan_oss_pvt::name, and chan_oss_pvt::next.
Referenced by __console_mute_unmute(), ast_ext_ctx(), console_active(), console_active_deprecated(), console_answer(), console_answer_deprecated(), console_autoanswer(), console_autoanswer_deprecated(), console_dial(), console_dial_deprecated(), console_flash(), console_flash_deprecated(), console_hangup(), console_hangup_deprecated(), console_sendtext(), console_sendtext_deprecated(), console_transfer(), console_transfer_deprecated(), do_boost(), load_module(), and oss_request().
00439 { 00440 struct chan_oss_pvt *o = NULL; 00441 00442 if (!dev) 00443 ast_log(LOG_WARNING, "null dev\n"); 00444 00445 for (o = oss_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next); 00446 00447 if (!o) 00448 ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--"); 00449 00450 return o; 00451 }
static int load_module | ( | void | ) | [static] |
Definition at line 1827 of file chan_oss.c.
References ast_category_browse(), ast_channel_register(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, find_desc(), global_jbconf, LOG_ERROR, LOG_NOTICE, and store_config().
01828 { 01829 struct ast_config *cfg = NULL; 01830 char *ctg = NULL; 01831 01832 /* Copy the default jb config over global_jbconf */ 01833 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 01834 01835 /* load config file */ 01836 if (!(cfg = ast_config_load(config))) { 01837 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 01838 return AST_MODULE_LOAD_DECLINE; 01839 } 01840 01841 do { 01842 store_config(cfg, ctg); 01843 } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL); 01844 01845 ast_config_destroy(cfg); 01846 01847 if (find_desc(oss_active) == NULL) { 01848 ast_log(LOG_NOTICE, "Device %s not found\n", oss_active); 01849 /* XXX we could default to 'dsp' perhaps ? */ 01850 /* XXX should cleanup allocated memory etc. */ 01851 return AST_MODULE_LOAD_FAILURE; 01852 } 01853 01854 if (ast_channel_register(&oss_tech)) { 01855 ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n"); 01856 return AST_MODULE_LOAD_FAILURE; 01857 } 01858 01859 ast_cli_register_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry)); 01860 01861 return AST_MODULE_LOAD_SUCCESS; 01862 }
static int oss_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 817 of file chan_oss.c.
References AST_CONTROL_ANSWER, ast_setstate(), AST_STATE_UP, ast_verbose(), chan_oss_pvt::cursound, chan_oss_pvt::nosound, ring(), and ast_channel::tech_pvt.
00818 { 00819 struct chan_oss_pvt *o = c->tech_pvt; 00820 00821 ast_verbose(" << Console call has been answered >> \n"); 00822 #if 0 00823 /* play an answer tone (XXX do we really need it ?) */ 00824 ring(o, AST_CONTROL_ANSWER); 00825 #endif 00826 ast_setstate(c, AST_STATE_UP); 00827 o->cursound = -1; 00828 o->nosound = 0; 00829 return 0; 00830 }
static int oss_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 793 of file chan_oss.c.
References AST_CONTROL_ANSWER, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_queue_frame(), ast_verbose(), chan_oss_pvt::autoanswer, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, ast_frame::frametype, ring(), ast_frame::subclass, and ast_channel::tech_pvt.
00794 { 00795 struct chan_oss_pvt *o = c->tech_pvt; 00796 struct ast_frame f = { 0, }; 00797 00798 ast_verbose(" << Call to device '%s' dnid '%s' rdnis '%s' on console from '%s' <%s> >>\n", dest, c->cid.cid_dnid, c->cid.cid_rdnis, c->cid.cid_name, c->cid.cid_num); 00799 if (o->autoanswer) { 00800 ast_verbose(" << Auto-answered >> \n"); 00801 f.frametype = AST_FRAME_CONTROL; 00802 f.subclass = AST_CONTROL_ANSWER; 00803 ast_queue_frame(c, &f); 00804 } else { 00805 ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n"); 00806 f.frametype = AST_FRAME_CONTROL; 00807 f.subclass = AST_CONTROL_RINGING; 00808 ast_queue_frame(c, &f); 00809 ring(o, AST_CONTROL_RING); 00810 } 00811 return 0; 00812 }
static int oss_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
static int oss_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 768 of file chan_oss.c.
References ast_verbose().
00769 { 00770 /* no better use for received digits than print them */ 00771 ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 00772 digit, duration); 00773 return 0; 00774 }
static int oss_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 941 of file chan_oss.c.
References chan_oss_pvt::owner, and ast_channel::tech_pvt.
00942 { 00943 struct chan_oss_pvt *o = newchan->tech_pvt; 00944 o->owner = newchan; 00945 return 0; 00946 }
static int oss_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 832 of file chan_oss.c.
References AST_CONTROL_CONGESTION, ast_module_unref(), ast_verbose(), chan_oss_pvt::autoanswer, chan_oss_pvt::autohangup, chan_oss_pvt::cursound, chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, chan_oss_pvt::owner, ring(), setformat(), and ast_channel::tech_pvt.
00833 { 00834 struct chan_oss_pvt *o = c->tech_pvt; 00835 00836 o->cursound = -1; 00837 o->nosound = 0; 00838 c->tech_pvt = NULL; 00839 o->owner = NULL; 00840 ast_verbose(" << Hangup on console >> \n"); 00841 ast_module_unref(ast_module_info->self); 00842 if (o->hookstate) { 00843 if (o->autoanswer || o->autohangup) { 00844 /* Assume auto-hangup too */ 00845 o->hookstate = 0; 00846 setformat(o, O_CLOSE); 00847 } else { 00848 /* Make congestion noise */ 00849 ring(o, AST_CONTROL_CONGESTION); 00850 } 00851 } 00852 return 0; 00853 }
static int oss_indicate | ( | struct ast_channel * | chan, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 948 of file chan_oss.c.
References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_verbose(), chan_oss_pvt::cursound, LOG_WARNING, chan_oss_pvt::mohinterpret, chan_oss_pvt::nosound, ring(), and ast_channel::tech_pvt.
00949 { 00950 struct chan_oss_pvt *o = c->tech_pvt; 00951 int res = -1; 00952 00953 switch (cond) { 00954 case AST_CONTROL_BUSY: 00955 case AST_CONTROL_CONGESTION: 00956 case AST_CONTROL_RINGING: 00957 res = cond; 00958 break; 00959 00960 case -1: 00961 o->cursound = -1; 00962 o->nosound = 0; /* when cursound is -1 nosound must be 0 */ 00963 return 0; 00964 00965 case AST_CONTROL_VIDUPDATE: 00966 res = -1; 00967 break; 00968 case AST_CONTROL_HOLD: 00969 ast_verbose(" << Console Has Been Placed on Hold >> \n"); 00970 ast_moh_start(c, data, o->mohinterpret); 00971 break; 00972 case AST_CONTROL_UNHOLD: 00973 ast_verbose(" << Console Has Been Retrieved from Hold >> \n"); 00974 ast_moh_stop(c); 00975 break; 00976 00977 default: 00978 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name); 00979 return -1; 00980 } 00981 00982 if (res > -1) 00983 ring(o, res); 00984 00985 return 0; 00986 }
static struct ast_channel* oss_new | ( | struct chan_oss_pvt * | o, | |
char * | ext, | |||
char * | ctx, | |||
int | state | |||
) | [static, read] |
Definition at line 991 of file chan_oss.c.
References ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_oss_pvt::cid_name, ast_callerid::cid_num, chan_oss_pvt::cid_num, chan_oss_pvt::device, ast_channel::fds, global_jbconf, language, chan_oss_pvt::language, LOG_WARNING, ast_channel::nativeformats, chan_oss_pvt::owner, ast_channel::readformat, setformat(), chan_oss_pvt::sounddev, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by console_dial(), console_dial_deprecated(), and oss_request().
00992 { 00993 struct ast_channel *c; 00994 00995 c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "OSS/%s", o->device + 5); 00996 if (c == NULL) 00997 return NULL; 00998 c->tech = &oss_tech; 00999 if (o->sounddev < 0) 01000 setformat(o, O_RDWR); 01001 c->fds[0] = o->sounddev; /* -1 if device closed, override later */ 01002 c->nativeformats = AST_FORMAT_SLINEAR; 01003 c->readformat = AST_FORMAT_SLINEAR; 01004 c->writeformat = AST_FORMAT_SLINEAR; 01005 c->tech_pvt = o; 01006 01007 if (!ast_strlen_zero(o->language)) 01008 ast_string_field_set(c, language, o->language); 01009 /* Don't use ast_set_callerid() here because it will 01010 * generate a needless NewCallerID event */ 01011 c->cid.cid_num = ast_strdup(o->cid_num); 01012 c->cid.cid_ani = ast_strdup(o->cid_num); 01013 c->cid.cid_name = ast_strdup(o->cid_name); 01014 if (!ast_strlen_zero(ext)) 01015 c->cid.cid_dnid = ast_strdup(ext); 01016 01017 o->owner = c; 01018 ast_module_ref(ast_module_info->self); 01019 ast_jb_configure(c, &global_jbconf); 01020 if (state != AST_STATE_DOWN) { 01021 if (ast_pbx_start(c)) { 01022 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name); 01023 ast_hangup(c); 01024 o->owner = c = NULL; 01025 /* XXX what about the channel itself ? */ 01026 /* XXX what about usecnt ? */ 01027 } 01028 } 01029 01030 return c; 01031 }
static struct ast_frame * oss_read | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 892 of file chan_oss.c.
References ast_channel::_state, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, AST_STATE_UP, chan_oss_pvt::boost, BOOST_SCALE, ast_frame::data, ast_frame::datalen, f, FRAME_SIZE, ast_frame::frametype, chan_oss_pvt::mute, ast_frame::offset, chan_oss_pvt::oss_read_buf, chan_oss_pvt::read_f, chan_oss_pvt::readpos, ast_frame::samples, chan_oss_pvt::sounddev, ast_frame::src, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel_tech::type.
00893 { 00894 int res; 00895 struct chan_oss_pvt *o = c->tech_pvt; 00896 struct ast_frame *f = &o->read_f; 00897 00898 /* XXX can be simplified returning &ast_null_frame */ 00899 /* prepare a NULL frame in case we don't have enough data to return */ 00900 bzero(f, sizeof(struct ast_frame)); 00901 f->frametype = AST_FRAME_NULL; 00902 f->src = oss_tech.type; 00903 00904 res = read(o->sounddev, o->oss_read_buf + o->readpos, sizeof(o->oss_read_buf) - o->readpos); 00905 if (res < 0) /* audio data not ready, return a NULL frame */ 00906 return f; 00907 00908 o->readpos += res; 00909 if (o->readpos < sizeof(o->oss_read_buf)) /* not enough samples */ 00910 return f; 00911 00912 if (o->mute) 00913 return f; 00914 00915 o->readpos = AST_FRIENDLY_OFFSET; /* reset read pointer for next frame */ 00916 if (c->_state != AST_STATE_UP) /* drop data if frame is not up */ 00917 return f; 00918 /* ok we can build and deliver the frame to the caller */ 00919 f->frametype = AST_FRAME_VOICE; 00920 f->subclass = AST_FORMAT_SLINEAR; 00921 f->samples = FRAME_SIZE; 00922 f->datalen = FRAME_SIZE * 2; 00923 f->data = o->oss_read_buf + AST_FRIENDLY_OFFSET; 00924 if (o->boost != BOOST_SCALE) { /* scale and clip values */ 00925 int i, x; 00926 int16_t *p = (int16_t *) f->data; 00927 for (i = 0; i < f->samples; i++) { 00928 x = (p[i] * o->boost) / BOOST_SCALE; 00929 if (x > 32767) 00930 x = 32767; 00931 else if (x < -32768) 00932 x = -32768; 00933 p[i] = x; 00934 } 00935 } 00936 00937 f->offset = AST_FRIENDLY_OFFSET; 00938 return f; 00939 }
static struct ast_channel * oss_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 1033 of file chan_oss.c.
References AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, find_desc(), LOG_NOTICE, LOG_WARNING, oss_new(), and chan_oss_pvt::owner.
01034 { 01035 struct ast_channel *c; 01036 struct chan_oss_pvt *o = find_desc(data); 01037 01038 ast_log(LOG_WARNING, "oss_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data); 01039 if (o == NULL) { 01040 ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data); 01041 /* XXX we could default to 'dsp' perhaps ? */ 01042 return NULL; 01043 } 01044 if ((format & AST_FORMAT_SLINEAR) == 0) { 01045 ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format); 01046 return NULL; 01047 } 01048 if (o->owner) { 01049 ast_log(LOG_NOTICE, "Already have a call (chan %p) on the OSS channel\n", o->owner); 01050 *cause = AST_CAUSE_BUSY; 01051 return NULL; 01052 } 01053 c = oss_new(o, NULL, NULL, AST_STATE_DOWN); 01054 if (c == NULL) { 01055 ast_log(LOG_WARNING, "Unable to create new OSS channel\n"); 01056 return NULL; 01057 } 01058 return c; 01059 }
static int oss_text | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 776 of file chan_oss.c.
References ast_verbose().
00777 { 00778 /* print received messages */ 00779 ast_verbose(" << Console Received text %s >> \n", text); 00780 return 0; 00781 }
static int oss_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 856 of file chan_oss.c.
References chan_oss_pvt::cursound, ast_frame::data, ast_frame::datalen, chan_oss_pvt::nosound, chan_oss_pvt::oss_write_buf, chan_oss_pvt::oss_write_dst, soundcard_writeframe(), and ast_channel::tech_pvt.
00857 { 00858 int src; 00859 struct chan_oss_pvt *o = c->tech_pvt; 00860 00861 /* Immediately return if no sound is enabled */ 00862 if (o->nosound) 00863 return 0; 00864 /* Stop any currently playing sound */ 00865 o->cursound = -1; 00866 /* 00867 * we could receive a block which is not a multiple of our 00868 * FRAME_SIZE, so buffer it locally and write to the device 00869 * in FRAME_SIZE chunks. 00870 * Keep the residue stored for future use. 00871 */ 00872 src = 0; /* read position into f->data */ 00873 while (src < f->datalen) { 00874 /* Compute spare room in the buffer */ 00875 int l = sizeof(o->oss_write_buf) - o->oss_write_dst; 00876 00877 if (f->datalen - src >= l) { /* enough to fill a frame */ 00878 memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l); 00879 soundcard_writeframe(o, (short *) o->oss_write_buf); 00880 src += l; 00881 o->oss_write_dst = 0; 00882 } else { /* copy residue */ 00883 l = f->datalen - src; 00884 memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l); 00885 src += l; /* but really, we are done */ 00886 o->oss_write_dst += l; 00887 } 00888 } 00889 return 0; 00890 }
static void ring | ( | struct chan_oss_pvt * | o, | |
int | x | |||
) | [static] |
Definition at line 784 of file chan_oss.c.
References chan_oss_pvt::sndcmd.
Referenced by ast_extension_state2(), console_answer(), console_answer_deprecated(), ind_load_module(), oss_answer(), oss_call(), oss_hangup(), and oss_indicate().
00785 { 00786 write(o->sndcmd[1], &x, sizeof(x)); 00787 }
static void send_sound | ( | struct chan_oss_pvt * | o | ) | [static] |
Definition at line 546 of file chan_oss.c.
References ast_log(), chan_oss_pvt::cursound, sound::data, sound::datalen, FRAME_SIZE, LOG_WARNING, chan_oss_pvt::nosound, sound::repeat, s, sound::samplen, chan_oss_pvt::sampsent, silence, sound::silencelen, and soundcard_writeframe().
00547 { 00548 short myframe[FRAME_SIZE]; 00549 int ofs, l, start; 00550 int l_sampsent = o->sampsent; 00551 struct sound *s; 00552 00553 if (o->cursound < 0) /* no sound to send */ 00554 return; 00555 00556 s = &sounds[o->cursound]; 00557 00558 for (ofs = 0; ofs < FRAME_SIZE; ofs += l) { 00559 l = s->samplen - l_sampsent; /* # of available samples */ 00560 if (l > 0) { 00561 start = l_sampsent % s->datalen; /* source offset */ 00562 if (l > FRAME_SIZE - ofs) /* don't overflow the frame */ 00563 l = FRAME_SIZE - ofs; 00564 if (l > s->datalen - start) /* don't overflow the source */ 00565 l = s->datalen - start; 00566 bcopy(s->data + start, myframe + ofs, l * 2); 00567 if (0) 00568 ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs); 00569 l_sampsent += l; 00570 } else { /* end of samples, maybe some silence */ 00571 static const short silence[FRAME_SIZE] = { 0, }; 00572 00573 l += s->silencelen; 00574 if (l > 0) { 00575 if (l > FRAME_SIZE - ofs) 00576 l = FRAME_SIZE - ofs; 00577 bcopy(silence, myframe + ofs, l * 2); 00578 l_sampsent += l; 00579 } else { /* silence is over, restart sound if loop */ 00580 if (s->repeat == 0) { /* last block */ 00581 o->cursound = -1; 00582 o->nosound = 0; /* allow audio data */ 00583 if (ofs < FRAME_SIZE) /* pad with silence */ 00584 bcopy(silence, myframe + ofs, (FRAME_SIZE - ofs) * 2); 00585 } 00586 l_sampsent = 0; 00587 } 00588 } 00589 } 00590 l = soundcard_writeframe(o, myframe); 00591 if (l > 0) 00592 o->sampsent = l_sampsent; /* update status */ 00593 }
static int setformat | ( | struct chan_oss_pvt * | o, | |
int | mode | |||
) | [static] |
Definition at line 665 of file chan_oss.c.
References ast_log(), ast_verbose(), DEFAULT_SAMPLE_RATE, chan_oss_pvt::device, chan_oss_pvt::duplex, ast_channel::fds, fmt, chan_oss_pvt::frags, chan_oss_pvt::lastopen, LOG_WARNING, chan_oss_pvt::M_FULL, chan_oss_pvt::M_READ, chan_oss_pvt::M_UNSET, chan_oss_pvt::M_WRITE, O_CLOSE, option_verbose, chan_oss_pvt::owner, chan_oss_pvt::sounddev, VERBOSE_PREFIX_2, WARN_frag, WARN_speed, and chan_oss_pvt::warned.
Referenced by console_hangup(), console_hangup_deprecated(), oss_hangup(), oss_new(), sound_thread(), soundcard_writeframe(), and store_config().
00666 { 00667 int fmt, desired, res, fd; 00668 00669 if (o->sounddev >= 0) { 00670 ioctl(o->sounddev, SNDCTL_DSP_RESET, 0); 00671 close(o->sounddev); 00672 o->duplex = M_UNSET; 00673 o->sounddev = -1; 00674 } 00675 if (mode == O_CLOSE) /* we are done */ 00676 return 0; 00677 if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000) 00678 return -1; /* don't open too often */ 00679 o->lastopen = ast_tvnow(); 00680 fd = o->sounddev = open(o->device, mode | O_NONBLOCK); 00681 if (fd < 0) { 00682 ast_log(LOG_WARNING, "Unable to re-open DSP device %s: %s\n", o->device, strerror(errno)); 00683 return -1; 00684 } 00685 if (o->owner) 00686 o->owner->fds[0] = fd; 00687 00688 #if __BYTE_ORDER == __LITTLE_ENDIAN 00689 fmt = AFMT_S16_LE; 00690 #else 00691 fmt = AFMT_S16_BE; 00692 #endif 00693 res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt); 00694 if (res < 0) { 00695 ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n"); 00696 return -1; 00697 } 00698 switch (mode) { 00699 case O_RDWR: 00700 res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); 00701 /* Check to see if duplex set (FreeBSD Bug) */ 00702 res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt); 00703 if (res == 0 && (fmt & DSP_CAP_DUPLEX)) { 00704 if (option_verbose > 1) 00705 ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n"); 00706 o->duplex = M_FULL; 00707 }; 00708 break; 00709 case O_WRONLY: 00710 o->duplex = M_WRITE; 00711 break; 00712 case O_RDONLY: 00713 o->duplex = M_READ; 00714 break; 00715 } 00716 00717 fmt = 0; 00718 res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt); 00719 if (res < 0) { 00720 ast_log(LOG_WARNING, "Failed to set audio device to mono\n"); 00721 return -1; 00722 } 00723 fmt = desired = DEFAULT_SAMPLE_RATE; /* 8000 Hz desired */ 00724 res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt); 00725 00726 if (res < 0) { 00727 ast_log(LOG_WARNING, "Failed to set audio device to mono\n"); 00728 return -1; 00729 } 00730 if (fmt != desired) { 00731 if (!(o->warned & WARN_speed)) { 00732 ast_log(LOG_WARNING, 00733 "Requested %d Hz, got %d Hz -- sound may be choppy\n", 00734 desired, fmt); 00735 o->warned |= WARN_speed; 00736 } 00737 } 00738 /* 00739 * on Freebsd, SETFRAGMENT does not work very well on some cards. 00740 * Default to use 256 bytes, let the user override 00741 */ 00742 if (o->frags) { 00743 fmt = o->frags; 00744 res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt); 00745 if (res < 0) { 00746 if (!(o->warned & WARN_frag)) { 00747 ast_log(LOG_WARNING, 00748 "Unable to set fragment size -- sound may be choppy\n"); 00749 o->warned |= WARN_frag; 00750 } 00751 } 00752 } 00753 /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */ 00754 res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; 00755 res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res); 00756 /* it may fail if we are in half duplex, never mind */ 00757 return 0; 00758 }
static void* sound_thread | ( | void * | arg | ) | [static] |
Definition at line 595 of file chan_oss.c.
References ast_log(), ast_select(), chan_oss_pvt::cursound, sound::ind, LOG_WARNING, MAX, chan_oss_pvt::nosound, O_CLOSE, chan_oss_pvt::owner, chan_oss_pvt::sampsent, send_sound(), setformat(), chan_oss_pvt::sndcmd, and chan_oss_pvt::sounddev.
00596 { 00597 char ign[4096]; 00598 struct chan_oss_pvt *o = (struct chan_oss_pvt *) arg; 00599 00600 /* 00601 * Just in case, kick the driver by trying to read from it. 00602 * Ignore errors - this read is almost guaranteed to fail. 00603 */ 00604 read(o->sounddev, ign, sizeof(ign)); 00605 for (;;) { 00606 fd_set rfds, wfds; 00607 int maxfd, res; 00608 00609 FD_ZERO(&rfds); 00610 FD_ZERO(&wfds); 00611 FD_SET(o->sndcmd[0], &rfds); 00612 maxfd = o->sndcmd[0]; /* pipe from the main process */ 00613 if (o->cursound > -1 && o->sounddev < 0) 00614 setformat(o, O_RDWR); /* need the channel, try to reopen */ 00615 else if (o->cursound == -1 && o->owner == NULL) 00616 setformat(o, O_CLOSE); /* can close */ 00617 if (o->sounddev > -1) { 00618 if (!o->owner) { /* no one owns the audio, so we must drain it */ 00619 FD_SET(o->sounddev, &rfds); 00620 maxfd = MAX(o->sounddev, maxfd); 00621 } 00622 if (o->cursound > -1) { 00623 FD_SET(o->sounddev, &wfds); 00624 maxfd = MAX(o->sounddev, maxfd); 00625 } 00626 } 00627 /* ast_select emulates linux behaviour in terms of timeout handling */ 00628 res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL); 00629 if (res < 1) { 00630 ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno)); 00631 sleep(1); 00632 continue; 00633 } 00634 if (FD_ISSET(o->sndcmd[0], &rfds)) { 00635 /* read which sound to play from the pipe */ 00636 int i, what = -1; 00637 00638 read(o->sndcmd[0], &what, sizeof(what)); 00639 for (i = 0; sounds[i].ind != -1; i++) { 00640 if (sounds[i].ind == what) { 00641 o->cursound = i; 00642 o->sampsent = 0; 00643 o->nosound = 1; /* block audio from pbx */ 00644 break; 00645 } 00646 } 00647 if (sounds[i].ind == -1) 00648 ast_log(LOG_WARNING, "invalid sound index: %d\n", what); 00649 } 00650 if (o->sounddev > -1) { 00651 if (FD_ISSET(o->sounddev, &rfds)) /* read and ignore errors */ 00652 read(o->sounddev, ign, sizeof(ign)); 00653 if (FD_ISSET(o->sounddev, &wfds)) 00654 send_sound(o); 00655 } 00656 } 00657 return NULL; /* Never reached */ 00658 }
static int soundcard_writeframe | ( | struct chan_oss_pvt * | o, | |
short * | data | |||
) | [static] |
Definition at line 512 of file chan_oss.c.
References ast_log(), FRAME_SIZE, LOG_WARNING, chan_oss_pvt::queuesize, setformat(), chan_oss_pvt::sounddev, used_blocks(), and chan_oss_pvt::w_errors.
Referenced by oss_write(), and send_sound().
00513 { 00514 int res; 00515 00516 if (o->sounddev < 0) 00517 setformat(o, O_RDWR); 00518 if (o->sounddev < 0) 00519 return 0; /* not fatal */ 00520 /* 00521 * Nothing complex to manage the audio device queue. 00522 * If the buffer is full just drop the extra, otherwise write. 00523 * XXX in some cases it might be useful to write anyways after 00524 * a number of failures, to restart the output chain. 00525 */ 00526 res = used_blocks(o); 00527 if (res > o->queuesize) { /* no room to write a block */ 00528 if (o->w_errors++ == 0 && (oss_debug & 0x4)) 00529 ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors); 00530 return 0; 00531 } 00532 o->w_errors = 0; 00533 return write(o->sounddev, ((void *) data), FRAME_SIZE * 2); 00534 }
static void store_boost | ( | struct chan_oss_pvt * | o, | |
char * | s | |||
) | [static] |
Definition at line 1572 of file chan_oss.c.
References ast_log(), chan_oss_pvt::boost, BOOST_MAX, BOOST_SCALE, and LOG_WARNING.
Referenced by do_boost(), and store_config().
01573 { 01574 double boost = 0; 01575 if (sscanf(s, "%lf", &boost) != 1) { 01576 ast_log(LOG_WARNING, "invalid boost <%s>\n", s); 01577 return; 01578 } 01579 if (boost < -BOOST_MAX) { 01580 ast_log(LOG_WARNING, "boost %s too small, using %d\n", s, -BOOST_MAX); 01581 boost = -BOOST_MAX; 01582 } else if (boost > BOOST_MAX) { 01583 ast_log(LOG_WARNING, "boost %s too large, using %d\n", s, BOOST_MAX); 01584 boost = BOOST_MAX; 01585 } 01586 boost = exp(log(10) * boost / 20) * BOOST_SCALE; 01587 o->boost = boost; 01588 ast_log(LOG_WARNING, "setting boost %s to %d\n", s, o->boost); 01589 }
static void store_callerid | ( | struct chan_oss_pvt * | o, | |
char * | s | |||
) | [static] |
Definition at line 1727 of file chan_oss.c.
References ast_callerid_split(), chan_oss_pvt::cid_name, and chan_oss_pvt::cid_num.
Referenced by store_config().
01728 { 01729 ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num)); 01730 }
static struct chan_oss_pvt* store_config | ( | struct ast_config * | cfg, | |
char * | ctg | |||
) | [static, read] |
Definition at line 1735 of file chan_oss.c.
References asprintf, ast_calloc, ast_jb_read_conf(), ast_log(), ast_pthread_create_background, ast_strdup, ast_strlen_zero(), ast_variable_browse(), ast_verbose(), chan_oss_pvt::autoanswer, chan_oss_pvt::autohangup, chan_oss_pvt::ctx, DEV_DSP, chan_oss_pvt::device, chan_oss_pvt::duplex, error(), chan_oss_pvt::ext, chan_oss_pvt::frags, free, global_jbconf, chan_oss_pvt::language, chan_oss_pvt::lastopen, LOG_ERROR, LOG_WARNING, M_BOOL, M_END, M_F, chan_oss_pvt::M_FULL, M_START, M_STR, M_UINT, chan_oss_pvt::mixer_cmd, chan_oss_pvt::mohinterpret, ast_variable::name, chan_oss_pvt::name, chan_oss_pvt::next, ast_variable::next, option_verbose, chan_oss_pvt::overridecontext, chan_oss_pvt::queuesize, setformat(), chan_oss_pvt::sndcmd, sound_thread(), chan_oss_pvt::sthread, store_boost(), store_callerid(), store_mixer(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module().
01736 { 01737 struct ast_variable *v; 01738 struct chan_oss_pvt *o; 01739 01740 if (ctg == NULL) { 01741 o = &oss_default; 01742 ctg = "general"; 01743 } else { 01744 if (!(o = ast_calloc(1, sizeof(*o)))) 01745 return NULL; 01746 *o = oss_default; 01747 /* "general" is also the default thing */ 01748 if (strcmp(ctg, "general") == 0) { 01749 o->name = ast_strdup("dsp"); 01750 oss_active = o->name; 01751 goto openit; 01752 } 01753 o->name = ast_strdup(ctg); 01754 } 01755 01756 strcpy(o->mohinterpret, "default"); 01757 01758 o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */ 01759 /* fill other fields from configuration */ 01760 for (v = ast_variable_browse(cfg, ctg); v; v = v->next) { 01761 M_START(v->name, v->value); 01762 01763 /* handle jb conf */ 01764 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 01765 continue; 01766 01767 M_BOOL("autoanswer", o->autoanswer) 01768 M_BOOL("autohangup", o->autohangup) 01769 M_BOOL("overridecontext", o->overridecontext) 01770 M_STR("device", o->device) 01771 M_UINT("frags", o->frags) 01772 M_UINT("debug", oss_debug) 01773 M_UINT("queuesize", o->queuesize) 01774 M_STR("context", o->ctx) 01775 M_STR("language", o->language) 01776 M_STR("mohinterpret", o->mohinterpret) 01777 M_STR("extension", o->ext) 01778 M_F("mixer", store_mixer(o, v->value)) 01779 M_F("callerid", store_callerid(o, v->value)) 01780 M_F("boost", store_boost(o, v->value)) 01781 M_END(; 01782 ); 01783 } 01784 if (ast_strlen_zero(o->device)) 01785 ast_copy_string(o->device, DEV_DSP, sizeof(o->device)); 01786 if (o->mixer_cmd) { 01787 char *cmd; 01788 01789 asprintf(&cmd, "mixer %s", o->mixer_cmd); 01790 ast_log(LOG_WARNING, "running [%s]\n", cmd); 01791 system(cmd); 01792 free(cmd); 01793 } 01794 if (o == &oss_default) /* we are done with the default */ 01795 return NULL; 01796 01797 openit: 01798 #if TRYOPEN 01799 if (setformat(o, O_RDWR) < 0) { /* open device */ 01800 if (option_verbose > 0) { 01801 ast_verbose(VERBOSE_PREFIX_2 "Device %s not detected\n", ctg); 01802 ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding " "'noload=chan_oss.so' in /etc/asterisk/modules.conf\n"); 01803 } 01804 goto error; 01805 } 01806 if (o->duplex != M_FULL) 01807 ast_log(LOG_WARNING, "XXX I don't work right with non " "full-duplex sound cards XXX\n"); 01808 #endif /* TRYOPEN */ 01809 if (pipe(o->sndcmd) != 0) { 01810 ast_log(LOG_ERROR, "Unable to create pipe\n"); 01811 goto error; 01812 } 01813 ast_pthread_create_background(&o->sthread, NULL, sound_thread, o); 01814 /* link into list of devices */ 01815 if (o != &oss_default) { 01816 o->next = oss_default.next; 01817 oss_default.next = o; 01818 } 01819 return o; 01820 01821 error: 01822 if (o != &oss_default) 01823 free(o); 01824 return NULL; 01825 }
static void store_mixer | ( | struct chan_oss_pvt * | o, | |
char * | s | |||
) | [static] |
Definition at line 1708 of file chan_oss.c.
References ast_log(), ast_strdup, free, LOG_WARNING, and chan_oss_pvt::mixer_cmd.
Referenced by store_config().
01709 { 01710 int i; 01711 01712 for (i = 0; i < strlen(s); i++) { 01713 if (!isalnum(s[i]) && index(" \t-/", s[i]) == NULL) { 01714 ast_log(LOG_WARNING, "Suspect char %c in mixer cmd, ignoring:\n\t%s\n", s[i], s); 01715 return; 01716 } 01717 } 01718 if (o->mixer_cmd) 01719 free(o->mixer_cmd); 01720 o->mixer_cmd = ast_strdup(s); 01721 ast_log(LOG_WARNING, "setting mixer %s\n", s); 01722 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1865 of file chan_oss.c.
References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, chan_oss_pvt::next, chan_oss_pvt::owner, chan_oss_pvt::sndcmd, and chan_oss_pvt::sounddev.
01866 { 01867 struct chan_oss_pvt *o; 01868 01869 ast_channel_unregister(&oss_tech); 01870 ast_cli_unregister_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry)); 01871 01872 for (o = oss_default.next; o; o = o->next) { 01873 close(o->sounddev); 01874 if (o->sndcmd[0] > 0) { 01875 close(o->sndcmd[0]); 01876 close(o->sndcmd[1]); 01877 } 01878 if (o->owner) 01879 ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD); 01880 if (o->owner) /* XXX how ??? */ 01881 return -1; 01882 /* XXX what about the thread ? */ 01883 /* XXX what about the memory allocated ? */ 01884 } 01885 return 0; 01886 }
static int used_blocks | ( | struct chan_oss_pvt * | o | ) | [static] |
Definition at line 490 of file chan_oss.c.
References ast_log(), LOG_WARNING, chan_oss_pvt::sounddev, chan_oss_pvt::total_blocks, WARN_used_blocks, and chan_oss_pvt::warned.
Referenced by soundcard_writeframe().
00491 { 00492 struct audio_buf_info info; 00493 00494 if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) { 00495 if (!(o->warned & WARN_used_blocks)) { 00496 ast_log(LOG_WARNING, "Error reading output space\n"); 00497 o->warned |= WARN_used_blocks; 00498 } 00499 return 1; 00500 } 00501 00502 if (o->total_blocks == 0) { 00503 if (0) /* debugging */ 00504 ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments); 00505 o->total_blocks = info.fragments; 00506 } 00507 00508 return o->total_blocks - info.fragments; 00509 }
char active_usage[] [static] |
Initial value:
"Usage: console active [device]\n" " If used without a parameter, displays which device is the current\n" "console. If a device is specified, the console sound device is changed to\n" "the device specified.\n"
Definition at line 1563 of file chan_oss.c.
char answer_usage[] [static] |
Initial value:
"Usage: console answer\n" " Answers an incoming call on the console (OSS) channel.\n"
Definition at line 1175 of file chan_oss.c.
char autoanswer_usage[] [static] |
Initial value:
"Usage: console autoanswer [on|off]\n" " Enables or disables autoanswer feature. If used without\n" " argument, displays the current on/off status of autoanswer.\n" " The default value of autoanswer is in 'oss.conf'.\n"
Definition at line 1122 of file chan_oss.c.
struct ast_cli_entry cli_oss[] [static] |
Definition at line 1657 of file chan_oss.c.
struct ast_cli_entry cli_oss_active_deprecated [static] |
Initial value:
{ { "console", NULL }, console_active_deprecated, NULL, NULL }
Definition at line 1652 of file chan_oss.c.
struct ast_cli_entry cli_oss_answer_deprecated [static] |
Initial value:
{ { "answer", NULL }, console_answer_deprecated, NULL, NULL }
Definition at line 1602 of file chan_oss.c.
struct ast_cli_entry cli_oss_autoanswer_deprecated [static] |
Initial value:
{ { "autoanswer", NULL }, console_autoanswer_deprecated, NULL, NULL, autoanswer_complete_deprecated }
Definition at line 1642 of file chan_oss.c.
struct ast_cli_entry cli_oss_boost_deprecated [static] |
Initial value:
{ { "oss", "boost", NULL }, do_boost, NULL, NULL }
Definition at line 1647 of file chan_oss.c.
struct ast_cli_entry cli_oss_dial_deprecated [static] |
Initial value:
{ { "dial", NULL }, console_dial_deprecated, NULL, NULL }
Definition at line 1617 of file chan_oss.c.
struct ast_cli_entry cli_oss_flash_deprecated [static] |
Initial value:
{ { "flash", NULL }, console_flash_deprecated, NULL, NULL }
Definition at line 1612 of file chan_oss.c.
struct ast_cli_entry cli_oss_hangup_deprecated [static] |
Initial value:
{ { "hangup", NULL }, console_hangup_deprecated, NULL, NULL }
Definition at line 1607 of file chan_oss.c.
struct ast_cli_entry cli_oss_mute_deprecated [static] |
Initial value:
{ { "mute", NULL }, console_mute_deprecated, NULL, NULL }
Definition at line 1622 of file chan_oss.c.
struct ast_cli_entry cli_oss_send_text_deprecated [static] |
Initial value:
{ { "send", "text", NULL }, console_sendtext_deprecated, NULL, NULL }
Definition at line 1637 of file chan_oss.c.
struct ast_cli_entry cli_oss_transfer_deprecated [static] |
Initial value:
{ { "transfer", NULL }, console_transfer_deprecated, NULL, NULL }
Definition at line 1632 of file chan_oss.c.
struct ast_cli_entry cli_oss_unmute_deprecated [static] |
Initial value:
{ { "unmute", NULL }, console_unmute_deprecated, NULL, NULL }
Definition at line 1627 of file chan_oss.c.
char* config = "oss.conf" [static] |
Definition at line 284 of file chan_oss.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 86 of file chan_oss.c.
char dial_usage[] [static] |
Initial value:
"Usage: console dial [extension[@context]]\n" " Dials a given extension (and context if specified)\n"
Definition at line 1403 of file chan_oss.c.
char flash_usage[] [static] |
Initial value:
"Usage: console flash\n" " Flashes the call currently placed on the console.\n"
Definition at line 1317 of file chan_oss.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 93 of file chan_oss.c.
char hangup_usage[] [static] |
Initial value:
"Usage: console hangup\n" " Hangs up any call currently placed on the console.\n"
Definition at line 1275 of file chan_oss.c.
char mute_usage[] [static] |
Initial value:
"Usage: console mute\nMutes the microphone\n"
Definition at line 1431 of file chan_oss.c.
char* oss_active [static] |
Definition at line 400 of file chan_oss.c.
int oss_debug [static] |
Definition at line 286 of file chan_oss.c.
struct chan_oss_pvt oss_default [static] |
Definition at line 385 of file chan_oss.c.
struct ast_channel_tech oss_tech [static] |
Definition at line 418 of file chan_oss.c.
char sendtext_usage[] [static] |
Initial value:
"Usage: console send text <message>\n" " Sends a text message for display on the remote terminal.\n"
Definition at line 1233 of file chan_oss.c.
Definition at line 303 of file chan_oss.c.
char tdesc[] = "OSS Console Channel Driver" [static] |
Definition at line 416 of file chan_oss.c.
char transfer_usage[] [static] |
Initial value:
"Usage: console transfer <extension>[@context]\n" " Transfers the currently connected call to the given extension (and\n" "context if specified)\n"
Definition at line 1514 of file chan_oss.c.
char unmute_usage[] [static] |
Initial value:
"Usage: console unmute\nUnmutes the microphone\n"
Definition at line 1450 of file chan_oss.c.