ooq931.c

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 1,944 行 · 第 1/5 页

C
1,944
字号
/* * Copyright (C) 2004-2005 by Objective Systems, Inc. * * This software is furnished under an open source license and may be  * used and copied only in accordance with the terms of this license.  * The text of the license may generally be found in the root  * directory of this installation in the COPYING file.  It  * can also be viewed online at the following URL: * *   http://www.obj-sys.com/open/license.html * * Any redistributions of this file including modified versions must  * maintain this copyright notice. * *****************************************************************************/#include "ooq931.h"#include "ootrace.h"#include "ooasn1.h"#include "oochannels.h"#include "printHandler.h"#include "ooCalls.h"#include "ooh323.h"#include "ooh245.h"#include "ooh323ep.h"#include "ooCapability.h"#include "ooGkClient.h"#include "ooUtils.h"#include "ootypes.h"#include <time.h>#include <ctype.h>/** Global endpoint structure */extern OOH323EndPoint gH323ep;static ASN1OBJID gProtocolID = {   6, { 0, 0, 8, 2250, 0, 4 }};EXTERN int ooQ931Decode    (OOH323CallData *call, Q931Message* msg, int length, ASN1OCTET *data) {   int offset, x;   int rv = ASN_OK;   char number[128];   OOCTXT *pctxt = &gH323ep.msgctxt;   dListInit (&msg->ies); /* clear information elements list */   if (length < 5)  /* Packet too short */      return Q931_E_TOOSHORT;   msg->protocolDiscriminator = data[0];   OOTRACEDBGB2("   protocolDiscriminator = %d\n", msg->protocolDiscriminator);   if (data[1] != 2) /* Call reference must be 2 bytes long */      return Q931_E_INVCALLREF;   msg->callReference = ((data[2] & 0x7f) << 8) | data[3];   OOTRACEDBGB2("   callReference = %d\n", msg->callReference);   msg->fromDestination = (data[2] & 0x80) != 0;   if(msg->fromDestination)      OOTRACEDBGB1("   from = destination\n");   else      OOTRACEDBGB1("   from = originator\n");      msg->messageType = data[4];   OOTRACEDBGB2("   messageType = %x\n", msg->messageType);      /* Have preamble, start getting the informationElements into buffers */   offset = 5;   while (offset < length) {      Q931InformationElement *ie;      int ieOff = offset;      /* Get field discriminator */      int discriminator = data[offset++];      /* For discriminator with high bit set there is no data */      if ((discriminator & 0x80) == 0) {         int len = data[offset++], alen;         if (discriminator == Q931UserUserIE) {            /* Special case of User-user field, there is some confusion here as               the Q931 documentation claims the length is a single byte,               unfortunately all H.323 based apps have a 16 bit length here, so               we allow for said longer length. There is presumably an addendum               to Q931 which describes this, and provides a means to                discriminate between the old 1 byte and the new 2 byte systems.                However, at present we assume it is always 2 bytes until we find               something that breaks it.             */            len <<= 8;            len |= data[offset++];            /* we also have a protocol discriminator, which we ignore */            offset++;            len--;         }         /* watch out for negative lengths! (ED, 11/5/03) */         if (len < 0) {            return Q931_E_INVLENGTH;         }         else if (offset + len > length) {            alen = 0;            len = -len;            rv = Q931_E_INVLENGTH;         }         else alen = len;         ie = (Q931InformationElement*)             memAlloc (pctxt, sizeof(*ie) - sizeof(ie->data) + alen);         if(!ie)         {            OOTRACEERR3("Error:Memory - ooQ931Decode - ie(%s, %s)\n",                          call->callType, call->callToken);            return OO_FAILED;         }         ie->discriminator = discriminator;         ie->offset = ieOff;         ie->length = len;         if (alen != 0)             memcpy(ie->data, data + offset, alen);         offset += len;      }      else {         ie = (Q931InformationElement*) memAlloc (pctxt,                                         sizeof(*ie) - sizeof(ie->data));         if(!ie)         {            OOTRACEERR3("Error:Memory - ooQ931Decode - ie(%s, %s)\n",                          call->callType, call->callToken);            return OO_FAILED;         }         ie->discriminator = discriminator;         ie->offset = offset;         ie->length = 0;      }      if(ie->discriminator == Q931BearerCapabilityIE)      {         OOTRACEDBGB1("   Bearer-Capability IE = {\n");         for(x=0; x<ie->length; x++)         {            if(x==0)               OOTRACEDBGB2("      %x", ie->data[x]);            else               OOTRACEDBGB2(", %x", ie->data[x]);         }         OOTRACEDBGB1("   }\n");      }      if(ie->discriminator == Q931DisplayIE)      {         OOTRACEDBGB1("   Display IE = {\n");         OOTRACEDBGB2("      %s\n", ie->data);         OOTRACEDBGB1("   }\n");      }      if(ie->discriminator == Q931KeypadIE)      {	 OOTRACEDBGB1("   Keypad IE = {\n");         OOTRACEDBGB2("      %s\n", ie->data);         OOTRACEDBGB1("   }\n");         if(gH323ep.h323Callbacks.onReceivedDTMF)         {	    gH323ep.h323Callbacks.onReceivedDTMF(call, ie->data);         }      }      /* Extract calling party number TODO:Give respect to presentation and          screening indicators ;-) */      if(ie->discriminator == Q931CallingPartyNumberIE)      {	 OOTRACEDBGB1("   CallingPartyNumber IE = {\n");         if(ie->length < OO_MAX_NUMBER_LENGTH)         {            int numoffset=1;             if(!(0x80 & ie->data[0])) numoffset = 2;            memcpy(number, ie->data+numoffset,ie->length-numoffset);            number[ie->length-numoffset]='\0';            OOTRACEDBGB2("      %s\n", number);            if(!call->callingPartyNumber)               ooCallSetCallingPartyNumber(call, number);         }else{            OOTRACEERR3("Error:Calling party number too long. (%s, %s)\n",                            call->callType, call->callToken);         }         OOTRACEDBGB1("   }\n");      }      /* Extract called party number */      if(ie->discriminator == Q931CalledPartyNumberIE)      {         OOTRACEDBGB1("   CalledPartyNumber IE = {\n");         if(ie->length < OO_MAX_NUMBER_LENGTH)         {            memcpy(number, ie->data+1,ie->length-1);            number[ie->length-1]='\0';            OOTRACEDBGB2("      %s\n", number);            if(!call->calledPartyNumber)               ooCallSetCalledPartyNumber(call, number);         }else{            OOTRACEERR3("Error:Calling party number too long. (%s, %s)\n",                            call->callType, call->callToken);         }         OOTRACEDBGB1("   }\n");      }      /* Handle Cause ie */      if(ie->discriminator == Q931CauseIE)      {         msg->causeIE = ie;         OOTRACEDBGB1("   Cause IE = {\n");         OOTRACEDBGB2("      %s\n", ooGetQ931CauseValueText(ie->data[1]&0x7f));         OOTRACEDBGB1("   }\n");      }      /* TODO: Get rid of ie list.*/      dListAppend (pctxt, &msg->ies, ie);      if (rv != ASN_OK)         return rv;   }      /*cisco router sends Q931Notify without UU ie,      we just ignore notify message as of now as handling is optional for     end point*/   if(msg->messageType != Q931NotifyMsg)      rv = ooDecodeUUIE(msg);   return rv;}EXTERN Q931InformationElement* ooQ931GetIE (const Q931Message* q931msg,                                               int ieCode){   DListNode* curNode;   unsigned int i;   for(i = 0, curNode = q931msg->ies.head; i < q931msg->ies.count; i++) {      Q931InformationElement *ie = (Q931InformationElement*) curNode->data;      if (ie->discriminator == ieCode) {         return ie;      }      curNode = curNode->next;   }   return NULL;}char* ooQ931GetMessageTypeName(int messageType, char* buf) {   switch (messageType) {      case Q931AlertingMsg :         strcpy(buf, "Alerting");         break;      case Q931CallProceedingMsg :         strcpy(buf, "CallProceeding");         break;      case Q931ConnectMsg :         strcpy(buf, "Connect");         break;      case Q931ConnectAckMsg :         strcpy(buf, "ConnectAck");         break;      case Q931ProgressMsg :         strcpy(buf, "Progress");         break;      case Q931SetupMsg :         strcpy(buf, "Setup");         break;      case Q931SetupAckMsg :         strcpy(buf, "SetupAck");         break;      case Q931FacilityMsg :         strcpy(buf, "Facility");         break;      case Q931ReleaseCompleteMsg :         strcpy(buf, "ReleaseComplete");         break;      case Q931StatusEnquiryMsg :         strcpy(buf, "StatusEnquiry");         break;      case Q931StatusMsg :         strcpy(buf, "Status");         break;      case Q931InformationMsg :         strcpy(buf, "Information");         break;      case Q931NationalEscapeMsg :         strcpy(buf, "Escape");         break;      default:         sprintf(buf, "<%u>", messageType);   }   return buf;}char* ooQ931GetIEName(int number, char* buf) {   switch (number) {      case Q931BearerCapabilityIE :         strcpy(buf, "Bearer-Capability");         break;      case Q931CauseIE :         strcpy(buf, "Cause");         break;      case Q931FacilityIE :         strcpy(buf, "Facility");         break;      case Q931ProgressIndicatorIE :         strcpy(buf, "Progress-Indicator");         break;      case Q931CallStateIE :         strcpy(buf, "Call-State");         break;      case Q931DisplayIE :         strcpy(buf, "Display");         break;      case Q931SignalIE :         strcpy(buf, "Signal");         break;      case Q931CallingPartyNumberIE :         strcpy(buf, "Calling-Party-Number");         break;      case Q931CalledPartyNumberIE :         strcpy(buf, "Called-Party-Number");         break;      case Q931RedirectingNumberIE :         strcpy(buf, "Redirecting-Number");         break;      case Q931UserUserIE :         strcpy(buf, "User-User");         break;      default:         sprintf(buf, "0x%02x", number);   }   return buf;}EXTERN void ooQ931Print (const Q931Message* q931msg) {   char buf[1000];   DListNode* curNode;   unsigned int i;   printf("Q.931 Message:\n");   printf("   protocolDiscriminator: %i\n", q931msg->protocolDiscriminator);   printf("   callReference: %i\n", q931msg->callReference);   printf("   from: %s\n", (q931msg->fromDestination ?                                        "destination" : "originator"));   printf("   messageType: %s (0x%X)\n\n",               ooQ931GetMessageTypeName(q931msg->messageType, buf),                                                q931msg->messageType);   for(i = 0, curNode = q931msg->ies.head; i < q931msg->ies.count; i++) {      Q931InformationElement *ie = (Q931InformationElement*) curNode->data;      int length = (ie->length >= 0) ? ie->length : -ie->length;      printf("   IE[%i] (offset 0x%X):\n", i, ie->offset);      printf("      discriminator: %s (0x%X)\n",                ooQ931GetIEName(ie->discriminator, buf), ie->discriminator);      printf("      data length: %i\n", length);       curNode = curNode->next;      printf("\n");   }}int ooCreateQ931Message(Q931Message **q931msg, int msgType){   OOCTXT *pctxt = &gH323ep.msgctxt;      *q931msg = (Q931Message*)memAllocZ(pctxt, sizeof(Q931Message));                   if(!*q931msg)   {      OOTRACEERR1("Error:Memory -  ooCreateQ931Message - q931msg\n");      return OO_FAILED;   }   else   {      (*q931msg)->protocolDiscriminator = 8;      (*q931msg)->fromDestination = FALSE;      (*q931msg)->messageType = msgType;      (*q931msg)->tunneledMsgType = msgType;      (*q931msg)->logicalChannelNo = 0;      (*q931msg)->bearerCapabilityIE = NULL;      (*q931msg)->callingPartyNumberIE = NULL;      (*q931msg)->calledPartyNumberIE = NULL;      (*q931msg)->causeIE = NULL;      return OO_OK;   }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?