Rudimentery support for transmitting and receiving calling name
via facility information elements git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@150 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
6bfef709dc
commit
cea480c941
4
Makefile
4
Makefile
@ -34,8 +34,8 @@ TOBJS=testpri.o
|
||||
T2OBJS=testprilib.o
|
||||
STATIC_LIBRARY=libpri.a
|
||||
DYNAMIC_LIBRARY=libpri.so.1.0
|
||||
STATIC_OBJS=pri.o q921.o prisched.o q931.o
|
||||
DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo
|
||||
STATIC_OBJS=pri.o q921.o prisched.o q931.o pri_facility.o
|
||||
DYNAMIC_OBJS=pri.lo q921.lo prisched.lo q931.lo pri_facility.lo
|
||||
CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g $(ALERTING) $(LIBPRI_COUNTERS)
|
||||
INSTALL_PREFIX=
|
||||
ifeq (${OSARCH},Linux)
|
||||
|
1
libpri.h
1
libpri.h
@ -51,6 +51,7 @@
|
||||
#define PRI_SWITCH_NI1 7 /* National ISDN 1 */
|
||||
#define PRI_SWITCH_GR303_EOC 8 /* GR-303 Embedded Operations Channel */
|
||||
#define PRI_SWITCH_GR303_TMC 9 /* GR-303 Timeslot Management Channel */
|
||||
#define PRI_SWITCH_QSIG 10 /* QSIG Switch */
|
||||
/* Switchtypes 10 - 20 are reserved for internal use */
|
||||
|
||||
|
||||
|
2
pri.c
2
pri.c
@ -58,6 +58,8 @@ char *pri_switch2str(int sw)
|
||||
return "GR303 EOC";
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
return "GR303 TMC";
|
||||
case PRI_SWITCH_QSIG:
|
||||
return "Q.SIG switch";
|
||||
default:
|
||||
return "Unknown switchtype";
|
||||
}
|
||||
|
@ -124,6 +124,79 @@ struct pri_sr {
|
||||
#define PRI_SWITCH_GR303_EOC_PATH 10
|
||||
#define PRI_SWITCH_GR303_TMC_SWITCHING 11
|
||||
|
||||
/* q931_call datastructure */
|
||||
|
||||
struct q931_call {
|
||||
struct pri *pri; /* PRI */
|
||||
int cr; /* Call Reference */
|
||||
int forceinvert; /* Force inversion of call number even if 0 */
|
||||
q931_call *next;
|
||||
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
|
||||
int slotmap;
|
||||
/* An explicit channel (Channel Identifier IE) (-1 means not specified) */
|
||||
int channelno;
|
||||
/* An explicit DS1 (-1 means not specified) */
|
||||
int ds1no;
|
||||
/* Channel flags (0 means none retrieved) */
|
||||
int chanflags;
|
||||
|
||||
int alive; /* Whether or not the call is alive */
|
||||
int acked; /* Whether setup has been acked or not */
|
||||
int sendhangupack; /* Whether or not to send a hangup ack */
|
||||
int proc; /* Whether we've sent a call proceeding / alerting */
|
||||
|
||||
int ri; /* Restart Indicator (Restart Indicator IE) */
|
||||
|
||||
/* Bearer Capability */
|
||||
int transcapability;
|
||||
int transmoderate;
|
||||
int transmultiple;
|
||||
int userl1;
|
||||
int userl2;
|
||||
int userl3;
|
||||
int rateadaption;
|
||||
|
||||
int sentchannel;
|
||||
|
||||
int progcode; /* Progress coding */
|
||||
int progloc; /* Progress Location */
|
||||
int progress; /* Progress indicator */
|
||||
|
||||
int notify; /* Notification */
|
||||
|
||||
int causecode; /* Cause Coding */
|
||||
int causeloc; /* Cause Location */
|
||||
int cause; /* Cause of clearing */
|
||||
|
||||
int peercallstate; /* Call state of peer as reported */
|
||||
int ourcallstate; /* Our call state */
|
||||
int sugcallstate; /* Status call state */
|
||||
|
||||
int callerplan;
|
||||
int callerpres; /* Caller presentation */
|
||||
char callernum[256]; /* Caller */
|
||||
char callername[256];
|
||||
|
||||
int ani2; /* ANI II */
|
||||
|
||||
int calledplan;
|
||||
int nonisdn;
|
||||
char callednum[256]; /* Called Number */
|
||||
int complete; /* no more digits coming */
|
||||
int newcall; /* if the received message has a new call reference value */
|
||||
|
||||
int retranstimer; /* Timer for retransmitting DISC */
|
||||
int t308_timedout; /* Whether t308 timed out once */
|
||||
int redirectingplan;
|
||||
int redirectingpres;
|
||||
int redirectingreason;
|
||||
char redirectingnum[256];
|
||||
|
||||
int useruserprotocoldisc;
|
||||
char useruserinfo[256];
|
||||
char callingsubaddr[256]; /* Calling parties sub address */
|
||||
};
|
||||
|
||||
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
|
||||
|
||||
extern pri_event *pri_schedule_run(struct pri *pri);
|
||||
|
166
q931.c
166
q931.c
@ -26,6 +26,7 @@
|
||||
#include "pri_internal.h"
|
||||
#include "pri_q921.h"
|
||||
#include "pri_q931.h"
|
||||
#include "pri_facility.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@ -201,76 +202,6 @@ struct msgtype facilities[] = {
|
||||
#define LOC_INTERNATIONAL_NETWORK 0x7
|
||||
#define LOC_NETWORK_BEYOND_INTERWORKING 0xa
|
||||
|
||||
struct q931_call {
|
||||
struct pri *pri; /* PRI */
|
||||
int cr; /* Call Reference */
|
||||
int forceinvert; /* Force inversion of call number even if 0 */
|
||||
q931_call *next;
|
||||
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
|
||||
int slotmap;
|
||||
/* An explicit channel (Channel Identifier IE) (-1 means not specified) */
|
||||
int channelno;
|
||||
/* An explicit DS1 (-1 means not specified) */
|
||||
int ds1no;
|
||||
/* Channel flags (0 means none retrieved) */
|
||||
int chanflags;
|
||||
|
||||
int alive; /* Whether or not the call is alive */
|
||||
int acked; /* Whether setup has been acked or not */
|
||||
int sendhangupack; /* Whether or not to send a hangup ack */
|
||||
int proc; /* Whether we've sent a call proceeding / alerting */
|
||||
|
||||
int ri; /* Restart Indicator (Restart Indicator IE) */
|
||||
|
||||
/* Bearer Capability */
|
||||
int transcapability;
|
||||
int transmoderate;
|
||||
int transmultiple;
|
||||
int userl1;
|
||||
int userl2;
|
||||
int userl3;
|
||||
int rateadaption;
|
||||
|
||||
int sentchannel;
|
||||
|
||||
int progcode; /* Progress coding */
|
||||
int progloc; /* Progress Location */
|
||||
int progress; /* Progress indicator */
|
||||
|
||||
int notify; /* Notification */
|
||||
|
||||
int causecode; /* Cause Coding */
|
||||
int causeloc; /* Cause Location */
|
||||
int cause; /* Cause of clearing */
|
||||
|
||||
int peercallstate; /* Call state of peer as reported */
|
||||
int ourcallstate; /* Our call state */
|
||||
int sugcallstate; /* Status call state */
|
||||
|
||||
int callerplan;
|
||||
int callerpres; /* Caller presentation */
|
||||
char callernum[256]; /* Caller */
|
||||
char callername[256];
|
||||
|
||||
int ani2; /* ANI II */
|
||||
|
||||
int calledplan;
|
||||
int nonisdn;
|
||||
char callednum[256]; /* Called Number */
|
||||
int complete; /* no more digits coming */
|
||||
int newcall; /* if the received message has a new call reference value */
|
||||
|
||||
int retranstimer; /* Timer for retransmitting DISC */
|
||||
int t308_timedout; /* Whether t308 timed out once */
|
||||
int redirectingplan;
|
||||
int redirectingpres;
|
||||
int redirectingreason;
|
||||
char redirectingnum[256];
|
||||
|
||||
int useruserprotocoldisc;
|
||||
char useruserinfo[256];
|
||||
char callingsubaddr[256]; /* Calling parties sub address */
|
||||
};
|
||||
|
||||
#define FUNC_DUMP(name) void ((name))(int full_ie, q931_ie *ie, int len, char prefix)
|
||||
#define FUNC_RECV(name) int ((name))(int full_ie, struct pri *pri, q931_call *call, int msgtype, q931_ie *ie, int len)
|
||||
@ -1053,15 +984,94 @@ static FUNC_RECV(receive_progress_indicator)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FUNC_SEND(transmit_facility)
|
||||
{
|
||||
int i = 0;
|
||||
struct rose_component *comp;
|
||||
unsigned char namelen = strlen(call->callername);
|
||||
|
||||
if ((pri->switchtype == PRI_SWITCH_QSIG)
|
||||
|| (pri->switchtype == PRI_SWITCH_ATT4ESS)
|
||||
|| (pri->switchtype == PRI_SWITCH_NI2)) {
|
||||
ie->data[i] = ROSE_NETWORK_EXTENSION;
|
||||
i++;
|
||||
/* Interpretation component */
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
comp->type = COMP_TYPE_INTERPRETATION;
|
||||
comp->len = 0x01;
|
||||
comp->data[0] = 0x00; /* Discard unrecognized invokes */
|
||||
|
||||
i += 3;
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
/* Invoke ID */
|
||||
comp->type = COMP_TYPE_INVOKE;
|
||||
comp->len = 3 /* sizeof Invoke ID */
|
||||
+ 3 /* sizeof Operation tag */
|
||||
+ 2 /* first two bytes of the Arguement section */
|
||||
+ namelen;
|
||||
|
||||
i += 2;
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
/* Invoke component contents */
|
||||
/* Invoke ID */
|
||||
comp->type = ASN1_INTEGER;
|
||||
comp->len = 0x01;
|
||||
comp->data[0] = 0x01; /* Invoke ID value */
|
||||
i += 3;
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
/* Operation Tag */
|
||||
comp->type = ASN1_INTEGER;
|
||||
comp->len = 0x01;
|
||||
comp->data[0] = 0x00; /* Calling name */
|
||||
i += 3;
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
/* Arugement Tag */
|
||||
comp->type = ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE;
|
||||
comp->len = namelen;
|
||||
i += 2;
|
||||
memcpy(comp->data, call->callername, namelen);
|
||||
i += namelen;
|
||||
return i+2 /* 2 = length of IE header */;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FUNC_RECV(receive_facility)
|
||||
{
|
||||
if (ie->len < 14) {
|
||||
pri_error("!! Facility message shorter than 14 bytes\n");
|
||||
return 0;
|
||||
int i = 0;
|
||||
struct rose_component *comp = NULL;
|
||||
|
||||
if (ie->len < 1)
|
||||
return -1;
|
||||
|
||||
if(ie->data[i] != 0x9F) {
|
||||
if (pri->debug) pri_message("!! Don't know how to handle Service Discriminator of type 0x%X\n", ie->data[i]);
|
||||
return -1;
|
||||
}
|
||||
if (ie->data[13] + 14 == ie->len) {
|
||||
q931_get_number(call->callername, sizeof(call->callername) - 1, ie->data + 14, ie->len - 14);
|
||||
i++;
|
||||
|
||||
if (ie->len < 3)
|
||||
return -1;
|
||||
|
||||
while ((i+1 < ie->len) && (&ie->data[i])) {
|
||||
comp = (struct rose_component*)&ie->data[i];
|
||||
if (comp->type) {
|
||||
switch (comp->type) {
|
||||
case COMP_TYPE_INTERPRETATION:
|
||||
if (pri->debug) pri_message("Handle ROSE interpretation component\n");
|
||||
break;
|
||||
case COMP_TYPE_INVOKE:
|
||||
rose_invoke_decode(call, comp->data, comp->len);
|
||||
break;
|
||||
default:
|
||||
if (pri->debug) pri_message("Don't know how to handle ROSE component of type 0x%X\n", comp->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += (comp->len + 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1457,7 +1467,7 @@ struct ie ies[] = {
|
||||
{ Q931_LOW_LAYER_COMPAT, "Low-layer Compatibility" },
|
||||
{ Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" },
|
||||
{ Q931_PACKET_SIZE, "Packet Size" },
|
||||
{ Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility },
|
||||
{ Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility },
|
||||
{ Q931_IE_REDIRECTION_NUMBER, "Redirection Number" },
|
||||
{ Q931_IE_REDIRECTION_SUBADDR, "Redirection Subaddress" },
|
||||
{ Q931_IE_FEATURE_ACTIVATE, "Feature Activation" },
|
||||
@ -1483,7 +1493,7 @@ struct ie ies[] = {
|
||||
{ Q931_IE_UPDATE, "Update" },
|
||||
{ Q931_SENDING_COMPLETE, "Sending Complete", dump_sending_complete, receive_sending_complete, transmit_sending_complete },
|
||||
/* Codeset 6 - Network specific */
|
||||
{ Q931_IE_FACILITY | Q931_CODESET(6), "Facility", dump_facility, receive_facility },
|
||||
{ Q931_IE_FACILITY | Q931_CODESET(6), "Facility", dump_facility, receive_facility, transmit_facility },
|
||||
{ Q931_IE_ORIGINATING_LINE_INFO, "Originating Line Information", dump_line_information, receive_line_information, transmit_line_information },
|
||||
/* Codeset 7 */
|
||||
};
|
||||
@ -2182,7 +2192,7 @@ int q931_disconnect(struct pri *pri, q931_call *c, int cause)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_PROGRESS_INDICATOR, Q931_NETWORK_SPEC_FAC, Q931_DISPLAY,
|
||||
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_SENDING_COMPLETE, Q931_IE_ORIGINATING_LINE_INFO, -1 };
|
||||
|
||||
static int gr303_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 };
|
||||
|
Loading…
Reference in New Issue
Block a user