[svn-commits] tilghman: branch group/issue10217 r877 - /team/group/issue10217/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jun 15 16:05:29 CDT 2009


Author: tilghman
Date: Mon Jun 15 16:05:25 2009
New Revision: 877

URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=877
Log:
Move around a structure into public space, implementing part of the public API
for using LLC, and implement the most useless IE ever: Repeat Indicator.

Modified:
    team/group/issue10217/libpri.h
    team/group/issue10217/pri.c
    team/group/issue10217/pri_internal.h
    team/group/issue10217/pri_q931.h
    team/group/issue10217/q931.c

Modified: team/group/issue10217/libpri.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue10217/libpri.h?view=diff&rev=877&r1=876&r2=877
==============================================================================
--- team/group/issue10217/libpri.h (original)
+++ team/group/issue10217/libpri.h Mon Jun 15 16:05:25 2009
@@ -526,6 +526,100 @@
 struct pri;
 struct pri_sr;
 
+struct pri_lowlayercompat {
+	int transcapability;
+	int negotiateoob;
+	int transmode;
+	int transrate;
+	int transmultiplier;
+	int layer1proto;
+	/* Note: this struct within a union within a struct within a union
+	 * is purely designed to make the code logic easier to follow without having to
+	 * ensure that the bitmaps are correct.
+	 */
+	union {
+		char octet5[4];
+		struct {
+			unsigned int extend5a:1;
+			unsigned int async:1;
+			unsigned int negot:1;
+			unsigned int userrate:5;
+			unsigned int extend5b:1;
+			union {
+				/* For V.110, I.460, and X.30 rate adaption */
+				struct {
+					unsigned int interrate:2;
+					unsigned int nicontx:1;
+					unsigned int niconrx:1;
+					unsigned int flowontx:1;
+					unsigned int flowonrx:1;
+				};
+				/* For V.120 rate adaption */
+				struct {
+					unsigned int header:1;
+					unsigned int multiframe:1;
+					unsigned int mode:1;
+					unsigned int negotlli:1; /*!< Logical Link Layer Negotiation */
+					unsigned int assignor:1;
+					unsigned int inbandnegot:1;
+				};
+			};
+			unsigned int spare5b:1;
+			unsigned int extend5c:1;
+			unsigned int stopbits:2;
+			unsigned int databits:2;
+			unsigned int parity:3;
+			unsigned int extend5d:1;
+			unsigned int duplex:1;
+			unsigned int modemtype:6;
+		} __attribute__((packed));
+	} layer1;
+
+	int layer2proto;
+	union {
+		char octet6[2];
+		struct {
+			unsigned int extend6a:1;
+			unsigned int mode:2;
+			unsigned int spare6a:3;
+			unsigned int q933:2;
+			unsigned int extend6b:1;
+			unsigned int windowsize:7;
+		};
+		struct {
+			unsigned int extend6a2:1;
+			unsigned int userproto:7;
+		};
+	} layer2 __attribute__((packed));
+
+	int layer3proto;
+	union {
+		char octet7[3];
+		struct {
+			unsigned int extend7a:1;
+			unsigned int mode:2;
+			unsigned int spare7a:5;
+			unsigned int extend7b:1;
+			unsigned int spare7b:3;
+			unsigned int packetsize:4;
+			unsigned int extend7c:1;
+			unsigned int windowsize:7;
+		}; /* Note 7 */
+		struct {
+			unsigned int extend7a2:1;
+			unsigned int optional:7;
+		}; /* Note 8 */
+		struct {
+			unsigned int extend7a3:1;
+			unsigned int spare7a3:3;
+			unsigned int infomsb:4;
+			unsigned int extend7b3:1;
+			unsigned int spare7b3:3;
+			unsigned int infolsb:4;
+		}; /* Note 9 */
+	} layer3 __attribute__((packed));
+};
+
 #define PRI_IO_FUNCS
 /* Type declaration for callbacks to read or write a HDLC frame as below */
 typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen);
@@ -660,7 +754,15 @@
 
 int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
 int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
-int pri_sr_set_lowlayer(struct pri_sr *sr, int transmode, int userl1);
+
+/*!\brief Set the call setup low layer compatibility record
+ * \param sr Call setup record
+ * \param record LLC record number.  Must be in the range 1-4.
+ * \param llc Pointer to a set of LLC negotiation parameters
+ * \retval 0 Success
+ * \retval <1 Invalid record
+ */
+int pri_sr_set_lowlayercompat(struct pri_sr *sr, int record, struct pri_lowlayercompat *llc);
 int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
 int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
 int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);

Modified: team/group/issue10217/pri.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue10217/pri.c?view=diff&rev=877&r1=876&r2=877
==============================================================================
--- team/group/issue10217/pri.c (original)
+++ team/group/issue10217/pri.c Mon Jun 15 16:05:25 2009
@@ -928,11 +928,14 @@
 	return 0;
 }
 
-int pri_sr_set_lowlayer(struct pri_sr *sr, int transmode, int userl1)
-{
-	sr->usellc = 1;
-	sr->llctransmode = transmode;
-	sr->llcuserl1 = userl1;
+int pri_sr_set_lowlayercompat(struct pri_sr *sr, int record, struct pri_lowlayercompat *llc)
+{
+	if (record < 1 || record > 4) {
+		/* Invalid record number */
+		return -1;
+	}
+	memcpy(&sr->llc[record - 1], llc, sizeof(*llc));
+
 	return 0;
 }
 

Modified: team/group/issue10217/pri_internal.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue10217/pri_internal.h?view=diff&rev=877&r1=876&r2=877
==============================================================================
--- team/group/issue10217/pri_internal.h (original)
+++ team/group/issue10217/pri_internal.h Mon Jun 15 16:05:25 2009
@@ -156,9 +156,7 @@
 	int justsignalling;
 	const char *useruserinfo;
 	int transferable;
-	int usellc;
-	int llctransmode;
-	int llcuserl1;
+	struct pri_lowlayercompat llc[4];
 };
 
 /* Internal switch types */
@@ -173,102 +171,6 @@
 	int apdu_len; 			/* Length of ADPU */
 	int sent;  			/* Have we been sent already? */
 	struct apdu_event *next;	/* Linked list pointer */
-};
-
-/* Organized into a structure, because we could have up to 4 in a single message. */
-struct llc {
-	int transcapability;
-	int negotiateoob;
-	int transmode;
-	int transrate;
-	int transmultiplier;
-	int layer1proto;
-	/* Note: this struct within a union within a struct within a union
-	 * is purely designed to make the code logic easier to follow without having to
-	 * ensure that the bitmaps are correct.  As this is an internal header, it does not
-	 * translate to assisting any part of the API (though that might be helpful in
-	 * libpri.h, as well). */
-	union {
-		char octet5[4];
-		struct {
-			unsigned int extend5a:1;
-			unsigned int async:1;
-			unsigned int negot:1;
-			unsigned int userrate:5;
-			unsigned int extend5b:1;
-			union {
-				/* For V.110, I.460, and X.30 rate adaption */
-				struct {
-					unsigned int interrate:2;
-					unsigned int nicontx:1;
-					unsigned int niconrx:1;
-					unsigned int flowontx:1;
-					unsigned int flowonrx:1;
-				};
-				/* For V.120 rate adaption */
-				struct {
-					unsigned int header:1;
-					unsigned int multiframe:1;
-					unsigned int mode:1;
-					unsigned int negotlli:1;
-					unsigned int assignor:1;
-					unsigned int inbandnegot:1;
-				};
-			};
-			unsigned int spare5b:1;
-			unsigned int extend5c:1;
-			unsigned int stopbits:2;
-			unsigned int databits:2;
-			unsigned int parity:3;
-			unsigned int extend5d:1;
-			unsigned int duplex:1;
-			unsigned int modemtype:6;
-		} __attribute__((packed));
-	} layer1;
-
-	int layer2proto;
-	union {
-		char octet6[2];
-		struct {
-			unsigned int extend6a:1;
-			unsigned int mode:2;
-			unsigned int spare6a:3;
-			unsigned int q933:2;
-			unsigned int extend6b:1;
-			unsigned int windowsize:7;
-		};
-		struct {
-			unsigned int extend6a2:1;
-			unsigned int userproto:7;
-		};
-	} layer2 __attribute__((packed));
-
-	int layer3proto;
-	union {
-		char octet7[3];
-		struct {
-			unsigned int extend7a:1;
-			unsigned int mode:2;
-			unsigned int spare7a:5;
-			unsigned int extend7b:1;
-			unsigned int spare7b:3;
-			unsigned int packetsize:4;
-			unsigned int extend7c:1;
-			unsigned int windowsize:7;
-		}; /* Note 7 */
-		struct {
-			unsigned int extend7a2:1;
-			unsigned int optional:7;
-		}; /* Note 8 */
-		struct {
-			unsigned int extend7a3:1;
-			unsigned int spare7a3:3;
-			unsigned int infomsb:4;
-			unsigned int extend7b3:1;
-			unsigned int spare7b3:3;
-			unsigned int infolsb:4;
-		}; /* Note 9 */
-	} layer3 __attribute__((packed));
 };
 
 /* q931_call datastructure */
@@ -310,7 +212,7 @@
 	int usellc;        /* Should we transmit LLC IEs? */
 	int llcacceptable; /* LLC negotiation successful? */
 	/* Organized into a structure, because we could have up to 4 in a single message. */
-	struct llc llc[4];
+	struct pri_lowlayercompat llc[4];
 
 	int sentchannel;
 	int justsignalling;		/* for a signalling-only connection */

Modified: team/group/issue10217/pri_q931.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue10217/pri_q931.h?view=diff&rev=877&r1=876&r2=877
==============================================================================
--- team/group/issue10217/pri_q931.h (original)
+++ team/group/issue10217/pri_q931.h Mon Jun 15 16:05:25 2009
@@ -150,6 +150,7 @@
 #define Q931_PACKET_SIZE			0x46
 #define Q931_CLOSED_USER_GROUP		0x47
 #define Q931_REVERSE_CHARGE_INDIC	0x4a
+#define Q931_REPEAT_INDIC			0x62
 #define Q931_CALLING_PARTY_NUMBER	0x6c
 #define Q931_CALLING_PARTY_SUBADDR	0x6d
 #define Q931_CALLED_PARTY_NUMBER	0x70

Modified: team/group/issue10217/q931.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue10217/q931.c?view=diff&rev=877&r1=876&r2=877
==============================================================================
--- team/group/issue10217/q931.c (original)
+++ team/group/issue10217/q931.c Mon Jun 15 16:05:25 2009
@@ -618,13 +618,14 @@
 		if (msgtype == Q931_CONNECT) {                                             \
 			/* Check for compatibility */                                          \
 			int i;                                                                 \
+			call->llcacceptable = 0;                                               \
 			for (i = 0; i < 4; i++) {                                              \
 				if (memcmp(llc, &call->llc[i], sizeof(*llc)) == 0) {               \
 					call->llcacceptable = 1;                                       \
 					if (i != 0) {                                                  \
 						/* Copy negotiated parameters into the first LLC record */ \
-						memcpy(&call->llc[0], llc, sizeof(struct llc));            \
-						memset(&call->llc[1], 0, sizeof(struct llc) * 3);          \
+						memcpy(&call->llc[0], llc, sizeof(call->llc[0]));          \
+						memset(&call->llc[1], 0, sizeof(call->llc[1]) * 3);        \
 					}                                                              \
 				}                                                                  \
 			}                                                                      \
@@ -637,8 +638,8 @@
 	/* pos is the offset from data[0] */
 	int pos = 0;
 	char octet = 'a';
-	struct llc *llc = &call->llc[call->llccount];
-	struct llc connect_llc;
+	struct pri_lowlayercompat *llc = &call->llc[call->llccount];
+	struct pri_lowlayercompat connect_llc;
 
 	pri_message(pri, "    receive_low_layer_compatibility\n");
 
@@ -669,6 +670,10 @@
 		/* octet 3a: OOB negot. indic. */
 		llc->negotiateoob = (ie->data[pos] & 0x40) ? 1 : 0;
 		pos++;
+	} else {
+		/* Lack of octet 3a indicates OOB negotiation is not possible.
+		 * See Q.931(05/98) Page 84, Table 4-16, NOTE 4 */
+		call->llcacceptable = llc->negotiateoob = 0;
 	}
 
 	if (pos >= len - 2) {
@@ -693,6 +698,7 @@
 
 	if (llc->negotiateoob == 0) {
 		if (msgtype == Q931_SETUP) {
+			call->llcacceptable = 0;
 			pri_message(pri, "Out-of-band negotiation not possible.  Will not negotiate LLC on CONNECT\n");
 		}
 		return 0;
@@ -820,12 +826,15 @@
 
 static FUNC_SEND(transmit_low_layer_compatibility)
 {
+	/* TODO Ensure that all bits are compatible with the transmitted bearer
+	 * info.  Where it conflicts, we use bearer information. */
+
 	/* len contains the full length of the IE, including octet 1 and 2 */
 	/* data[] starts with octet 3 */
 	/* pos is the offset from data[0] */
 	int pos = 0;
 	int tc;
-	struct llc *llc = &call->llc[order];
+	struct pri_lowlayercompat *llc = &call->llc[order];
 
 	/* We are ready to transmit single IE only */	
 	if (msgtype == Q931_CONNECT && order > 1) {
@@ -1204,6 +1213,24 @@
  	return pos + 2;
 }
 
+static FUNC_DUMP(dump_repeat_indicator)
+{
+	pri_message(pri, "Restart Indicator");
+}
+
+static FUNC_RECV(receive_repeat_indicator)
+{
+	/* We really don't care - this is fairly useless */
+	return 0;
+}
+
+static FUNC_SEND(transmit_repeat_indicator)
+{
+	/* Again, mostly useless */
+	ie->data[0] = 0x80 | Q931_REPEAT_INDIC;
+	return 1;
+}
+
 char *pri_plan2str(int plan)
 {
 	static struct msgtype plans[] = {
@@ -2499,6 +2526,7 @@
 	{ 1, Q931_WINDOW_SIZE, "Packet-layer Window Size" },
 	{ 1, Q931_CLOSED_USER_GROUP, "Closed User Group" },
 	{ 1, Q931_REVERSE_CHARGE_INDIC, "Reverse Charging Indication" },
+	{ 0, Q931_REPEAT_INDIC, "Repeat Indicator", dump_repeat_indicator, receive_repeat_indicator, transmit_repeat_indicator },
 	{ 1, Q931_CALLING_PARTY_NUMBER, "Calling Party Number", dump_calling_party_number, receive_calling_party_number, transmit_calling_party_number },
 	{ 1, Q931_CALLING_PARTY_SUBADDR, "Calling Party Subaddress", dump_calling_party_subaddr, receive_calling_party_subaddr },
 	{ 1, Q931_CALLED_PARTY_NUMBER, "Called Party Number", dump_called_party_number, receive_called_party_number, transmit_called_party_number },
@@ -3262,6 +3290,8 @@
 	return send_message(ctrl, c, Q931_ALERTING, alerting_ies);
 }
 
+static int llc_connect_ies[] = {  Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, Q931_LOW_LAYER_COMPAT, -1 };
+ 
 static int connect_ies[] = {  Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, -1 };
  
 int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
@@ -3372,7 +3402,7 @@
 	c->retranstimer = 0;
 	if ((c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) && (ctrl->bri || (!ctrl->subchannel)))
 		c->retranstimer = pri_schedule_event(ctrl, ctrl->timers[PRI_TIMER_T313], pri_connect_timeout, c);
-	return send_message(ctrl, c, Q931_CONNECT, connect_ies);
+	return send_message(ctrl, c, Q931_CONNECT, c->usellc ? llc_connect_ies : connect_ies);
 }
 
 static int release_ies[] = { Q931_CAUSE, Q931_IE_USER_USER, -1 };
@@ -3444,7 +3474,11 @@
 }
 
 static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY,
-	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_IE_USER_USER, Q931_LOW_LAYER_COMPAT, Q931_SENDING_COMPLETE,
+	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_IE_USER_USER, Q931_SENDING_COMPLETE,
+	Q931_IE_ORIGINATING_LINE_INFO, Q931_IE_GENERIC_DIGITS, -1 };
+
+static int llc_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY,
+	Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_REDIRECTING_NUMBER, Q931_IE_USER_USER, Q931_REPEAT_INDIC, Q931_LOW_LAYER_COMPAT, 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 };
@@ -3463,14 +3497,14 @@
 	c->userl1 = req->userl1;
 	c->userl2 = -1;
 	c->userl3 = -1;
-	c->usellc = req->usellc;
+	if ((c->llcacceptable = c->usellc = ((req->llc[0].negotiateoob || req->llc[1].negotiateoob || req->llc[2].negotiateoob || req->llc[2].negotiateoob) ? 1 : 0))) {
+		memcpy(&c->llc[0], &req->llc[0], sizeof(req->llc[0]) * 4);
+	}
+#if 0
+	/* These should probably be worked into a check to verify if LLC is compatible with bearer */
 	c->llc[0].transcapability = req->llctransmode;
 	c->llc[0].transrate = TRANS_MODE_64_CIRCUIT;
-
-	if (!req->llcuserl1) {
-		req->llcuserl1 = PRI_LAYER_1_ULAW;
-	}
-	c->llc[0].layer1proto = req->llcuserl1;
+#endif
 
 	c->ds1no = (req->channel & 0xff00) >> 8;
 	c->ds1explicit = (req->channel & 0x10000) >> 16;
@@ -3545,12 +3579,15 @@
 
 	pri_call_add_standard_apdus(ctrl, c);
 
-	if (ctrl->subchannel && !ctrl->bri)
+	if (ctrl->subchannel && !ctrl->bri) {
 		res = send_message(ctrl, c, Q931_SETUP, gr303_setup_ies);
-	else if (c->justsignalling)
+	} else if (c->justsignalling) {
 		res = send_message(ctrl, c, Q931_SETUP, cis_setup_ies);
-	else
+	} else if (c->usellc) {
+		res = send_message(ctrl, c, Q931_SETUP, llc_setup_ies);
+	} else {
 		res = send_message(ctrl, c, Q931_SETUP, setup_ies);
+	}
 	if (!res) {
 		c->alive = 1;
 		/* make sure we call PRI_EVENT_HANGUP_ACK once we send/receive RELEASE_COMPLETE */




More information about the svn-commits mailing list