windows-nt/Source/XPSP1/NT/net/rras/ip/nath323/q931msg.h
2020-09-26 16:20:57 +08:00

229 lines
6 KiB
C++

#ifndef __iptel_q931msg_h
#define __iptel_q931msg_h
// To use the Q931_MESSAGE class:
//
// To decode Q.931 PDUs:
//
// Create an instance of the Q931_MESSAGE class.
// Call the AssignDecodePdu method, supplying the buffer and length of the PDU data.
// If the AssignDecodePdu succeeds, then the buffer is now "bound" to the
// Q931_MESSAGE instance. You may then examine the elements of Q931_MESSAGE:
//
// MessageType - The type of Q.931 PDU received (Setup, etc.)
// CallReferenceValue
// InfoElementArray - An ordered array of IEs that were in the PDU
// UserInformation - If an ASN.1 UUIE was present, this field will be non-NULL
//
// You may also use the FindInfoElement method to locate a specific IE (cause code, etc.)
//
// When you are done using the contents of the Q931_MESSAGE instance, you must call the
// FreeAll method. This destroys the association between the buffer and the Q931_MESSAGE class.
// This step MUST be performed before destroying the instance of the Q931_MESSAGE class.
//
//
// To encode Q.931 PDUs:
//
// Create an instance of the Q931_MESSAGE class.
// Set the MessageType and CallReferenceValue fields.
// For each IE that should be encoded, call AppendInfoElement.
// (This includes the UUIE.)
// Call EncodePdu. The buffer on return contains the fully encoded PDU.
//
// If the buffer supplied to EncodePdu is not long enough, then the ReturnLength
// parameter will contain the required length, and the method will return
// HRESULT_FROM_WIN32 (ERROR_MORE_DATA).
//
// When calling InsertInfoElement, you must insure that the buffer supplied in the
// Q931_IE structure is still valid when the EncodePdu call is made. All IE buffers
// should remain valid until the Q931_MESSAGE::FreeAll method is called.
#include "q931defs.h"
#include "dynarray.h"
struct H323_UserInformation;
struct Q931_ENCODE_CONTEXT;
struct Q931_BEARER_CAPABILITY
{
};
// Q931_IE_DATA contains the decoded contents of those information elements whose
// interpretation is known and implemented in this module.
// Not all IEs are supported.
union Q931_IE_DATA
{
// Q931_IE_USER_TO_USER
struct {
Q931_UUIE_TYPE Type;
H323_UserInformation * PduStructure;
BOOL IsOwner; // if true, delete PduStructure on deletion
} UserToUser;
// Q931_IE_CAUSE
DWORD CauseCode;
// Q931_BEARER_CAPABILITY
Q931_BEARER_CAPABILITY BearerCapability;
// Q931_DISPLAY
struct {
LPSTR String;
} Display;
// IEs that are not implemented here, and are of variable length
struct {
LPBYTE Data;
DWORD Length;
} UnknownVariable;
// IEs that are not implemented here, and are of fixed length
struct {
BYTE Value;
} UnknownFixed;
};
struct Q931_IE
{
Q931_IE_IDENTIFIER Identifier;
Q931_IE_DATA Data;
};
// it is the responsibility of the user of this object to synchronize access
// and object lifetime.
//
// The Decode method builds the InfoElementArray. Elements in this array
// may refer to the original buffer passed to Encode. Therefore, users of
// Q931_MESSAGE::Decode must insure that the original buffer remains accessible
// and does not change, until the user no longer requires the use of this Q931_MESSAGE
// object, or calls Q931_MESSAGE::FreeAll.
struct Q931_MESSAGE
{
public:
Q931_MESSAGE_TYPE MessageType;
WORD CallReferenceValue;
DYNAMIC_ARRAY <Q931_IE> InfoElementArray;
LPBYTE Buffer;
DWORD BufferLength;
BOOL BufferIsOwner;
private:
HRESULT DecodeInfoElement (
IN OUT LPBYTE * Pos,
IN LPBYTE End,
OUT Q931_IE * ReturnInfoElement);
void FreeInfoElementArray (void);
// ParseInfoElement examines the contents of an IE that has already been decoded
// (type and length determined), and for known IE types, decodes their contents
// and assigns to data structures
HRESULT ParseIE (
IN Q931_IE * InfoElement);
HRESULT ParseIE_UUIE (
IN Q931_IE * InfoElement);
HRESULT EncodeIE_UUIE (
IN Q931_ENCODE_CONTEXT * Context,
IN Q931_IE * InfoElement);
// for those IEs that have attached allocated data, free it
void FreeInfoElement (
IN Q931_IE * InfoElement);
HRESULT EncodeHeader (
IN Q931_ENCODE_CONTEXT * Context);
HRESULT EncodeInfoElement (
IN Q931_ENCODE_CONTEXT * Context,
IN Q931_IE * InfoElement);
static INT __cdecl CompareInfoElement (const Q931_IE *, const Q931_IE *);
static INT InfoElementSearchFunc (
IN const Q931_IE_IDENTIFIER * SearchKey,
IN const Q931_IE * Comparand);
public:
// initializes array and UserInformation
Q931_MESSAGE (void);
// will free the UserInformation field if present
~Q931_MESSAGE (void);
HRESULT EncodePdu (
IN OUT LPBYTE Data,
IN OUT LPDWORD Length);
HRESULT AttachDecodePdu (
IN LPBYTE Data,
IN DWORD Length,
IN BOOL IsDataOwner); // if TRUE, Q931_MESSAGE will free on dtor
void FreeAll (void);
// if Q931_MESSAGE currently has a Buffer, and it owns the Buffer,
// then it will free it here, using GkHeapFree
void Detach (void);
// if Q931_MESSAGE currently has a Buffer, regardless of whether it owns the buffer,
// then it will be returned here
// returns S_OK if a buffer was returned
// returns S_FALSE if no buffer was returned, and ReturnBuffer set to null
HRESULT Detach (
OUT LPBYTE * ReturnBuffer,
OUT DWORD * ReturnBufferLength);
void SetUserInformation (
IN H323_UserInformation *,
IN BOOL FreeOnDelete);
// information element manipulation
HRESULT AppendInfoElement (
IN Q931_IE * InfoElement);
HRESULT DeleteInfoElement (
IN Q931_IE_IDENTIFIER Identifier);
HRESULT FindInfoElement (
IN Q931_IE_IDENTIFIER Identifier,
OUT Q931_IE ** ReturnInfoElement);
void SortInfoElementArray (void);
};
DECLARE_SEARCH_FUNC_CAST(Q931_IE_IDENTIFIER, Q931_IE);
#if DBG
// in debug builds, this function will take a Q.931 PDU buffer,
// decode it, re-encode it, verify that the contents match,
// and attempt to decode the re-encoded PDU.
// this is good for verifying the integrity of the Q931_MESSAGE class.
void Q931TestDecoder (
IN LPBYTE PduData,
IN DWORD PduLength);
#else
#define Q931TestDecoder(x,y) 0
#endif
#endif // __iptel_q931msg_h