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 + -
显示快捷键?