📄 q931pdu.cpp
字号:
/* * Q931pdu.cpp * * Copyright (c) 2001 Institute for Information Industry, Taiwan, Republic of China * (http://www.iii.org.tw/iiia/ewelcome.htm) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 1, or (at your option) * any later version. * * 2001/07/27 Huang-Ming Huang * Fixed Progress indicator and Call state information element identifier coding. * * 2001/07/16 Huang-Ming Huang * Fixed the bug when parsing CallingPartyNumber and add ConnectedPartyNumberInformationElement * Thanks to Danail Kirov for providing this patch. * */#include "h323_messages.h"#include "q931pdu.h"#include "perattacher.h"class InformationElement{public: static InformationElement* Build(Q931Decoder& strm); InformationElement(const unsigned char* pFrame, int nSize = 1) : data(pFrame), len(nSize){}; int getLength() const { return len; } virtual void attachProperties(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return ""; }protected: const unsigned char* data; int len;};class VariableLengthInformationElement : public InformationElement{public: VariableLengthInformationElement(const unsigned char* pFrame) : InformationElement(pFrame, pFrame[1] +2 ){} virtual void attachProperties(HFRAME hFrame, HPROPERTY hProperty) const; virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const;};class UserUserInformationElement : public InformationElement{public: UserUserInformationElement(const unsigned char* pFrame, ASN1::CoderEnv* coderEnv) : InformationElement(pFrame, (pFrame[1] << 8) | pFrame[2] + 3 ) , env(coderEnv){} virtual void attachProperties(HFRAME hFrame, HPROPERTY hProperty) const; virtual const char* getName() const { return "User-User"; } bool decodeIE() const;private: ASN1::CoderEnv* env;};class IA5StringInformationElement : public VariableLengthInformationElement{public: IA5StringInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ;};class DisplayInformationElement : public IA5StringInformationElement{public: DisplayInformationElement(const unsigned char* pFrame) : IA5StringInformationElement(pFrame){} virtual const char* getName() const { return "Display";}};class KeypadFacilityInformationElement : public IA5StringInformationElement{public: KeypadFacilityInformationElement(const unsigned char* pFrame) : IA5StringInformationElement(pFrame){} virtual const char* getName() const { return "Keypad Facility";}};class CauseInformationElement : public VariableLengthInformationElement{public: CauseInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Cause";}};class CalledPartyNumberInformationElement : public VariableLengthInformationElement{public: CalledPartyNumberInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Called Party Number";}};class CallingPartyNumberInformationElement : public VariableLengthInformationElement{public: CallingPartyNumberInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Calling Party Number";}};class ConnectedPartyNumberInformationElement : public VariableLengthInformationElement{public: ConnectedPartyNumberInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Connected Party Number";}};class ProgressInformationElement : public VariableLengthInformationElement{public: ProgressInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Progress";}};class BearerCapabilityInformationElement : public VariableLengthInformationElement{public: BearerCapabilityInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Bearer Capability";}};class CallStateInformationElement : public VariableLengthInformationElement{public: CallStateInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Call State";}};class SignalInformationElement : public VariableLengthInformationElement{public: SignalInformationElement(const unsigned char* pFrame) : VariableLengthInformationElement(pFrame){} virtual void attachContent(HFRAME hFrame, HPROPERTY hProperty) const ; virtual const char* getName() const { return "Signal";}};struct TableEntry{ int code; const char* str;};const char* FindStringFromTable(int code, const TableEntry* table, int tableSize){ // linear search for (int i = 0; i < tableSize; ++i) if (table[i].code == code) return table[i].str; return "";}#define FindString(code) FindStringFromTable(code, code##Table, sizeof(code##Table)) void FormatBits(char* buf, int highBit, int lowBit, int value){ for (int i = 7; i >= 0; --i) { if (i > highBit || i < lowBit) buf[7-i] = '.'; else if ((value >> i) & 0x01 ) buf[7-i] = '1'; else buf[7-i] = '0'; }} InformationElement* InformationElement::Build(Q931Decoder& decoder){ InformationElement* result = NULL; if (decoder.offset < decoder.size) { int discriminator = decoder.data[decoder.offset]; if ((discriminator & 0x80) == 1) result = new InformationElement(&decoder.data[decoder.offset]); else { switch (discriminator) { case 0x04: result = new BearerCapabilityInformationElement(&decoder.data[decoder.offset]); break; case 0x08: result = new CauseInformationElement(&decoder.data[decoder.offset]); break; case 0x1E: result = new ProgressInformationElement(&decoder.data[decoder.offset]); break; case 0x14: result = new CallStateInformationElement(&decoder.data[decoder.offset]); break; case 0x28: result = new DisplayInformationElement(&decoder.data[decoder.offset]); break; case 0x2C: result = new KeypadFacilityInformationElement(&decoder.data[decoder.offset]); break; case 0x34: result = new SignalInformationElement(&decoder.data[decoder.offset]); break; case 0x4C: result = new ConnectedPartyNumberInformationElement(&decoder.data[decoder.offset]); break; case 0x6c: result = new CallingPartyNumberInformationElement(&decoder.data[decoder.offset]); break; case 0x70: result = new CalledPartyNumberInformationElement(&decoder.data[decoder.offset]); break; case 0x7E: result = new UserUserInformationElement(&decoder.data[decoder.offset], decoder.env); break; default: result = new VariableLengthInformationElement(&decoder.data[decoder.offset]); } } decoder.offset += result->getLength(); } return result;}void InformationElement::attachProperties(HFRAME hFrame, HPROPERTY hProperty) const{ char buf[80]; wsprintf(buf, "%s Information Element", getName()); AttachPropertyInstanceEx(hFrame, hProperty, len, (void*)data, strlen(buf)+1, buf, 0, 1, 0); wsprintf(buf, "Information Element Identifier = 0x%02x (%s)", data[0], getName()); AttachPropertyInstanceEx(hFrame, hProperty, 1, (void*) data, strlen(buf) + 1, buf , 0, 2, 0);}const char* VariableLengthInformationElement::getName() const{ switch (data[0]) { case 0x1c: return "Facility"; } return "";}void VariableLengthInformationElement::attachProperties(HFRAME hFrame, HPROPERTY hProperty) const{ InformationElement::attachProperties(hFrame, hProperty); char buf[80]; wsprintf(buf, "Information Element Content Length = %d", data[1]); AttachPropertyInstanceEx(hFrame, hProperty, 1,(void*) (data+1), strlen(buf) + 1, buf , 0, 2, 0); if (data[1] >0) attachContent(hFrame, hProperty);}void VariableLengthInformationElement::attachContent(HFRAME hFrame, HPROPERTY hProperty) const{ AttachPropertyInstanceEx(hFrame, hProperty, (DWORD) data[1] , (void*) (data+2), 28, "Information Element Content" , 0, 2, 0 );}void UserUserInformationElement::attachProperties(HFRAME hFrame, HPROPERTY hProperty) const{ InformationElement::attachProperties(hFrame, hProperty); char buf[80]; wsprintf(buf, "Information Element Content Length = %d", len-3 ); AttachPropertyInstanceEx(hFrame, hProperty, 2, (void*) (data+1), strlen(buf) + 1, buf , 0, 2, 0); H323_MESSAGES::H323_UserInformation userInformation; ASN1::PERDecoder decoder((char*)data+4, (char*)data+len, env); PERAttacher attacher(decoder, hFrame, hProperty, "H323_UserInformation ",2); userInformation.accept(attacher);}bool UserUserInformationElement::decodeIE() const{ H323_MESSAGES::H323_UserInformation userInformation; ASN1::PERDecoder decoder((char*)data+4, (char*)data+len); return userInformation.accept(decoder);}void IA5StringInformationElement::attachContent(HFRAME hFrame, HPROPERTY hProperty) const{ char buf[80]; int len; wsprintf(buf, "Information Element Content = \""); len = strlen(buf); memcpy(buf+len, data+2, data[1]); len += data[1]; buf[len++] = '"'; buf[len++] = 0; AttachPropertyInstanceEx(hFrame, hProperty, (DWORD) data[1] , (void*) (data+2), len, buf , 0, 2, 0 );}enum EXT_STATUS{ BOTH, FORCE_0, FORCE_1};char* extensionStringTable[][2] = { {" - Octet continues through the next octet", " - Last octet"}, {"", " - Coding Error : This bit has to be 0" }, {" - Coding Error : This bit has to be 1", "" }};void AttachExtensionIndicator(HFRAME hFrame, HPROPERTY hProperty, const unsigned char* Byte, enum EXT_STATUS status ){ char buf[80]; // extension indicator bool ext = (Byte[0] & 0x80) > 1; wsprintf(buf, "%d....... = Extention Indicator %s", ext , extensionStringTable[status][ext]); AttachPropertyInstanceEx(hFrame, hProperty, 1 , (void*)Byte, strlen(buf)+1 , buf , 0, 2, 0 );}void AttachCodingStandard(HFRAME hFrame, HPROPERTY hProperty, const unsigned char* Byte , int startBit = 6){ static const char* codeStandardString[] = { "CCITT standardized coding", "ISO/IEC standard", "National standard", "Standard specific to identified location" }; char buf[100]; int codingStandard = (Byte[0] & 0x60) ; FormatBits(buf, startBit, startBit-1,codingStandard); wsprintf(buf+8, " = Coding Standard - %s", codeStandardString[codingStandard >> (startBit-1)]); AttachPropertyInstanceEx(hFrame, hProperty, 1 , (void*) Byte, strlen(buf)+1 , buf , 0, 2, 0 );}void AttachLocation(HFRAME hFrame, HPROPERTY hProperty, const unsigned char* Byte){ const char* locationString[] = { "User ", "Private network serving the local user", "Public network serving the local user", "Transit network", "Public network serving the remote user", "Private network serving the remote user", "International network", "Reserved", "Reserved", "Network beyond interworking point" "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", }; int location = (Byte[0] & 0x0f); char buf[100]; FormatBits(buf, 3, 0, location); wsprintf(buf+8 , " = Location - %s", locationString[location]); AttachPropertyInstanceEx(hFrame, hProperty, 1 , (void*) Byte, strlen(buf)+1 , buf , 0, 2, 0 );}TableEntry recommendationTable[] = { {0, "Q.931"}, {3, "X.21" }, {4,"X.25"}, {5,"Public land mobile networks, Q.1031/Q.1051"},};TableEntry causeTable[] = { {0x02,"No Route To Network"}, {0x03,"No Route To Destination"}, {0x06,"Channel Unacceptable"}, {0x10,"Normal Call Clearing"}, {0x11,"User Busy"}, {0x12,"No Response"}, {0x13,"No Answer"}, {0x14,"Subscriber Absent"}, {0x15,"Call Rejected"}, {0x16,"Number Changed"}, {0x17,"Redirection"}, {0x1b,"Destination Out Of Order"}, {0x1c,"Invalid Number Format"}, {0x1e,"StatusEnquiryResponse"}, {0x2a,"Congestion"}, {0x51,"InvalidCallReference"}};void CauseInformationElement::attachContent(HFRAME hFrame, HPROPERTY hProperty) const{ char buf[80]; // extension indicator AttachExtensionIndicator(hFrame, hProperty, data+2, BOTH); AttachCodingStandard(hFrame, hProperty, data+2); AttachLocation(hFrame, hProperty, data+2); int pos = 3; if ((data[2]& 0x80) == 0) { AttachExtensionIndicator(hFrame, hProperty, data+3, FORCE_1); int recommendation = data[3] & 0x7F; FormatBits(buf, 6, 0, recommendation); wsprintf(buf+8, " = Recommendation - %s", FindString(recommendation) ); AttachPropertyInstanceEx(hFrame, hProperty, 1 , (void*) (data+3), strlen(buf)+1 , buf , 0, 2, 0 ); pos ++; } AttachExtensionIndicator(hFrame, hProperty, data+3, FORCE_0); int cause = data[pos] & 0x7F; FormatBits(buf, 6, 0, cause); wsprintf(buf+8, " = Cause Value (0x%02x) - %s", cause, FindString(cause) ); AttachPropertyInstanceEx(hFrame, hProperty, 1 , (void*) (data+pos), strlen(buf)+1 , buf , 0, 2, 0 );}void AttachPartyNumber_TypeOfNumber( HFRAME hFrame, HPROPERTY hProperty, const unsigned char* Byte ){ static const char* str[] = {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -