From 3ac6881c22bce18091f19b06958ac66016bf9a32 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Tue, 27 Oct 2009 08:02:16 +0100 Subject: [PATCH 1/1] Added keypad forwarding, keypad parameter, chan_lcr keypad option 'k'. modified: README modified: action.cpp modified: apppbx.cpp modified: chan_lcr.c modified: chan_lcr.h modified: dss1.cpp modified: joinpbx.cpp modified: joinpbx.h modified: message.h modified: route.c modified: route.h --- README | 3 +++ action.cpp | 6 ++++++ apppbx.cpp | 15 +++++++++++---- chan_lcr.c | 29 +++++++++++++++++++++++++---- chan_lcr.h | 2 ++ dss1.cpp | 7 +++++-- joinpbx.cpp | 15 +++++++++++---- joinpbx.h | 2 +- message.h | 1 + route.c | 7 +++++-- route.h | 1 + 11 files changed, 71 insertions(+), 17 deletions(-) diff --git a/README b/README index 8c0d65a..8a33e07 100644 --- a/README +++ b/README @@ -522,5 +522,8 @@ Changes after Version 1.6 - Added experimental CCITT No. 5 signalling system. (for educational purpose) - Added socket owner/group options to options.conf - Fixed/simplyfied config parser. The last digit of the last line was ignored. +- Added Keypad facility + -> New option for chan_lcr: 'k' + -> New dialing parameter for LCR: keypad diff --git a/action.cpp b/action.cpp index 8c06137..d720dbe 100644 --- a/action.cpp +++ b/action.cpp @@ -213,6 +213,12 @@ void EndpointAppPBX::action_dialing_external(void) if ((rparam = routeparam(e_action, PARAM_PREFIX))) SPRINT(dialinginfo.id, "%s%s", rparam->string_value, e_extdialing); + /* process keypad */ + if ((rparam = routeparam(e_action, PARAM_KEYPAD))) { + SCPY(dialinginfo.keypad, dialinginfo.id); + dialinginfo.id[0] = '\0'; + } + /* process number complete */ if ((rparam = routeparam(e_action, PARAM_COMPLETE))) if ((rparam = routeparam(e_action, PARAM_PREFIX))) diff --git a/apppbx.cpp b/apppbx.cpp index 06e3d92..9dee717 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -1128,9 +1128,12 @@ void EndpointAppPBX::out_setup(void) /* *********************** external call */ default: - PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: '%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id); + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) dialing external: called='%s' keypad='%s'\n", ea_endpoint->ep_serial, e_dialinginfo.id, e_dialinginfo.keypad); /* call to extenal interfaces */ - p = e_dialinginfo.id; + if (e_dialinginfo.keypad[0]) + p = e_dialinginfo.keypad; + else + p = e_dialinginfo.id; do { number[0] = '\0'; while(*p!=',' && *p!='\0') @@ -1168,7 +1171,10 @@ void EndpointAppPBX::out_setup(void) earlyb = mISDNport->earlyb; PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name); memset(&dialinginfo, 0, sizeof(dialinginfo)); - SCPY(dialinginfo.id, number); + if (e_dialinginfo.keypad[0]) + SCPY(dialinginfo.keypad, number); + else + SCPY(dialinginfo.id, number); dialinginfo.itype = INFO_ITYPE_ISDN; dialinginfo.ntype = e_dialinginfo.ntype; portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, mISDNport->earlyb); @@ -1180,7 +1186,6 @@ void EndpointAppPBX::out_setup(void) //printf("EXTERNAL caller=%s,id=%s,dial=%s\n", param.setup.networkid, param.setup.callerinfo.id, param.setup.dialinginfo.id); message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_SETUP); memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info)); - SCPY(message->param.setup.dialinginfo.id, number); memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info)); memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info)); memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info)); @@ -3844,6 +3849,8 @@ void EndpointAppPBX::logmessage(int message_type, union parameter *param, unsign } if (param->setup.dialinginfo.id[0]) add_trace("dialing", NULL, "%s", param->setup.dialinginfo.id); + if (param->setup.dialinginfo.keypad[0]) + add_trace("keypad", NULL, "%s", param->setup.dialinginfo.keypad); if (param->setup.dialinginfo.display[0]) add_trace("display", NULL, "%s", param->setup.dialinginfo.display); if (param->setup.dialinginfo.sending_complete) diff --git a/chan_lcr.c b/chan_lcr.c index d1b57e6..e50847c 100644 --- a/chan_lcr.c +++ b/chan_lcr.c @@ -555,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); } @@ -586,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; @@ -657,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); } @@ -1927,8 +1942,13 @@ static int lcr_digit(struct ast_channel *ast, char digit) 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 @@ -2742,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" ); diff --git a/chan_lcr.h b/chan_lcr.h index 60a64fd..5905ea1 100644 --- a/chan_lcr.h +++ b/chan_lcr.h @@ -65,6 +65,8 @@ struct chan_call { /* echo cancel pipeline by option */ int tx_gain, rx_gain; /* gain by option */ + int keypad; + /* use keypad to dial number */ unsigned char bf_key[56]; int bf_len; /* blowfish crypt key */ struct ast_dsp *dsp; /* ast dsp processor for fax/tone detection */ diff --git a/dss1.cpp b/dss1.cpp index 1cb52d1..e318aa3 100644 --- a/dss1.cpp +++ b/dss1.cpp @@ -402,7 +402,7 @@ void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m) int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user; int exclusive, channel; int ret; - unsigned char keypad[32] = ""; + unsigned char keypad[33] = ""; unsigned char useruser[128]; int useruser_len = 0, useruser_protocol; class Endpoint *epoint; @@ -746,7 +746,7 @@ void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m) void Pdss1::information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m) { int type, plan; - unsigned char keypad[32] = "", display[128] = ""; + unsigned char keypad[33] = "", display[128] = ""; struct lcr_msg *message; l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_IND, DIRECTION_IN); @@ -2098,6 +2098,9 @@ void Pdss1::message_setup(unsigned int epoint_id, int message_id, union paramete enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max); SCPY(p_m_d_queue, p_dialinginfo.id + max); } + /* keypad */ + if (p_dialinginfo.keypad[0]) + enc_ie_keypad(l3m, (unsigned char *)p_dialinginfo.keypad); /* sending complete */ if (p_dialinginfo.sending_complete) enc_ie_complete(l3m, 1); diff --git a/joinpbx.cpp b/joinpbx.cpp index af070b1..d21daf3 100644 --- a/joinpbx.cpp +++ b/joinpbx.cpp @@ -855,12 +855,17 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par if (param->setup.dialinginfo.itype == INFO_ITYPE_ISDN_EXTENSION) { numbers = param->setup.dialinginfo.id; while((number = strsep(&numbers, ","))) { - if (out_setup(epoint_id, message_type, param, number)) + if (out_setup(epoint_id, message_type, param, number, NULL)) + return; // join destroyed + } + numbers = param->setup.dialinginfo.id; + while((number = strsep(&numbers, ","))) { + if (out_setup(epoint_id, message_type, param, NULL, number)) return; // join destroyed } break; } - if (out_setup(epoint_id, message_type, param, NULL)) + if (out_setup(epoint_id, message_type, param, NULL, NULL)) return; // join destroyed break; @@ -945,7 +950,7 @@ int track_notify(int oldstate, int notify) * if other outgoing endpoints already exists, they are release as well. * note: if this functions fails, it will destroy its own join object! */ -int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter *param, char *newnumber) +int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter *param, char *newnumber, char *newkeypad) { struct join_relation *relation; struct lcr_msg *message; @@ -974,7 +979,9 @@ int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter memcpy(&message->param, param, sizeof(union parameter)); if (newnumber) SCPY(message->param.setup.dialinginfo.id, newnumber); - PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id); + if (newkeypad) + SCPY(message->param.setup.dialinginfo.keypad, newkeypad); + PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s' keypad='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id, message->param.setup.dialinginfo.keypad); message_put(message); return(0); } diff --git a/joinpbx.h b/joinpbx.h index 3e275b7..18e38c0 100644 --- a/joinpbx.h +++ b/joinpbx.h @@ -70,7 +70,7 @@ class JoinPBX : public Join void bridge_data(unsigned int epoint_from, struct join_relation *relation_from, union parameter *param); void remove_relation(struct join_relation *relation); struct join_relation *add_relation(void); - int out_setup(unsigned int epoint_id, int message, union parameter *param, char *newnumber); + int out_setup(unsigned int epoint_id, int message, union parameter *param, char *newnumber, char *newkeypad); void play_jingle(int in); }; diff --git a/message.h b/message.h index 0849f54..63abc65 100644 --- a/message.h +++ b/message.h @@ -178,6 +178,7 @@ struct dialing_info { int ntype; /* type of number */ int sending_complete; /* end of dialing */ char display[84]; /* display information */ + char keypad[33]; /* send keypad facility */ }; /* call-info structure CONNECT */ diff --git a/route.c b/route.c index 4fecf38..126424f 100644 --- a/route.c +++ b/route.c @@ -242,13 +242,16 @@ struct param_defs param_defs[] = { { PARAM_ON, "on", PARAM_TYPE_STRING, "on=[init|hangup]", "Defines if the action is executed on call init or on hangup."}, + { PARAM_KEYPAD, + "keypad", PARAM_TYPE_NULL, + "keypad", "Use 'keypad facility' for dialing, instead of 'called number'."}, { 0, NULL, 0, NULL, NULL} }; struct action_defs action_defs[] = { { ACTION_EXTERNAL, "extern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call, - PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT, + PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT, "Call is routed to extern number as dialed."}, { ACTION_INTERNAL, "intern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call, @@ -256,7 +259,7 @@ struct action_defs action_defs[] = { "Call is routed to intern extension as given by the dialed number or specified by option."}, { ACTION_OUTDIAL, "outdial", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call, - PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT, + PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT, "Same as 'extern'"}, { ACTION_REMOTE, "remote", &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call, diff --git a/route.h b/route.h index 837aebd..3530ef4 100644 --- a/route.h +++ b/route.h @@ -146,6 +146,7 @@ enum { /* defines when a statement should be executed */ #define PARAM_CONTEXT (1LL<<45) #define PARAM_EXTEN (1LL<<46) #define PARAM_ON (1LL<<47) +#define PARAM_KEYPAD (1LL<<48) /* action index * NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!! -- 2.13.6