From e0de929e2024548d9e05c706f6c30e2160913373 Mon Sep 17 00:00:00 2001 From: Matthew Fredrickson Date: Fri, 21 Oct 2005 20:20:22 +0000 Subject: [PATCH] Updates so that one can do user to user IE transmission git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@253 2fbb986a-6c06-0410-b554-c9c1f0a7f128 --- libpri.h | 9 ++++++++- pri.c | 11 +++++++++++ pri_internal.h | 1 + q931.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/libpri.h b/libpri.h index f4ef1eb..c41cc17 100755 --- a/libpri.h +++ b/libpri.h @@ -274,6 +274,7 @@ typedef struct pri_event_ringing { int progress; int progressmask; q931_call *call; + char useruserinfo[260]; /* User->User info */ } pri_event_ringing; typedef struct pri_event_answer { @@ -283,6 +284,7 @@ typedef struct pri_event_answer { int progress; int progressmask; q931_call *call; + char useruserinfo[260]; /* User->User info */ } pri_event_answer; typedef struct pri_event_facname { @@ -312,7 +314,7 @@ typedef struct pri_event_ring { char redirectingname[256]; /* Redirecting name */ int redirectingreason; /* Reason for redirect */ int callingplanrdnis; /* Dialing plan of Redirecting Number */ - char useruserinfo[256]; /* User->User info */ + char useruserinfo[260]; /* User->User info */ int flexible; /* Are we flexible with our channel selection? */ int cref; /* Call Reference Number */ int ctype; /* Call type (see PRI_TRANS_CAP_* */ @@ -335,6 +337,7 @@ typedef struct pri_event_hangup { int cref; q931_call *call; /* Opaque call pointer */ long aoc_units; /* Advise of Charge number of charged units */ + char useruserinfo[260]; /* User->User info */ } pri_event_hangup; typedef struct pri_event_restart_ack { @@ -519,6 +522,10 @@ extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1); extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete); extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres); extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason); +/* Set the user user field. Warning! don't send binary data accross this field */ +extern void pri_sr_set_useruser(struct pri_sr *sr, char *userchars); + +extern void pri_call_set_useruser(q931_call *sr, char *userchars); extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req); diff --git a/pri.c b/pri.c index 64fe5f8..74fa44b 100755 --- a/pri.c +++ b/pri.c @@ -247,6 +247,17 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste return p; } +void pri_call_set_useruser(q931_call *c, char *userchars) +{ + if (userchars) + libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo)); +} + +void pri_sr_set_useruser(struct pri_sr *sr, char *userchars) +{ + sr->useruserinfo = userchars; +} + int pri_restart(struct pri *pri) { /* Restart Q.921 layer */ diff --git a/pri_internal.h b/pri_internal.h index d075c83..b0a7064 100755 --- a/pri_internal.h +++ b/pri_internal.h @@ -129,6 +129,7 @@ struct pri_sr { int redirectingpres; int redirectingreason; int justsignalling; + char *useruserinfo; }; /* Internal switch types */ diff --git a/q931.c b/q931.c index ef5dbea..d2585ac 100755 --- a/q931.c +++ b/q931.c @@ -969,6 +969,27 @@ static FUNC_RECV(receive_user_user) return 0; } +static FUNC_SEND(transmit_user_user) +{ + int datalen = strlen(call->useruserinfo); + if (datalen > 0) { + /* Restricted to 35 characters */ + if (msgtype == Q931_USER_INFORMATION) { + if (datalen > 260) + datalen = 260; + } else { + if (datalen > 35) + datalen = 35; + } + ie->data[0] = 4; /* IA5 characters */ + memcpy(&ie->data[1], call->useruserinfo, datalen); + call->useruserinfo[0] = '\0'; + return datalen + 3; + } + + return 0; +} + static char *prog2str(int prog) { static struct msgtype progs[] = { @@ -1927,7 +1948,7 @@ struct ie ies[] = { { 1, Q931_IE_KEYPAD_FACILITY, "Keypad Facility", dump_keypad_facility, receive_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 }, + { 1, Q931_IE_USER_USER, "User-User", dump_user_user, receive_user_user, transmit_user_user }, { 1, Q931_IE_ESCAPE_FOR_EXT, "Escape for Extension" }, { 1, Q931_IE_CALL_STATUS, "Call Status" }, { 1, Q931_IE_CHANGE_STATUS, "Change Status" }, @@ -2504,7 +2525,7 @@ int q931_call_proceeding(struct pri *pri, q931_call *c, int channel, int info) return send_message(pri, c, Q931_CALL_PROCEEDING, call_proceeding_ies); } #ifndef ALERTING_NO_PROGRESS -static int alerting_ies[] = { Q931_PROGRESS_INDICATOR, -1 }; +static int alerting_ies[] = { Q931_PROGRESS_INDICATOR, Q931_IE_USER_USER -1 }; #else static int alerting_ies[] = { -1 }; #endif @@ -2627,7 +2648,7 @@ int q931_connect(struct pri *pri, q931_call *c, int channel, int nonisdn) return send_message(pri, c, Q931_CONNECT, connect_ies); } -static int release_ies[] = { Q931_CAUSE, -1 }; +static int release_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 }; int q931_release(struct pri *pri, q931_call *c, int cause) { @@ -2675,7 +2696,7 @@ int q931_restart(struct pri *pri, int channel) return send_message(pri, c, Q931_RESTART, restart_ies); } -static int disconnect_ies[] = { Q931_CAUSE, -1 }; +static int disconnect_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 }; int q931_disconnect(struct pri *pri, q931_call *c, int cause) { @@ -2695,7 +2716,7 @@ int q931_disconnect(struct pri *pri, q931_call *c, int cause) return 0; } -static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, +static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY, Q931_IE_USER_USER, Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 }; static int gr303_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 }; @@ -2773,6 +2794,9 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) } else return -1; + if (req->useruserinfo) + libpri_copy_string(c->useruserinfo, req->useruserinfo, sizeof(c->useruserinfo)); + if (req->nonisdn && (pri->switchtype == PRI_SWITCH_NI2)) c->progressmask = PRI_PROG_CALLER_NOT_ISDN; else @@ -2797,7 +2821,7 @@ int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req) } -static int release_complete_ies[] = { -1 }; +static int release_complete_ies[] = { Q931_IE_USER_USER, -1 }; static int q931_release_complete(struct pri *pri, q931_call *c, int cause) { @@ -3018,6 +3042,7 @@ int q931_receive(struct pri *pri, q931_h *h, int len) case Q931_CONNECT: case Q931_ALERTING: case Q931_PROGRESS: + c->useruserinfo[0] = '\0'; c->cause = -1; case Q931_CALL_PROCEEDING: c->progress = -1; @@ -3037,11 +3062,13 @@ int q931_receive(struct pri *pri, q931_h *h, int len) if (c->retranstimer) pri_schedule_del(pri, c->retranstimer); c->retranstimer = 0; + c->useruserinfo[0] = '\0'; break; case Q931_RELEASE_COMPLETE: if (c->retranstimer) pri_schedule_del(pri, c->retranstimer); c->retranstimer = 0; + c->useruserinfo[0] = '\0'; case Q931_STATUS: c->cause = -1; c->causecode = -1; @@ -3225,6 +3252,7 @@ int q931_receive(struct pri *pri, q931_h *h, int len) libpri_copy_string(pri->ev.ring.redirectingnum, c->redirectingnum, sizeof(pri->ev.ring.redirectingnum)); libpri_copy_string(pri->ev.ring.redirectingname, c->redirectingname, sizeof(pri->ev.ring.redirectingname)); libpri_copy_string(pri->ev.ring.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); + c->useruserinfo[0] = '\0'; pri->ev.ring.redirectingreason = c->redirectingreason; pri->ev.ring.origredirectingreason = c->origredirectingreason; pri->ev.ring.flexible = ! (c->chanflags & FLAG_EXCLUSIVE); @@ -3250,6 +3278,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.ringing.call = c; pri->ev.ringing.progress = c->progress; pri->ev.ringing.progressmask = c->progressmask; + libpri_copy_string(pri->ev.ringing.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); + c->useruserinfo[0] = '\0'; return Q931_RES_HAVEEVENT; case Q931_CONNECT: if (c->newcall) { @@ -3268,6 +3298,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.answer.call = c; pri->ev.answer.progress = c->progress; pri->ev.answer.progressmask = c->progressmask; + libpri_copy_string(pri->ev.answer.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); + c->useruserinfo[0] = '\0'; q931_connect_acknowledge(pri, c); if (c->justsignalling) { /* Make sure WE release when we initiatie a signalling only connection */ q931_release(pri, c, PRI_CAUSE_NORMAL_CLEARING); @@ -3381,6 +3413,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.hangup.cref = c->cr; pri->ev.hangup.cause = c->cause; pri->ev.hangup.call = c; + libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); + c->useruserinfo[0] = '\0'; /* Free resources */ if (c->alive) { pri->ev.e = PRI_EVENT_HANGUP; @@ -3414,6 +3448,8 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.hangup.cause = c->cause; pri->ev.hangup.call = c; pri->ev.hangup.aoc_units = c->aoc_units; + libpri_copy_string(pri->ev.hangup.useruserinfo, c->useruserinfo, sizeof(pri->ev.ring.useruserinfo)); + c->useruserinfo[0] = '\0'; /* Don't send release complete if they send us release while we sent it, assume a NULL state */ if (c->newcall)