mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-10 03:41:16 +00:00
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@753 a93c3328-9c30-0410-af19-c9cd2b2d52af
3075 lines
82 KiB
C
3075 lines
82 KiB
C
/*****************************************************************************
|
|
|
|
FileName: Q931ie.c
|
|
|
|
Contents: Information Element Pack/Unpack functions.
|
|
|
|
These functions will pack out a Q931 message from the bit
|
|
packed original format into structs that are easier to process
|
|
and pack the same structs back into bit fields when sending
|
|
messages out.
|
|
|
|
The messages contains a short for each possible IE. The MSB
|
|
bit flags the precense of an IE, while the remaining bits
|
|
are the offset into a buffer to find the actual IE.
|
|
|
|
Each IE are supported by 3 functions:
|
|
|
|
Q931Pie_XXX Pack struct into Q.931 IE
|
|
Q931Uie_XXX Unpack Q.931 IE into struct
|
|
Q931InitIEXXX Initialize IE (see Q931api.c).
|
|
|
|
Dialect Note: This file will only contain standard DSS1 IE. Other IE as
|
|
used in QSIG, NI2, Q.932 etc are located in separate files.
|
|
|
|
See q931.h for description.
|
|
|
|
License/Copyright:
|
|
|
|
Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
|
|
email:janvb@caselaboratories.com
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
* Neither the name of the Case Labs, Ltd nor the names of its contributors
|
|
may be used to endorse or promote products derived from this software
|
|
without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
*****************************************************************************/
|
|
|
|
#include "Q931.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#ifndef __inline__
|
|
#define __inline__ __inline
|
|
#endif
|
|
#if (_MSC_VER >= 1400) /* VC8+ */
|
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
#endif
|
|
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
|
#define _CRT_NONSTDC_NO_DEPRECATE
|
|
#endif
|
|
#endif
|
|
#ifndef strcasecmp
|
|
#define strcasecmp(s1, s2) _stricmp(s1, s2)
|
|
#endif
|
|
#ifndef strncasecmp
|
|
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
|
|
#endif
|
|
#ifndef snprintf
|
|
#define snprintf _snprintf
|
|
#endif
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
|
|
Macro: Q931MoreIE
|
|
|
|
Description: Local helper macro detecting if there is more IE space left
|
|
based on the 3 standard parameters Octet, Off and IESpace.
|
|
This can be used to test if the IE is completed to avoid
|
|
that the header of the next IE is interpreted as a part of
|
|
the current IE.
|
|
|
|
*****************************************************************************/
|
|
#define Q931MoreIE() (Octet + Off - 2 < IESize)
|
|
|
|
#define Q931IESizeTest(x) {\
|
|
if (Octet + Off - 2 != IESize) {\
|
|
Q931SetError(pTrunk, x, Octet, Off);\
|
|
return x;\
|
|
}\
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931ReadExt
|
|
|
|
Description: Many of the octets in the standard have an MSB 'ext.1'. This
|
|
means that the octet usually is the latest octet, but that a
|
|
futhure standard may extend the octet. A stack must be able
|
|
to handle such extensions by skipping the extension octets.
|
|
|
|
This function will increase the offset counter with 1 for
|
|
each octet with an MSB of zero. This will allow the stack to
|
|
skip extensions wihout knowing anything about them.
|
|
|
|
Parameters: IBuf ptr to octet array.
|
|
Off Starting offset counter
|
|
|
|
Return Value: New offset value.
|
|
|
|
*****************************************************************************/
|
|
|
|
L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off)
|
|
{
|
|
L3INT c = 0;
|
|
while ((IBuf[c] & 0x80) == 0) {
|
|
c++;
|
|
}
|
|
return Off + c;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_BearerCap
|
|
|
|
Description: Unpack a bearer capability ie.
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
|
|
L3INT Q931Uie_BearerCap(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_BearerCap *pie = (Q931ie_BearerCap*)OBuf;
|
|
ie *pIE = &pMsg->BearerCap;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5);
|
|
pie->ITC = ieGetOctet(IBuf[Octet] & 0x1f);
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
pie->TransMode = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->ITR = ieGetOctet(IBuf[Octet + Off] & 0x1f);
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Octet++;
|
|
|
|
/* Octet 4.1. Rate multiplier is only present if ITR = Multirate */
|
|
if (pie->ITR == 0x18) {
|
|
pie->RateMul = ieGetOctet(IBuf[Octet + Off] & 0x7f);
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Off ++;
|
|
}
|
|
|
|
/* Octet 5 */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x20 && Q931MoreIE()) {
|
|
pie->Layer1Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->UIL1Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f);
|
|
Octet++;
|
|
|
|
/* Octet 5a. The octet may be present if ITC is unrestrictd digital info
|
|
* and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also
|
|
* be present if ITC = 3.1 kHz audio and UIL1Prot is G.711.
|
|
* Bit 8 of Octet 5 = 0 indicates that 5a is present.
|
|
*/
|
|
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08))
|
|
|| ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) {
|
|
pie->SyncAsync = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
|
|
pie->Negot = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
|
|
pie->UserRate = ieGetOctet(IBuf[Octet + Off] & 0x1f);
|
|
Off ++;
|
|
}
|
|
else {
|
|
/* We have detected bit 8 = 0, but no setting that require the */
|
|
/* additional octets ??? */
|
|
Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off);
|
|
return Q931E_BEARERCAP;
|
|
}
|
|
|
|
/* Octet 5b. Two different structures used. */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (pie->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */
|
|
pie->InterRate = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->NIConTx = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
|
|
pie->NIConRx = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
|
|
pie->FlowCtlTx = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
|
|
pie->FlowCtlRx = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 1);
|
|
Off++;
|
|
}
|
|
else if (pie->UIL1Prot == 0x08) { /* ITU V.120 */
|
|
pie->HDR = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
|
|
pie->MultiFrame = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
|
|
pie->Mode = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
|
|
pie->LLInegot = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
|
|
pie->Assignor = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
|
|
pie->InBandNeg = ieGetOctet((IBuf[Octet + Off] & 0x02) >> 1);
|
|
Off++;
|
|
}
|
|
else {
|
|
Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off);
|
|
return Q931E_BEARERCAP;
|
|
}
|
|
|
|
/* Octet 5c */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->NumStopBits = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->NumDataBits = ieGetOctet((IBuf[Octet + Off] & 0x18) >> 3);
|
|
pie->Parity = ieGetOctet(IBuf[Octet + Off] & 0x07);
|
|
Off++;
|
|
|
|
/* Octet 5d */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->DuplexMode = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
|
|
pie->ModemType = ieGetOctet(IBuf[Octet + Off] & 0x3f);
|
|
Off ++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Octet 6 */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x40 && Q931MoreIE()) {
|
|
pie->Layer2Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->UIL2Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f);
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Octet ++;
|
|
}
|
|
|
|
/* Octet 7 */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x60 && Q931MoreIE()) {
|
|
pie->Layer3Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
|
|
pie->UIL3Prot = ieGetOctet(IBuf[Octet + Off] & 0x1f);
|
|
Octet++;
|
|
|
|
/* Octet 7a */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (pie->UIL3Prot == 0x0c) {
|
|
pie->AL3Info1 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
|
|
Off++;
|
|
|
|
/* Octet 7b */
|
|
if (IsQ931Ext(IBuf[Octet + Off])) {
|
|
pie->AL3Info2 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
|
|
Off++;
|
|
}
|
|
}
|
|
else {
|
|
Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off);
|
|
return Q931E_BEARERCAP;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_BEARERCAP);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_BearerCap);
|
|
pie->Size = sizeof(Q931ie_BearerCap);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_BearerCap
|
|
|
|
Description: Packing a Q.931 Bearer Capability element from a generic
|
|
struct into a packed octet structure in accordance with the
|
|
standard.
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
|
|
L3INT Q931Pie_BearerCap(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_BearerCap *pIE = (Q931ie_BearerCap*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet; /* remember current offset */
|
|
L3INT li;
|
|
|
|
Q931Log(pTrunk, Q931_LOG_DEBUG, "Encoding Bearer Capability IE\n");
|
|
|
|
OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ;
|
|
li = (*Octet)++; /* remember length position */
|
|
|
|
/* Octet 3 - Coding standard / Information transfer capability */
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | (pIE->ITC & 0x1f);
|
|
|
|
/* Octet 4 - Transfer mode / Information transfer rate */
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->TransMode << 5) & 0x60) | (pIE->ITR & 0x1f);
|
|
|
|
if (pIE->ITR == 0x18) {
|
|
/* Octet 4.1 - Rate Multiplier */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->RateMul & 0x7f);
|
|
}
|
|
|
|
/* Octet 5 - Layer 1 Ident / User information layer 1 protocol */
|
|
if (pIE->Layer1Ident == 0x01) {
|
|
if (((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) ||
|
|
((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
|
|
OBuf[(*Octet)++] = 0x00 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x15);
|
|
|
|
/* Octet 5a - SyncAsync/Negot/UserRate */
|
|
OBuf[(*Octet)++] = 0x00 | ((pIE->SyncAsync << 6) & 0x40) | ((pIE->Negot << 5) & 0x20) | (pIE->UserRate & 0x1f);
|
|
|
|
/* Octet 5b - one of two types */
|
|
if (pIE->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */
|
|
/* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */
|
|
OBuf[(*Octet)++] = 0x00
|
|
| ((pIE->InterRate << 6) & 0x60)
|
|
| ((pIE->NIConTx << 4) & 0x10)
|
|
| ((pIE->NIConRx << 3) & 0x08)
|
|
| ((pIE->FlowCtlTx << 2) & 0x04)
|
|
| ((pIE->FlowCtlRx << 1) & 0x02);
|
|
}
|
|
else if (pIE->UIL1Prot == 0x08) { /* ITU V.120 */
|
|
/* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/
|
|
OBuf[(*Octet)++] = 0x00
|
|
| ((pIE->InterRate << 6) & 0x60)
|
|
| ((pIE->MultiFrame << 5) & 0x20)
|
|
| ((pIE->Mode << 4) & 0x10)
|
|
| ((pIE->LLInegot << 3) & 0x08)
|
|
| ((pIE->Assignor << 2) & 0x04)
|
|
| ((pIE->InBandNeg << 1) & 0x02);
|
|
}
|
|
|
|
/* Octet 5c - NumStopBits/NumStartBits/Parity */
|
|
OBuf[(*Octet)++] = 0x00
|
|
| ((pIE->NumStopBits << 5) & 0x60)
|
|
| ((pIE->NumDataBits << 3) & 0x18)
|
|
| (pIE->Parity & 0x07);
|
|
|
|
/* Octet 5d - Duplex Mode/Modem Type */
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->DuplexMode << 6) & 0x40) | (pIE->ModemType & 0x3f);
|
|
}
|
|
else {
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x1f);
|
|
}
|
|
}
|
|
|
|
/* Octet 6 - Layer2Ident/User information layer 2 prtocol */
|
|
if (pIE->Layer2Ident == 0x02) {
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->Layer2Ident << 5) & 0x60) | (pIE->UIL2Prot & 0x1f);
|
|
}
|
|
|
|
/* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */
|
|
if (pIE->Layer3Ident == 0x03) {
|
|
if (pIE->UIL3Prot == 0x0c) {
|
|
OBuf[(*Octet)++] = 0x00 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
|
|
|
|
/* Octet 7a - Additional information layer 3 msb */
|
|
OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1 & 0x0f);
|
|
|
|
/* Octet 7b - Additional information layer 3 lsb */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2 & 0x0f);
|
|
}
|
|
else {
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
|
|
}
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CallID
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CallID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CallID *pie = (Q931ie_CallID*)OBuf;
|
|
ie *pIE = &pMsg->CallID;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
do {
|
|
pie->CallId[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
x++;
|
|
} while (Q931MoreIE());
|
|
|
|
Q931IESizeTest(Q931E_CALLID);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CallID) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CallID) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CallID
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
|
|
L3INT Q931Pie_CallID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CallID *pIE = (Q931ie_CallID*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;/* remember current offset */
|
|
L3INT li;
|
|
L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1;
|
|
L3INT x;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ;
|
|
li = (*Octet)++; /* remember length position */
|
|
|
|
for (x = 0; x < sCI; x++) {
|
|
OBuf[(*Octet)++] = pIE->CallId[x];
|
|
}
|
|
|
|
OBuf[(*Octet) - 1] |= 0x80; /* set complete flag at last octet*/
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CallState
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CallState(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CallState *pie = (Q931ie_CallState*)OBuf;
|
|
ie *pIE = &pMsg->CallState;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->CodStand = (IBuf[Octet + Off] >> 6) & 0x03;
|
|
pie->CallState = IBuf[Octet + Off] & 0x3f;
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_CALLSTATE);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CallState);
|
|
pie->Size = sizeof(Q931ie_CallState);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CallState
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CallState(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CallState *pIE = (Q931ie_CallState*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet; /* remember current offset */
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CALL_STATE;
|
|
li = (*Octet)++; /* remember length position */
|
|
|
|
OBuf[(*Octet)++] = (pIE->CodStand << 6) | (pIE->CallState & 0x3f);
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CalledSub
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CalledSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CalledSub *pie = (Q931ie_CalledSub*)OBuf;
|
|
ie *pIE = &pMsg->CalledSub;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07;
|
|
pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
x++;
|
|
} while (Q931MoreIE() && x < 20);
|
|
|
|
Q931IESizeTest(Q931E_CALLEDSUB);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledSub) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CalledSub
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CalledSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CalledSub *pIE = (Q931ie_CalledSub*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1;
|
|
L3INT x;
|
|
|
|
/* Octet 1 */
|
|
OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
|
|
|
|
/* Octet 4 */
|
|
for (x = 0; x<sN; x++) {
|
|
OBuf[(*Octet)++] = pIE->Digit[x];
|
|
}
|
|
|
|
OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CalledNum
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CalledNum *pie = (Q931ie_CalledNum*)OBuf;
|
|
ie *pIE = &pMsg->CalledNum;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x;
|
|
L3INT IESize; /* # digits in this case */
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07;
|
|
pie->NumPlanID = IBuf[Octet + Off] & 0x0f;
|
|
Octet++;
|
|
|
|
/* Octet 4*/
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
x++;
|
|
} while ((IBuf[Octet + Off]&0x80) == 0 && Q931MoreIE());
|
|
|
|
pie->Digit[x] = '\0';
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CalledNum
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CalledNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CalledNum *pIE = (Q931ie_CalledNum*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT sN = pIE->Size - sizeof(Q931ie_CalledNum);
|
|
L3INT x;
|
|
|
|
/* Octet 1 */
|
|
OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER;
|
|
|
|
/* Octet 2 */
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->NumPlanID);
|
|
|
|
/* Octet 4 */
|
|
for (x = 0; x<sN; x++) {
|
|
OBuf[(*Octet)++] = pIE->Digit[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CallingNum
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CallingNum *pie = (Q931ie_CallingNum*)OBuf;
|
|
ie *pIE = &pMsg->CallingNum;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07;
|
|
pie->NumPlanID = IBuf[Octet + Off] & 0x0f;
|
|
|
|
/* Octet 3a */
|
|
if ((IBuf[Octet + Off] & 0x80) == 0) {
|
|
Off++;
|
|
pie->PresInd = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->ScreenInd = IBuf[Octet + Off] & 0x03;
|
|
}
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
x = 0;
|
|
while (Q931MoreIE()) {
|
|
pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
|
|
|
|
if ((IBuf[Octet + Off] & 0x80) != 0) {
|
|
break;
|
|
}
|
|
Off++;
|
|
}
|
|
pie->Digit[x] = '\0';
|
|
|
|
Q931IESizeTest(Q931E_CALLINGNUM);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CallingNum
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CallingNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CallingNum *pIE = (Q931ie_CallingNum*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT sN = pIE->Size - sizeof(Q931ie_CallingNum);
|
|
L3INT x;
|
|
|
|
/* Octet 1 */
|
|
OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_NUMBER;
|
|
|
|
/* Octet 2 */
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x00 | (pIE->TypNum << 4) | (pIE->NumPlanID);
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = 0x80;
|
|
|
|
/* Octet 5 */
|
|
for (x = 0; x<sN; x++) {
|
|
OBuf[(*Octet)++] = pIE->Digit[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CallingSub
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CallingSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CallingSub *pie = (Q931ie_CallingSub*)OBuf;
|
|
ie *pIE = &pMsg->CallingSub;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->TypNum = (IBuf[Octet + Off] >> 4) & 0x07;
|
|
pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
|
|
Octet++;
|
|
|
|
/* Octet 4*/
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
x++;
|
|
} while (Q931MoreIE() && x < 20);
|
|
|
|
Q931IESizeTest(Q931E_CALLINGSUB);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x -1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CallingSub
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CallingSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CallingSub *pIE = (Q931ie_CallingSub*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1;
|
|
L3INT x;
|
|
|
|
/* Octet 1 */
|
|
OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
|
|
|
|
/* Octet 4 */
|
|
for (x = 0; x<sN; x++) {
|
|
OBuf[(*Octet)++] = pIE->Digit[x];
|
|
}
|
|
|
|
OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_Cause
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_Cause(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_Cause *pie = (Q931ie_Cause*)OBuf;
|
|
ie *pIE = &pMsg->Cause;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2*/
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3*/
|
|
pie->CodStand = (IBuf[Octet + Off]>>5) & 0x03;
|
|
pie->Location = IBuf[Octet + Off] & 0x0f;
|
|
|
|
/* Octet 3a */
|
|
if ((IBuf[Octet + Off] & 0x80) == 0) {
|
|
Off++;
|
|
pie->Recom = IBuf[Octet + Off] & 0x7f;
|
|
}
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
pie->Value = IBuf[Octet + Off] & 0x7f;
|
|
Octet++;
|
|
|
|
/* Consume optional Diagnostic bytes */
|
|
while (Q931MoreIE()) {
|
|
Off++;
|
|
};
|
|
|
|
Q931IESizeTest(Q931E_CAUSE);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_Cause);
|
|
pie->Size = sizeof(Q931ie_Cause);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_Cause
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_Cause(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_Cause *pIE = (Q931ie_Cause*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CAUSE;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location;
|
|
|
|
/* Octet 3a - currently not supported in send */
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->Value;
|
|
|
|
/* Octet 5 - diagnostics not supported in send */
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CongLevel
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf;
|
|
ie *pIE = &pMsg->CongestionLevel;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet] & 0xf0;
|
|
pie->CongLevel = IBuf[Octet] & 0x0f;
|
|
Octet ++;
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CongLevel);
|
|
pie->Size = sizeof(Q931ie_CongLevel);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_CongLevel
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_CongLevel *pIE = (Q931ie_CongLevel*)IBuf;
|
|
L3INT rc = 0;
|
|
/* L3INT Beg = *Octet; */
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_ChanID
|
|
|
|
Parameters: IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_ChanID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_ChanID *pie = (Q931ie_ChanID*)OBuf;
|
|
ie *pIE = &pMsg->ChanID;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
//18 04 e1 80 83 01
|
|
*pIE = 0;
|
|
|
|
Q931Log(pTrunk, Q931_LOG_DEBUG, "Decoding ChanID IE\n");
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01;
|
|
pie->IntType = (IBuf[Octet] >> 5) & 0x01;
|
|
pie->PrefExcl = (IBuf[Octet] >> 3) & 0x01;
|
|
pie->DChanInd = (IBuf[Octet] >> 2) & 0x01;
|
|
pie->InfoChanSel = IBuf[Octet] & 0x03;
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet++], Off);
|
|
|
|
/* Octet 3.1 */
|
|
if (pie->IntIDPresent) {
|
|
pie->InterfaceID = IBuf[Octet + Off] & 0x7f;
|
|
|
|
/* Temp fix. Interface id can be extended using the extension bit */
|
|
/* this will read the octets, but do nothing with them. this is done */
|
|
/* because the usage of this field is a little unclear */
|
|
/* 30.jan.2001/JVB */
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Off++;
|
|
}
|
|
|
|
if ((Octet + Off - 2) != IESize) {
|
|
/* Octet 3.2 */
|
|
if (pie->IntType == 1) { /* PRI etc */
|
|
pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->NumMap = (IBuf[Octet + Off] >> 4) & 0x01;
|
|
pie->ChanMapType = IBuf[Octet + Off] & 0x0f;
|
|
Off++;
|
|
|
|
/* Octet 3.3 */
|
|
/* Temp fix. Assume B channel. H channels not supported */
|
|
pie->ChanSlot = IBuf[Octet + Off] & 0x7f;
|
|
|
|
/* Some dialects don't follow the extension coding properly for this, but this should be safe for all */
|
|
if ((Octet + Off - 1) != IESize) {
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
}
|
|
Off++;
|
|
}
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_CHANID);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_ChanID);
|
|
pie->Size = sizeof(Q931ie_ChanID);
|
|
|
|
if (pTrunk->loglevel == Q931_LOG_DEBUG) {
|
|
const char *iface;
|
|
char tmp[100] = "";
|
|
|
|
if (!pie->IntType) {
|
|
switch (pie->InfoChanSel) {
|
|
case 0x0:
|
|
iface = "None";
|
|
break;
|
|
case 0x1:
|
|
iface = "B1";
|
|
break;
|
|
case 0x2:
|
|
iface = "B2";
|
|
break;
|
|
default:
|
|
iface = "Any Channel";
|
|
}
|
|
|
|
snprintf(tmp, sizeof(tmp)-1, "InfoChanSel: %d (%s)", pie->InfoChanSel, iface);
|
|
}
|
|
|
|
Q931Log(pTrunk, Q931_LOG_DEBUG,
|
|
"\n-------------------------- Q.931 Channel ID ------------------------\n"
|
|
" Pref/Excl: %s, Interface Type: %s\n"
|
|
" %s\n"
|
|
"--------------------------------------------------------------------\n\n",
|
|
((pie->PrefExcl) ? "Preferred" : "Exclusive"),
|
|
((pie->IntType) ? "PRI/Other" : "BRI"),
|
|
tmp);
|
|
}
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_ChanID
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_ChanID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_ChanID *pIE = (Q931ie_ChanID*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet; /* remember current offset */
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION;
|
|
li = (*Octet)++; /* remember length position */
|
|
|
|
/* Octet 3 flags & BRI chan # */
|
|
OBuf[(*Octet)++] = 0x80
|
|
| ((pIE->IntIDPresent << 6) & 0x40)
|
|
| ((pIE->IntType << 5) & 0x20)
|
|
| ((pIE->PrefExcl << 3) & 0x08)
|
|
| (pIE->InfoChanSel & 0x03);
|
|
|
|
/* Octet 3.1 - Interface Identifier */
|
|
if (pIE->IntIDPresent) {
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->InterfaceID & 0x7f);
|
|
}
|
|
|
|
/* Octet 3.2 & 3.3 - PRI */
|
|
if (pIE->IntType) {
|
|
OBuf[(*Octet)++] = 0x80
|
|
| ((pIE->CodStand << 5) & 0x60)
|
|
| ((pIE->NumMap << 4) & 0x10)
|
|
| (pIE->ChanMapType & 0x0f); /* TODO: support all possible channel map types */
|
|
|
|
/* Octet 3.3 Channel number */
|
|
switch (pIE->ChanMapType) {
|
|
case 0x6: /* Slot map: H0 Channel Units */ /* unsupported, Octets 3.3.1 - 3.3.3 */
|
|
return Q931E_CHANID;
|
|
|
|
case 0x8: /* Slot map: H11 Channel Units */
|
|
case 0x9: /* Slot map: H12 Channel Units */
|
|
default: /* Channel number */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->ChanSlot & 0x7f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_CRV
|
|
|
|
Description: Reading CRV.
|
|
|
|
The CRV is currently returned in the return value that
|
|
Q921Rx23 will assign to the CRV field in the unpacked
|
|
message. CRV is basically 2 bytes etc, but the spec allows
|
|
the use of longer CRV values.
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: CRV
|
|
|
|
*****************************************************************************/
|
|
L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
L3USHORT CRV = 0;
|
|
L3INT Octet = *IOff;
|
|
L3INT l = IBuf[Octet++];
|
|
|
|
if (l == 1) { /* One octet CRV */
|
|
CRV = IBuf[Octet++] & 0x7F;
|
|
}
|
|
else if (l == 2) { /* two octet CRV */
|
|
CRV = (IBuf[Octet++] & 0x7f) << 8;
|
|
CRV |= IBuf[Octet++];
|
|
}
|
|
else {
|
|
/* Long CRV is not used, so we skip this */
|
|
/* TODO: is it right to set to 0 here? */
|
|
CRV = 0;
|
|
Octet += l;
|
|
}
|
|
|
|
*IOff = Octet;
|
|
return CRV;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_DateTime
|
|
|
|
Parameters: pTrunk [IN] Ptr to trunk information.
|
|
pIE [OUT] ptr to Information Element id.
|
|
IBuf [IN] ptr to a packed ie.
|
|
OBuf [OUT] ptr to buffer for Unpacked ie.
|
|
IOff [IN\OUT] Input buffer offset
|
|
OOff [IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_DateTime(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf;
|
|
ie *pIE = &pMsg->DateTime;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize = 0;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 - Year */
|
|
pie->Year = IBuf[Octet++];
|
|
|
|
/* Octet 4 - Month */
|
|
pie->Month = IBuf[Octet++];
|
|
|
|
/* Octet 5 - Day */
|
|
pie->Day = IBuf[Octet++];
|
|
|
|
/*******************************************************************
|
|
The remaining part of the IE are optioinal, but only the length
|
|
can now tell us wherever these fields are present or not
|
|
(always remember: IESize does not include ID and Size octet)
|
|
********************************************************************/
|
|
pie->Format = 0;
|
|
|
|
/* Octet 6 - Hour (optional)*/
|
|
if (IESize >= 4) {
|
|
pie->Format = 1;
|
|
pie->Hour = IBuf[Octet++];
|
|
|
|
/* Octet 7 - Minute (optional)*/
|
|
if (IESize >= 5) {
|
|
pie->Format = 2;
|
|
pie->Minute = IBuf[Octet++];
|
|
|
|
/* Octet 8 - Second (optional)*/
|
|
if (IESize >= 6) {
|
|
pie->Format = 3;
|
|
pie->Second = IBuf[Octet++];
|
|
}
|
|
}
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_DATETIME);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_DateTime);
|
|
pie->Size = sizeof(Q931ie_DateTime);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_DateTime
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_DateTime(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_DateTime *pIE = (Q931ie_DateTime*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_DATETIME;
|
|
li = (*Octet)++;
|
|
|
|
OBuf[(*Octet)++] = pIE->Year;
|
|
OBuf[(*Octet)++] = pIE->Month;
|
|
OBuf[(*Octet)++] = pIE->Day;
|
|
if (pIE->Format >= 1) {
|
|
OBuf[(*Octet)++] = pIE->Hour;
|
|
|
|
if (pIE->Format >= 2) {
|
|
OBuf[(*Octet)++] = pIE->Minute;
|
|
|
|
if (pIE->Format >= 3) {
|
|
OBuf[(*Octet)++] = pIE->Second;
|
|
}
|
|
}
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_Display
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_Display(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_Display *pie = (Q931ie_Display*)OBuf;
|
|
ie *pIE = &pMsg->Display;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
L3INT x;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
IESize = IBuf[Octet++];
|
|
|
|
for (x = 0; x<IESize; x++) {
|
|
pie->Display[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_DISPLAY);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_Display) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_Display
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_Display(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_Display *pIE = (Q931ie_Display*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT DSize;
|
|
L3INT x;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_DISPLAY;
|
|
li = (*Octet)++;
|
|
|
|
DSize = pIE->Size - sizeof(Q931ie_Display);
|
|
|
|
for (x = 0; x< DSize; x++) {
|
|
|
|
OBuf[(*Octet)++] = pIE->Display[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_HLComp
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_HLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf;
|
|
ie *pIE = &pMsg->HLComp;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3*/
|
|
pie->CodStand = (IBuf[Octet + Off] >>5) & 0x03;
|
|
pie->Interpret = (IBuf[Octet + Off] >>2) & 0x07;
|
|
pie->PresMeth = IBuf[Octet + Off] & 0x03;
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
pie->HLCharID = IBuf[Octet + Off] & 0x7f;
|
|
Octet++;
|
|
|
|
/* Octet 4a*/
|
|
if ((IBuf[Octet + Off - 1] & 0x80) == 0 && Q931MoreIE()) {
|
|
if (pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) {
|
|
pie->EHLCharID = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
else if ( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) {
|
|
pie->EVideoTlfCharID = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
else {
|
|
/* error Octet 4a indicated, but invalid value in Octet 4. */
|
|
Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off);
|
|
return Q931E_HLCOMP;
|
|
}
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_HLCOMP);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_HLComp);
|
|
pie->Size = sizeof(Q931ie_HLComp);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_HLComp
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_HLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_HLComp *pIE = (Q931ie_HLComp*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | ((pIE->Interpret << 2) & 0x1c) | (pIE->PresMeth & 0x03);
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = pIE->HLCharID;
|
|
|
|
/* Octet 4a */
|
|
if (pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) {
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->EHLCharID & 0x7f);
|
|
}
|
|
else if ( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) {
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->EVideoTlfCharID & 0x7f);
|
|
}
|
|
else {
|
|
OBuf[(*Octet) - 1] |= 0x80;
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_KeypadFac
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_KeypadFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_KeypadFac *pie = (Q931ie_KeypadFac*)OBuf;
|
|
ie *pIE = &pMsg->KeypadFac;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
L3INT x;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
IESize = IBuf[Octet++];
|
|
|
|
for (x = 0; x<IESize; x++) {
|
|
pie->KeypadFac[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_KEYPADFAC);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_KeypadFac) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_KeypadFac
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_KeypadFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_KeypadFac *pIE = (Q931ie_KeypadFac*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT DSize;
|
|
L3INT x;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY;
|
|
li = (*Octet)++;
|
|
|
|
DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1;
|
|
|
|
for (x = 0; x< DSize; x++) {
|
|
OBuf[(*Octet)++] = pIE->KeypadFac[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_LLComp
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_LLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_LLComp *pie = (Q931ie_LLComp*)OBuf;
|
|
ie *pIE = &pMsg->LLComp;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->ITransCap = IBuf[Octet + Off] & 0x1f;
|
|
Octet++;
|
|
|
|
/* Octet 3a*/
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->NegotInd = (IBuf[Octet + Off] >> 6) & 0x01;
|
|
Off++;
|
|
}
|
|
|
|
/* Octet 4 */
|
|
pie->TransMode = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->InfoRate = IBuf[Octet + Off] & 0x1f;
|
|
|
|
Octet++;
|
|
|
|
/* Octet 4.1 */
|
|
if (pie->InfoRate == 0x14) { /* Mutirate */
|
|
pie->RateMul = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
|
|
/* Octet 5 - Layer 1 Ident */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x20) { /* Layer 1 Ident ? */
|
|
pie->Layer1Ident = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->UIL1Prot = IBuf[Octet + Off] & 0x1f;
|
|
Octet++;
|
|
|
|
/* Octet 5a */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->SyncAsync = (IBuf[Octet + Off] >> 6) & 0x01;
|
|
pie->Negot = (IBuf[Octet + Off] >> 5) & 0x01;
|
|
pie->UserRate = IBuf[Octet + Off] & 0x1f;
|
|
Off++;
|
|
|
|
/* Octet 5b - 2 options */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (pie->UIL1Prot == 0x01) { /* V.110, I.460 and X.30*/
|
|
pie->InterRate = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->NIConTx = (IBuf[Octet + Off] >> 4) & 0x01;
|
|
pie->NIConRx = (IBuf[Octet + Off] >> 3) & 0x01;
|
|
pie->FlowCtlTx = (IBuf[Octet + Off] >> 2) & 0x01;
|
|
pie->FlowCtlRx = (IBuf[Octet + Off] >> 1) & 0x01;
|
|
Off++;
|
|
}
|
|
else if (pie->UIL1Prot == 0x80) { /* V.120 */
|
|
pie->HDR = (IBuf[Octet + Off] >> 6) & 0x01;
|
|
pie->MultiFrame = (IBuf[Octet + Off] >> 5) & 0x01;
|
|
pie->ModeL1 = (IBuf[Octet + Off] >> 4) & 0x01;
|
|
pie->NegotLLI = (IBuf[Octet + Off] >> 3) & 0x01;
|
|
pie->Assignor = (IBuf[Octet + Off] >> 2) & 0x01;
|
|
pie->InBandNeg = (IBuf[Octet + Off] >> 1) & 0x01;
|
|
Off++;
|
|
}
|
|
else if (pie->UIL1Prot == 0x07) { /* non standard */
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Off++;
|
|
}
|
|
else {
|
|
Q931SetError(pTrunk,Q931E_LLCOMP, 5,2);
|
|
return Q931E_LLCOMP;
|
|
}
|
|
|
|
/* Octet 5c */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->NumStopBits = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->NumDataBits = (IBuf[Octet + Off] >> 3) & 0x03;
|
|
pie->Parity = IBuf[Octet + Off] & 0x07;
|
|
Off++;
|
|
|
|
/* Octet 5d */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->DuplexMode = (IBuf[Octet + Off] >> 6) & 0x01;
|
|
pie->ModemType = IBuf[Octet + Off] & 0x3f;
|
|
Off = Q931ReadExt(&IBuf[Octet + Off], Off);
|
|
Off++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Octet 6 - Layer 2 Ident */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x40) { /* Layer 1 Ident ? */
|
|
pie->Layer2Ident = (IBuf[Octet + Off] >>5) & 0x03;
|
|
pie->UIL2Prot = IBuf[Octet + Off] & 0x1f;
|
|
Octet++;
|
|
|
|
/* Octet 6a */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (pie->UIL2Prot == 0x10) { /* 2nd 6a */
|
|
pie->UsrSpcL2Prot = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
else { /* assume 1st 6a */
|
|
pie->ModeL2 = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->Q933use = IBuf[Octet + Off] & 0x03;
|
|
Off++;
|
|
}
|
|
/* Octet 6b */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->WindowSize = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Octet 7 - layer 3 Ident */
|
|
if ((IBuf[Octet + Off] & 0x60) == 0x60) { /* Layer 3 Ident ? */
|
|
pie->Layer3Ident = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->UIL3Prot = IBuf[Octet + Off] & 0x1f;
|
|
Octet++;
|
|
|
|
/* Octet 7a */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
if (pie->UIL3Prot == 0x0b) {
|
|
/* Octet 7a + 7b AddL3Info */
|
|
pie->AddL3Info = ((IBuf[Octet + Off] << 4) & 0xf0)
|
|
| (IBuf[Octet + Off + 1] & 0x0f);
|
|
Off += 2;
|
|
}
|
|
else {
|
|
if (pie->UIL3Prot == 0x1f) {
|
|
pie->ModeL3 = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
Off++;
|
|
}
|
|
else {
|
|
pie->OptL3Info = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
|
|
/* Octet 7b*/
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->DefPackSize = IBuf[Octet + Off] & 0x0f;
|
|
Off++;
|
|
|
|
/* Octet 7c */
|
|
if (IsQ931Ext(IBuf[Octet + Off - 1])) {
|
|
pie->PackWinSize= IBuf[Octet + Off] & 0x7f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_LLCOMP);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_LLComp);
|
|
pie->Size = sizeof(Q931ie_LLComp);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_LLComp
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_LLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_LLComp *pIE = (Q931ie_LLComp*)IBuf;
|
|
L3INT rc = 0;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap;
|
|
|
|
/* Octet 3a */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6);
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate;
|
|
|
|
/* Octet 4.1 */
|
|
if (pIE->InfoRate == 0x18) {
|
|
OBuf[(*Octet)++] = 0x80 | pIE->RateMul;
|
|
}
|
|
|
|
/* Octet 5 */
|
|
if (pIE->Layer1Ident == 0x01) {
|
|
OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot;
|
|
|
|
/* Octet 5a */
|
|
if ((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08))
|
|
|| (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
|
|
OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate;
|
|
|
|
/* Octet 5b*/
|
|
if (pIE->UIL1Prot == 0x01) {
|
|
OBuf[(*Octet)++] = (pIE->InterRate << 5)
|
|
| (pIE->NIConTx << 4)
|
|
| (pIE->NIConTx << 3)
|
|
| (pIE->FlowCtlTx << 2)
|
|
| (pIE->FlowCtlRx << 1);
|
|
}
|
|
else if (pIE->UIL1Prot == 0x08) {
|
|
OBuf[(*Octet)++] = (pIE->HDR << 6)
|
|
| (pIE->MultiFrame << 5)
|
|
| (pIE->ModeL1 << 4)
|
|
| (pIE->NegotLLI << 3)
|
|
| (pIE->Assignor << 2)
|
|
| (pIE->InBandNeg << 1);
|
|
}
|
|
else {
|
|
OBuf[(*Octet) - 1] |= 0x80;
|
|
}
|
|
|
|
/* How to detect wherever 5c and 5d is to present is not clear
|
|
* but they have been inculded as 'standard'
|
|
* Octet 5c
|
|
*/
|
|
if (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) {
|
|
OBuf[(*Octet)++] = (pIE->NumStopBits << 5) | (pIE->NumDataBits << 3) | pIE->Parity ;
|
|
|
|
/* Octet 5d */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode << 6) | pIE->ModemType;
|
|
}
|
|
}
|
|
else {
|
|
OBuf[(*Octet) - 1] |= 0x80;
|
|
}
|
|
}
|
|
|
|
/* Octet 6 */
|
|
if (pIE->Layer2Ident == 0x02) {
|
|
OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot;
|
|
|
|
/* Octet 6a*/
|
|
if (pIE->UIL2Prot == 0x02 /* Q.921/I.441 */
|
|
|| pIE->UIL2Prot == 0x06 /* X.25 link layer */
|
|
|| pIE->UIL2Prot == 0x07 /* X.25 multilink */
|
|
|| pIE->UIL2Prot == 0x09 /* HDLC ARM */
|
|
|| pIE->UIL2Prot == 0x0a /* HDLC NRM */
|
|
|| pIE->UIL2Prot == 0x0b /* HDLC ABM */
|
|
|| pIE->UIL2Prot == 0x0d /* X.75 SLP */
|
|
|| pIE->UIL2Prot == 0x0e /* Q.922 */
|
|
|| pIE->UIL2Prot == 0x11) { /* ISO/ECE 7776 DTE-DCE */
|
|
OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use;
|
|
|
|
/* Octet 6b */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->WindowSize;
|
|
}
|
|
else if (pIE->UIL2Prot == 0x10) { /* User Specific */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot;
|
|
}
|
|
else {
|
|
OBuf[(*Octet) - 1] |= 0x80;
|
|
}
|
|
}
|
|
|
|
/* Octet 7 */
|
|
if (pIE->Layer3Ident == 0x03) {
|
|
OBuf[(*Octet)++] = (pIE->Layer3Ident << 5) | pIE->UIL3Prot;
|
|
|
|
/* Octet 7a - 3 different ones */
|
|
if (pIE->UIL3Prot == 0x10) {
|
|
OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info;
|
|
}
|
|
else if (pIE->UIL3Prot == 0x06
|
|
|| pIE->UIL3Prot == 0x07
|
|
|| pIE->UIL3Prot == 0x08) {
|
|
OBuf[(*Octet)++] = pIE->ModeL3 << 5;
|
|
|
|
/* Octet 7b note 7 */
|
|
OBuf[(*Octet)++] = pIE->DefPackSize;
|
|
|
|
/* Octet 7c note 7 */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize;
|
|
}
|
|
else if (pIE->UIL3Prot == 0x0b) {
|
|
OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f;
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f);
|
|
}
|
|
else {
|
|
OBuf[(*Octet) - 1] |= 0x80;
|
|
}
|
|
}
|
|
else {
|
|
Q931SetError(pTrunk,Q931E_LLCOMP, 7,0);
|
|
rc = Q931E_LLCOMP;
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_NetFac
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_NetFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_NetFac *pie = (Q931ie_NetFac*)OBuf;
|
|
ie *pIE = &pMsg->NetFac;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
pie->LenNetID = IBuf[Octet + Off]; /* full octet is used */
|
|
Octet++;
|
|
|
|
if (pie->LenNetID > 0) {
|
|
/* Octet 3.1 */
|
|
pie->TypeNetID = (IBuf[Octet + Off] >> 4) & 0x0f;
|
|
pie->NetIDPlan = IBuf[Octet + Off] & 0x0f;
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Off++;
|
|
|
|
/* Octet 3.2*/
|
|
for (x = 0; x < pie->LenNetID; x++) {
|
|
pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
}
|
|
|
|
/* Octet 4*/
|
|
pie->NetFac = IBuf[Octet + Off]; /* Full Octet is used */
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_NETFAC);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_NetFac) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_NetFac
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_NetFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_NetFac *pIE = (Q931ie_NetFac*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT x;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = pIE->LenNetID;
|
|
|
|
if (pIE->LenNetID > 0) {
|
|
/* Octet 3.1 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan;
|
|
|
|
/* Octet 3.2 */
|
|
for (x = 0; x <pIE->LenNetID; x++) {
|
|
OBuf[(*Octet)++] = pIE->NetID[x];
|
|
}
|
|
}
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = pIE->NetFac;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_NotifInd
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_NotifInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_NotifInd *pie = (Q931ie_NotifInd*)OBuf;
|
|
ie *pIE = &pMsg->NotifInd;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2*/
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->Notification = IBuf[Octet + Off] & 0x7f;
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_NOTIFIND);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_NotifInd);
|
|
pie->Size = sizeof(Q931ie_NotifInd);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_NotifInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_NotifInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_NotifInd *pIE = (Q931ie_NotifInd*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = pIE->Notification;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_ProgInd
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_ProgInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_ProgInd *pie = (Q931ie_ProgInd*)OBuf;
|
|
ie *pIE = &pMsg->ProgInd;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
|
|
pie->Location = IBuf[Octet + Off] & 0x0f;
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
pie->ProgDesc = IBuf[Octet + Off] & 0x7f;
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_PROGIND);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_ProgInd);
|
|
pie->Size = sizeof(Q931ie_ProgInd);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_ProgInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset L3INTo OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_ProgInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_ProgInd *pIE = (Q931ie_ProgInd*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location;
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_RepeatInd
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_RepeatInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf;
|
|
ie *pIE = &pMsg->RepeatInd;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet] & 0xf0;
|
|
pie->RepeatInd = IBuf[Octet] & 0x0f;
|
|
Octet ++;
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_RepeatInd);
|
|
pie->Size = sizeof(Q931ie_RepeatInd);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_RepeatInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_RepeatInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_RepeatInd *pIE = (Q931ie_RepeatInd*)IBuf;
|
|
L3INT rc = 0;
|
|
/* L3INT Beg = *Octet; */
|
|
|
|
OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_RevChargeInd
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
ie iE;
|
|
/* ie *pIE = &pMsg->RevChargeInd; */
|
|
Q931SetIE(iE, *OOff);
|
|
|
|
return iE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_RevChargeInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
L3BOOL RetCode = L3FALSE;
|
|
|
|
NoWarning(OBuf);
|
|
NoWarning(IBuf);
|
|
|
|
return RetCode;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_RestartInd
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_RestartInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_RestartInd *pie = (Q931ie_RestartInd*)OBuf;
|
|
ie *pIE = &pMsg->RestartInd;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->Class = IBuf[Octet + Off] & 0x07;
|
|
pie->Spare = IBuf[Octet + Off] & 0x78;
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_RESTARTIND);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_RestartInd);
|
|
pie->Size = sizeof(Q931ie_RestartInd);
|
|
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_RestartInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_RestartInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_RestartInd *pIE = (Q931ie_RestartInd*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3*/
|
|
OBuf[(*Octet)++] = 0x80 | pIE->Class ;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_Segment
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_Segment *pie = (Q931ie_Segment*)OBuf;
|
|
ie *pIE = &pMsg->Segment;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
Octet++;
|
|
|
|
/* Octet 2*/
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->FSI = (IBuf[Octet + Off] & 0x80) >> 7;
|
|
pie->NumSegRem = IBuf[Octet + Off] & 0x7f;
|
|
Octet++;
|
|
|
|
/* Octet 4 */
|
|
pie->SegType = IBuf[Octet + Off] & 0x7f;
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_SEGMENT);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_Segment);
|
|
pie->Size = sizeof(Q931ie_Segment);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_Segment
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_Segment *pIE = (Q931ie_Segment*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = (pIE->FSI << 7) | pIE->NumSegRem;
|
|
|
|
/* Octet 4 */
|
|
OBuf[(*Octet)++] = pIE->SegType;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_SendComplete
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_SendComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf;
|
|
ie *pIE = &pMsg->SendComplete;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
|
|
*pIE = 0;
|
|
Octet++;
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_SendComplete);
|
|
pie->Size = sizeof(Q931ie_SendComplete);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_ProgInd
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_SendComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
/* Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; */
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
/* L3INT Beg = *Octet; */
|
|
|
|
OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_Signal
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_Signal(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_Signal *pie = (Q931ie_Signal*)OBuf;
|
|
ie *pIE = &pMsg->Signal;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->Signal = IBuf[Octet + Off];
|
|
Octet++;
|
|
|
|
Q931IESizeTest(Q931E_SIGNAL);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_Signal);
|
|
pie->Size = sizeof(Q931ie_Signal);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_Signal
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_Signal(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_Signal *pIE = (Q931ie_Signal*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_SIGNAL;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = pIE->Signal;
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_TransNetSel
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_TransNetSel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_TransNetSel *pie = (Q931ie_TransNetSel*)OBuf;
|
|
ie *pIE = &pMsg->TransNetSel;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x = 0;
|
|
L3INT l;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
l = IBuf[Octet++] - 3;
|
|
|
|
/* Octet 3 */
|
|
pie->Type = (IBuf[Octet + Off] >> 4) & 0x07;
|
|
|
|
Off = Q931ReadExt(&IBuf[Octet], Off);
|
|
Octet++;
|
|
|
|
for (x = 0; x < l; x++) {
|
|
pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
}
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_TransNetSel) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_TransNetSel
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_TransNetSel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_TransNetSel *pIE = (Q931ie_TransNetSel*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT x;
|
|
L3INT l;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | (pIE->Type << 4) | pIE->NetIDPlan;
|
|
|
|
/* Octet 4 */
|
|
l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1;
|
|
for (x = 0; x < l; x++) {
|
|
OBuf[(*Octet)++] = pIE->NetID[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_UserUser
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_UserUser(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_UserUser *pie = (Q931ie_UserUser*)OBuf;
|
|
ie *pIE = &pMsg->UserUser;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT l;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
l = IBuf[Octet++] - 1;
|
|
|
|
/* Octet 3 */
|
|
pie->ProtDisc = IBuf[Octet++];
|
|
|
|
for (Off = 0; Off < l; Off++) {
|
|
pie->User[Off] = IBuf[Octet + Off];
|
|
}
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_UserUser) + Off - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_UserUser) + Off - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_UserUser
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_UserUser *pIE = (Q931ie_UserUser*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
L3INT x;
|
|
L3INT l;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_USER_USER;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = pIE->ProtDisc;
|
|
|
|
/* Octet 4 */
|
|
l = pIE->Size - sizeof(Q931ie_UserUser) + 1;
|
|
for (x = 0; x < l; x++) {
|
|
OBuf[(*Octet)++] = pIE->User[x];
|
|
}
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_GenericDigits
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_GenericDigits *pie = (Q931ie_GenericDigits*)OBuf;
|
|
ie *pIE = &pMsg->GenericDigits;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT x;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
/* Octet 1 */
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->Type = (IBuf[Octet]) & 0x1F;
|
|
pie->Encoding = (IBuf[Octet] >> 5) & 0x07;
|
|
Octet++;
|
|
|
|
/* Octet 4*/
|
|
if (pie->Encoding == 0) { /* BCD Even */
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x++] = IBuf[Octet + Off] & 0x0f;
|
|
pie->Digit[x++] = (IBuf[Octet + Off] >> 4) & 0x0f;
|
|
Off++;
|
|
} while (Q931MoreIE());
|
|
} else if (pie->Encoding == 1) { /* BCD Odd */
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x++] = IBuf[Octet + Off] & 0x0f;
|
|
if (Q931MoreIE()) {
|
|
pie->Digit[x] = (IBuf[Octet + Off] >> 4) & 0x0f;
|
|
}
|
|
x++;
|
|
Off++;
|
|
} while (Q931MoreIE());
|
|
} else if (pie->Encoding == 2) { /* IA5 */
|
|
x = 0;
|
|
do {
|
|
pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
|
|
Off++;
|
|
} while (Q931MoreIE());
|
|
} else {
|
|
/* Binary encoding type unkown */
|
|
Q931SetError(pTrunk, Q931E_GENERIC_DIGITS, Octet, Off);
|
|
return Q931E_GENERIC_DIGITS;
|
|
}
|
|
|
|
Q931IESizeTest(Q931E_GENERIC_DIGITS);
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x - 1;
|
|
pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x - 1);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_GenericDigits
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
|
|
L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF);
|
|
OBuf[(*Octet)++] = 0;
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Uie_ChangeStatus
|
|
|
|
Parameters: pIE[OUT] ptr to Information Element id.
|
|
IBuf[IN] ptr to a packed ie.
|
|
OBuf[OUT] ptr to buffer for Unpacked ie.
|
|
IOff[IN\OUT] Input buffer offset
|
|
OOff[IN\OUT] Output buffer offset
|
|
|
|
Ibuf and OBuf points directly to buffers. The IOff and OOff
|
|
must be updated, but are otherwise not used in the ie unpack.
|
|
|
|
Return Value: Error Message
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
Q931ie_ChangeStatus *pie = (Q931ie_ChangeStatus*)OBuf;
|
|
ie *pIE = &pMsg->ChangeStatus;
|
|
L3INT Off = 0;
|
|
L3INT Octet = 0;
|
|
L3INT IESize;
|
|
|
|
*pIE = 0;
|
|
|
|
pie->IEId = IBuf[Octet++];
|
|
|
|
/* Octet 2 */
|
|
IESize = IBuf[Octet++];
|
|
|
|
/* Octet 3 */
|
|
pie->Preference = (IBuf[Octet + Off] >> 6) & 0x01;
|
|
pie->Spare = IBuf[Octet + Off] & 0x38;
|
|
pie->NewStatus = IBuf[Octet + Off] & 0x07;
|
|
Octet++;
|
|
|
|
Q931SetIE(*pIE, *OOff);
|
|
|
|
*IOff = (*IOff) + Octet + Off;
|
|
*OOff = (*OOff) + sizeof(Q931ie_ChangeStatus);
|
|
pie->Size = sizeof(Q931ie_ChangeStatus);
|
|
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
Function: Q931Pie_ChangeStatus
|
|
|
|
Parameters: IBuf[IN] Ptr to struct.
|
|
OBuf[OUT] Ptr tp packed output buffer.
|
|
Octet[IN/OUT] Offset into OBuf.
|
|
|
|
Return Value: Error code, 0 = OK
|
|
|
|
*****************************************************************************/
|
|
L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
Q931ie_ChangeStatus *pIE = (Q931ie_ChangeStatus*)IBuf;
|
|
L3INT rc = Q931E_NO_ERROR;
|
|
L3INT Beg = *Octet;
|
|
L3INT li;
|
|
|
|
OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS;
|
|
li = (*Octet)++;
|
|
|
|
/* Octet 3 */
|
|
OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6);
|
|
|
|
OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
|
|
{
|
|
L3INT Octet = 0;
|
|
L3UCHAR id = 0;
|
|
|
|
/* id */
|
|
id = IBuf[Octet++];
|
|
|
|
/* Length */
|
|
Octet += IBuf[Octet];
|
|
Octet++;
|
|
|
|
Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding IE %#hhx with length %d\n", id, Octet - 2);
|
|
|
|
*IOff += Octet;
|
|
return Q931E_NO_ERROR;
|
|
}
|
|
|
|
L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
|
|
{
|
|
/* do nothing */
|
|
return Q931E_NO_ERROR;
|
|
}
|