Split justsignalling into cis_call and cis_auto_disconnect functionality.
git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1042 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
61f7a372d9
commit
e7c9ecb1b2
17
libpri.h
17
libpri.h
@ -599,7 +599,7 @@ typedef struct pri_event_hangup {
|
||||
long aoc_units; /* Advise of Charge number of charged units */
|
||||
char useruserinfo[260]; /* User->User info */
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_hangup;
|
||||
} pri_event_hangup;
|
||||
|
||||
typedef struct pri_event_restart_ack {
|
||||
int e;
|
||||
@ -617,7 +617,7 @@ typedef struct pri_event_proceeding {
|
||||
q931_call *call;
|
||||
struct pri_subcommands *subcmds;
|
||||
} pri_event_proceeding;
|
||||
|
||||
|
||||
typedef struct pri_event_setup_ack {
|
||||
int e;
|
||||
int channel;
|
||||
@ -681,7 +681,7 @@ typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen);
|
||||
|
||||
/* Create a D-channel on a given file descriptor. The file descriptor must be a
|
||||
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 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_* */
|
||||
struct pri *pri_new(int fd, int nodetype, int switchtype);
|
||||
struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype);
|
||||
@ -856,9 +856,18 @@ 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) */
|
||||
/*!
|
||||
* \brief Set a call as a call indpendent signalling connection (i.e. no bchan)
|
||||
* \note Call will automaticlly disconnect after signalling sent.
|
||||
*/
|
||||
int pri_sr_set_connection_call_independent(struct pri_sr *req);
|
||||
|
||||
/*!
|
||||
* \brief Set a call as a call indpendent signalling connection (i.e. no bchan)
|
||||
* \note Call will stay connected until explicitly disconnected.
|
||||
*/
|
||||
int pri_sr_set_no_channel_call(struct pri_sr *req);
|
||||
|
||||
/* Send an MWI indication to a remote location. If activate is non zero, activates, if zero, deactivates */
|
||||
int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
|
||||
|
||||
|
13
pri.c
13
pri.c
@ -911,7 +911,18 @@ int pri_sr_set_connection_call_independent(struct pri_sr *req)
|
||||
if (!req)
|
||||
return -1;
|
||||
|
||||
req->justsignalling = 1; /* have to set justsignalling for all those pesky IEs we need to setup */
|
||||
req->cis_call = 1; /* have to set cis_call for all those pesky IEs we need to setup */
|
||||
req->cis_auto_disconnect = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pri_sr_set_no_channel_call(struct pri_sr *req)
|
||||
{
|
||||
if (!req) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
req->cis_call = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,8 @@ struct pri_sr {
|
||||
struct q931_party_address called;
|
||||
int userl1;
|
||||
int numcomplete;
|
||||
int justsignalling;
|
||||
int cis_call;
|
||||
int cis_auto_disconnect;
|
||||
const char *useruserinfo;
|
||||
int transferable;
|
||||
int reversecharge;
|
||||
@ -367,7 +368,13 @@ struct q931_call {
|
||||
int userl3;
|
||||
int rateadaption;
|
||||
|
||||
int justsignalling; /* for a signalling-only connection */
|
||||
/*!
|
||||
* \brief TRUE if the call is a Call Independent Signalling connection.
|
||||
* \note The call has no B channel associated with it. (Just signalling)
|
||||
*/
|
||||
int cis_call;
|
||||
/*! \brief TRUE if we will auto disconnect the cis_call we originated. */
|
||||
int cis_auto_disconnect;
|
||||
|
||||
int progcode; /* Progress coding */
|
||||
int progloc; /* Progress Location */
|
||||
|
74
q931.c
74
q931.c
@ -650,13 +650,13 @@ static int receive_channel_id(int full_ie, struct pri *ctrl, q931_call *call, in
|
||||
#ifndef NOAUTO_CHANNEL_SELECTION_SUPPORT
|
||||
if (ctrl->bri) {
|
||||
if (!(ie->data[0] & 3))
|
||||
call->justsignalling = 1;
|
||||
call->cis_call = 1;
|
||||
else
|
||||
call->channelno = ie->data[0] & 3;
|
||||
} else {
|
||||
switch (ie->data[0] & 3) {
|
||||
case 0:
|
||||
call->justsignalling = 1;
|
||||
call->cis_call = 1;
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
@ -719,10 +719,14 @@ static int transmit_channel_id(int full_ie, struct pri *ctrl, q931_call *call, i
|
||||
/* We are ready to transmit single IE only */
|
||||
if (order > 1)
|
||||
return 0;
|
||||
|
||||
if (call->justsignalling) {
|
||||
ie->data[pos++] = 0xac; /* Read the standards docs to figure this out
|
||||
ECMA-165 section 7.3 */
|
||||
|
||||
if (call->cis_call) {
|
||||
/*
|
||||
* Read the standards docs to figure this out.
|
||||
* Q.SIG ECMA-165 section 7.3
|
||||
* ITU Q.931 section 4.5.13
|
||||
*/
|
||||
ie->data[pos++] = ctrl->bri ? 0x8c : 0xac;
|
||||
return pos + 2;
|
||||
}
|
||||
|
||||
@ -1178,20 +1182,20 @@ static int transmit_bearer_capability(int full_ie, struct pri *ctrl, q931_call *
|
||||
if(order > 1)
|
||||
return 0;
|
||||
|
||||
tc = call->transcapability;
|
||||
if (ctrl->subchannel && !ctrl->bri) {
|
||||
/* Bearer capability is *hard coded* in GR-303 */
|
||||
ie->data[0] = 0x88;
|
||||
ie->data[1] = 0x90;
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (call->justsignalling) {
|
||||
|
||||
if (call->cis_call) {
|
||||
ie->data[0] = 0xa8;
|
||||
ie->data[1] = 0x80;
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
tc = call->transcapability;
|
||||
ie->data[0] = 0x80 | tc;
|
||||
ie->data[1] = call->transmoderate | 0x80;
|
||||
|
||||
@ -3804,7 +3808,8 @@ static int setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_F
|
||||
|
||||
static int gr303_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, -1 };
|
||||
|
||||
static int cis_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_CALLED_PARTY_NUMBER, -1 };
|
||||
/*! Call Independent Signalling SETUP ie's */
|
||||
static int cis_setup_ies[] = { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_CALLING_PARTY_NUMBER, Q931_CALLED_PARTY_NUMBER, Q931_SENDING_COMPLETE, -1 };
|
||||
|
||||
int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
{
|
||||
@ -3830,7 +3835,8 @@ int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
c->slotmap = -1;
|
||||
c->nonisdn = req->nonisdn;
|
||||
c->newcall = 0;
|
||||
c->justsignalling = req->justsignalling;
|
||||
c->cis_call = req->cis_call;
|
||||
c->cis_auto_disconnect = req->cis_auto_disconnect;
|
||||
c->complete = req->numcomplete;
|
||||
if (req->exclusive)
|
||||
c->chanflags = FLAG_EXCLUSIVE;
|
||||
@ -3871,7 +3877,7 @@ int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
|
||||
if (ctrl->subchannel && !ctrl->bri)
|
||||
res = send_message(ctrl, c, Q931_SETUP, gr303_setup_ies);
|
||||
else if (c->justsignalling)
|
||||
else if (c->cis_call)
|
||||
res = send_message(ctrl, c, Q931_SETUP, cis_setup_ies);
|
||||
else
|
||||
res = send_message(ctrl, c, Q931_SETUP, setup_ies);
|
||||
@ -3936,15 +3942,29 @@ int q931_hangup(struct pri *ctrl, q931_call *c, int cause)
|
||||
/* If mandatory IE was missing, insist upon that cause code */
|
||||
if (c->cause == PRI_CAUSE_MANDATORY_IE_MISSING)
|
||||
cause = c->cause;
|
||||
if (cause == 34 || cause == 44 || cause == 82 || cause == 1 || cause == 81) {
|
||||
switch (cause) {
|
||||
case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
|
||||
case PRI_CAUSE_REQUESTED_CHAN_UNAVAIL:
|
||||
case PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST:
|
||||
case PRI_CAUSE_UNALLOCATED:
|
||||
case PRI_CAUSE_INVALID_CALL_REFERENCE:
|
||||
/* We'll send RELEASE_COMPLETE with these causes */
|
||||
disconnect = 0;
|
||||
release_compl = 1;
|
||||
}
|
||||
if (cause == 6 || cause == 7 || cause == 26) {
|
||||
break;
|
||||
case PRI_CAUSE_CHANNEL_UNACCEPTABLE:
|
||||
case PRI_CAUSE_CALL_AWARDED_DELIVERED:
|
||||
case 26:
|
||||
/* We'll send RELEASE with these causes */
|
||||
disconnect = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (c->cis_call) {
|
||||
disconnect = 0;
|
||||
}
|
||||
|
||||
/* All other causes we send with DISCONNECT */
|
||||
switch(c->ourcallstate) {
|
||||
case Q931_CALL_STATE_NULL:
|
||||
@ -3973,21 +3993,34 @@ int q931_hangup(struct pri *ctrl, q931_call *c, int cause)
|
||||
case Q931_CALL_STATE_OVERLAP_RECEIVING:
|
||||
/* received SETUP_ACKNOWLEDGE */
|
||||
/* send DISCONNECT in general */
|
||||
if (c->peercallstate != Q931_CALL_STATE_NULL && c->peercallstate != Q931_CALL_STATE_DISCONNECT_REQUEST && c->peercallstate != Q931_CALL_STATE_DISCONNECT_INDICATION && c->peercallstate != Q931_CALL_STATE_RELEASE_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART_REQUEST && c->peercallstate != Q931_CALL_STATE_RESTART) {
|
||||
switch (c->peercallstate) {
|
||||
default:
|
||||
if (disconnect)
|
||||
q931_disconnect(ctrl,c,cause);
|
||||
else if (release_compl)
|
||||
q931_release_complete(ctrl,c,cause);
|
||||
else
|
||||
q931_release(ctrl,c,cause);
|
||||
} else
|
||||
break;
|
||||
case Q931_CALL_STATE_NULL:
|
||||
case Q931_CALL_STATE_DISCONNECT_REQUEST:
|
||||
case Q931_CALL_STATE_DISCONNECT_INDICATION:
|
||||
case Q931_CALL_STATE_RELEASE_REQUEST:
|
||||
case Q931_CALL_STATE_RESTART_REQUEST:
|
||||
case Q931_CALL_STATE_RESTART:
|
||||
pri_error(ctrl,
|
||||
"Wierd, doing nothing but this shouldn't happen, ourstate %s, peerstate %s\n",
|
||||
q931_call_state_str(c->ourcallstate),
|
||||
q931_call_state_str(c->peercallstate));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Q931_CALL_STATE_ACTIVE:
|
||||
/* received CONNECT */
|
||||
if (c->cis_call) {
|
||||
q931_release(ctrl, c, cause);
|
||||
break;
|
||||
}
|
||||
q931_disconnect(ctrl,c,cause);
|
||||
break;
|
||||
case Q931_CALL_STATE_DISCONNECT_REQUEST:
|
||||
@ -4621,8 +4654,9 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
|
||||
q931_connect_acknowledge(ctrl, c);
|
||||
|
||||
if (c->justsignalling) { /* Make sure WE release when we initiatie a signalling only connection */
|
||||
q931_release(ctrl, c, PRI_CAUSE_NORMAL_CLEARING);
|
||||
if (c->cis_auto_disconnect && c->cis_call) {
|
||||
/* Make sure WE release when we initiate a signalling only connection */
|
||||
q931_hangup(ctrl, c, PRI_CAUSE_NORMAL_CLEARING);
|
||||
break;
|
||||
} else {
|
||||
c->incoming_ct_state = INCOMING_CT_STATE_IDLE;
|
||||
|
Loading…
Reference in New Issue
Block a user