X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=chan_lcr.c;h=e50847c53e4b99fdad1821896b00136841ed3c9b;hp=9f293389f393dce8fcbaf78fd00e795e15f334c0;hb=3ac6881c22bce18091f19b06958ac66016bf9a32;hpb=57ca16397c03cb2b002b532a3762293767282873 diff --git a/chan_lcr.c b/chan_lcr.c index 9f29338..e50847c 100644 --- a/chan_lcr.c +++ b/chan_lcr.c @@ -129,6 +129,8 @@ it is called from ast_channel process which has already locked ast_channel. #define HAVE_ATTRIBUTE_always_inline 1 #define HAVE_ARPA_INET_H 1 #define HAVE_TIMERSUB 1 +#define HAVE_STRTOQ 1 +#define HAVE_INET_ATON 1 #include #ifdef LCR_FOR_ASTERISK @@ -252,8 +254,7 @@ struct chan_call *find_call_ref(unsigned int ref) struct chan_call *call = call_first; int assigned = (ref > 0); - while(call) - { + while(call) { if (call->ref == ref && call->ref_was_assigned == assigned) break; call = call->next; @@ -265,23 +266,19 @@ void free_call(struct chan_call *call) { struct chan_call **temp = &call_first; - while(*temp) - { - if (*temp == call) - { + while(*temp) { + if (*temp == call) { *temp = (*temp)->next; if (call->pipe[0] > -1) close(call->pipe[0]); if (call->pipe[1] > -1) close(call->pipe[1]); - if (call->bchannel) - { + if (call->bchannel) { if (call->bchannel->call != call) CERROR(call, NULL, "Linked bchannel structure has no link to us.\n"); call->bchannel->call = NULL; } - if (call->bridge_call) - { + if (call->bridge_call) { if (call->bridge_call->bridge_call != call) CERROR(call, NULL, "Linked call structure has no link to us.\n"); call->bridge_call->bridge_call = NULL; @@ -325,11 +322,9 @@ unsigned short new_bridge_id(void) unsigned short id = 1; /* search for lowest bridge id that is not in use and not 0 */ - while(id) - { + while(id) { call = call_first; - while(call) - { + while(call) { if (call->bridge_id == id) break; call = call->next; @@ -389,8 +384,7 @@ void apply_opt(struct chan_call *call, char *data) string[sizeof(string)-1] = '\0'; /* parse options */ - while((opt = strsep(&p, ":"))) - { + while((opt = strsep(&p, ":"))) { switch(opt[0]) { case 'd': if (opt[1] == '\0') { @@ -412,7 +406,11 @@ void apply_opt(struct chan_call *call, char *data) break; } CDEBUG(call, call->ast, "Option 'n' (no DTMF).\n"); - call->no_dtmf = 1; + if (call->dsp_dtmf) { + call->dsp_dtmf = 0; + if (call->bchannel) + bchannel_dtmf(call->bchannel, 0); + } break; case 'c': if (opt[1] == '\0') { @@ -431,8 +429,7 @@ void apply_opt(struct chan_call *call, char *data) break; } i = 0; - while(*key) - { + while(*key) { if (*key>='0' && *key<='9') call->bf_key[i] = (*key-'0') << 8; else if (*key>='a' && *key<='f') @@ -503,7 +500,12 @@ void apply_opt(struct chan_call *call, char *data) ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_CNG_DETECT); #endif #ifdef LCR_FOR_ASTERISK + #ifdef DSP_FEATURE_DTMF_DETECT ast_dsp_set_features(call->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT); + #else + ast_dsp_set_features(call->dsp, DSP_FEATURE_DIGIT_DETECT| DSP_FEATURE_FAX_DETECT); + #endif + #endif if (!call->trans) #ifdef LCR_FOR_CALLWEAVER @@ -553,6 +555,15 @@ void apply_opt(struct chan_call *call, char *data) bchannel_gain(call->bchannel, call->tx_gain, 1); } break; + case 'k': + if (opt[1] != '\0') { + CERROR(call, call->ast, "Option 'k' (keypad) expects no parameter.\n", opt); + break; + } + CDEBUG(call, call->ast, "Option 'k' (keypad).\n"); + if (!call->keypad) + call->keypad = 1; + break; default: CERROR(call, call->ast, "Option '%s' unknown.\n", opt); } @@ -584,7 +595,10 @@ static void send_setup_to_lcr(struct chan_call *call) memset(&newparam, 0, sizeof(union parameter)); newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN; newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN; - strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1); + if (call->keypad) + strncpy(newparam.setup.dialinginfo.keypad, call->dialstring, sizeof(newparam.setup.dialinginfo.keypad)-1); + else + strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1); strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1); newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN; newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN; @@ -594,14 +608,12 @@ static void send_setup_to_lcr(struct chan_call *call) strncpy(newparam.setup.callerinfo.id, call->cid_num, sizeof(newparam.setup.callerinfo.id)-1); if (call->cid_name[0]) strncpy(newparam.setup.callerinfo.name, call->cid_name, sizeof(newparam.setup.callerinfo.name)-1); - if (call->cid_rdnis[0]) - { + if (call->cid_rdnis[0]) { strncpy(newparam.setup.redirinfo.id, call->cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1); newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN; newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN; } - switch(ast->cid.cid_pres & AST_PRES_RESTRICTION) - { + switch(ast->cid.cid_pres & AST_PRES_RESTRICTION) { case AST_PRES_RESTRICTED: newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED; break; @@ -612,8 +624,7 @@ static void send_setup_to_lcr(struct chan_call *call) default: newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED; } - switch(ast->cid.cid_ton) - { + switch(ast->cid.cid_ton) { case 4: newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER; break; @@ -658,7 +669,10 @@ static void send_dialque_to_lcr(struct chan_call *call) /* send setup message to LCR */ memset(&newparam, 0, sizeof(union parameter)); - strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1); + if (call->keypad) + strncpy(newparam.information.keypad, call->dialque, sizeof(newparam.information.keypad)-1); + else + strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1); call->dialque[0] = '\0'; send_message(MESSAGE_INFORMATION, call->ref, &newparam); } @@ -712,17 +726,14 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", exten, ast->context, complete?"yes":"no"); - if (complete) - { + if (complete) { /* if not match */ - if (!ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) - { + if (!ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) { CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at context '%s' - releasing.\n", exten, ast->context); cause = 1; goto release; } - if (!ast_exists_extension(ast, ast->context, exten, 1, call->oad)) - { + if (!ast_exists_extension(ast, ast->context, exten, 1, call->oad)) { CDEBUG(call, ast, "Got 'sending complete', but extension '%s' would match at context '%s', if more digits would be dialed - releasing.\n", exten, ast->context); cause = 28; goto release; @@ -738,8 +749,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c goto start; } - if (ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) - { + if (ast_canmatch_extension(ast, ast->context, exten, 1, call->oad)) { /* send setup acknowledge to lcr */ if (call->state != CHAN_LCR_STATE_IN_DIALING) { memset(&newparam, 0, sizeof(union parameter)); @@ -790,8 +800,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c #endif ret = ast_pbx_start(ast); - if (ret < 0) - { + if (ret < 0) { cause = (ret==-2)?34:27; goto release; } @@ -818,8 +827,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel); #endif - if (!ast) - { + if (!ast) { /* release */ CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n"); send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL); @@ -846,8 +854,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet ast->cid.cid_name = strdup(param->setup.callerinfo.name); if (param->setup.redirinfo.id[0]) ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international)); - switch (param->setup.callerinfo.present) - { + switch (param->setup.callerinfo.present) { case INFO_PRESENT_ALLOWED: ast->cid.cid_pres = AST_PRES_ALLOWED; break; @@ -857,8 +864,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet default: ast->cid.cid_pres = AST_PRES_UNAVAILABLE; } - switch (param->setup.callerinfo.ntype) - { + switch (param->setup.callerinfo.ntype) { case INFO_NTYPE_SUBSCRIBER: ast->cid.cid_ton = 4; break; @@ -957,7 +963,7 @@ static void lcr_in_connect(struct chan_call *call, int message_type, union param memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info)); /* queue event to asterisk */ if (call->ast && call->pbx_started) - strncat(call->queue_string, "A", sizeof(call->queue_string)-1); + strncat(call->queue_string, "N", sizeof(call->queue_string)-1); } /* @@ -977,8 +983,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa /* if bridge, forward disconnect and return */ #ifdef TODO feature flag - if (call->bridge_call) - { + if (call->bridge_call) { CDEBUG(call, call->ast, "Only signal disconnect via bridge.\n"); bridge_message_if_bridged(call, message_type, param); return; @@ -990,8 +995,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa /* change to release state */ call->state = CHAN_LCR_STATE_RELEASE; /* queue release asterisk */ - if (ast) - { + if (ast) { ast->hangupcause = call->cause; if (call->pbx_started) strcpy(call->queue_string, "H"); // overwrite other indications @@ -1015,22 +1019,19 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param /* change to release state */ call->state = CHAN_LCR_STATE_RELEASE; /* copy release info */ - if (!call->cause) - { + if (!call->cause) { call->cause = param->disconnectinfo.cause; call->location = param->disconnectinfo.location; } /* if we have an asterisk instance, queue hangup, else we are done */ - if (ast) - { + if (ast) { ast->hangupcause = call->cause; if (call->pbx_started) strcpy(call->queue_string, "H"); else { ast_hangup(ast); // call will be destroyed here } - } else - { + } else { free_call(call); } @@ -1048,8 +1049,7 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p if (!ast) return; /* pbx not started */ - if (!call->pbx_started) - { + if (!call->pbx_started) { CDEBUG(call, call->ast, "Asterisk not started, adding digits to number.\n"); strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1); lcr_start_pbx(call, ast, param->information.sending_complete); @@ -1111,6 +1111,34 @@ static void lcr_in_facility(struct chan_call *call, int message_type, union para } /* + * incoming pattern from LCR + */ +static void lcr_in_pattern(struct chan_call *call, int message_type, union parameter *param) +{ + union parameter newparam; + + CDEBUG(call, call->ast, "Incomming pattern indication from LCR.\n"); + + if (!call->ast) return; + + /* pattern are indicated only once */ + if (call->has_pattern) + return; + call->has_pattern = 1; + + /* request bchannel */ + if (!call->bchannel) { + CDEBUG(call, call->ast, "Requesting B-channel.\n"); + memset(&newparam, 0, sizeof(union parameter)); + newparam.bchannel.type = BCHANNEL_REQUEST; + send_message(MESSAGE_BCHANNEL, call->ref, &newparam); + } + /* queue PROGRESS, because tones are available */ + if (call->ast && call->pbx_started) + strncat(call->queue_string, "T", sizeof(call->queue_string)-1); +} + +/* * got dtmf from bchannel (locked state) */ void lcr_in_dtmf(struct chan_call *call, int val) @@ -1123,6 +1151,11 @@ void lcr_in_dtmf(struct chan_call *call, int val) if (!call->pbx_started) return; + if (!call->dsp_dtmf) { + CDEBUG(call, call->ast, "Recognised DTMF digit '%c', but ignoring. This is fixed in later mISDN driver.\n", val); + return; + } + CDEBUG(call, call->ast, "Recognised DTMF digit '%c'.\n", val); digit[0] = val; digit[1] = '\0'; @@ -1141,21 +1174,17 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) memset(&newparam, 0, sizeof(union parameter)); /* handle bchannel message*/ - if (message_type == MESSAGE_BCHANNEL) - { - switch(param->bchannel.type) - { + if (message_type == MESSAGE_BCHANNEL) { + switch(param->bchannel.type) { case BCHANNEL_ASSIGN: CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx) for ref %d\n", param->bchannel.handle, ref); - if ((bchannel = find_bchannel_handle(param->bchannel.handle))) - { + if ((bchannel = find_bchannel_handle(param->bchannel.handle))) { CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle); return(-1); } /* create bchannel */ bchannel = alloc_bchannel(param->bchannel.handle); - if (!bchannel) - { + if (!bchannel) { CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle); return(-1); } @@ -1164,24 +1193,21 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) bchannel->b_tx_gain = param->bchannel.tx_gain; bchannel->b_rx_gain = param->bchannel.rx_gain; strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1); - if (param->bchannel.crypt_len && param->bchannel.crypt_len <= sizeof(bchannel->b_bf_key)) - { + if (param->bchannel.crypt_len && param->bchannel.crypt_len <= sizeof(bchannel->b_bf_key)) { bchannel->b_bf_len = param->bchannel.crypt_len; memcpy(bchannel->b_bf_key, param->bchannel.crypt, param->bchannel.crypt_len); } bchannel->b_txdata = 0; - bchannel->b_dtmf = 1; bchannel->b_tx_dejitter = 1; /* in case, ref is not set, this bchannel instance must * be created until it is removed again by LCR */ /* link to call */ call = find_call_ref(ref); - if (call) - { + if (call) { bchannel->call = call; call->bchannel = bchannel; - if (call->dtmf) + if (call->dsp_dtmf) bchannel_dtmf(bchannel, 1); if (call->bf_len) bchannel_blowfish(bchannel, call->bf_key, call->bf_len); @@ -1214,8 +1240,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) case BCHANNEL_REMOVE: CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle); - if (!(bchannel = find_bchannel_handle(param->bchannel.handle))) - { + if (!(bchannel = find_bchannel_handle(param->bchannel.handle))) { CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle); return(-1); } @@ -1236,14 +1261,11 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) } /* handle new ref */ - if (message_type == MESSAGE_NEWREF) - { - if (param->direction) - { + if (message_type == MESSAGE_NEWREF) { + if (param->direction) { /* new ref from lcr */ CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref); - if (!ref || find_call_ref(ref)) - { + if (!ref || find_call_ref(ref)) { CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref); return(-1); } @@ -1254,14 +1276,14 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) /* set ref */ call->ref = ref; call->ref_was_assigned = 1; + /* set dtmf (default, use option 'n' to disable */ + call->dsp_dtmf = 1; /* wait for setup (or release from asterisk) */ - } else - { + } else { /* new ref, as requested from this remote application */ CDEBUG(NULL, NULL, "Received new ref by LCR, as requested from chan_lcr. (ref=%ld)\n", ref); call = find_call_ref(0); - if (!call) - { + if (!call) { /* send release, if ref does not exist */ CDEBUG(NULL, NULL, "No call found, that requests a ref.\n"); send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); @@ -1274,8 +1296,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) if (call->state == CHAN_LCR_STATE_OUT_PREPARE) send_setup_to_lcr(call); /* release if asterisk has signed off */ - else if (call->state == CHAN_LCR_STATE_RELEASE) - { + else if (call->state == CHAN_LCR_STATE_RELEASE) { /* send release */ if (call->cause) send_release_and_import(call, call->cause, call->location); @@ -1290,22 +1311,19 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) } /* check ref */ - if (!ref) - { + if (!ref) { CERROR(NULL, NULL, "Received message %d without ref.\n", message_type); return(-1); } call = find_call_ref(ref); - if (!call) - { + if (!call) { /* ignore ref that is not used (anymore) */ CDEBUG(NULL, NULL, "Message %d from LCR ignored, because no call instance found.\n", message_type); return(0); } /* handle messages */ - switch(message_type) - { + switch(message_type) { case MESSAGE_SETUP: lcr_in_setup(call, message_type, param); break; @@ -1347,6 +1365,8 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) break; case MESSAGE_PATTERN: // audio available from LCR + if (!call->has_pattern) + lcr_in_pattern(call, message_type, param); break; case MESSAGE_NOPATTERN: // audio not available from LCR @@ -1416,29 +1436,23 @@ int handle_socket(void) /* read from socket */ len = read(lcr_sock, &msg, sizeof(msg)); - if (len == 0) - { + if (len == 0) { CERROR(NULL, NULL, "Socket closed.\n"); return(-1); // socket closed } - if (len > 0) - { - if (len != sizeof(msg)) - { + if (len > 0) { + if (len != sizeof(msg)) { CERROR(NULL, NULL, "Socket short read. (len %d)\n", len); return(-1); // socket error } - if (msg.message != ADMIN_MESSAGE) - { + if (msg.message != ADMIN_MESSAGE) { CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message); return(-1); } receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param); work = 1; - } else - { - if (errno != EWOULDBLOCK) - { + } else { + if (errno != EWOULDBLOCK) { CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno); return(-1); } @@ -1449,15 +1463,12 @@ int handle_socket(void) return(work); admin = admin_first; len = write(lcr_sock, &admin->msg, sizeof(msg)); - if (len == 0) - { + if (len == 0) { CERROR(NULL, NULL, "Socket closed.\n"); return(-1); // socket closed } - if (len > 0) - { - if (len != sizeof(msg)) - { + if (len > 0) { + if (len != sizeof(msg)) { CERROR(NULL, NULL, "Socket short write. (len %d)\n", len); return(-1); // socket error } @@ -1466,10 +1477,8 @@ int handle_socket(void) free(admin); work = 1; - } else - { - if (errno != EWOULDBLOCK) - { + } else { + if (errno != EWOULDBLOCK) { CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno); return(-1); } @@ -1490,8 +1499,7 @@ int open_socket(void) union parameter param; /* open socket */ - if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - { + if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { CERROR(NULL, NULL, "Failed to create socket.\n"); return(lcr_sock); } @@ -1502,8 +1510,7 @@ int open_socket(void) sprintf(sock_address.sun_path, SOCKET_NAME, options.lock); /* connect socket */ - if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0) - { + if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0) { close(lcr_sock); lcr_sock = -1; CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path); @@ -1511,8 +1518,7 @@ int open_socket(void) } /* set non-blocking io */ - if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0) - { + if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0) { close(lcr_sock); lcr_sock = -1; CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n"); @@ -1565,6 +1571,10 @@ static int queue_send(void) if (!ast_channel_trylock(ast)) { /* succeed */ while(*p) { switch (*p) { + case 'T': + CDEBUG(call, ast, "Sending queued PROGRESS to Asterisk.\n"); + ast_queue_control(ast, AST_CONTROL_PROGRESS); + break; case 'P': CDEBUG(call, ast, "Sending queued PROCEEDING to Asterisk.\n"); ast_queue_control(ast, AST_CONTROL_PROCEEDING); @@ -1574,7 +1584,7 @@ static int queue_send(void) ast_queue_control(ast, AST_CONTROL_RINGING); ast_setstate(ast, AST_STATE_RINGING); break; - case 'A': + case 'N': CDEBUG(call, ast, "Sending queued ANSWER to Asterisk.\n"); ast_queue_control(ast, AST_CONTROL_ANSWER); break; @@ -1582,10 +1592,10 @@ static int queue_send(void) CDEBUG(call, ast, "Sending queued HANGUP to Asterisk.\n"); ast_queue_hangup(ast); break; - case '1': case '2': case '3': case 'a': - case '4': case '5': case '6': case 'b': - case '7': case '8': case '9': case 'c': - case '*': case '0': case '#': case 'd': + case '1': case '2': case '3': case 'A': + case '4': case '5': case '6': case 'B': + case '7': case '8': case '9': case 'C': + case '*': case '0': case '#': case 'D': CDEBUG(call, ast, "Sending queued digit '%c' to Asterisk.\n", *p); /* send digit to asterisk */ memset(&fr, 0, sizeof(fr)); @@ -1609,7 +1619,7 @@ static int queue_send(void) break; default: - CDEBUG(call, ast, "Ignoring queued digit 0x%02d.\n", *p); + CDEBUG(call, ast, "Ignoring queued digit 0x%02x.\n", *p); } p++; } @@ -1725,8 +1735,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c CDEBUG(NULL, NULL, "Received request from Asterisk. (data=%s)\n", (char *)data); /* if socket is closed */ - if (lcr_sock < 0) - { + if (lcr_sock < 0) { CERROR(NULL, NULL, "Rejecting call from Asterisk, because LCR not running.\n"); ast_mutex_unlock(&chan_lock); return NULL; @@ -1734,8 +1743,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c /* create call instance */ call = alloc_call(); - if (!call) - { + if (!call) { /* failed to create instance */ ast_mutex_unlock(&chan_lock); return NULL; @@ -1751,8 +1759,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c ast = ast_channel_alloc(1); #endif - if (!ast) - { + if (!ast) { CERROR(NULL, NULL, "Failed to create Asterisk channel.\n"); free_call(call); /* failed to create instance */ @@ -1932,17 +1939,20 @@ static int lcr_digit(struct ast_channel *ast, char digit) CDEBUG(call, ast, "Received digit '%c' from Asterisk.\n", digit); /* send information or queue them */ - if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING) - { + if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING) { CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n"); memset(&newparam, 0, sizeof(union parameter)); - newparam.information.id[0] = digit; - newparam.information.id[1] = '\0'; + if (call->keypad) { + newparam.information.keypad[0] = digit; + newparam.information.keypad[1] = '\0'; + } else { + newparam.information.id[0] = digit; + newparam.information.id[1] = '\0'; + } send_message(MESSAGE_INFORMATION, call->ref, &newparam); } else if (!call->ref - && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP)) - { + && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP)) { CDEBUG(call, ast, "Queue digits, because we are in setup/dialing state and have no ref yet.\n"); *buf = digit; strncat(call->dialque, buf, strlen(call->dialque)-1); @@ -2024,11 +2034,6 @@ static int lcr_answer(struct ast_channel *ast) /* enable keypad */ // memset(&newparam, 0, sizeof(union parameter)); // send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam); - /* enable dtmf */ - if (call->no_dtmf) - CDEBUG(call, ast, "DTMF is disabled by option.\n"); - else - call->dtmf = 1; ast_mutex_unlock(&chan_lock); return 0; @@ -2057,8 +2062,7 @@ static int lcr_hangup(struct ast_channel *ast) /* disconnect asterisk, maybe not required */ ast->tech_pvt = NULL; ast->fds[0] = -1; - if (call->ref) - { + if (call->ref) { /* release */ CDEBUG(call, ast, "Releasing ref and freeing call instance.\n"); if (ast->hangupcause > 0) @@ -2070,16 +2074,13 @@ static int lcr_hangup(struct ast_channel *ast) if (!pthread_equal(tid, chan_tid)) ast_mutex_unlock(&chan_lock); return 0; - } else - { + } else { /* ref is not set, due to prepare setup or release */ - if (call->state == CHAN_LCR_STATE_RELEASE) - { + if (call->state == CHAN_LCR_STATE_RELEASE) { /* we get the response to our release */ CDEBUG(call, ast, "Freeing call instance, because we have no ref AND we are requesting no ref.\n"); free_call(call); - } else - { + } else { /* during prepare, we change to release state */ CDEBUG(call, ast, "We must wait until we received our ref, until we can free call instance.\n"); call->state = CHAN_LCR_STATE_RELEASE; @@ -2107,7 +2108,7 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *f) return -1; } if (call->bchannel && f->samples) - bchannel_transmit(call->bchannel, (unsigned char *)f->data, f->samples); + bchannel_transmit(call->bchannel, *((unsigned char **)&(f->data)), f->samples); ast_mutex_unlock(&chan_lock); return 0; } @@ -2228,7 +2229,7 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz break; case AST_CONTROL_RINGING: CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n"); - ast_setstate(ast, AST_STATE_RINGING); + ast_setstate(ast, AST_STATE_RING); if (call->state == CHAN_LCR_STATE_IN_SETUP || call->state == CHAN_LCR_STATE_IN_DIALING || call->state == CHAN_LCR_STATE_IN_PROCEEDING) { @@ -2239,6 +2240,16 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz call->state = CHAN_LCR_STATE_IN_ALERTING; } break; + case AST_CONTROL_PROGRESS: + CDEBUG(call, ast, "Received indicate AST_CONTROL_PROGRESS from Asterisk.\n"); + /* request bchannel */ + if (!call->bchannel) { + CDEBUG(call, ast, "Requesting B-channel.\n"); + memset(&newparam, 0, sizeof(union parameter)); + newparam.bchannel.type = BCHANNEL_REQUEST; + send_message(MESSAGE_BCHANNEL, call->ref, &newparam); + } + break; case -1: CDEBUG(call, ast, "Received indicate -1.\n"); res = -1; @@ -2481,16 +2492,14 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, ast_mutex_lock(&chan_lock); call1 = ast1->tech_pvt; call2 = ast2->tech_pvt; - if (call1 && call1->bridge_id) - { + if (call1 && call1->bridge_id) { call1->bridge_id = 0; if (call1->bchannel) bchannel_join(call1->bchannel, 0); if (call1->bridge_call) call1->bridge_call->bridge_call = NULL; } - if (call2 && call1->bridge_id) - { + if (call2 && call1->bridge_id) { call2->bridge_id = 0; if (call2->bchannel) bchannel_join(call2->bchannel, 0); @@ -2680,7 +2689,7 @@ int load_module(void) if (read_options() == 0) { CERROR(NULL, NULL, "%s", options_error); - #ifdef LCR_FOR_ASTERISK || ASTERISK_1_6 + #ifdef LCR_FOR_ASTERISK return AST_MODULE_LOAD_DECLINE; #endif @@ -2753,6 +2762,7 @@ int load_module(void) " vr - rxgain control\n" " vt - txgain control\n" " Volume changes at factor 2 ^ optarg.\n" + " k - use keypad to dial this call.\n" ); @@ -2767,8 +2777,7 @@ int load_module(void) #endif quit = 0; - if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0)) - { + if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0)) { /* failed to create thread */ bchannel_deinitialize(); close_socket();