[libpri-commits] tilghman: branch group/issue10217 r877 - /team/group/issue10217/
SVN commits to the libpri project
libpri-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 libpri-commits
mailing list