--- q931.orig.c 2004-03-15 00:53:25.000000000 -0500 +++ q931.c 2004-03-30 15:40:57.000000000 -0500 @@ -133,6 +133,28 @@ { PRI_CAUSE_INTERWORKING, "Interworking, unspecified" }, }; +struct msgtype nsf_services[] { + { PRI_NETWORK_SPEC_FAC_SERVICE_SDN, "SDN "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_TOLL_FREE_MEGACOM, "Toll Free MEGACOM "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_MEGACOM, "MEGACOM "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_ACCUNET, "ACCUNET Switched Digital Service "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_INTERNATIONAL_TOLL_FREE, "International Toll Free Service "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_MULTIQUEST, "AT&T MultiQuest "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_LONG_DISTANCE, "Long Distance Service "}, + { PRI_NETWORK_SPEC_FAC_SERVICE_CALL_REDIRECTION, "Call Redirection Service "}, +}; + +struct msgtype nsf_features[] { + { PRI_NETWORK_SPEC_FAC_FEATURE_CPN_SID_PREFERRED, "CPN (SID) Preferred " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_BN_ANI_PREFERRED, "BN (ANI) Preferred " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_CPN_SID_ONLY, "CPN (SID) Only " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_BN_ANI_ONLY, "BN (ANI) Only " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_CALL_ASSOCIATED_TSC, "Call Associated TSC " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_CALL_ASSOCIATED_TSC_UNAVAILABLE, "Notification of Call Associated TSC Clearing or Resource Unavailable " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_OPERATOR, "Operator " }, + { PRI_NETWORK_SPEC_FAC_FEATURE_PRESUBSCRIBED_COMMON_CARRIER_OPERATOR, "Pre-Subscribed Common Carrier Operator (PCCO) " }, +}; + #define FLAG_PREFERRED 2 #define FLAG_EXCLUSIVE 4 @@ -1094,6 +1116,46 @@ pri_message(" ]\n"); } +/* Required for SDN Marking contact: mark.schaefer@onstar.com */ +static void dump_network_spec_fac(q931_ie *ie, int len, char prefix) +{ + pri_message("%c Network-Specific Facilities (len=%2d) [ ", prefix, ie->len); + if (ie->len == 2) /* I know how to handle these */ + { + if (!(ie->data[0] & 0x80)) /* Length is zero */ + if (ie->data[1] & 0x80) { /* Binary Facility */ + if (ie->data[1] & 0x20) { /* Service vs. Feature */ + /* Service */ + pri_message("Service: "); + pri_message(code2str(ie->data[1]&0x1f, nsf_services, sizeof(nsf_services) / sizeof(nsf_services[0]))); + } + else { + /* Feature */ + pri_message("Feature: "); + pri_message(code2str(ie->data[1]&0x1f, nsf_features, sizeof(nsf_features) / sizeof(nsf_features[0]))); + } + } + pri_message(" ]\n"); + return; + } + dump_ie_data(ie->data, ie->len); +} + +static int receive_network_spec_fac(struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len) +{ + /* For advanced switching, I may want this, but for now, ignore */ + return 0; +} + +static int transmit_network_spec_fac(struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len) +{ + /* For now, I just want SDN Support. This really needs to be in the q931_call structure! */ + ie->data[0] = 0x00; + ie->data[1] = 0xE0; /* Set as a Service */ + ie->data[1] |= PRI_NETWORK_SPEC_FAC_SERVICE_SDN; + return 4; +} + char *pri_cause2str(int cause) { return code2str(cause, causes, sizeof(causes) / sizeof(causes[0])); @@ -1163,7 +1225,7 @@ { if (!pri->overlapdial && ((pri->switchtype == PRI_SWITCH_EUROISDN_E1) || (pri->switchtype == PRI_SWITCH_EUROISDN_T1))) { /* Include this single-byte IE */ - ie->f = 1; + ie->ie |= 0x80; return 1; } return 0; @@ -1171,13 +1233,16 @@ struct ie ies[] = { { NATIONAL_CHANGE_STATUS, "Change Status" }, - { Q931_LOCKING_SHIFT, "Locking Shift" }, + { Q931_LOCKING_SHIFT_TO_CODESET_6, "Locking Shift To Codeset 6" }, + { Q931_LOCKING_SHIFT_TO_CODESET_7, "Locking Shift To Codeset 7" }, + { Q931_NON_LOCKING_SHIFT_TO_CODESET_6, "Locking Shift To Codeset 6" }, + { Q931_NON_LOCKING_SHIFT_TO_CODESET_7, "Locking Shift To Codeset 7" }, { Q931_BEARER_CAPABILITY, "Bearer Capability", dump_bearer_capability, receive_bearer_capability, transmit_bearer_capability }, { Q931_CAUSE, "Cause", dump_cause, receive_cause, transmit_cause }, { Q931_CALL_STATE, "Call State", dump_call_state, receive_call_state, transmit_call_state }, { Q931_CHANNEL_IDENT, "Channel Identification", dump_channel_id, receive_channel_id, transmit_channel_id }, { Q931_PROGRESS_INDICATOR, "Progress Indicator", dump_progress_indicator, receive_progress_indicator, transmit_progress_indicator }, - { Q931_NETWORK_SPEC_FAC, "Network-Specific Facilities" }, + { Q931_NETWORK_SPEC_FAC, "Network-Specific Facilities", dump_network_spec_fac, receive_network_spec_fac, transmit_network_spec_fac}, { Q931_INFORMATION_RATE, "Information Rate" }, { Q931_TRANSIT_DELAY, "End-to-End Transit Delay" }, { Q931_TRANS_DELAY_SELECT, "Transmit Delay Selection and Indication" }, @@ -1233,7 +1298,7 @@ static inline int ielen(q931_ie *ie) { - if (ie->f) + if (ie->ie & 0x80) return 1; else return 2 + ie->len; @@ -1373,13 +1438,12 @@ for (x=0;xf = 0; iet->ie = ie; if (ies[x].transmit) { res = ies[x].transmit(pri, call, msgtype, iet, maxlen); if (res < 0) return res; - if (!iet->f) + if (!(iet->ie&0x80)) iet->len = res - 2; return res; } else { @@ -1744,7 +1808,7 @@ return 0; } -static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR, +static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_DISPLAY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 }; int q931_setup(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive, @@ -2091,8 +2155,12 @@ return -1; } y = q931_handle_ie(pri, c, mh->msg, ie); - if (!(ie->ie & 0xf0) && (y < 0)) - mandies[MAX_MAND_IES - 1] = ie->ie; + if (!(ie->ie & 0xf0) && (y < 0)) { + pri_error("Unknown IE: %d/%d \n",ie->ie,ie->ie&0xf0); + /* Commented out - don't know why we care about this. + Seems that the mandatory IE's are listed + mandies[MAX_MAND_IES - 1] = ie->ie; */ + } x += r; len -= r; }