Minor code clean up.

git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@794 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett 2009-05-07 16:21:24 +00:00
parent a5b9b792ea
commit 5484712af0
3 changed files with 91 additions and 126 deletions

View File

@ -177,7 +177,6 @@ struct apdu_event {
struct q931_call { struct q931_call {
struct pri *pri; /* PRI */ struct pri *pri; /* PRI */
int cr; /* Call Reference */ int cr; /* Call Reference */
int forceinvert; /* Force inversion of call number even if 0 */
q931_call *next; q931_call *next;
/* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */ /* Slotmap specified (bitmap of channels 31/24-1) (Channel Identifier IE) (-1 means not specified) */
int slotmap; int slotmap;
@ -270,7 +269,7 @@ struct q931_call {
unsigned int rlt_call_id; /* RLT call id */ unsigned int rlt_call_id; /* RLT call id */
/* Bridged call info */ /* Bridged call info */
q931_call *bridged_call; /* Pointer to other leg of bridged call */ q931_call *bridged_call; /* Pointer to other leg of bridged call (Used by Q.SIG when eliminating tromboned calls) */
int changestatus; /* SERVICE message changestatus */ int changestatus; /* SERVICE message changestatus */
}; };

View File

@ -30,44 +30,6 @@
#ifndef _PRI_Q931_H #ifndef _PRI_Q931_H
#define _PRI_Q931_H #define _PRI_Q931_H
typedef enum q931_state {
/* User states */
U0_NULL_STATE,
U1_CALL_INITIATED,
U2_OVERLAP_SENDING,
U3_OUTGOING_CALL_PROCEEDING,
U4_CALL_DELIVERED,
U6_CALL_PRESENT,
U7_CALL_RECEIVED,
U8_CONNECT_REQUEST,
U9_INCOMING_CALL_PROCEEDING,
U10_ACTIVE,
U11_DISCONNECT_REQUEST,
U12_DISCONNECT_INDICATION,
U15_SUSPEND_REQUEST,
U17_RESUME_REQUEST,
U19_RELEASE_REQUEST,
U25_OVERLAP_RECEIVING,
/* Network states */
N0_NULL_STATE,
N1_CALL_INITIATED,
N2_OVERLAP_SENDING,
N3_OUTGOING_CALL_PROCEEDING,
N4_CALL_DELIVERED,
N6_CALL_PRESENT,
N7_CALL_RECEIVED,
N8_CONNECT_REQUEST,
N9_INCOMING_CALL_PROCEEDING,
N10_ACTIVE,
N11_DISCONNECT_REQUEST,
N12_DISCONNECT_INDICATION,
N15_SUSPEND_REQUEST,
N17_RESUME_REQUEST,
N19_RELEASE_REQUEST,
N22_CALL_ABORT,
N25_OVERLAP_RECEIVING
} q931_state;
typedef enum q931_mode { typedef enum q931_mode {
UNKNOWN_MODE, UNKNOWN_MODE,
CIRCUIT_MODE, CIRCUIT_MODE,

176
q931.c
View File

@ -276,17 +276,6 @@ static char *pritype(int type)
} }
} }
static void call_init(struct q931_call *c)
{
c->forceinvert = -1;
c->cr = -1;
c->slotmap = -1;
c->channelno = -1;
c->newcall = 1;
c->ourcallstate = Q931_CALL_STATE_NULL;
c->peercallstate = Q931_CALL_STATE_NULL;
}
static char *binary(int b, int len) { static char *binary(int b, int len) {
static char res[33]; static char res[33];
int x; int x;
@ -2352,52 +2341,65 @@ static inline void q931_dumpie(struct pri *pri, int codeset, q931_ie *ie, char p
pri_error(pri, "!! %c Unknown IE %d (cs%d, len = %d)\n", prefix, Q931_IE_IE(base_ie), Q931_IE_CODESET(base_ie), ielen(ie)); pri_error(pri, "!! %c Unknown IE %d (cs%d, len = %d)\n", prefix, Q931_IE_IE(base_ie), Q931_IE_CODESET(base_ie), ielen(ie));
} }
static q931_call *q931_getcall(struct pri *pri, int cr, int outboundnew) static q931_call *q931_getcall(struct pri *ctrl, int cr)
{ {
q931_call *cur, *prev; q931_call *cur;
q931_call *prev;
struct pri *master; struct pri *master;
/* Find the master - He has the call pool */ /* Find the master - He has the call pool */
if (pri->master) if (ctrl->master) {
master = pri->master; master = ctrl->master;
else } else {
master = pri; master = ctrl;
}
cur = *master->callpool; cur = *master->callpool;
prev = NULL; prev = NULL;
while(cur) { while (cur) {
if (cur->cr == cr) if (cur->cr == cr) {
return cur; return cur;
}
prev = cur; prev = cur;
cur = cur->next; cur = cur->next;
} }
/* No call exists, make a new one */
if (pri->debug & PRI_DEBUG_Q931_STATE)
pri_message(pri, "-- Making new call for cr %d\n", cr);
if (!(cur = calloc(1, sizeof(*cur))))
return NULL;
call_init(cur); /* No call exists, make a new one */
/* Call reference */ if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
pri_message(ctrl, "-- Making new call for cr %d\n", cr);
}
cur = calloc(1, sizeof(*cur));
if (!cur) {
return NULL;
}
/* Initialize call structure. */
cur->cr = cr; cur->cr = cr;
cur->slotmap = -1;
cur->channelno = -1;
cur->newcall = 1;
cur->ourcallstate = Q931_CALL_STATE_NULL;
cur->peercallstate = Q931_CALL_STATE_NULL;
/* PRI is set to whoever called us */ /* PRI is set to whoever called us */
if (pri->bri && (pri->localtype == PRI_CPE)) { if (ctrl->bri && (ctrl->localtype == PRI_CPE)) {
/* /*
* Point to the master to avoid stale pointer problems if * Point to the master to avoid stale pointer problems if
* the TEI is removed later. * the TEI is removed later.
*/ */
cur->pri = master; cur->pri = master;
} else { } else {
cur->pri = pri; cur->pri = ctrl;
} }
/* Append to end of list */ /* Append to end of list */
if (prev) if (prev) {
prev->next = cur; prev->next = cur;
else } else {
*master->callpool = cur; *master->callpool = cur;
}
return cur; return cur;
} }
@ -2422,7 +2424,7 @@ q931_call *q931_new_call(struct pri *pri)
} }
} while(cur); } while(cur);
return q931_getcall(pri, pri->cref | 0x8000, 1); return q931_getcall(pri, pri->cref | 0x8000);
} }
static void q931_destroy(struct pri *pri, int cr, q931_call *c) static void q931_destroy(struct pri *pri, int cr, q931_call *c)
@ -2454,17 +2456,17 @@ static void q931_destroy(struct pri *pri, int cr, q931_call *c)
pri_error(pri, "Can't destroy call %d!\n", cr); pri_error(pri, "Can't destroy call %d!\n", cr);
} }
static void q931_destroycall(struct pri *pri, int cr) static void q931_destroycall(struct pri *ctrl, int cr)
{ {
return q931_destroy(pri, cr, NULL); q931_destroy(ctrl, cr, NULL);
} }
void __q931_destroycall(struct pri *pri, q931_call *c) void __q931_destroycall(struct pri *ctrl, q931_call *call)
{ {
if (pri && c) if (ctrl && call) {
q931_destroy(pri,0, c); q931_destroy(ctrl, 0, call);
return; }
} }
static int add_ie(struct pri *pri, q931_call *call, int msgtype, int ie, q931_ie *iet, int maxlen, int *codeset) static int add_ie(struct pri *pri, q931_call *call, int msgtype, int ie, q931_ie *iet, int maxlen, int *codeset)
@ -2540,9 +2542,15 @@ void q931_dump(struct pri *pri, q931_h *h, int len, int txrx)
int x=0, r; int x=0, r;
int cur_codeset; int cur_codeset;
int codeset; int codeset;
int cref;
c = txrx ? '>' : '<'; c = txrx ? '>' : '<';
pri_message(pri, "%c Protocol Discriminator: %s (%d) len=%d\n", c, disc2str(h->pd), h->pd, len); pri_message(pri, "%c Protocol Discriminator: %s (%d) len=%d\n", c, disc2str(h->pd), h->pd, len);
pri_message(pri, "%c Call Ref: len=%2d (reference %d/0x%X) (%s)\n", c, h->crlen, q931_cr(h) & 0x7FFF, q931_cr(h) & 0x7FFF, (h->crv[0] & 0x80) ? "Terminator" : "Originator"); cref = q931_cr(h);
pri_message(pri, "%c Call Ref: len=%2d (reference %d/0x%X) (%s)\n",
c, h->crlen, cref & 0x7FFF, cref & 0x7FFF,
(cref & 0x8000) ? "Terminator" : "Originator");
/* Message header begins at the end of the call reference number */ /* Message header begins at the end of the call reference number */
mh = (q931_mh *)(h->contents + h->crlen); mh = (q931_mh *)(h->contents + h->crlen);
if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) { if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
@ -2595,49 +2603,44 @@ static int q931_handle_ie(int codeset, struct pri *pri, q931_call *c, int msg, q
return -1; return -1;
} }
static void init_header(struct pri *pri, q931_call *call, unsigned char *buf, q931_h **hb, q931_mh **mhb, int *len, int protodisc) /* Returns header and message header and modifies length in place */
static void init_header(struct pri *ctrl, q931_call *call, unsigned char *buf, q931_h **hb, q931_mh **mhb, int *len, int protodisc)
{ {
/* Returns header and message header and modifies length in place */ q931_h *h = (q931_h *) buf;
q931_h *h = (q931_h *)buf; q931_mh *mh;
q931_mh * mh; unsigned crv;
if (protodisc) { if (protodisc) {
h->pd = protodisc; h->pd = protodisc;
} else { } else {
h->pd = pri->protodisc; h->pd = ctrl->protodisc;
} }
h->x0 = 0; /* Reserved 0 */ h->x0 = 0; /* Reserved 0 */
if (!pri->bri) { if (!ctrl->bri) {
h->crlen = 2; /* Two bytes of Call Reference. Invert the top bit to make it from our sense */ /* Two bytes of Call Reference. */
if (call->cr || call->forceinvert) { h->crlen = 2;
h->crv[0] = ((call->cr ^ 0x8000) & 0xff00) >> 8; /* Invert the top bit to make it from our sense */
h->crv[1] = (call->cr & 0xff); crv = (unsigned) call->cr;
} else { h->crv[0] = ((crv >> 8) ^ 0x80) & 0xff;
/* Unless of course this has no call reference */ h->crv[1] = crv & 0xff;
h->crv[0] = 0; if (ctrl->subchannel && !ctrl->bri) {
h->crv[1] = 0;
}
if (pri->subchannel && !pri->bri) {
/* On GR-303, top bit is always 0 */ /* On GR-303, top bit is always 0 */
h->crv[0] &= 0x7f; h->crv[0] &= 0x7f;
} }
} else { } else {
h->crlen = 1; h->crlen = 1;
if (call->cr || call->forceinvert) { /* Invert the top bit to make it from our sense */
h->crv[0] = (((call->cr ^ 0x8000) & 0x8000) >> 8) | (call->cr & 0x7f); crv = (unsigned) call->cr;
} else { h->crv[0] = (((crv >> 8) ^ 0x80) & 0x80) | (crv & 0x7f);
/* Unless of course this has no call reference */
h->crv[0] = 0;
}
} }
mh = (q931_mh *)(h->contents + h->crlen);
mh->f = 0;
*hb = h; *hb = h;
*len -= 3;/* Protocol discriminator, call reference length, message type id */
*len -= h->crlen;
mh = (q931_mh *) (h->contents + h->crlen);
mh->f = 0;
*mhb = mh; *mhb = mh;
if (h->crlen == 2)
*len -= 5;
else
*len -= 4;
} }
static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr) static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr)
@ -2654,7 +2657,7 @@ static int q931_xmit(struct pri *pri, q931_h *h, int len, int cr)
return 0; return 0;
} }
static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[]) static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[])
{ {
unsigned char buf[1024]; unsigned char buf[1024];
q931_h *h; q931_h *h;
@ -2664,18 +2667,17 @@ static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[])
int offset=0; int offset=0;
int x; int x;
int codeset; int codeset;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
len = sizeof(buf); len = sizeof(buf);
init_header(pri, c, buf, &h, &mh, &len, (msgtype >> 8)); init_header(ctrl, call, buf, &h, &mh, &len, (msgtype >> 8));
mh->msg = msgtype & 0x00ff; mh->msg = msgtype & 0x00ff;
x=0; x=0;
codeset = 0; codeset = 0;
while(ies[x] > -1) { while(ies[x] > -1) {
res = add_ie(pri, c, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset); res = add_ie(ctrl, call, mh->msg, ies[x], (q931_ie *)(mh->data + offset), len, &codeset);
if (res < 0) { if (res < 0) {
pri_error(pri, "!! Unable to add IE '%s'\n", ie2str(ies[x])); pri_error(ctrl, "!! Unable to add IE '%s'\n", ie2str(ies[x]));
return -1; return -1;
} }
@ -2686,19 +2688,19 @@ static int send_message(struct pri *pri, q931_call *c, int msgtype, int ies[])
/* Invert the logic */ /* Invert the logic */
len = sizeof(buf) - len; len = sizeof(buf) - len;
pri = c->pri; ctrl = call->pri;
if (pri->bri && (pri->localtype == PRI_CPE)) { if (ctrl->bri && (ctrl->localtype == PRI_CPE)) {
/* /*
* Must use the BRI subchannel structure to send with the correct TEI. * Must use the BRI subchannel structure to send with the correct TEI.
* Note: If the subchannel is NULL then there is no TEI assigned and * Note: If the subchannel is NULL then there is no TEI assigned and
* we should not be sending anything out at this time. * we should not be sending anything out at this time.
*/ */
pri = pri->subchannel; ctrl = ctrl->subchannel;
} }
if (pri) { if (ctrl) {
q931_xmit(pri, h, len, 1); q931_xmit(ctrl, h, len, 1);
} }
c->acked = 1; call->acked = 1;
return 0; return 0;
} }
@ -2712,7 +2714,7 @@ int maintenance_service_ack(struct pri *pri, q931_call *c)
int maintenance_service(struct pri *pri, int span, int channel, int changestatus) int maintenance_service(struct pri *pri, int span, int channel, int changestatus)
{ {
struct q931_call *c; struct q931_call *c;
c = q931_getcall(pri, 0x8000, 0); c = q931_getcall(pri, 0 | 0x8000);
if (!c) { if (!c) {
return -1; return -1;
} }
@ -3055,7 +3057,7 @@ static int restart_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 };
int q931_restart(struct pri *pri, int channel) int q931_restart(struct pri *pri, int channel)
{ {
struct q931_call *c; struct q931_call *c;
c = q931_getcall(pri, 0 | 0x8000, 1); c = q931_getcall(pri, 0 | 0x8000);
if (!c) if (!c)
return -1; return -1;
if (!channel) if (!channel)
@ -3504,6 +3506,7 @@ int q931_receive(struct pri *pri, q931_h *h, int len)
int missingmand; int missingmand;
int codeset, cur_codeset; int codeset, cur_codeset;
int last_ie[8]; int last_ie[8];
int cref;
memset(last_ie, 0, sizeof(last_ie)); memset(last_ie, 0, sizeof(last_ie));
if (pri->debug & PRI_DEBUG_Q931_DUMP) if (pri->debug & PRI_DEBUG_Q931_DUMP)
@ -3527,9 +3530,10 @@ int q931_receive(struct pri *pri, q931_h *h, int len)
q931_xmit(pri, h, len, 1); q931_xmit(pri, h, len, 1);
return 0; return 0;
} }
c = q931_getcall(pri, q931_cr(h), 0); cref = q931_cr(h);
c = q931_getcall(pri, cref);
if (!c) { if (!c) {
pri_error(pri, "Unable to locate call %d\n", q931_cr(h)); pri_error(pri, "Unable to locate call %d\n", cref);
return -1; return -1;
} }
/* Preliminary handling */ /* Preliminary handling */