[libpri-commits] mattf: trunk r422 - /trunk/
libpri-commits at lists.digium.com
libpri-commits at lists.digium.com
Wed Jun 6 14:47:36 MST 2007
Author: mattf
Date: Wed Jun 6 16:47:36 2007
New Revision: 422
URL: http://svn.digium.com/view/libpri?view=rev&rev=422
Log:
Preliminary patch plus mods for Q.SIG Path Replacement (Q.SIG version of 2BCT) #7778
Modified:
trunk/pri.c
trunk/pri_facility.c
trunk/pri_facility.h
trunk/pri_internal.h
trunk/q931.c
Modified: trunk/pri.c
URL: http://svn.digium.com/view/libpri/trunk/pri.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri.c (original)
+++ trunk/pri.c Wed Jun 6 16:47:36 2007
@@ -544,6 +544,12 @@
if (call1->pri->switchtype == PRI_SWITCH_DMS100)
return rlt_initiate_transfer(call1->pri, call1, call2);
+ if (call1->pri->switchtype == PRI_SWITCH_QSIG) {
+ call1->bridged_call = call2;
+ call2->bridged_call = call1;
+ return anfpr_initiate_transfer(call1->pri, call1, call2);
+ }
+
return -1;
}
Modified: trunk/pri_facility.c
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_facility.c (original)
+++ trunk/pri_facility.c Wed Jun 6 16:47:36 2007
@@ -1191,6 +1191,162 @@
return 0;
}
/* End EECT */
+
+static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_ie *ie)
+{
+ int res;
+
+ res = pri_call_apdu_queue_cleanup(call->bridged_call);
+ if (res) {
+ pri_message(pri, "Could not Clear queue ADPU\n");
+ return -1;
+ }
+
+ /* Send message */
+ res = pri_call_apdu_queue(call->bridged_call, Q931_FACILITY, ie->data, ie->len, 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(call->bridged_call->pri, call->bridged_call);
+ if (res) {
+ pri_message(pri, "Could not schedule facility message for call %d\n", call->bridged_call->cr);
+ return -1;
+ }
+
+ return 0;
+}
+/* AFN-PR */
+extern 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 */
+ /* TODO */
+ int i = 0;
+ int res = 0;
+ unsigned char buffer[255] = "";
+ unsigned short call_reference = c2->cr;
+ struct rose_component *comp = NULL, *compstk[10];
+ unsigned char buffer2[255] = "";
+ int compsp = 0;
+ static unsigned char op_tag[] = {
+ 0x0C,
+ };
+
+ /* Channel 1 */
+ 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;
+
+ ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ buffer[i++] = (0x0a);
+ buffer[i++] = (0x01);
+ buffer[i++] = (0x00);
+ buffer[i++] = (0x81);
+ buffer[i++] = (0x00);
+ buffer[i++] = (0x0a);
+ buffer[i++] = (0x01);
+ buffer[i++] = (0x01);
+ ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer, i, call_reference);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+ ASN1_FIXUP(compstk, compsp, buffer, i);
+
+ res = pri_call_apdu_queue(c1, 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(c1->pri, c1);
+ if (res) {
+ pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);
+ return -1;
+ }
+
+ /* Channel 2 */
+ i = 0;
+ res = 0;
+ compsp = 0;
+
+ buffer2[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
+ /* Interpretation component */
+
+ ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer2, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer2, i, 0);
+ ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer2, i, 0);
+ ASN1_FIXUP(compstk, compsp, buffer2, i);
+
+ ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer2, i, 2); /* reject */
+
+ ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer2, i);
+ ASN1_PUSH(compstk, compsp, comp);
+
+ ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer2, i, get_invokeid(pri));
+
+ res = asn1_string_encode(ASN1_INTEGER, &buffer2[i], sizeof(buffer2)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
+ if (res < 0)
+ return -1;
+ i += res;
+
+ ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer2, i);
+ ASN1_PUSH(compstk, compsp, comp);
+ buffer2[i++] = (0x0a);
+ buffer2[i++] = (0x01);
+ buffer2[i++] = (0x01);
+ buffer2[i++] = (0x81);
+ buffer2[i++] = (0x00);
+ buffer2[i++] = (0x0a);
+ buffer2[i++] = (0x01);
+ buffer2[i++] = (0x01);
+ ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer2, i, call_reference);
+ ASN1_FIXUP(compstk, compsp, buffer2, i);
+ ASN1_FIXUP(compstk, compsp, buffer2, i);
+
+
+ res = pri_call_apdu_queue(c2, Q931_FACILITY, buffer2, 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(c2->pri, c2);
+ if (res) {
+ pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);
+ return -1;
+ }
+
+ return 0;
+}
+/* End AFN-PR */
/* AOC */
static int aoc_aoce_charging_request_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
@@ -1824,7 +1980,7 @@
-int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_reject_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
{
int i = 0;
int problemtag = -1;
@@ -1892,7 +2048,7 @@
return -1;
}
-int rose_return_error_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_return_error_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
{
int i = 0;
int errorvalue = -1;
@@ -1956,7 +2112,7 @@
return -1;
}
-int rose_return_result_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_return_result_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
{
int i = 0;
int operationidvalue = -1;
@@ -2018,9 +2174,10 @@
return -1;
}
-int rose_invoke_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_invoke_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
{
int i = 0;
+ int res = 0;
int operation_tag;
unsigned char *vdata = data;
struct rose_component *comp = NULL, *invokeid = NULL, *operationid = NULL;
@@ -2169,6 +2326,15 @@
dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
}
return -1;
+ case SS_ANFPR_PATHREPLACEMENT:
+ /* Clear Queue */
+ res = pri_call_apdu_queue_cleanup(call->bridged_call);
+ if (res) {
+ pri_message(pri, "Could not Clear queue ADPU\n");
+ return -1;
+ }
+ anfpr_pathreplacement_respond(pri, call, ie);
+ break;
default:
if (pri->debug & PRI_DEBUG_APDU) {
pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag);
Modified: trunk/pri_facility.h
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.h?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_facility.h (original)
+++ trunk/pri_facility.h Wed Jun 6 16:47:36 2007
@@ -9,6 +9,7 @@
#ifndef _PRI_FACILITY_H
#define _PRI_FACILITY_H
+#include "pri_q931.h"
/* Protocol Profile field */
#define Q932_PROTOCOL_ROSE 0x11 /* X.219 & X.229 */
@@ -57,6 +58,7 @@
#define ROSE_AOC_IDENTIFICATION_OF_CHARGE 37
/* Q.SIG operations */
#define SS_CNID_CALLINGNAME 0
+#define SS_ANFPR_PATHREPLACEMENT 4
#define SS_DIVERTING_LEG_INFORMATION2 21
#define SS_MWI_ACTIVATE 80
#define SS_MWI_DEACTIVATE 81
@@ -254,16 +256,16 @@
} while (0)
/* Decoder for the invoke ROSE component */
-int rose_invoke_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_invoke_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
/* Decoder for the return result ROSE component */
-int rose_return_result_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_return_result_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
/* Decoder for the return error ROSE component */
-int rose_return_error_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_return_error_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
/* Decoder for the reject ROSE component */
-int rose_reject_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_reject_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
@@ -283,6 +285,9 @@
int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
+
+/* starts a QSIG Path Replacement */
+extern 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: trunk/pri_internal.h
URL: http://svn.digium.com/view/libpri/trunk/pri_internal.h?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_internal.h (original)
+++ trunk/pri_internal.h Wed Jun 6 16:47:36 2007
@@ -246,6 +246,9 @@
int transferable;
unsigned int rlt_call_id; /* RLT call id */
+
+ /* Bridged call info */
+ q931_call *bridged_call; /* Pointer to other leg of bridged call */
};
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
Modified: trunk/q931.c
URL: http://svn.digium.com/view/libpri/trunk/q931.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/q931.c (original)
+++ trunk/q931.c Wed Jun 6 16:47:36 2007
@@ -1174,7 +1174,7 @@
state = my_state; \
if (pri->debug) \
pri_message(pri, "Handle Q.932 %s component\n", name); \
- (handler)(pri, call, comp->data, comp->len); \
+ (handler)(pri, call, ie, comp->data, comp->len); \
break;
#define Q932_HANDLE_NULL(component, my_state, name, handle) \
case component: \
More information about the libpri-commits
mailing list