[libpri-commits] moy: branch moy/tap-1.4 r1119 - /team/moy/tap-1.4/

SVN commits to the libpri project libpri-commits at lists.digium.com
Tue Sep 22 11:48:57 CDT 2009


Author: moy
Date: Tue Sep 22 11:48:53 2009
New Revision: 1119

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1119
Log:
added pri_read_event API to read events passively from the PRI link

Modified:
    team/moy/tap-1.4/libpri.h
    team/moy/tap-1.4/pri.c
    team/moy/tap-1.4/pri_q931.h
    team/moy/tap-1.4/pridump.c
    team/moy/tap-1.4/q931.c

Modified: team/moy/tap-1.4/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/moy/tap-1.4/libpri.h?view=diff&rev=1119&r1=1118&r2=1119
==============================================================================
--- team/moy/tap-1.4/libpri.h (original)
+++ team/moy/tap-1.4/libpri.h Tue Sep 22 11:48:53 2009
@@ -735,6 +735,9 @@
 /* Check for an outstanding event on the PRI */
 pri_event *pri_check_event(struct pri *pri);
 
+/* Check for PRI events */
+pri_event *pri_read_event(struct pri *pri);
+
 /* Give a name to a given event ID */
 char *pri_event2str(int id);
 

Modified: team/moy/tap-1.4/pri.c
URL: http://svnview.digium.com/svn/libpri/team/moy/tap-1.4/pri.c?view=diff&rev=1119&r1=1118&r2=1119
==============================================================================
--- team/moy/tap-1.4/pri.c (original)
+++ team/moy/tap-1.4/pri.c Tue Sep 22 11:48:53 2009
@@ -405,6 +405,26 @@
 	return e;
 }
 
+pri_event *pri_read_event(struct pri *pri)
+{
+	char buf[1024];
+	int res;
+	res = pri->read_func ? pri->read_func(pri, buf, sizeof(buf)) : 0;
+	/* this check should be at some routine in q921.c */
+	/* at least 4 bytes of Q921 and at check buf[4] for Q931 Network packet */
+	if (res < 5 || ((int)buf[4] != 8)) {
+		return NULL;	
+	}
+	res = q931_read_event(pri, (q931_h*)(buf + 4), res - 4 - 2 /* remove 4 bytes of Q921 h and 2 of CRC */);
+	if (res == -1) {
+		return NULL;
+	}
+	if (res & Q931_RES_HAVEEVENT) {
+		return &pri->ev;
+	}
+	return NULL;
+}
+
 static int wait_pri(struct pri *pri)
 {	
 	struct timeval *tv, real;
@@ -886,7 +906,15 @@
 		pri_message(pri, "Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
 		pri_message(pri, "Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
 		break;
+	case PRI_EVENT_ANSWER:
+		pri_message(pri, "Channel: %d Reference number: %d\n", e->answer.channel, e->answer.cref);
+		break;
+	case PRI_EVENT_PROCEEDING:
+		pri_message(pri, "Channel: %d Reference number: %d\n", e->proceeding.channel, e->proceeding.cref);
 	case PRI_EVENT_HANGUP:
+		pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
+		break;
+	case PRI_EVENT_HANGUP_ACK:
 		pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
 		break;
 	default:

Modified: team/moy/tap-1.4/pri_q931.h
URL: http://svnview.digium.com/svn/libpri/team/moy/tap-1.4/pri_q931.h?view=diff&rev=1119&r1=1118&r2=1119
==============================================================================
--- team/moy/tap-1.4/pri_q931.h (original)
+++ team/moy/tap-1.4/pri_q931.h Tue Sep 22 11:48:53 2009
@@ -427,6 +427,8 @@
 /* Q.SIG specific */
 #define QSIG_IE_TRANSIT_COUNT		0x31
 
+extern int q931_read_event(struct pri *pri, q931_h *h, int len);
+
 extern int q931_receive(struct pri *pri, q931_h *h, int len);
 
 extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);

Modified: team/moy/tap-1.4/pridump.c
URL: http://svnview.digium.com/svn/libpri/team/moy/tap-1.4/pridump.c?view=diff&rev=1119&r1=1118&r2=1119
==============================================================================
--- team/moy/tap-1.4/pridump.c (original)
+++ team/moy/tap-1.4/pridump.c Tue Sep 22 11:48:53 2009
@@ -42,7 +42,7 @@
 #include <sys/ioctl.h>
 #include <sys/select.h>
 #include <sys/types.h>
-#include <zaptel/zaptel.h>
+#include <dahdi/user.h>
 #include "libpri.h"
 #include "pri_q921.h"
 #include "pri_q931.h"
@@ -50,18 +50,18 @@
 static int pri_open(char *dev)
 {
 	int dfd;
-	struct zt_params p;
+	struct dahdi_params p;
 	
 	dfd = open(dev, O_RDWR);
 	if (dfd < 0) {
 		fprintf(stderr, "Failed to open dchannel '%s': %s\n", dev, strerror(errno));
 		return -1;
 	}
-	if (ioctl(dfd, ZT_GET_PARAMS, &p)) {
+	if (ioctl(dfd, DAHDI_GET_PARAMS, &p)) {
 		fprintf(stderr, "Unable to get parameters on '%s': %s\n", dev, strerror(errno));
 		return -1;
 	}
-	if ((p.sigtype != ZT_SIG_HDLCRAW) && (p.sigtype != ZT_SIG_HDLCFCS)) {
+	if ((p.sigtype != DAHDI_SIG_HDLCRAW) && (p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
 		fprintf(stderr, "%s is in %d signalling, not FCS HDLC or RAW HDLC mode\n", dev, p.sigtype);
 		return -1;
 	}
@@ -70,11 +70,33 @@
 
 static void dump_packet(struct pri *pri, char *buf, int len, int txrx)
 {
-	q921_h *h = (q921_h *)buf;
-	q921_dump(pri, h, len, 1, txrx);
+	//q921_h *h = (q921_h *)buf;
+
+	//q921_dump(pri, h, len, 1, txrx);
+	
+	// Check if data is long enough and if this is a Q931 frame
+	if ((len < 5) || ((int)buf[4] != 8)) {
+		return;
+	}
+	q931_dump(pri, (void*)(buf + 4), len - 4 - 2, txrx);
+
+#if 0
+	switch (h->h.data[0] & Q921_FRAMETYPE_MASK) {
+	case 0:
+	case 2:
+		q931_dump(pri, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
+		break;
+	default:
+		break;
+	}
+
+	// serch for 0 in the first 2 bits (which __q921_receive_qualified handles just as 2, frame 3 can also have q931 msg though)
 	if (!((h->h.data[0] & Q921_FRAMETYPE_MASK) & 0x3)) {
+		// case 3 h->h.data[0] & Q921_FRAMETYPE_MASK, res = q931_receive(pri, (q931_h *) h->u.data, len - 3);
 		q931_dump(pri, (q931_h *)(h->i.data), len - 4 - 2 /* FCS */, txrx);
 	}
+#endif
+
 	fflush(stdout);
 	fflush(stderr);
 }
@@ -94,8 +116,8 @@
 		max = d1;
 		if (max < d2)
 			max = d2;
-		ioctl(d1, ZT_GETEVENT, &e);
-		ioctl(d2, ZT_GETEVENT, &e);
+		ioctl(d1, DAHDI_GETEVENT, &e);
+		ioctl(d2, DAHDI_GETEVENT, &e);
 		res = select(max + 1, &fds, NULL, NULL, NULL);
 		if (res < 0) {
 			fprintf(stderr, "Select returned %d: %s\n", res, strerror(errno));

Modified: team/moy/tap-1.4/q931.c
URL: http://svnview.digium.com/svn/libpri/team/moy/tap-1.4/q931.c?view=diff&rev=1119&r1=1118&r2=1119
==============================================================================
--- team/moy/tap-1.4/q931.c (original)
+++ team/moy/tap-1.4/q931.c Tue Sep 22 11:48:53 2009
@@ -91,7 +91,7 @@
 	{ Q931_SUSPEND_ACKNOWLEDGE, "SUSPEND ACKNOWLEDGE" },
 	{ Q931_SUSPEND_REJECT, "SUSPEND REJECT" },
 };
-static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct q931_call *c, int missingmand);
+static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct q931_call *c, int missingmand, int checkstate);
 
 struct msgtype att_maintenance_msgs[] = {
 	{ ATT_SERVICE, "SERVICE", { Q931_CHANNEL_IDENT } },
@@ -171,6 +171,7 @@
        { PRI_NSF_ATT_MULTIQUEST, "AT&T MultiQuest" },
        { PRI_NSF_CALL_REDIRECTION_SERVICE, "Call Redirection Service" }
 };
+static int q931_process_ies(struct pri *ctrl, q931_h *h, int len, q931_mh *mh, q931_call *c, int *missingmand);
 
 #define FLAG_WHOLE_INTERFACE	0x01
 #define FLAG_PREFERRED			0x02
@@ -4313,22 +4314,47 @@
 	return 0;
 }
 
-int q931_receive(struct pri *ctrl, q931_h *h, int len)
+/* here we trust receiving q931 only (no maintenance or anything else)*/
+int q931_read_event(struct pri *ctrl, q931_h *h, int len)
 {
 	q931_mh *mh;
 	q931_call *c;
-	q931_ie *ie;
-	unsigned int x;
-	int y;
+	int cref;
+	int missingmand;
+
+	//q931_dump(ctrl, h, len, 0);
+	
+	mh = (q931_mh *)(h->contents + h->crlen);
+
+	cref = q931_cr(h);
+
+	/* XXX FIXME: when does the call structure will be freed???? when!? XXX */	
+	c = q931_getcall(ctrl, cref);
+	if (!c) {
+		pri_error(ctrl, "Unable to locate call %d\n", cref);
+		return -1;
+	}
+
+	if (prepare_to_handle_q931_message(ctrl, mh, c)) {
+		return 0;
+	}
+
+	missingmand = 0;
+	if (q931_process_ies(ctrl, h, len, mh, c, &missingmand)) {
+		return -1;
+	}
+
+	return post_handle_q931_message(ctrl, mh, c, missingmand, 0);
+}
+
+int q931_receive(struct pri *ctrl, q931_h *h, int len)
+{
+	q931_mh *mh;
+	q931_call *c;
+	int missingmand;
 	int res;
-	int r;
-	int mandies[MAX_MAND_IES];
-	int missingmand;
-	int codeset, cur_codeset;
-	int last_ie[8];
 	int cref;
 
-	memset(last_ie, 0, sizeof(last_ie));
 	if (ctrl->debug & PRI_DEBUG_Q931_DUMP)
 		q931_dump(ctrl, h, len, 0);
 #ifdef LIBPRI_COUNTERS
@@ -4362,11 +4388,43 @@
 	} else {
 		prepare_to_handle_q931_message(ctrl, mh, c);
 	}
+
+	/* Handle IEs */
+	missingmand = 0;
+	if (q931_process_ies(ctrl, h, len, mh, c, &missingmand)) {
+		return -1;
+	}
+
+	/* Post handling */
+	if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
+		res = post_handle_maintenance_message(ctrl, h->pd, mh, c);
+	} else {
+		res = post_handle_q931_message(ctrl, mh, c, missingmand, 1);
+	}
+	return res;
+}
+
+/*!
+ * \internal
+ * \brief Process all IEs in a Q931 msg
+ */
+static int q931_process_ies(struct pri *ctrl, q931_h *h, int len, q931_mh *mh, q931_call *c, int *missingmand)
+{
+	int mandies[MAX_MAND_IES];
+	unsigned int x;
+	int y;
+	int r;
+	int codeset, cur_codeset;
+	int last_ie[8];
+	q931_ie *ie;
+
+	memset(last_ie, 0, sizeof(last_ie));
+
 	q931_clr_subcommands(ctrl);
 	
 	/* Handle IEs */
 	memset(mandies, 0, sizeof(mandies));
-	missingmand = 0;
+	*missingmand = 0;
 	for (x=0;x<sizeof(msgs) / sizeof(msgs[0]); x++)  {
 		if (msgs[x].msgnum == mh->msg) {
 			memcpy(mandies, msgs[x].mandies, sizeof(mandies));
@@ -4439,25 +4497,18 @@
 		x += r;
 		len -= r;
 	}
-	missingmand = 0;
+	*missingmand = 0;
 	for (x=0;x<MAX_MAND_IES;x++) {
 		if (mandies[x]) {
 			/* check if there is no channel identification when we're configured as network -> that's not an error */
 			if (((ctrl->localtype != PRI_NETWORK) || (mh->msg != Q931_SETUP) || (mandies[x] != Q931_CHANNEL_IDENT)) &&
 			     ((mh->msg != Q931_PROGRESS) || (mandies[x] != Q931_PROGRESS_INDICATOR))) {
 				pri_error(ctrl, "XXX Missing handling for mandatory IE %d (cs%d, %s) XXX\n", Q931_IE_IE(mandies[x]), Q931_IE_CODESET(mandies[x]), ie2str(mandies[x]));
-				missingmand++;
+				(*missingmand)++;
 			}
 		}
 	}
-
-	/* Post handling */
-	if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
-		res = post_handle_maintenance_message(ctrl, h->pd, mh, c);
-	} else {
-		res = post_handle_q931_message(ctrl, mh, c, missingmand);
-	}
-	return res;
+	return 0;
 }
 
 static int post_handle_maintenance_message(struct pri *ctrl, int protodisc, struct q931_mh *mh, struct q931_call *c)
@@ -4549,12 +4600,13 @@
  * \param mh Q.931 message header.
  * \param c Q.931 call leg.
  * \param missingmand Number of missing mandatory ie's.
+ * \param checkstate Whether or not to check the state of the call
  *
  * \retval 0 if no error or event.
  * \retval Q931_RES_HAVEEVENT if have an event.
  * \retval -1 on error.
  */
-static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct q931_call *c, int missingmand)
+static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct q931_call *c, int missingmand, int checkstate)
 {
 	int res;
 	struct apdu_event *cur = NULL;
@@ -4580,8 +4632,9 @@
 			q931_release_complete(ctrl, c, PRI_CAUSE_MANDATORY_IE_MISSING);
 			break;
 		}
+
 		/* Must be new call */
-		if (!c->newcall) {
+		if (checkstate && !c->newcall) {
 			break;
 		}
 		if (c->progressmask & PRI_PROG_CALLER_NOT_ISDN)
@@ -4620,7 +4673,6 @@
 			c->redirecting.to.number.presentation =
 				PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
 		}
-
 		ctrl->ev.e = PRI_EVENT_RING;
 		ctrl->ev.ring.subcmds = &ctrl->subcmds;
 		ctrl->ev.ring.channel = q931_encode_channel(c);
@@ -4690,10 +4742,12 @@
 
 		return Q931_RES_HAVEEVENT;
 	case Q931_ALERTING:
-		if (c->newcall) {
+
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}
+
 		UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_CALL_DELIVERED);
 		c->peercallstate = Q931_CALL_STATE_CALL_RECEIVED;
 		ctrl->ev.e = PRI_EVENT_RINGING;
@@ -4718,14 +4772,16 @@
 
 		return Q931_RES_HAVEEVENT;
 	case Q931_CONNECT:
-		if (c->newcall) {
+
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}
-		if (c->ourcallstate == Q931_CALL_STATE_ACTIVE) {
+		if (checkstate && c->ourcallstate == Q931_CALL_STATE_ACTIVE) {
 			q931_status(ctrl, c, PRI_CAUSE_WRONG_MESSAGE);
 			break;
 		}
+
 		UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_ACTIVE);
 		c->peercallstate = Q931_CALL_STATE_CONNECT_REQUEST;
 
@@ -4790,17 +4846,18 @@
 		/* Fall through */
 	case Q931_CALL_PROCEEDING:
 		ctrl->ev.proceeding.subcmds = &ctrl->subcmds;
-		if (c->newcall) {
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}
-		if ((c->ourcallstate != Q931_CALL_STATE_CALL_INITIATED) &&
+		if (checkstate && (c->ourcallstate != Q931_CALL_STATE_CALL_INITIATED) &&
 		    (c->ourcallstate != Q931_CALL_STATE_OVERLAP_SENDING) && 
 		    (c->ourcallstate != Q931_CALL_STATE_CALL_DELIVERED) && 
 		    (c->ourcallstate != Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING)) {
 			q931_status(ctrl,c,PRI_CAUSE_WRONG_MESSAGE);
 			break;
 		}
+
 		ctrl->ev.proceeding.channel = q931_encode_channel(c);
 		if (mh->msg == Q931_CALL_PROCEEDING) {
 			ctrl->ev.e = PRI_EVENT_PROCEEDING;
@@ -4822,18 +4879,21 @@
 		}
 		return Q931_RES_HAVEEVENT;
 	case Q931_CONNECT_ACKNOWLEDGE:
-		if (c->newcall) {
+
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}
-		if (!(c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) &&
+		if (checkstate && !(c->ourcallstate == Q931_CALL_STATE_CONNECT_REQUEST) &&
 		    !(c->ourcallstate == Q931_CALL_STATE_ACTIVE &&
 		      (ctrl->localtype == PRI_NETWORK || ctrl->switchtype == PRI_SWITCH_QSIG))) {
 			q931_status(ctrl,c,PRI_CAUSE_WRONG_MESSAGE);
 			break;
 		}
+
 		UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_ACTIVE);
 		c->peercallstate = Q931_CALL_STATE_ACTIVE;
+
 		break;
 	case Q931_STATUS:
 		if (missingmand) {
@@ -4936,7 +4996,7 @@
 		c->useruserinfo[0] = '\0';
 		/* Don't send release complete if they send us release 
 		   while we sent it, assume a NULL state */
-		if (c->newcall)
+		if (checkstate && c->newcall)
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 		else 
 			return Q931_RES_HAVEEVENT;
@@ -4946,7 +5006,7 @@
 			/* Still let user call release */
 			c->cause = PRI_CAUSE_MANDATORY_IE_MISSING;
 		}
-		if (c->newcall) {
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}
@@ -5012,7 +5072,7 @@
 			q931_status(ctrl,c, 0);
 		break;
 	case Q931_SETUP_ACKNOWLEDGE:
-		if (c->newcall) {
+		if (checkstate && c->newcall) {
 			q931_release_complete(ctrl,c,PRI_CAUSE_INVALID_CALL_REFERENCE);
 			break;
 		}




More information about the libpri-commits mailing list