From 14c3616e02a82577315458774b0f482b4d3eafed Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 26 Apr 2010 19:54:00 +0000 Subject: [PATCH] Simplified some protocol discriminator handling code. git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1675 2fbb986a-6c06-0410-b554-c9c1f0a7f128 --- q931.c | 102 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/q931.c b/q931.c index c8c3345..d1b0325 100644 --- a/q931.c +++ b/q931.c @@ -3890,12 +3890,23 @@ static char *disc2str(int disc) static struct msgtype discs[] = { { Q931_PROTOCOL_DISCRIMINATOR, "Q.931" }, { GR303_PROTOCOL_DISCRIMINATOR, "GR-303" }, - { 0x3, "AT&T Maintenance" }, - { 0x43, "New AT&T Maintenance" }, + { MAINTENANCE_PROTOCOL_DISCRIMINATOR_1, "AT&T Maintenance" }, + { MAINTENANCE_PROTOCOL_DISCRIMINATOR_2, "New AT&T Maintenance" }, }; return code2str(disc, discs, sizeof(discs) / sizeof(discs[0])); } +/*! + * \brief Debug dump the given Q.931 packet. + * + * \param ctrl D channel controller. + * \param tei TEI the packet is associated with. + * \param h Q.931 packet contents/header. + * \param len Received length of the Q.931 packet + * \param txrx TRUE if packet is transmitted/outgoing + * + * \return Nothing + */ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx) { q931_mh *mh; @@ -3907,6 +3918,7 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx) int cref; c = txrx ? '>' : '<'; + pri_message(ctrl, "%c Protocol Discriminator: %s (%d) len=%d\n", c, disc2str(h->pd), h->pd, len); if (len < 2 || len < 2 + h->crlen) { @@ -3930,10 +3942,17 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx) /* Message header begins at the end of the call reference number */ mh = (q931_mh *)(h->contents + h->crlen); - if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) { + switch (h->pd) { + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1: + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2: pri_message(ctrl, "%c Message Type: %s (%d)\n", c, maintenance_msg2str(mh->msg, h->pd), mh->msg); - } else { + break; + default: + /* Unknown protocol discriminator but we will treat it as Q.931 anyway. */ + case GR303_PROTOCOL_DISCRIMINATOR: + case Q931_PROTOCOL_DISCRIMINATOR: pri_message(ctrl, "%c Message Type: %s (%d)\n", c, msg2str(mh->msg), mh->msg); + break; } /* Drop length of header, including call reference */ len -= (h->crlen + 3); @@ -3958,6 +3977,7 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx) default: /* Reset temporary codeset change */ cur_codeset = codeset; + break; } } } @@ -5882,6 +5902,8 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) int codeset, cur_codeset; int last_ie[8]; int cref; + int allow_event; + int allow_posthandle; memset(last_ie, 0, sizeof(last_ie)); if (ctrl->debug & PRI_DEBUG_Q931_DUMP) @@ -5893,21 +5915,29 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) /* Message too short for supported protocols. */ return -1; } - mh = (q931_mh *)(h->contents + h->crlen); - if ((h->pd != ctrl->protodisc) && (h->pd != MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) && (h->pd != MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) { - pri_error(ctrl, "Warning: unknown/inappropriate protocol discriminator received (%02x/%d)\n", h->pd, h->pd); - return 0; - } - if (((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) && (!ctrl->service_message_support)) { - /* Real service message support has not been enabled (and is OFF in libpri by default), - * so we have to revert to the 'traditional' KLUDGE of changing byte 4 from a 0xf (SERVICE) - * to a 0x7 (SERVICE ACKNOWLEDGE) */ - /* This is the weird maintenance stuff. We majorly - KLUDGE this by changing byte 4 from a 0xf (SERVICE) - to a 0x7 (SERVICE ACKNOWLEDGE) */ - h->raw[h->crlen + 2] -= 0x8; - q931_xmit(ctrl, ctrl->tei, h, len, 1, 0); - return 0; + switch (h->pd) { + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1: + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2: + if (!ctrl->service_message_support) { + /* Real service message support has not been enabled (and is OFF in libpri by default), + * so we have to revert to the 'traditional' KLUDGE of changing byte 4 from a 0xf (SERVICE) + * to a 0x7 (SERVICE ACKNOWLEDGE) */ + /* This is the weird maintenance stuff. We majorly + KLUDGE this by changing byte 4 from a 0xf (SERVICE) + to a 0x7 (SERVICE ACKNOWLEDGE) */ + h->raw[h->crlen + 2] -= 0x8; + q931_xmit(ctrl, ctrl->tei, h, len, 1, 0); + return 0; + } + break; + default: + if (h->pd != ctrl->protodisc) { + pri_error(ctrl, + "Warning: unknown/inappropriate protocol discriminator received (%02x/%d)\n", + h->pd, h->pd); + return 0; + } + break; } cref = q931_cr(h); @@ -5936,19 +5966,27 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) ctrl->facility.count = 0; c->connected_number_in_message = 0; c->redirecting_number_in_message = 0; - if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) { + mh = (q931_mh *)(h->contents + h->crlen); + switch (h->pd) { + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1: + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2: prepare_to_handle_maintenance_message(ctrl, mh, c); - } else { + break; + default: + /* Unknown protocol discriminator but we will treat it as Q.931 anyway. */ + case GR303_PROTOCOL_DISCRIMINATOR: + case Q931_PROTOCOL_DISCRIMINATOR: prepare_to_handle_q931_message(ctrl, mh, c); + break; } q931_clr_subcommands(ctrl); /* Handle IEs */ memset(mandies, 0, sizeof(mandies)); - missingmand = 0; - for (x=0;xmsg) { memcpy(mandies, msgs[x].mandies, sizeof(mandies)); + break; } } /* Do real IE processing */ @@ -5966,7 +6004,7 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) } return -1; } - for (y=0;yie)) mandies[y] = 0; } @@ -6015,13 +6053,15 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) /* XXX Applicable to codeset 0 only? XXX */ if (!cur_codeset && !(ie->ie & 0xf0) && (y < 0)) mandies[MAX_MAND_IES - 1] = Q931_FULL_IE(cur_codeset, ie->ie); + break; } /* Reset current codeset */ cur_codeset = codeset; + break; } } missingmand = 0; - for (x=0;x that's not an error */ if (((ctrl->localtype != PRI_NETWORK) || (mh->msg != Q931_SETUP) || (mandies[x] != Q931_CHANNEL_IDENT)) && @@ -6036,10 +6076,14 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) q931_handle_facilities(ctrl, c, mh->msg); /* Post handling */ - if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) { + switch (h->pd) { + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_1: + case MAINTENANCE_PROTOCOL_DISCRIMINATOR_2: res = post_handle_maintenance_message(ctrl, h->pd, mh, c); - } else { - int allow_event = 1, allow_posthandle = 1; + break; + default: + allow_event = 1; + allow_posthandle = 1; if (c->master_call->outboundbroadcast) { nt_ptmp_handle_q931_message(ctrl, mh, c, &allow_event, &allow_posthandle); @@ -6047,13 +6091,13 @@ int q931_receive(struct pri *ctrl, int tei, q931_h *h, int len) if (allow_posthandle) { res = post_handle_q931_message(ctrl, mh, c, missingmand); - if (res == Q931_RES_HAVEEVENT && !allow_event) { res = 0; } } else { res = 0; } + break; } return res; }