[libpri-commits] mattf: branch 1.4 r636 - /branches/1.4/
SVN commits to the libpri project
libpri-commits at lists.digium.com
Fri Oct 17 11:13:43 CDT 2008
Author: mattf
Date: Fri Oct 17 11:13:42 2008
New Revision: 636
URL: http://svn.digium.com/view/libpri?view=rev&rev=636
Log:
Merging in additional Q.SIG features in #13454. Includes Q.SIG physical/logical channel mapping support, extended coding of Q.SIG name operations (calling name), and call rerouting support via added dialplan application.
Modified:
branches/1.4/libpri.h
branches/1.4/pri.c
branches/1.4/pri_facility.c
branches/1.4/pri_facility.h
branches/1.4/pri_internal.h
branches/1.4/pri_q931.h
branches/1.4/q931.c
Modified: branches/1.4/libpri.h
URL: http://svn.digium.com/view/libpri/branches/1.4/libpri.h?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Fri Oct 17 11:13:42 2008
@@ -615,6 +615,10 @@
#define PRI_SET_OVERLAPDIAL
void pri_set_overlapdial(struct pri *pri,int state);
+/* QSIG logical channel mapping option, do not skip channel 16 */
+#define PRI_SET_CHAN_MAPPING_LOGICAL
+void pri_set_chan_mapping_logical(struct pri *pri, int state);
+
#define PRI_DUMP_INFO_STR
char *pri_dump_info_str(struct pri *pri);
@@ -622,8 +626,11 @@
int pri_fd(struct pri *pri);
#define PRI_PROGRESS
-/* Send call proceeding */
+/* Send progress */
int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
+
+/* Send progress with cause IE */
+int pri_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause);
#define PRI_PROCEEDING_FULL
/* Send call proceeding */
@@ -646,6 +653,8 @@
/* Send notification */
int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
+
+int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason);
/* Get/Set PRI Timers */
#define PRI_GETSET_TIMERS
Modified: branches/1.4/pri.c
URL: http://svn.digium.com/view/libpri/branches/1.4/pri.c?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/pri.c (original)
+++ branches/1.4/pri.c Fri Oct 17 11:13:42 2008
@@ -483,10 +483,19 @@
return q931_call_proceeding(pri, call, channel, info);
}
+int pri_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause)
+{
+ if (!pri || !call)
+ return -1;
+
+ return q931_call_progress_with_cause(pri, call, channel, info, cause);
+}
+
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
{
if (!pri || !call)
return -1;
+
return q931_call_progress(pri, call, channel, info);
}
@@ -503,6 +512,15 @@
return -1;
return q931_keypad_facility(pri, call, digits);
+}
+
+
+int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason)
+{
+ if (!pri || !call)
+ return -1;
+
+ return qsig_cf_callrerouting(pri, call, dest, original, reason);
}
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
@@ -787,6 +805,12 @@
pri->overlapdial = state;
}
+void pri_set_chan_mapping_logical(struct pri *pri, int state)
+{
+ if (pri->switchtype == PRI_SWITCH_QSIG)
+ pri->chan_mapping_logical = state;
+}
+
void pri_set_inbanddisconnect(struct pri *pri, unsigned int enable)
{
pri->acceptinbanddisconnect = (enable != 0);
@@ -830,6 +854,7 @@
len += sprintf(buf + len, "Retrans: %d\n", pri->retrans);
len += sprintf(buf + len, "Busy: %d\n", pri->busy);
len += sprintf(buf + len, "Overlap Dial: %d\n", pri->overlapdial);
+ len += sprintf(buf + len, "Logical Channel Mapping: %d\n", pri->chan_mapping_logical);
len += sprintf(buf + len, "T200 Timer: %d\n", pri->timers[PRI_TIMER_T200]);
len += sprintf(buf + len, "T203 Timer: %d\n", pri->timers[PRI_TIMER_T203]);
len += sprintf(buf + len, "T305 Timer: %d\n", pri->timers[PRI_TIMER_T305]);
Modified: branches/1.4/pri_facility.c
URL: http://svn.digium.com/view/libpri/branches/1.4/pri_facility.c?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Fri Oct 17 11:13:42 2008
@@ -1186,6 +1186,198 @@
}
/* End EECT */
+/* QSIG CF CallRerouting */
+int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason)
+{
+/*CallRerouting ::= OPERATION
+ -- Sent from the Served User PINX to the Rerouting PINX
+ ARGUMENT SEQUENCE
+ { reroutingReason DiversionReason,
+ originalReroutingReason [0] IMPLICIT DiversionReason OPTIONAL,
+ calledAddress Address,
+ diversionCounter INTEGER (1..15),
+ pSS1InfoElement PSS1InformationElement,
+ -- The basic call information elements Bearer capability, High layer compatibility, Low
+ -- layer compatibity, Progress indicator and Party category can be embedded in the
+ -- pSS1InfoElement in accordance with 6.5.3.1.5
+ lastReroutingNr [1] PresentedNumberUnscreened,
+ subscriptionOption [2] IMPLICIT SubscriptionOption,
+
+ callingPartySubaddress [3] PartySubaddress OPTIONAL,
+
+ callingNumber [4] PresentedNumberScreened,
+
+ callingName [5] Name OPTIONAL,
+ originalCalledNr [6] PresentedNumberUnscreened OPTIONAL,
+ redirectingName [7] Name OPTIONAL,
+ originalCalledName [8] Name OPTIONAL,
+ extension CHOICE {
+ [9] IMPLICIT Extension ,
+ [10] IMPLICIT SEQUENCE OF Extension } OPTIONAL }
+*/
+
+ int i = 0, j;
+ int res = 0;
+ unsigned char buffer[255] = "";
+ int len = 253;
+ struct rose_component *comp = NULL, *compstk[10];
+ int compsp = 0;
+ static unsigned char op_tag[] = {
+ 0x13,
+ };
+
+ buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
+ /* Interpretation component */
+
+ ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
+ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2); /* reject - to get feedback from QSIG switch */
+
+ ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
+
+ res = asn1_string_encode(ASN1_INTEGER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
+ if (res < 0)
+ return -1;
+ i += res;
+
+ /* call rerouting argument */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ /* reroutingReason DiversionReason */
+
+ if (reason) {
+ if (!strcasecmp(reason, "cfu"))
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1); /* cfu */
+ else if (!strcasecmp(reason, "cfb"))
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 2); /* cfb */
+ else if (!strcasecmp(reason, "cfnr"))
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3); /* cfnr */
+ } else {
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0); /* unknown */
+ }
+
+
+ /* calledAddress Address */
+ /* explicit sequence tag for Address */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ /* implicit choice public party number tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ /* type of public party number = unknown */
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
+ /* NumberDigits of public party number */
+ j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, (char*)dest, strlen(dest));
+ if (j < 0)
+ return -1;
+
+ i += j;
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ /* diversionCounter INTEGER (1..15) */
+ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);
+
+ /* pSS1InfoElement */
+ ASN1_ADD_SIMPLE(comp, (ASN1_APPLICATION | ASN1_TAG_0 ), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ buffer[i++] = (0x04); /* add BC */
+ buffer[i++] = (0x03);
+ buffer[i++] = (0x80);
+ buffer[i++] = (0x90);
+ buffer[i++] = (0xa3);
+ buffer[i++] = (0x95);
+ buffer[i++] = (0x32);
+ buffer[i++] = (0x01);
+ buffer[i++] = (0x81);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ /* lastReroutingNr [1]*/
+ /* implicit optional lastReroutingNr tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ /* implicit choice presented number unscreened tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ /* implicit choice public party number tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ /* type of public party number = unknown */
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
+ j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, original?(char*)original:c->callednum, original?strlen(original):strlen(c->callednum));
+ if (j < 0)
+ return -1;
+
+ i += j;
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ /* subscriptionOption [2]*/
+ /* implicit optional lastReroutingNr tag */
+ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0); /* noNotification */
+
+ /* callingNumber [4]*/
+ /* implicit optional callingNumber tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ /* implicit choice presented number screened tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ /* implicit choice presentationAllowedAddress tag */
+ ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ /* type of public party number = subscriber number */
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 4);
+ j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, c->callernum, strlen(c->callernum));
+ if (j < 0)
+ return -1;
+
+ i += j;
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ /* Screeening Indicator network provided */
+ ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 3);
+
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ /**/
+
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ res = pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL);
+ if (res) {
+ pri_message(pri, "Could not queue ADPU in facility message\n");
+ return -1;
+ }
+
+ /* Remember that if we queue a facility IE for a facility message we
+ * have to explicitly send the facility message ourselves */
+
+ res = q931_facility(c->pri, c);
+ if (res) {
+ pri_message(pri, "Could not schedule facility message for call %d\n", c->cr);
+ return -1;
+ }
+
+ return 0;
+}
+/* End QSIG CC-CallRerouting */
+
static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_ie *ie)
{
int res;
@@ -1215,7 +1407,7 @@
return 0;
}
/* AFN-PR */
-extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
+int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
{
/* Did all the tests to see if we're on the same PRI and
* are on a compatible switchtype */
@@ -1548,6 +1740,47 @@
}
/* End AOC */
+static int rose_calling_name_decode(struct pri *pri, q931_call *call, struct rose_component *choice, int len)
+{
+ int i = 0;
+ struct rose_component *comp = NULL;
+ unsigned char *vdata = choice->data;
+ int characterSet = 1;
+ switch (choice->type) {
+ case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:
+ memcpy(call->callername, choice->data, choice->len);
+ call->callername[choice->len] = 0;
+ if (pri->debug & PRI_DEBUG_APDU)
+ pri_message(pri, " Received simple calling name '%s'\n", call->callername);
+ return 0;
+
+ case ROSE_NAME_PRESENTATION_ALLOWED_EXTENDED:
+ do {
+ GET_COMPONENT(comp, i, vdata, len);
+ CHECK_COMPONENT(comp, ASN1_OCTETSTRING, "Don't know what to do if nameData is of type 0x%x\n");
+ memcpy(call->callername, comp->data, comp->len);
+ call->callername[comp->len] = 0;
+ NEXT_COMPONENT(comp, i);
+
+ GET_COMPONENT(comp, i, vdata, len);
+ CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if CharacterSet is of type 0x%x\n");
+ ASN1_GET_INTEGER(comp, characterSet);
+ }
+ while (0);
+
+ if (pri->debug & PRI_DEBUG_APDU)
+ pri_message(pri, " Received extended calling name '%s', characterset %d\n", call->callername, characterSet);
+ return 0;
+ case ROSE_NAME_PRESENTATION_RESTRICTED_SIMPLE:
+ case ROSE_NAME_PRESENTATION_RESTRICTED_EXTENDED:
+ case ROSE_NAME_PRESENTATION_RESTRICTED_NULL:
+ case ROSE_NAME_NOT_AVAIL:
+ default:
+ if (pri->debug & PRI_DEBUG_APDU)
+ pri_message(pri, "Do not handle argument of type 0x%X\n", choice->type);
+ return -1;
+ }
+}
/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */
static int rose_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
@@ -2158,6 +2391,12 @@
pri_message(pri, "Could not parse invoke of type 0x%x!\n", invokeidvalue);
return -1;
}
+ } else if (pri->switchtype == PRI_SWITCH_QSIG) {
+ switch (invokeidvalue) {
+ case 0x13:
+ if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Successfully completed QSIG CF callRerouting!\n");
+ return 0;
+ }
} else {
pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
return -1;
@@ -2209,19 +2448,7 @@
case SS_CNID_CALLINGNAME:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, " Handle Name display operation\n");
- switch (comp->type) {
- case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:
- memcpy(call->callername, comp->data, comp->len);
- call->callername[comp->len] = 0;
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Received caller name '%s'\n", call->callername);
- return 0;
- default:
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, "Do not handle argument of type 0x%X\n", comp->type);
- return -1;
- }
- break;
+ return rose_calling_name_decode(pri, call, comp, len-i);
case ROSE_CALL_TRANSFER_IDENTIFY:
if (pri->debug & PRI_DEBUG_APDU)
pri_message(pri, "ROSE %i: CallTransferIdentify - not handled!\n", operation_tag);
@@ -2267,8 +2494,10 @@
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
return -1;
case ROSE_DIVERTING_LEG_INFORMATION2:
- if (pri->debug & PRI_DEBUG_APDU)
- pri_message(pri, " Handle DivertingLegInformation2\n");
+ if (pri->debug & PRI_DEBUG_APDU) {
+ pri_message(pri, "ROSE %i: Handle CallingName\n", operation_tag);
+ dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+ }
return rose_diverting_leg_information2_decode(pri, call, comp, len-i);
case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE:
if (pri->debug & PRI_DEBUG_APDU) {
Modified: branches/1.4/pri_facility.h
URL: http://svn.digium.com/view/libpri/branches/1.4/pri_facility.h?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/pri_facility.h (original)
+++ branches/1.4/pri_facility.h Fri Oct 17 11:13:42 2008
@@ -41,7 +41,10 @@
/* Argument values */
#define ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE 0x80
#define ROSE_NAME_PRESENTATION_RESTRICTED_NULL 0x87
-#define ROSE_NAME_NOT_AVAIL 0x84
+#define ROSE_NAME_PRESENTATION_ALLOWED_EXTENDED 0xA1
+#define ROSE_NAME_PRESENTATION_RESTRICTED_SIMPLE 0xA2
+#define ROSE_NAME_PRESENTATION_RESTRICTED_EXTENDED 0xA3
+#define ROSE_NAME_NOT_AVAIL 0x84
/* Component types */
#define COMP_TYPE_INTERPRETATION 0x8B
@@ -306,8 +309,10 @@
int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
+int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const char* original, const char* reason);
+
/* starts a QSIG Path Replacement */
-extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
+int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
/* Use this function to queue a facility-IE born APDU onto a call
* call is the call to use, messagetype is any one of the Q931 messages,
Modified: branches/1.4/pri_internal.h
URL: http://svn.digium.com/view/libpri/branches/1.4/pri_internal.h?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/pri_internal.h (original)
+++ branches/1.4/pri_internal.h Fri Oct 17 11:13:42 2008
@@ -113,6 +113,9 @@
/* do we do overlap dialing */
int overlapdial;
+
+ /* do not skip channel 16 */
+ int chan_mapping_logical;
#ifdef LIBPRI_COUNTERS
/* q921/q931 packet counters */
Modified: branches/1.4/pri_q931.h
URL: http://svn.digium.com/view/libpri/branches/1.4/pri_q931.h?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/pri_q931.h (original)
+++ branches/1.4/pri_q931.h Fri Oct 17 11:13:42 2008
@@ -256,6 +256,8 @@
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
+extern int q931_call_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause);
+
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);
Modified: branches/1.4/q931.c
URL: http://svn.digium.com/view/libpri/branches/1.4/q931.c?view=diff&rev=636&r1=635&r2=636
==============================================================================
--- branches/1.4/q931.c (original)
+++ branches/1.4/q931.c Fri Oct 17 11:13:42 2008
@@ -345,6 +345,8 @@
pos++;
/* Only expect a particular channel */
call->channelno = ie->data[pos] & 0x7f;
+ if (pri->chan_mapping_logical && call->channelno > 15)
+ call->channelno++;
return 0;
}
} else
@@ -400,7 +402,10 @@
ie->data[pos++] = 0x83;
if (call->channelno > -1) {
/* Channel number specified */
- ie->data[pos++] = 0x80 | call->channelno;
+ if (pri->chan_mapping_logical && call->channelno > 16)
+ ie->data[pos++] = 0x80 | (call->channelno - 1);
+ else
+ ie->data[pos++] = 0x80 | call->channelno;
return pos + 2;
}
/* We have to send a channel map */
@@ -2731,6 +2736,8 @@
#ifdef ALERTING_NO_PROGRESS
static int call_progress_ies[] = { -1 };
#else
+static int call_progress_with_cause_ies[] = { Q931_PROGRESS_INDICATOR, Q931_CAUSE, -1 };
+
static int call_progress_ies[] = { Q931_PROGRESS_INDICATOR, -1 };
#endif
@@ -2742,6 +2749,7 @@
channel &= 0xff;
c->channelno = channel;
}
+
if (info) {
c->progloc = LOC_PRIV_NET_LOCAL_USER;
c->progcode = CODE_CCITT;
@@ -2751,8 +2759,36 @@
pri_error(pri, "XXX Progress message requested but no information is provided\n");
c->progressmask = 0;
}
+
c->alive = 1;
return send_message(pri, c, Q931_PROGRESS, call_progress_ies);
+}
+
+int q931_call_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause)
+{
+ if (channel) {
+ c->ds1no = (channel & 0xff00) >> 8;
+ c->ds1explicit = (channel & 0x10000) >> 16;
+ channel &= 0xff;
+ c->channelno = channel;
+ }
+
+ if (info) {
+ c->progloc = LOC_PRIV_NET_LOCAL_USER;
+ c->progcode = CODE_CCITT;
+ c->progressmask = PRI_PROG_INBAND_AVAILABLE;
+ } else {
+ /* PI is mandatory IE for PROGRESS message - Q.931 3.1.8 */
+ pri_error(pri, "XXX Progress message requested but no information is provided\n");
+ c->progressmask = 0;
+ }
+
+ c->cause = cause;
+ c->causecode = CODE_CCITT;
+ c->causeloc = LOC_PRIV_NET_LOCAL_USER;
+
+ c->alive = 1;
+ return send_message(pri, c, Q931_PROGRESS, call_progress_with_cause_ies);
}
#ifdef ALERTING_NO_PROGRESS
More information about the libpri-commits
mailing list