[libpri-commits] mattf: branch 1.4 r557 - /branches/1.4/

SVN commits to the libpri project libpri-commits at lists.digium.com
Wed May 7 14:51:45 CDT 2008


Author: mattf
Date: Wed May  7 14:51:44 2008
New Revision: 557

URL: http://svn.digium.com/view/libpri?view=rev&rev=557
Log:
Moving trunk changes back into 1.4

Modified:
    branches/1.4/Makefile
    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_q921.h
    branches/1.4/pri_timers.h
    branches/1.4/prisched.c
    branches/1.4/pritest.c
    branches/1.4/q921.c
    branches/1.4/q931.c
    branches/1.4/testprilib.c

Modified: branches/1.4/Makefile
URL: http://svn.digium.com/view/libpri/branches/1.4/Makefile?view=diff&rev=557&r1=556&r2=557
==============================================================================
--- branches/1.4/Makefile (original)
+++ branches/1.4/Makefile Wed May  7 14:51:44 2008
@@ -34,14 +34,19 @@
 OSARCH=$(shell uname -s)
 PROC?=$(shell uname -m)
 
+# SONAME version; should be changed on every ABI change
+# please don't change it needlessly; it's perfectly fine to have a SONAME
+# of 1.2 and a version of 1.4.x
+SONAME:=1.4
+
 STATIC_LIBRARY=libpri.a
-DYNAMIC_LIBRARY=libpri.so.1.0
+DYNAMIC_LIBRARY:=libpri.so.$(SONAME)
 STATIC_OBJS=copy_string.o pri.o q921.o prisched.o q931.o pri_facility.o version.o
 DYNAMIC_OBJS=copy_string.lo pri.lo q921.lo prisched.lo q931.lo pri_facility.lo version.lo
 CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC $(ALERTING) $(LIBPRI_COUNTERS)
 INSTALL_PREFIX=$(DESTDIR)
 INSTALL_BASE=/usr
-SOFLAGS = -Wl,-hlibpri.so.1.0
+SOFLAGS:=-Wl,-h$(DYNAMIC_LIBRARY)
 LDCONFIG = /sbin/ldconfig
 ifneq (,$(findstring X$(OSARCH)X, XLinuxX XGNU/kFreeBSDX))
 LDCONFIG_FLAGS=-n
@@ -56,7 +61,6 @@
 CFLAGS += -DSOLARIS -I../zaptel-solaris
 LDCONFIG = 
 LDCONFIG_FLAGS = \# # Trick to comment out the period in the command below
-SOSLINK = ln -sf libpri.so.1.0 libpri.so.1
 #INSTALL_PREFIX = /opt/asterisk  # Uncomment out to install in standard Solaris location for 3rd party code
 endif
 
@@ -77,7 +81,16 @@
 update:
 	@if [ -d .svn ]; then \
 		echo "Updating from Subversion..." ; \
-		svn update -q; \
+		fromrev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
+		svn update | tee update.out; \
+		torev="`svn info | $(AWK) '/Revision: / {print $$2}'`"; \
+		echo "`date`  Updated from revision $${fromrev} to $${torev}." >> update.log; \
+		rm -f .version; \
+		if [ `grep -c ^C update.out` -gt 0 ]; then \
+			echo ; echo "The following files have conflicts:" ; \
+			grep ^C update.out | cut -b4- ; \
+		fi ; \
+		rm -f update.out; \
 	else \
 		echo "Not under version control";  \
 	fi
@@ -89,20 +102,19 @@
 	install -m 644 libpri.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
 	install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
 	if [ -x /usr/sbin/sestatus ] && ( /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"); then /sbin/restorecon -v $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/$(DYNAMIC_LIBRARY); fi
-	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.1.0 libpri.so ; ln -sf libpri.so.1.0 libpri.so.1 )
+	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
 	install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
 	if test $$(id -u) = 0; then $(LDCONFIG) $(LDCONFIG_FLAGS) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib; fi
 else
 	install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include -m 644 libpri.h
 	install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 755 $(DYNAMIC_LIBRARY)
-	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.1.0 libpri.so ; $(SOSLINK) )
+	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libpri.so.$(SONAME) libpri.so)
 	install -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib -m 644 $(STATIC_LIBRARY)
 endif
 
 uninstall:
 	@echo "Removing Libpri"
-	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.1.0
-	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.1
+	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so.$(SONAME)
 	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.so
 	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/lib/libpri.a
 	rm -f $(INSTALL_PREFIX)$(INSTALL_BASE)/include/libpri.h
@@ -133,9 +145,7 @@
 $(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
 	$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
 	$(LDCONFIG) $(LDCONFIG_FLAGS) .
-	ln -sf libpri.so.1.0 libpri.so
-	ln -sf libpri.so.1.0 libpri.so.1
-	$(SOSLINK)
+	ln -sf libpri.so.$(SONAME) libpri.so
 
 version.c:
 	@build_tools/make_version_c > $@.tmp
@@ -143,7 +153,7 @@
 	@rm -f $@.tmp
 
 clean:
-	rm -f *.o *.so *.lo *.so.1 *.so.1.0
+	rm -f *.o *.so *.lo *.so.$(SONAME)
 	rm -f testprilib $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
 	rm -f pritest pridump
 	rm -f .depend

Modified: branches/1.4/libpri.h
URL: http://svn.digium.com/view/libpri/branches/1.4/libpri.h?view=diff&rev=557&r1=556&r2=557
==============================================================================
--- branches/1.4/libpri.h (original)
+++ branches/1.4/libpri.h Wed May  7 14:51:44 2008
@@ -342,6 +342,8 @@
 	int channel;
 	int cref;
 	q931_call *call;
+	int callingpres;			/* Presentation of Calling CallerID */
+	int callingplan;			/* Dialing plan of Calling entity */
 } pri_event_facname;
 
 #define PRI_CALLINGPLANANI
@@ -451,77 +453,78 @@
    channel operating in HDLC mode with FCS computed by the fd's driver.  Also it
    must be NON-BLOCKING! Frames received on the fd should include FCS.  Nodetype 
    must be one of PRI_NETWORK or PRI_CPE.  switchtype should be PRI_SWITCH_* */
-extern struct pri *pri_new(int fd, int nodetype, int switchtype);
+struct pri *pri_new(int fd, int nodetype, int switchtype);
+struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype);
 
 /* Create D-channel just as above with user defined I/O callbacks and data */
-extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
+struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
 
 /* Retrieve the user data associated with the D channel */
-extern void *pri_get_userdata(struct pri *pri);
+void *pri_get_userdata(struct pri *pri);
 
 /* Set the user data associated with the D channel */
-extern void pri_set_userdata(struct pri *pri, void *userdata);
+void pri_set_userdata(struct pri *pri, void *userdata);
 
 /* Set Network Specific Facility for PRI */
-extern void pri_set_nsf(struct pri *pri, int nsf);
+void pri_set_nsf(struct pri *pri, int nsf);
 
 /* Set debug parameters on PRI -- see above debug definitions */
-extern void pri_set_debug(struct pri *pri, int debug);
+void pri_set_debug(struct pri *pri, int debug);
 
 /* Get debug parameters on PRI -- see above debug definitions */
-extern int pri_get_debug(struct pri *pri);
+int pri_get_debug(struct pri *pri);
 
 #define PRI_FACILITY_ENABLE
 /* Enable transmission support of Facility IEs on the pri */
-extern void pri_facility_enable(struct pri *pri);
+void pri_facility_enable(struct pri *pri);
 
 /* Run PRI on the given D-channel, taking care of any events that
    need to be handled.  If block is set, it will block until an event
    occurs which needs to be handled */
-extern pri_event *pri_dchannel_run(struct pri *pri, int block);
+pri_event *pri_dchannel_run(struct pri *pri, int block);
 
 /* Check for an outstanding event on the PRI */
 pri_event *pri_check_event(struct pri *pri);
 
 /* Give a name to a given event ID */
-extern char *pri_event2str(int id);
+char *pri_event2str(int id);
 
 /* Give a name to a node type */
-extern char *pri_node2str(int id);
+char *pri_node2str(int id);
 
 /* Give a name to a switch type */
-extern char *pri_switch2str(int id);
+char *pri_switch2str(int id);
 
 /* Print an event */
-extern void pri_dump_event(struct pri *pri, pri_event *e);
+void pri_dump_event(struct pri *pri, pri_event *e);
 
 /* Turn presentation into a string */
-extern char *pri_pres2str(int pres);
+char *pri_pres2str(int pres);
 
 /* Turn numbering plan into a string */
-extern char *pri_plan2str(int plan);
+char *pri_plan2str(int plan);
 
 /* Turn cause into a string */
-extern char *pri_cause2str(int cause);
+char *pri_cause2str(int cause);
 
 /* Acknowledge a call and place it on the given channel.  Set info to non-zero if there
    is in-band data available on the channel */
-extern int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
+int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
 
 /* Send a digit in overlap mode */
-extern int pri_information(struct pri *pri, q931_call *call, char digit);
+int pri_information(struct pri *pri, q931_call *call, char digit);
 
 #define PRI_KEYPAD_FACILITY_TX
 /* Send a keypad facility string of digits */
-extern int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits);
+int pri_keypad_facility(struct pri *pri, q931_call *call, char *digits);
 
 /* Answer the incomplete(call without called number) call on the given channel.
    Set non-isdn to non-zero if you are not connecting to ISDN equipment */
-extern int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
+int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
 
 /* Answer the call on the given channel (ignored if you called acknowledge already).
    Set non-isdn to non-zero if you are not connecting to ISDN equipment */
-extern int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
+int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
 
 /* Set CRV reference for GR-303 calls */
 
@@ -538,60 +541,60 @@
 
 /* Hangup a call */
 #define PRI_HANGUP
-extern int pri_hangup(struct pri *pri, q931_call *call, int cause);
+int pri_hangup(struct pri *pri, q931_call *call, int cause);
 
 #define PRI_DESTROYCALL
-extern void pri_destroycall(struct pri *pri, q931_call *call);
+void pri_destroycall(struct pri *pri, q931_call *call);
 
 #define PRI_RESTART
-extern int pri_restart(struct pri *pri);
-
-extern int pri_reset(struct pri *pri, int channel);
+int pri_restart(struct pri *pri);
+
+int pri_reset(struct pri *pri, int channel);
 
 /* Create a new call */
-extern q931_call *pri_new_call(struct pri *pri);
+q931_call *pri_new_call(struct pri *pri);
 
 /* Retrieve CRV reference for GR-303 calls.  Returns >0 on success. */
-extern int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
+int pri_get_crv(struct pri *pri, q931_call *call, int *callmode);
 
 /* Retrieve CRV reference for GR-303 calls.  CRV must be >0, call mode should be 0 */
-extern int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode);
+int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode);
 
 /* How long until you need to poll for a new event */
-extern struct timeval *pri_schedule_next(struct pri *pri);
+struct timeval *pri_schedule_next(struct pri *pri);
 
 /* Run any pending schedule events */
 extern pri_event *pri_schedule_run(struct pri *pri);
 extern pri_event *pri_schedule_run_tv(struct pri *pri, const struct timeval *now);
 
-extern int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
+int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
    int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
 	 char *called,int calledplan, int ulayer1);
 
-extern struct pri_sr *pri_sr_new(void);
-extern void pri_sr_free(struct pri_sr *sr);
-
-extern int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
-extern int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
-extern int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
-extern int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
-extern int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
+struct pri_sr *pri_sr_new(void);
+void pri_sr_free(struct pri_sr *sr);
+
+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_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);
 #define PRI_USER_USER_TX
 /* Set the user user field.  Warning!  don't send binary data accross this field */
-extern void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);
-
-extern void pri_call_set_useruser(q931_call *sr, const char *userchars);
-
-extern int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
+void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);
+
+void pri_call_set_useruser(q931_call *sr, const char *userchars);
+
+int pri_setup(struct pri *pri, q931_call *call, struct pri_sr *req);
 
 /* Set a call has a call indpendent signalling connection (i.e. no bchan) */
-extern int pri_sr_set_connection_call_independent(struct pri_sr *req);
+int pri_sr_set_connection_call_independent(struct pri_sr *req);
 
 /* Send an MWI indication to a remote location.  If activate is non zero, activates, if zero, decativates */
-extern int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
+int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
 
 /* Send an MWI deactivate request to a remote location */
-extern int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
+int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
 
 #define PRI_2BCT
 /* Attempt to pass the channels back to the NET side if compatable and
@@ -600,30 +603,30 @@
 
 /* Override message and error stuff */
 #define PRI_NEW_SET_API
-extern void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
-extern void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
+void pri_set_message(void (*__pri_error)(struct pri *pri, char *));
+void pri_set_error(void (*__pri_error)(struct pri *pri, char *));
 
 /* Set overlap mode */
 #define PRI_SET_OVERLAPDIAL
-extern void pri_set_overlapdial(struct pri *pri,int state);
+void pri_set_overlapdial(struct pri *pri,int state);
 
 #define PRI_DUMP_INFO_STR
-extern char *pri_dump_info_str(struct pri *pri);
+char *pri_dump_info_str(struct pri *pri);
 
 /* Get file descriptor */
-extern int pri_fd(struct pri *pri);
+int pri_fd(struct pri *pri);
 
 #define PRI_PROGRESS
 /* Send call proceeding */
-extern int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
+int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
 
 #define PRI_PROCEEDING_FULL
 /* Send call proceeding */
-extern int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
+int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
 
 /* Enslave a PRI to another, so they share the same call list
    (and maybe some timers) */
-extern void pri_enslave(struct pri *master, struct pri *slave);
+void pri_enslave(struct pri *master, struct pri *slave);
 
 #define PRI_GR303_SUPPORT
 #define PRI_ENSLAVE_SUPPORT
@@ -634,20 +637,20 @@
 #define PRI_ANI
 
 /* Send notification */
-extern int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
+int pri_notify(struct pri *pri, q931_call *c, int channel, int info);
 
 /* Get/Set PRI Timers  */
 #define PRI_GETSET_TIMERS
-extern int pri_set_timer(struct pri *pri, int timer, int value);
-extern int pri_get_timer(struct pri *pri, int timer);
-extern int pri_timer2idx(char *timer);
+int pri_set_timer(struct pri *pri, int timer, int value);
+int pri_get_timer(struct pri *pri, int timer);
+int pri_timer2idx(char *timer);
 
 #define PRI_MAX_TIMERS 32
 
 #define PRI_TIMER_N200	0	/* Maximum numer of q921 retransmissions */
 #define PRI_TIMER_N201	1	/* Maximum numer of octets in an information field */
 #define PRI_TIMER_N202	2	/* Maximum numer of transmissions of the TEI identity request message */
-#define PRI_TIMER_K	3	/* Maximum number of outstanding I-frames */
+#define PRI_TIMER_K		3	/* Maximum number of outstanding I-frames */
 
 #define PRI_TIMER_T200	4	/* time between SABME's */
 #define PRI_TIMER_T201	5	/* minimum time between retransmissions of the TEI Identity check messages */
@@ -675,6 +678,9 @@
 #define PRI_TIMER_T321	26
 #define PRI_TIMER_T322	27
 
+#define PRI_TIMER_TM20	28	/* maximum time avaiting XID response */
+#define PRI_TIMER_NM20	29	/* number of XID retransmits */
+
 /* Get PRI version */
 const char *pri_get_version(void);
 

Modified: branches/1.4/pri.c
URL: http://svn.digium.com/view/libpri/branches/1.4/pri.c?view=diff&rev=557&r1=556&r2=557
==============================================================================
--- branches/1.4/pri.c (original)
+++ branches/1.4/pri.c Wed May  7 14:51:44 2008
@@ -81,7 +81,7 @@
 
 static void pri_default_timers(struct pri *pri, int switchtype)
 {
-	int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
+	static const int defaulttimers[20][PRI_MAX_TIMERS] = PRI_TIMERS_ALL;
 	int x;
 
 	for (x = 0; x<PRI_MAX_TIMERS; x++) {
@@ -187,63 +187,76 @@
 	return res;
 }
 
-static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata)
+/* Pass in the master for this function */
+void __pri_free_tei(struct pri * p)
+{
+	free (p);
+}
+
+struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri)
 {
 	struct pri *p;
-	p = malloc(sizeof(struct pri));
-	if (p) {
-		memset(p, 0, sizeof(struct pri));
-		p->fd = fd;
-		p->read_func = rd;
-		p->write_func = wr;
-		p->userdata = userdata;
-		p->localtype = node;
-		p->switchtype = switchtype;
-		p->cref = 1;
-		p->sapi = Q921_SAPI_CALL_CTRL;
-		p->tei = 0;
-		p->nsf = PRI_NSF_NONE;
-		p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
-		p->master = master;
-		p->callpool = &p->localpool;
-		pri_default_timers(p, switchtype);
+
+	if (!(p = calloc(1, sizeof(*p))))
+		return NULL;
+
+	p->bri = bri;
+	p->fd = fd;
+	p->read_func = rd;
+	p->write_func = wr;
+	p->userdata = userdata;
+	p->localtype = node;
+	p->switchtype = switchtype;
+	p->cref = 1;
+	p->sapi = (tei == Q921_TEI_GROUP) ? Q921_SAPI_LAYER2_MANAGEMENT : Q921_SAPI_CALL_CTRL;
+	p->tei = tei;
+	p->nsf = PRI_NSF_NONE;
+	p->protodisc = Q931_PROTOCOL_DISCRIMINATOR;
+	p->master = master;
+	p->callpool = &p->localpool;
+	pri_default_timers(p, switchtype);
+	if (master) {
+		pri_set_debug(p, master->debug);
+		if (master->sendfacility)
+			pri_facility_enable(p);
+	}
 #ifdef LIBPRI_COUNTERS
-		p->q921_rxcount = 0;
-		p->q921_txcount = 0;
-		p->q931_rxcount = 0;
-		p->q931_txcount = 0;
+	p->q921_rxcount = 0;
+	p->q921_txcount = 0;
+	p->q931_rxcount = 0;
+	p->q931_txcount = 0;
 #endif
-		if (switchtype == PRI_SWITCH_GR303_EOC) {
-			p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-			p->sapi = Q921_SAPI_GR303_EOC;
-			p->tei = Q921_TEI_GR303_EOC_OPS;
-			p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL);
-			if (!p->subchannel) {
-				free(p);
-				p = NULL;
-			}
-		} else if (switchtype == PRI_SWITCH_GR303_TMC) {
-			p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-			p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
-			p->tei = Q921_TEI_GR303_TMC_CALLPROC;
-			p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL);
-			if (!p->subchannel) {
-				free(p);
-				p = NULL;
-			}
-		} else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
-			p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-			p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
-			p->tei = Q921_TEI_GR303_TMC_SWITCHING;
-		} else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
-			p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
-			p->sapi = Q921_SAPI_GR303_EOC;
-			p->tei = Q921_TEI_GR303_EOC_PATH;
+	if (switchtype == PRI_SWITCH_GR303_EOC) {
+		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		p->sapi = Q921_SAPI_GR303_EOC;
+		p->tei = Q921_TEI_GR303_EOC_OPS;
+		p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0);
+		if (!p->subchannel) {
+			free(p);
+			p = NULL;
 		}
-		/* Start Q.921 layer, Wait if we're the network */
-		if (p)
-			q921_start(p, p->localtype == PRI_CPE);
-	}
+	} else if (switchtype == PRI_SWITCH_GR303_TMC) {
+		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
+		p->tei = Q921_TEI_GR303_TMC_CALLPROC;
+		p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0);
+		if (!p->subchannel) {
+			free(p);
+			p = NULL;
+		}
+	} else if (switchtype == PRI_SWITCH_GR303_TMC_SWITCHING) {
+		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		p->sapi = Q921_SAPI_GR303_TMC_SWITCHING;
+		p->tei = Q921_TEI_GR303_TMC_SWITCHING;
+	} else if (switchtype == PRI_SWITCH_GR303_EOC_PATH) {
+		p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
+		p->sapi = Q921_SAPI_GR303_EOC;
+		p->tei = Q921_TEI_GR303_EOC_PATH;
+	}
+	/* Start Q.921 layer, Wait if we're the network */
+	if (p)
+		q921_start(p, p->localtype == PRI_CPE);
+	
 	return p;
 }
 
@@ -270,7 +283,15 @@
 
 struct pri *pri_new(int fd, int nodetype, int switchtype)
 {
-	return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL);
+	return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0);
+}
+
+struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype)
+{
+	if (ptpmode)
+		return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1);
+	else
+		return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1);
 }
 
 struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
@@ -279,7 +300,7 @@
 		io_read = __pri_read;
 	if (!io_write)
 		io_write = __pri_write;
-	return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata);
+	return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0);
 }
 
 void *pri_get_userdata(struct pri *pri)
@@ -556,6 +577,14 @@
 			else
 				return 0;
 			break;
+		case PRI_SWITCH_QSIG:
+			call1->bridged_call = call2;
+			call2->bridged_call = call1;
+			if (anfpr_initiate_transfer(call1->pri, call1, call2))
+				return -1;
+			else
+				return 0;
+			break;
 		default:
 			return -1;
 	}
@@ -821,7 +850,7 @@
 struct pri_sr *pri_sr_new(void)
 {
 	struct pri_sr *req;
-	req = malloc(sizeof(struct pri_sr));
+	req = malloc(sizeof(*req));
 	if (req) 
 		pri_sr_init(req);
 	return req;

Modified: branches/1.4/pri_facility.c
URL: http://svn.digium.com/view/libpri/branches/1.4/pri_facility.c?view=diff&rev=557&r1=556&r2=557
==============================================================================
--- branches/1.4/pri_facility.c (original)
+++ branches/1.4/pri_facility.c Wed May  7 14:51:44 2008
@@ -167,9 +167,18 @@
 struct addressingdataelements_presentednumberunscreened {
 	char partyaddress[21];
 	char partysubaddress[21];
-	int  npi;
-	int  ton;
-	int  pres;
+	int  npi;       /* Numbering Plan Indicator */
+	int  ton;       /* Type Of Number */
+	int  pres;      /* Presentation */
+};
+
+struct addressingdataelements_presentednumberscreened {
+	char partyaddress[21];
+	char partysubaddress[21];
+	int  npi;       /* Numbering Plan Indicator */
+	int  ton;       /* Type Of Number */
+	int  pres;      /* Presentation */
+	int  scrind;    /* Screening Indicator */
 };
 
 #define PRI_CHECKOVERFLOW(size) \
@@ -445,6 +454,35 @@
 		res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
 		if (res < 0)
 			return -1;
+		value->ton = ton;
+
+		return res + 3;
+
+	} while(0);
+	return -1;
+}
+
+static int rose_private_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
+{
+	int i = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+	int ton;
+	int res = 0;
+
+	if (len < 2)
+	return -1;
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PrivatePartyNumber ROSE component type 0x%x\n");
+		ASN1_GET_INTEGER(comp, ton);
+		NEXT_COMPONENT(comp, i);
+		ton = typeofnumber_for_q931(pri, ton);
+
+		res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
+		if (res < 0)
+		  return -1;
 		value->ton = ton;
 
 		return res + 3;
@@ -503,9 +541,11 @@
 			pri_message(pri, "!! telexPartyNumber isn't handled\n");
 			return -1;
 		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):	/* [5] priavePartyNumber */
-			pri_message(pri, "!! privatePartyNumber isn't handled\n");
+			res = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
+			if (res < 0)
+			return -1;
 			value->npi = PRI_NPI_PRIVATE;
-			return -1;
+			break;
 		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):	/* [8] nationalStandardPartyNumber */
 			res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
 			if (res < 0)
@@ -589,6 +629,8 @@
 	struct rose_component *comp = NULL;
 	unsigned char *vdata = sequence->data;
 	int res = 0;
+	memset(&divertingnr, 0, sizeof(divertingnr));
+	memset(&originalcallednr, 0, sizeof(originalcallednr));
 
 	/* Data checks */
 	if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
@@ -670,6 +712,9 @@
 				if (pri->debug & PRI_DEBUG_APDU)
 					pri_message(pri, "    Received Originally Called Name '%s'\n", origcalledname);
 				break;
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):
+				pri_message(pri, "!! Ignoring DivertingLegInformation2 component 0x%X\n", comp->type);
+				break;
 			default:
 				if (comp->type == 0 && comp->len == 0) {
 					break; /* Found termination characters */
@@ -684,11 +729,13 @@
 			call->redirectingpres = divertingnr.pres;
 			call->redirectingreason = diversion_reason;
 			libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum));
+			pri_message(pri, "    Received redirectingnum '%s' (%d)\n", call->redirectingnum, (int)call->redirectingnum[0]);
 		}
 		if (originalcallednr.pres >= 0) {
 			call->origcalledplan = originalcallednr.npi;
 			call->origcalledpres = originalcallednr.pres;
 			libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
+			pri_message(pri, "    Received origcallednum '%s' (%d)\n", call->origcallednum, (int)call->origcallednum[0]);
 		}
 		libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
 		libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
@@ -1133,6 +1180,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) 
@@ -1340,7 +1543,433 @@
 }
 /* End AOC */
 
-int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+/* ===== 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)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+
+		switch(comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   /* [0] IMPLICIT NumberDigits -- default: unknownPartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: UnknownPartyNumber len=%d\n", len);
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_UNKNOWN;
+				value->ton = PRI_TON_UNKNOWN;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):   /* [1] IMPLICIT PublicPartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: PublicPartyNumber len=%d\n", len);
+				size = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_E163_E164;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):   /* [3] IMPLICIT NumberDigits -- not used: dataPartyNumber */
+				pri_message(pri, "!! PartyNumber: dataPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_X121 /* ??? */;
+				value->ton = PRI_TON_UNKNOWN /* ??? */;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):   /* [4] IMPLICIT NumberDigits -- not used: telexPartyNumber */
+				pri_message(pri, "!! PartyNumber: telexPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_F69 /* ??? */;
+				value->ton = PRI_TON_UNKNOWN /* ??? */;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):   /* [5] IMPLICIT PrivatePartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: PrivatePartyNumber len=%d\n", len);
+				size = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+ 				value->npi = PRI_NPI_PRIVATE;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):   /* [8] IMPLICIT NumberDigits -- not used: nationalStandatdPartyNumber */
+				pri_message(pri, "!! PartyNumber: nationalStandardPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_NATIONAL;
+				value->ton = PRI_TON_NATIONAL;
+				break;
+
+			default:
+				pri_message(pri, "Invalid PartyNumber component 0x%X\n", comp->type);
+				return -1;
+		}
+		ASN1_FIXUP_LEN(comp, size);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     PartyNumber: '%s' size=%d len=%d\n", value->partyaddress, size, len);
+		return size;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+	int scrind = -1;
+
+	do {
+		/* Party Number */
+		GET_COMPONENT(comp, i, vdata, len);
+		size = rose_party_number_decode(pri, call, (u_int8_t *)comp, comp->len + 2, (struct addressingdataelements_presentednumberunscreened*) value);
+		if (size < 0)
+			return -1;
+		comp->len = size;
+		NEXT_COMPONENT(comp, i);
+
+		/* Screening Indicator */
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with NumberScreened ROSE component type 0x%x\n");
+		ASN1_GET_INTEGER(comp, scrind);
+		// Todo: scrind = screeningindicator_for_q931(pri, scrind);
+		NEXT_COMPONENT(comp, i);
+
+		value->scrind = scrind;
+
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     NumberScreened: '%s' ScreeningIndicator=%d  i=%d  len=%d\n", value->partyaddress, scrind, i, len);
+
+		return i-2;  // We do not have a sequence header here.
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_presented_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+	/* Fill in default values */
+	value->ton = PRI_TON_UNKNOWN;
+	value->npi = PRI_NPI_UNKNOWN;
+	value->pres = -1; /* Data is not available */
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+
+		switch(comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   /* [0] IMPLICIT presentationAllowedNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationAllowedNumber comp->len=%d\n", comp->len);
+				value->pres = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
+				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, size);
+				return size + 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):    /* [1] IMPLICIT presentationRestricted */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationRestricted comp->len=%d\n", comp->len);
+				if (comp->len != 0) { /* must be NULL */
+					pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
+					return -1;
+				}
+				value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
+				return 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2):    /* [2] IMPLICIT numberNotAvailableDueToInterworking */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: NumberNotAvailableDueToInterworking comp->len=%d\n", comp->len);
+				if (comp->len != 0) { /* must be NULL */
+					pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n");
+					return -1;
+				}
+				value->pres = PRES_NUMBER_NOT_AVAILABLE;
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: numberNotAvailableDueToInterworking Type=0x%X  i=%d len=%d size=%d\n", comp->type, i, len);
+				return 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):    /* [3] IMPLICIT presentationRestrictedNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationRestrictedNumber comp->len=%d\n", comp->len);
+				value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
+				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, size);
+				return size + 2;
+
+			default:
+				pri_message(pri, "Invalid PresentedNumberScreened component 0x%X\n", comp->type);
+		}
+		return -1;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_call_transfer_complete_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
+{
+	int i = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = sequence->data;
+	int res = 0;
+
+	int end_designation = 0;

[... 1607 lines stripped ...]



More information about the libpri-commits mailing list