From 8d6d58ab091232b0ce6ec5e49fd0658b0aef1de8 Mon Sep 17 00:00:00 2001 From: Matthew Fredrickson Date: Thu, 1 Dec 2005 17:59:56 +0000 Subject: [PATCH] Add in keypad facility transmission support git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@271 2fbb986a-6c06-0410-b554-c9c1f0a7f128 --- libpri.h | 4 ++++ pri.c | 8 ++++++++ pri_internal.h | 2 +- pri_q931.h | 2 ++ q931.c | 52 +++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/libpri.h b/libpri.h index 0f8aa5c..b97b9c4 100644 --- a/libpri.h +++ b/libpri.h @@ -462,6 +462,10 @@ extern int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int in /* Send a digit in overlap mode */ extern int pri_information(struct pri *pri, q931_call *call, char digit); +#define PRI_KEYPAD_FACILITY +/* Send a keypad facility string of digits */ +extern int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits); + /* Answer the incomplete(call without called number) call on the given channel. Set non-isdn to non-zero if you are not connecting to ISDN equipment */ extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn); diff --git a/pri.c b/pri.c index 74fa44b..1cb8069 100644 --- a/pri.c +++ b/pri.c @@ -471,6 +471,14 @@ int pri_information(struct pri *pri, q931_call *call, char digit) return q931_information(pri, call, digit); } +int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits) +{ + if (!pri || !call || !digits || !digits[0]) + return -1; + + return q931_keypad_facility(pri, call, digits); +} + int pri_notify(struct pri *pri, q931_call *call, int channel, int info) { if (!pri || !call) diff --git a/pri_internal.h b/pri_internal.h index b0a7064..a057d92 100644 --- a/pri_internal.h +++ b/pri_internal.h @@ -206,7 +206,7 @@ struct q931_call { char callernum[256]; char callername[256]; - char digitbuf[64]; /* Buffer for digits that come in KEYPAD_FACILITY */ + char keypad_digits[64]; /* Buffer for digits that come in KEYPAD_FACILITY */ int ani2; /* ANI II */ diff --git a/pri_q931.h b/pri_q931.h index 6b3fe50..cdb49b8 100644 --- a/pri_q931.h +++ b/pri_q931.h @@ -257,6 +257,8 @@ extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int non extern int q931_information(struct pri *pri, q931_call *call, char digit); +extern int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits); + extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn); extern int q931_release(struct pri *pri, q931_call *call, int cause); diff --git a/q931.c b/q931.c index f025e16..022643e 100644 --- a/q931.c +++ b/q931.c @@ -1371,7 +1371,8 @@ static FUNC_DUMP(dump_keypad_facility) if (ie->len == 0 || ie->len > sizeof(tmp)) return; - libpri_copy_string(tmp, (char *) ie->data, sizeof(tmp)); + memcpy(tmp, ie->data, ie->len); + tmp[ie->len] = '\0'; pri_message(pri, "%c Keypad Facility (len=%2d) [ %s ]\n", prefix, ie->len, tmp ); } @@ -1382,18 +1383,37 @@ static FUNC_RECV(receive_keypad_facility) if (ie->len == 0) return -1; - if (ie->len > (sizeof(call->digitbuf) - 1)) - mylen = (sizeof(call->digitbuf) - 1); + if (ie->len > (sizeof(call->keypad_digits) - 1)) + mylen = (sizeof(call->keypad_digits) - 1); else mylen = ie->len; - memcpy(call->digitbuf, ie->data, mylen); - - call->digitbuf[mylen] = 0; + memcpy(call->keypad_digits, ie->data, mylen); + call->keypad_digits[mylen] = 0; return 0; } +static FUNC_SEND(transmit_keypad_facility) +{ + int sublen; + + sublen = strlen(call->keypad_digits); + + if (sublen > 32) { + sublen = 32; + call->keypad_digits[32] = '\0'; + } + + if (sublen) { + libpri_copy_string(ie->data, (char *) call->keypad_digits, sizeof(call->keypad_digits)); + /* Make sure we clear the field */ + call->keypad_digits[0] = '\0'; + return sublen + 2; + } else + return 0; +} + static FUNC_DUMP(dump_display) { int x, y; @@ -1947,7 +1967,7 @@ struct ie ies[] = { { 1, Q931_IE_NOTIFY_IND, "Notification Indicator", dump_notify, receive_notify, transmit_notify }, { 1, Q931_DISPLAY, "Display", dump_display, receive_display, transmit_display }, { 1, Q931_IE_TIME_DATE, "Date/Time", dump_time_date }, - { 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility }, + { 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_keypad_facility, transmit_keypad_facility }, { 0, Q931_IE_SIGNAL, "Signal", dump_signal }, { 1, Q931_IE_SWITCHHOOK, "Switch-hook" }, { 1, Q931_IE_USER_USER, "User-User", dump_user_user, receive_user_user, transmit_user_user }, @@ -2430,15 +2450,23 @@ static int q931_status(struct pri *pri, q931_call *c, int cause) return send_message(pri, cur, Q931_STATUS, status_ies); } -static int information_ies[] = { Q931_CALLED_PARTY_NUMBER, -1 }; +static int information_ies[] = { Q931_IE_KEYPAD_FACILITY, Q931_CALLED_PARTY_NUMBER, -1 }; int q931_information(struct pri *pri, q931_call *c, char digit) { - c->callednum[0]=digit; - c->callednum[1]='\0'; + c->callednum[0] = digit; + c->callednum[1] = '\0'; return send_message(pri, c, Q931_INFORMATION, information_ies); } +static int keypad_facility_ies[] = { Q931_IE_KEYPAD_FACILITY, -1 }; + +int q931_keypad_facility(struct pri *pri, q931_call *call, char *digits) +{ + libpri_copy_string(call->keypad_digits, digits, sizeof(call->keypad_digits)); + return send_message(pri, call, Q931_INFORMATION, keypad_facility_ies); +} + static int restart_ack_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 }; static int restart_ack(struct pri *pri, q931_call *c) @@ -3502,7 +3530,9 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.e = PRI_EVENT_KEYPAD_DIGIT; pri->ev.digit.call = c; pri->ev.digit.channel = c->channelno | (c->ds1no << 8); - libpri_copy_string(pri->ev.digit.digits, c->digitbuf, sizeof(pri->ev.digit.digits)); + libpri_copy_string(pri->ev.digit.digits, c->keypad_digits, sizeof(pri->ev.digit.digits)); + /* Make sure we clear it out before we return */ + c->keypad_digits[0] = '\0'; return Q931_RES_HAVEEVENT; } pri->ev.e = PRI_EVENT_INFO_RECEIVED;