From 6ccb8df10118e88891bfc6e06d491a9c01b13466 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Mon, 14 Jun 2004 02:48:24 +0000 Subject: [PATCH] Add notify support courtesy PCadach git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@110 2fbb986a-6c06-0410-b554-c9c1f0a7f128 --- libpri.h | 35 +++++++++++++++++++++++++++ pri_q931.h | 2 ++ q931.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/libpri.h b/libpri.h index 9fdea60..2c764c9 100755 --- a/libpri.h +++ b/libpri.h @@ -70,6 +70,7 @@ #define PRI_EVENT_PROCEEDING 13 /* When we get CALL_PROCEEDING or PROGRESS */ #define PRI_EVENT_SETUP_ACK 14 /* When we get SETUP_ACKNOWLEDGE */ #define PRI_EVENT_HANGUP_REQ 15 /* Requesting the higher layer to hangup */ +#define PRI_EVENT_NOTIFY 16 /* Notification received */ /* Simple states */ #define PRI_STATE_DOWN 0 @@ -184,6 +185,30 @@ #define PRI_LAYER_1_V120_RATE_ADAPT 0x28 #define PRI_LAYER_1_X31_RATE_ADAPT 0x29 +/* Notifications */ +#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */ +#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */ +#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */ +#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */ +#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */ +#define PRI_NOTIFY_CONF_ESTABLISHED 0x42 /* Conference established */ +#define PRI_NOTIFY_CONF_DISCONNECTED 0x43 /* Conference disconnected */ +#define PRI_NOTIFY_CONF_PARTY_ADDED 0x44 /* Other party added */ +#define PRI_NOTIFY_CONF_ISOLATED 0x45 /* Isolated */ +#define PRI_NOTIFY_CONF_REATTACHED 0x46 /* Reattached */ +#define PRI_NOTIFY_CONF_OTHER_ISOLATED 0x47 /* Other party isolated */ +#define PRI_NOTIFY_CONF_OTHER_REATTACHED 0x48 /* Other party reattached */ +#define PRI_NOTIFY_CONF_OTHER_SPLIT 0x49 /* Other party split */ +#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */ +#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */ +#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */ +#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */ +#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */ +#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */ +#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */ +#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */ +#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */ + #define PRI_COPY_DIGITS_CALLED_NUMBER typedef struct q931_call q931_call; @@ -268,6 +293,12 @@ typedef struct pri_event_setup_ack { int channel; } pri_event_setup_ack; +typedef struct pri_event_notify { + int e; + int channel; + int info; +} pri_event_notify; + typedef union { int e; pri_event_generic gen; /* Generic view */ @@ -281,6 +312,7 @@ typedef union { pri_event_restart_ack restartack; /* Restart Acknowledge */ pri_event_proceeding proceeding; /* Call proceeding & Progress */ pri_event_setup_ack setup_ack; /* SETUP_ACKNOWLEDGE structure */ + pri_event_notify notify; /* Notification */ } pri_event; struct pri; @@ -412,3 +444,6 @@ extern void pri_enslave(struct pri *master, struct pri *slave); #define PRI_GR303_SUPPORT #define PRI_ENSLAVE_SUPPORT #endif + +/* Send notification */ +extern int pri_notify(struct pri *pri, q931_call *c, int channel, int info); diff --git a/pri_q931.h b/pri_q931.h index aa551a7..102874d 100755 --- a/pri_q931.h +++ b/pri_q931.h @@ -246,6 +246,8 @@ extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info); +extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info); + extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info); extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn); diff --git a/q931.c b/q931.c index d962a0e..a8dd3fa 100755 --- a/q931.c +++ b/q931.c @@ -222,6 +222,8 @@ struct q931_call { int progloc; /* Progress Location */ int progress; /* Progress indicator */ + int notify; /* Notification */ + int causecode; /* Cause Coding */ int causeloc; /* Cause Location */ int cause; /* Cause of clearing */ @@ -1189,6 +1191,56 @@ static int transmit_sending_complete(struct pri *pri, q931_call *call, int msgty return 0; } +static char *notify2str(int info) +{ + /* ITU-T Q.763 */ + static struct msgtype notifies[] = { + { PRI_NOTIFY_USER_SUSPENDED, "User suspended" }, + { PRI_NOTIFY_USER_RESUMED, "User resumed" }, + { PRI_NOTIFY_BEARER_CHANGE, "Bearer service change (DSS1)" }, + { PRI_NOTIFY_ASN1_COMPONENT, "ASN.1 encoded component (DSS1)" }, + { PRI_NOTIFY_COMPLETION_DELAY, "Call completion delay" }, + { PRI_NOTIFY_CONF_ESTABLISHED, "Conference established" }, + { PRI_NOTIFY_CONF_DISCONNECTED, "Conference disconnected" }, + { PRI_NOTIFY_CONF_PARTY_ADDED, "Other party added" }, + { PRI_NOTIFY_CONF_ISOLATED, "Isolated" }, + { PRI_NOTIFY_CONF_REATTACHED, "Reattached" }, + { PRI_NOTIFY_CONF_OTHER_ISOLATED, "Other party isolated" }, + { PRI_NOTIFY_CONF_OTHER_REATTACHED, "Other party reattached" }, + { PRI_NOTIFY_CONF_OTHER_SPLIT, "Other party split" }, + { PRI_NOTIFY_CONF_OTHER_DISCONNECTED, "Other party disconnected" }, + { PRI_NOTIFY_CONF_FLOATING, "Conference floating" }, + { PRI_NOTIFY_WAITING_CALL, "Call is waiting call" }, + { PRI_NOTIFY_DIVERSION_ACTIVATED, "Diversion activated (DSS1)" }, + { PRI_NOTIFY_TRANSFER_ALERTING, "Call transfer, alerting" }, + { PRI_NOTIFY_TRANSFER_ACTIVE, "Call transfer, active" }, + { PRI_NOTIFY_REMOTE_HOLD, "Remote hold" }, + { PRI_NOTIFY_REMOTE_RETRIEVAL, "Remote retrieval" }, + { PRI_NOTIFY_CALL_DIVERTING, "Call is diverting" }, + }; + return code2str(info, notifies, sizeof(notifies) / sizeof(notifies[0])); +} + +static void dump_notify(q931_ie *ie, int len, char prefix) +{ + pri_message("%c Notification indicator (len=%2d): Ext: %d %s (%d)\n", prefix, len, ie->data[0] >> 7, notify2str(ie->data[0] & 0x7f), ie->data[0] & 0x7f); +} + +static int receive_notify(struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len) +{ + call->notify = ie->data[0] & 0x7F; + return 0; +} + +static int transmit_notify(struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len) +{ + if (call->notify >= 0) { + ie->data[0] = 0x80 | call->notify; + return 3; + } + return 0; +} + struct ie ies[] = { { NATIONAL_CHANGE_STATUS, "Change Status" }, { Q931_LOCKING_SHIFT, "Locking Shift" }, @@ -1225,7 +1277,7 @@ struct ie ies[] = { { Q931_IE_SEGMENTED_MSG, "Segmented Message" }, { Q931_IE_CALL_IDENTITY, "Call Identity", dump_call_identity }, { Q931_IE_ENDPOINT_ID, "Endpoint Identification" }, - { Q931_IE_NOTIFY_IND, "Notification Indicator" }, + { Q931_IE_NOTIFY_IND, "Notification Indicator", dump_notify, receive_notify, transmit_notify }, { Q931_DISPLAY, "Display", dump_display, receive_display, transmit_display }, { Q931_IE_TIME_DATE, "Date/Time", dump_time_date }, { Q931_IE_KEYPAD_FACILITY, "Keypad Facility" }, @@ -1593,6 +1645,17 @@ static int restart_ack(struct pri *pri, q931_call *c) return send_message(pri, c, Q931_RESTART_ACKNOWLEDGE, restart_ack_ies); } +static int notify_ies[] = { Q931_IE_NOTIFY_IND, -1 }; + +int q931_notify(struct pri *pri, q931_call *c, int channel, int info) +{ + if (info >= 0) + c->notify = info & 0x7F; + else + c->notify = -1; + return send_message(pri, c, Q931_NOTIFY, notify_ies); +} + #ifdef ALERTING_NO_PROGRESS static int call_progress_ies[] = { -1 }; #else @@ -2490,8 +2553,10 @@ int q931_receive(struct pri *pri, q931_h *h, int len) pri->ev.setup_ack.channel = c->channelno; return Q931_RES_HAVEEVENT; case Q931_NOTIFY: - /* Do nothing */ - break; + pri->ev.e = PRI_EVENT_NOTIFY; + pri->ev.notify.channel = c->channelno; + pri->ev.notify.info = c->notify; + return Q931_RES_HAVEEVENT; case Q931_USER_INFORMATION: case Q931_SEGMENT: case Q931_CONGESTION_CONTROL: