1 /*****************************************************************************
2 
3   FileName:	 Q931ie.c
4 
5   Contents:	 Information Element Pack/Unpack functions.
6 
7 		These functions will pack out a Q931 message from the bit
8 		packed original format into structs that are easier to process
9 		and pack the same structs back into bit fields when sending
10 		messages out.
11 
12 		The messages contains a short for each possible IE. The MSB
13 		bit flags the precense of an IE, while the remaining bits
14 		are the offset into a buffer to find the actual IE.
15 
16 		Each IE are supported by 3 functions:
17 
18 		Q931Pie_XXX	 Pack struct into Q.931 IE
19 		Q931Uie_XXX	 Unpack Q.931 IE into struct
20 		Q931InitIEXXX   Initialize IE (see Q931api.c).
21 
22   Dialect Note: This file will only contain standard DSS1 IE. Other IE as
23 		used in QSIG, NI2, Q.932 etc are located in separate files.
24 
25 		See	q931.h for description.
26 
27   License/Copyright:
28 
29   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
30   email:janvb@caselaboratories.com
31 
32   Redistribution and use in source and binary forms, with or without
33   modification, are permitted provided that the following conditions are
34   met:
35 
36 	* Redistributions of source code must retain the above copyright notice,
37 	  this list of conditions and the following disclaimer.
38 	* Redistributions in binary form must reproduce the above copyright notice,
39 	  this list of conditions and the following disclaimer in the documentation
40 	  and/or other materials provided with the distribution.
41 	* Neither the name of the Case Labs, Ltd nor the names of its contributors
42 	  may be used to endorse or promote products derived from this software
43 	  without specific prior written permission.
44 
45   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55   POSSIBILITY OF SUCH DAMAGE.
56 *****************************************************************************/
57 
58 #include "Q931.h"
59 
60 #ifdef _MSC_VER
61 #ifndef __inline__
62 #define __inline__ __inline
63 #endif
64 #if (_MSC_VER >= 1400)			/* VC8+ */
65 #ifndef _CRT_SECURE_NO_DEPRECATE
66 #define _CRT_SECURE_NO_DEPRECATE
67 #endif
68 #ifndef _CRT_NONSTDC_NO_DEPRECATE
69 #define _CRT_NONSTDC_NO_DEPRECATE
70 #endif
71 #endif
72 #ifndef strcasecmp
73 #define strcasecmp(s1, s2) _stricmp(s1, s2)
74 #endif
75 #ifndef strncasecmp
76 #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
77 #endif
78 #ifndef snprintf
79 #define snprintf _snprintf
80 #endif
81 #endif
82 
83 /*****************************************************************************
84 
85   Macro:		Q931MoreIE
86 
87   Description:  Local helper macro detecting if there is more IE space left
88 		based on the 3 standard parameters Octet, Off and IESpace.
89 		This can be used to test if the IE is completed to avoid
90 		that the header of the next IE is interpreted as a part of
91 		the current IE.
92 
93 *****************************************************************************/
94 #define Q931MoreIE() (Octet + Off - 2 < IESize)
95 
96 #define Q931IESizeTest(x) {\
97 	if (Octet + Off - 2 != IESize) {\
98 		Q931SetError(pTrunk, x, Octet, Off);\
99 		return x;\
100 	}\
101 }
102 
103 /*****************************************************************************
104 
105   Function:	 Q931ReadExt
106 
107   Description:  Many of the octets in the standard have an MSB 'ext.1'. This
108 				means that the octet usually is the latest octet, but that a
109 				futhure standard may extend the octet. A stack must be able
110 				to handle such extensions by skipping the extension octets.
111 
112 				This function will increase the offset counter with 1 for
113 				each octet with an MSB of zero. This will allow the stack to
114 				skip extensions wihout knowing anything about them.
115 
116   Parameters:   IBuf	ptr to octet array.
117 				Off	 Starting offset counter
118 
119   Return Value: New offset value.
120 
121 *****************************************************************************/
122 
Q931ReadExt(L3UCHAR * IBuf,L3INT Off)123 L3INT Q931ReadExt(L3UCHAR * IBuf, L3INT Off)
124 {
125 	L3INT c = 0;
126 	while ((IBuf[c] & 0x80) == 0) {
127 		c++;
128 	}
129 	return Off + c;
130 }
131 
132 /*****************************************************************************
133 
134   Function:	 Q931Uie_BearerCap
135 
136   Description:  Unpack a bearer capability ie.
137 
138   Parameters:   pIE[OUT]	ptr to Information Element id.
139 		IBuf[IN]	ptr to a packed ie.
140 		OBuf[OUT]	ptr to buffer for Unpacked ie.
141 		IOff[IN\OUT]	Input buffer offset
142 		OOff[IN\OUT]	Output buffer offset
143 
144 		Ibuf and OBuf points directly to buffers. The IOff and OOff
145 		must be updated, but are otherwise not used in the ie unpack.
146 
147   Return Value: Error Message
148 
149 *****************************************************************************/
150 
Q931Uie_BearerCap(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)151 L3INT Q931Uie_BearerCap(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
152 {
153 	Q931ie_BearerCap *pie = (Q931ie_BearerCap*)OBuf;
154 	ie *pIE = &pMsg->BearerCap;
155 	L3INT Off = 0;
156 	L3INT Octet = 0;
157 	L3INT IESize;
158 	*pIE = 0;
159 
160 	/* Octet 1 */
161 	pie->IEId = IBuf[Octet++];
162 
163 	/* Octet 2 */
164 	IESize = IBuf[Octet++];
165 
166 	/* Octet 3 */
167 	pie->CodStand = ieGetOctet((IBuf[Octet] & 0x60) >> 5);
168 	pie->ITC      = ieGetOctet(IBuf[Octet] & 0x1f);
169 	Off           = Q931ReadExt(&IBuf[Octet], Off);
170 	Octet++;
171 
172 	/* Octet 4 */
173 	pie->TransMode = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
174 	pie->ITR       = ieGetOctet(IBuf[Octet + Off] & 0x1f);
175 	Off            = Q931ReadExt(&IBuf[Octet + Off], Off);
176 	Octet++;
177 
178 	/* Octet 4.1. Rate multiplier is only present if ITR = Multirate		*/
179 	if (pie->ITR == 0x18) {
180 		pie->RateMul = ieGetOctet(IBuf[Octet + Off] & 0x7f);
181 		Off = Q931ReadExt(&IBuf[Octet + Off], Off);
182 		Off ++;
183 	}
184 
185 	/* Octet 5 */
186 	if ((IBuf[Octet + Off] & 0x60) == 0x20 && Q931MoreIE()) {
187 		pie->Layer1Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
188 		pie->UIL1Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
189 		Octet++;
190 
191 		/* Octet 5a. The octet may be present if ITC is unrestrictd digital info
192 		 * and UIL1Prot is either V.110, I.460 and X.30 or V.120. It may also
193 		 * be present if ITC = 3.1 kHz audio and UIL1Prot is G.711.
194 		 * Bit 8 of Octet 5 = 0 indicates that 5a is present.
195 		 */
196 
197 		if (IsQ931Ext(IBuf[Octet + Off - 1])) {
198 			if (((pie->ITC == 0x08) && (pie->UIL1Prot == 0x01 || pie->UIL1Prot == 0x08))
199 			|| ((pie->ITC == 0x10) && (pie->UIL1Prot == 0x02 || pie->UIL1Prot == 0x03))) {
200 				pie->SyncAsync = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
201 				pie->Negot     = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
202 				pie->UserRate  = ieGetOctet(IBuf[Octet + Off] & 0x1f);
203 				Off ++;
204 			}
205 			else {
206 				/* We have detected bit 8 = 0, but no setting that require the  */
207 				/* additional octets ??? */
208 				Q931SetError(pTrunk, Q931E_BEARERCAP, 5,Off);
209 				return Q931E_BEARERCAP;
210 			}
211 
212 			/* Octet 5b. Two different structures used. */
213 			if (IsQ931Ext(IBuf[Octet + Off - 1])) {
214 				if (pie->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30 */
215 					pie->InterRate = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
216 					pie->NIConTx   = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
217 					pie->NIConRx   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
218 					pie->FlowCtlTx = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
219 					pie->FlowCtlRx = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 1);
220 					Off++;
221 				}
222 				else if (pie->UIL1Prot == 0x08) { /* ITU V.120 */
223 					pie->HDR        = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
224 					pie->MultiFrame = ieGetOctet((IBuf[Octet + Off] & 0x20) >> 5);
225 					pie->Mode       = ieGetOctet((IBuf[Octet + Off] & 0x10) >> 4);
226 					pie->LLInegot   = ieGetOctet((IBuf[Octet + Off] & 0x08) >> 3);
227 					pie->Assignor   = ieGetOctet((IBuf[Octet + Off] & 0x04) >> 2);
228 					pie->InBandNeg  = ieGetOctet((IBuf[Octet + Off] & 0x02) >> 1);
229 					Off++;
230 				}
231 				else {
232 					Q931SetError(pTrunk,Q931E_BEARERCAP, 5,Off);
233 					return Q931E_BEARERCAP;
234 				}
235 
236 				/* Octet 5c */
237 				if (IsQ931Ext(IBuf[Octet + Off - 1])) {
238 					pie->NumStopBits = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
239 					pie->NumDataBits = ieGetOctet((IBuf[Octet + Off] & 0x18) >> 3);
240 					pie->Parity      = ieGetOctet(IBuf[Octet + Off] & 0x07);
241 					Off++;
242 
243 					/* Octet 5d */
244 					if (IsQ931Ext(IBuf[Octet + Off - 1])) {
245 						pie->DuplexMode = ieGetOctet((IBuf[Octet + Off] & 0x40) >> 6);
246 						pie->ModemType  = ieGetOctet(IBuf[Octet + Off] & 0x3f);
247 						Off ++;
248 					}
249 				}
250 			}
251 		}
252 	}
253 
254 	/* Octet 6 */
255 	if ((IBuf[Octet + Off] & 0x60) == 0x40 && Q931MoreIE()) {
256 		pie->Layer2Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
257 		pie->UIL2Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
258 
259 		Off = Q931ReadExt(&IBuf[Octet + Off], Off);
260 		Octet ++;
261 	}
262 
263 	/* Octet 7 */
264 	if ((IBuf[Octet + Off] & 0x60) == 0x60 && Q931MoreIE()) {
265 		pie->Layer3Ident = ieGetOctet((IBuf[Octet + Off] & 0x60) >> 5);
266 		pie->UIL3Prot    = ieGetOctet(IBuf[Octet + Off] & 0x1f);
267 		Octet++;
268 
269 		/* Octet 7a */
270 		if (IsQ931Ext(IBuf[Octet + Off - 1])) {
271 			if (pie->UIL3Prot == 0x0c) {
272 				pie->AL3Info1 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
273 				Off++;
274 
275 				/* Octet 7b */
276 				if (IsQ931Ext(IBuf[Octet + Off])) {
277 					pie->AL3Info2 = ieGetOctet(IBuf[Octet + Off] & 0x0f);
278 					Off++;
279 				}
280 			}
281 			else {
282 				Q931SetError(pTrunk,Q931E_BEARERCAP, 7, Off);
283 				return Q931E_BEARERCAP;
284 
285 			}
286 		}
287 	}
288 
289 	Q931IESizeTest(Q931E_BEARERCAP);
290 	Q931SetIE(*pIE, *OOff);
291 
292 	*IOff = (*IOff) + Octet + Off;
293 	*OOff = (*OOff) + sizeof(Q931ie_BearerCap);
294 	pie->Size = sizeof(Q931ie_BearerCap);
295 
296 	return Q931E_NO_ERROR;
297 }
298 
299 /*****************************************************************************
300 
301   Function:	 Q931Pie_BearerCap
302 
303   Description:  Packing a Q.931 Bearer Capability element from a generic
304 				struct into a packed octet structure in accordance with the
305 				standard.
306 
307   Parameters:   IBuf[IN]		Ptr to struct.
308 				OBuf[OUT]		Ptr tp packed output buffer.
309 				Octet[IN/OUT]	Offset into OBuf.
310 
311   Return Value:	Error code, 0 = OK
312 
313 *****************************************************************************/
314 
Q931Pie_BearerCap(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)315 L3INT Q931Pie_BearerCap(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
316 {
317 	Q931ie_BearerCap *pIE = (Q931ie_BearerCap*)IBuf;
318 	L3INT rc = 0;
319 	L3INT Beg = *Octet; /* remember current offset */
320 	L3INT li;
321 
322 	Q931Log(pTrunk, Q931_LOG_DEBUG, "Encoding Bearer Capability IE\n");
323 
324 	OBuf[(*Octet)++] = Q931ie_BEARER_CAPABILITY ;
325 	li = (*Octet)++; /* remember length position */
326 
327 	/* Octet 3 - Coding standard / Information transfer capability */
328 	OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | (pIE->ITC & 0x1f);
329 
330 	/* Octet 4 - Transfer mode / Information transfer rate */
331 	OBuf[(*Octet)++] = 0x80 | ((pIE->TransMode << 5) & 0x60) | (pIE->ITR & 0x1f);
332 
333 	if (pIE->ITR == 0x18) {
334 		/* Octet 4.1 - Rate Multiplier */
335 		OBuf[(*Octet)++] = 0x80 | (pIE->RateMul & 0x7f);
336 	}
337 
338 	/* Octet 5 - Layer 1 Ident / User information layer 1 protocol */
339 	if (pIE->Layer1Ident == 0x01) {
340 		if (((pIE->ITC == 0x08) && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08)) ||
341 		   ((pIE->ITC == 0x10) && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
342 			OBuf[(*Octet)++] = 0x00 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x15);
343 
344 			/* Octet 5a - SyncAsync/Negot/UserRate */
345 			OBuf[(*Octet)++] = 0x00 | ((pIE->SyncAsync << 6) & 0x40) | ((pIE->Negot << 5) & 0x20) | (pIE->UserRate & 0x1f);
346 
347 			/* Octet 5b - one of two types */
348 			if (pIE->UIL1Prot == 0x01) { /* ITU V.110, I.460 and X.30	*/
349 				/* Octet 5b - Intermed rate/ Nic on Tx/Nix on Rx/FlowCtlTx/FlowCtlRx */
350 				OBuf[(*Octet)++] = 0x00
351 						| ((pIE->InterRate << 6) & 0x60)
352 						| ((pIE->NIConTx   << 4) & 0x10)
353 						| ((pIE->NIConRx   << 3) & 0x08)
354 						| ((pIE->FlowCtlTx << 2) & 0x04)
355 						| ((pIE->FlowCtlRx << 1) & 0x02);
356 			}
357 			else if (pIE->UIL1Prot == 0x08) { /* ITU V.120 */
358 				/* Octet 5b - HDR/Multiframe/Mode/LLINegot/Assignor/Inbandneg*/
359 				OBuf[(*Octet)++] = 0x00
360 						| ((pIE->InterRate  << 6) & 0x60)
361 						| ((pIE->MultiFrame << 5) & 0x20)
362 						| ((pIE->Mode       << 4) & 0x10)
363 						| ((pIE->LLInegot   << 3) & 0x08)
364 						| ((pIE->Assignor   << 2) & 0x04)
365 						| ((pIE->InBandNeg  << 1) & 0x02);
366 			}
367 
368 			/* Octet 5c - NumStopBits/NumStartBits/Parity					*/
369 			OBuf[(*Octet)++] = 0x00
370 					| ((pIE->NumStopBits << 5) & 0x60)
371 					| ((pIE->NumDataBits << 3) & 0x18)
372 					| (pIE->Parity & 0x07);
373 
374 			/* Octet 5d - Duplex Mode/Modem Type */
375 			OBuf[(*Octet)++] = 0x80 | ((pIE->DuplexMode << 6) & 0x40) | (pIE->ModemType & 0x3f);
376 		}
377 		else {
378 			OBuf[(*Octet)++] = 0x80 | ((pIE->Layer1Ident << 5) & 0x60) | (pIE->UIL1Prot & 0x1f);
379 		}
380 	}
381 
382 	/* Octet 6 - Layer2Ident/User information layer 2 prtocol */
383 	if (pIE->Layer2Ident == 0x02) {
384 		OBuf[(*Octet)++] = 0x80 | ((pIE->Layer2Ident << 5) & 0x60) | (pIE->UIL2Prot & 0x1f);
385 	}
386 
387 	/* Octet 7 - Layer 3 Ident/ User information layer 3 protocol */
388 	if (pIE->Layer3Ident == 0x03) {
389 		if (pIE->UIL3Prot == 0x0c) {
390 			OBuf[(*Octet)++] = 0x00 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
391 
392 			/* Octet 7a - Additional information layer 3 msb */
393 			OBuf[(*Octet)++] = 0x00 | (pIE->AL3Info1 & 0x0f);
394 
395 			/* Octet 7b - Additional information layer 3 lsb */
396 			OBuf[(*Octet)++] = 0x80 | (pIE->AL3Info2 & 0x0f);
397 		}
398 		else {
399 			OBuf[(*Octet)++] = 0x80 | ((pIE->Layer3Ident << 5) & 0x60) | (pIE->UIL3Prot & 0x1f);
400 		}
401 	}
402 
403 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
404 	return rc;
405 }
406 
407 /*****************************************************************************
408 
409   Function:	 Q931Uie_CallID
410 
411   Parameters:   pIE[OUT]		ptr to Information Element id.
412 				IBuf[IN]		ptr to a packed ie.
413 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
414 				IOff[IN\OUT]	Input buffer offset
415 				OOff[IN\OUT]	Output buffer offset
416 
417 
418 				Ibuf and OBuf points directly to buffers. The IOff and OOff
419 				must be updated, but are otherwise not used in the ie unpack.
420 
421   Return Value: Error Message
422 
423 *****************************************************************************/
Q931Uie_CallID(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)424 L3INT Q931Uie_CallID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
425 {
426 	Q931ie_CallID *pie = (Q931ie_CallID*)OBuf;
427 	ie *pIE = &pMsg->CallID;
428 	L3INT Off = 0;
429 	L3INT Octet = 0;
430 	L3INT x = 0;
431 	L3INT IESize;
432 
433 	*pIE = 0;
434 
435 	/* Octet 1 */
436 	pie->IEId = IBuf[Octet++];
437 
438 	/* Octet 2 */
439 	IESize = IBuf[Octet++];
440 
441 	/* Octet 3 */
442 	do {
443 		pie->CallId[x] = IBuf[Octet + Off] & 0x7f;
444 		Off++;
445 		x++;
446 	} while (Q931MoreIE());
447 
448 	Q931IESizeTest(Q931E_CALLID);
449 	Q931SetIE(*pIE, *OOff);
450 
451 	*IOff = (*IOff) + Octet + Off;
452 	*OOff = (*OOff) + sizeof(Q931ie_CallID) + x - 1;
453 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CallID) + x - 1);
454 
455 	return Q931E_NO_ERROR;
456 }
457 
458 /*****************************************************************************
459 
460   Function:	 Q931Pie_CallID
461 
462   Parameters:   IBuf[IN]		Ptr to struct.
463 				OBuf[OUT]		Ptr tp packed output buffer.
464 				Octet[IN/OUT]	Offset into OBuf.
465 
466   Return Value:	Error code, 0 = OK
467 
468 *****************************************************************************/
469 
Q931Pie_CallID(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)470 L3INT Q931Pie_CallID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
471 {
472 	Q931ie_CallID *pIE = (Q931ie_CallID*)IBuf;
473 	L3INT rc = 0;
474 	L3INT Beg = *Octet;/* remember current offset */
475 	L3INT li;
476 	L3INT sCI = pIE->Size - sizeof(Q931ie_CallID) + 1;
477 	L3INT x;
478 
479 	OBuf[(*Octet)++] = Q931ie_CALL_IDENTITY ;
480 	li = (*Octet)++; /* remember length position */
481 
482 	for (x = 0; x < sCI; x++) {
483 		OBuf[(*Octet)++] = pIE->CallId[x];
484 	}
485 
486 	OBuf[(*Octet) - 1] |= 0x80; /* set complete flag at last octet*/
487 
488 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
489 	return rc;
490 }
491 
492 /*****************************************************************************
493 
494   Function:	 Q931Uie_CallState
495 
496   Parameters:   pIE[OUT]		ptr to Information Element id.
497 				IBuf[IN]		ptr to a packed ie.
498 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
499 				IOff[IN\OUT]	Input buffer offset
500 				OOff[IN\OUT]	Output buffer offset
501 
502 				Ibuf and OBuf points directly to buffers. The IOff and OOff
503 				must be updated, but are otherwise not used in the ie unpack.
504 
505   Return Value: Error Message
506 
507 *****************************************************************************/
Q931Uie_CallState(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)508 L3INT Q931Uie_CallState(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
509 {
510 	Q931ie_CallState *pie = (Q931ie_CallState*)OBuf;
511 	ie *pIE = &pMsg->CallState;
512 	L3INT Off = 0;
513 	L3INT Octet = 0;
514 	L3INT IESize;
515 
516 	*pIE = 0;
517 
518 	/* Octet 1 */
519 	pie->IEId = IBuf[Octet++];
520 
521 	/* Octet 2 */
522 	IESize = IBuf[Octet++];
523 
524 	/* Octet 3 */
525 	pie->CodStand  = (IBuf[Octet + Off] >> 6) & 0x03;
526 	pie->CallState =  IBuf[Octet + Off] & 0x3f;
527 	Octet++;
528 
529 	Q931IESizeTest(Q931E_CALLSTATE);
530 	Q931SetIE(*pIE, *OOff);
531 
532 	*IOff = (*IOff) + Octet + Off;
533 	*OOff = (*OOff) + sizeof(Q931ie_CallState);
534 	pie->Size = sizeof(Q931ie_CallState);
535 
536 	return Q931E_NO_ERROR;
537 }
538 
539 /*****************************************************************************
540 
541   Function:	 Q931Pie_CallState
542 
543   Parameters:   IBuf[IN]		Ptr to struct.
544 				OBuf[OUT]		Ptr tp packed output buffer.
545 				Octet[IN/OUT]	Offset into OBuf.
546 
547   Return Value: Error code, 0 = OK
548 
549 *****************************************************************************/
Q931Pie_CallState(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)550 L3INT Q931Pie_CallState(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
551 {
552 	Q931ie_CallState *pIE = (Q931ie_CallState*)IBuf;
553 	L3INT rc = 0;
554 	L3INT Beg = *Octet; /* remember current offset */
555 	L3INT li;
556 
557 	OBuf[(*Octet)++] = Q931ie_CALL_STATE;
558 	li = (*Octet)++; /* remember length position */
559 
560 	OBuf[(*Octet)++] = (pIE->CodStand << 6) | (pIE->CallState & 0x3f);
561 
562 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
563 	return rc;
564 }
565 
566 /*****************************************************************************
567 
568   Function:	 Q931Uie_CalledSub
569 
570   Parameters:   pIE[OUT]		ptr to Information Element id.
571 				IBuf[IN]		ptr to a packed ie.
572 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
573 				IOff[IN\OUT]	Input buffer offset
574 				OOff[IN\OUT]	Output buffer offset
575 
576 				Ibuf and OBuf points directly to buffers. The IOff and OOff
577 				must be updated, but are otherwise not used in the ie unpack.
578 
579   Return Value: Error Message
580 
581 *****************************************************************************/
Q931Uie_CalledSub(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)582 L3INT Q931Uie_CalledSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
583 {
584 	Q931ie_CalledSub *pie = (Q931ie_CalledSub*)OBuf;
585 	ie *pIE = &pMsg->CalledSub;
586 	L3INT Off = 0;
587 	L3INT Octet = 0;
588 	L3INT x;
589 	L3INT IESize;
590 
591 	*pIE = 0;
592 
593 	/* Octet 1 */
594 	pie->IEId = IBuf[Octet++];
595 
596 	/* Octet 2 */
597 	IESize = IBuf[Octet++];
598 
599 	/* Octet 3 */
600 	pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
601 	pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
602 	Octet++;
603 
604 	/* Octet 4 */
605 	x = 0;
606 	do {
607 		pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
608 		Off++;
609 		x++;
610 	} while (Q931MoreIE() && x < 20);
611 
612 	Q931IESizeTest(Q931E_CALLEDSUB);
613 	Q931SetIE(*pIE, *OOff);
614 
615 	*IOff = (*IOff) + Octet + Off;
616 	*OOff = (*OOff) + sizeof(Q931ie_CalledSub) + x - 1;
617 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledSub) + x - 1);
618 
619 	return Q931E_NO_ERROR;
620 }
621 
622 /*****************************************************************************
623 
624   Function:	 Q931Pie_CalledSub
625 
626   Parameters:   IBuf[IN]		Ptr to struct.
627 				OBuf[OUT]		Ptr tp packed output buffer.
628 				Octet[IN/OUT]	Offset into OBuf.
629 
630   Return Value:	Error code, 0 = OK
631 
632 *****************************************************************************/
Q931Pie_CalledSub(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)633 L3INT Q931Pie_CalledSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
634 {
635 	Q931ie_CalledSub *pIE = (Q931ie_CalledSub*)IBuf;
636 	L3INT rc = 0;
637 	L3INT Beg = *Octet;
638 	L3INT li;
639 	L3INT sN = pIE->Size - sizeof(Q931ie_CalledSub) + 1;
640 	L3INT x;
641 
642 	/* Octet 1 */
643 	OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_SUBADDRESS;
644 	li = (*Octet)++;
645 
646 	/* Octet 3 */
647 	OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
648 
649 	/* Octet 4 */
650 	for (x = 0; x<sN; x++) {
651 		OBuf[(*Octet)++] = pIE->Digit[x];
652 	}
653 
654 	OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
655 
656 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
657 	return rc;
658 }
659 
660 /*****************************************************************************
661 
662   Function:	 Q931Uie_CalledNum
663 
664   Parameters:   pIE[OUT]		ptr to Information Element id.
665 				IBuf[IN]		ptr to a packed ie.
666 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
667 				IOff[IN\OUT]	Input buffer offset
668 				OOff[IN\OUT]	Output buffer offset
669 
670 				Ibuf and OBuf points directly to buffers. The IOff and OOff
671 				must be updated, but are otherwise not used in the ie unpack.
672 
673   Return Value: Error Message
674 
675 *****************************************************************************/
Q931Uie_CalledNum(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)676 L3INT Q931Uie_CalledNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
677 {
678 	Q931ie_CalledNum *pie = (Q931ie_CalledNum*)OBuf;
679 	ie *pIE = &pMsg->CalledNum;
680 	L3INT Off = 0;
681 	L3INT Octet = 0;
682 	L3INT x;
683 	L3INT IESize; /* # digits in this case */
684 
685 	*pIE = 0;
686 
687 	/* Octet 1 */
688 	pie->IEId = IBuf[Octet++];
689 
690 	/* Octet 2 */
691 	IESize = IBuf[Octet++];
692 
693 	/* Octet 3 */
694 	pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
695 	pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
696 	Octet++;
697 
698 	/* Octet 4*/
699 	x = 0;
700 	do {
701 		pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
702 		Off++;
703 		x++;
704 	} while ((IBuf[Octet + Off]&0x80) == 0 && Q931MoreIE());
705 
706 	pie->Digit[x] = '\0';
707 
708 	Q931SetIE(*pIE, *OOff);
709 
710 	*IOff = (*IOff) + Octet + Off;
711 	*OOff = (*OOff) + sizeof(Q931ie_CalledNum) + x;
712 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CalledNum) + x);
713 
714 	return Q931E_NO_ERROR;
715 }
716 
717 /*****************************************************************************
718 
719   Function:	 Q931Pie_CalledNum
720 
721   Parameters:   IBuf[IN]		Ptr to struct.
722 				OBuf[OUT]		Ptr tp packed output buffer.
723 				Octet[IN/OUT]	Offset into OBuf.
724 
725   Return Value:	Error code, 0 = OK
726 
727 *****************************************************************************/
Q931Pie_CalledNum(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)728 L3INT Q931Pie_CalledNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
729 {
730 	Q931ie_CalledNum *pIE = (Q931ie_CalledNum*)IBuf;
731 	L3INT rc = 0;
732 	L3INT Beg = *Octet;
733 	L3INT li;
734 	L3INT sN = pIE->Size - sizeof(Q931ie_CalledNum);
735 	L3INT x;
736 
737 	/* Octet 1 */
738 	OBuf[(*Octet)++] = Q931ie_CALLED_PARTY_NUMBER;
739 
740 	/* Octet 2 */
741 	li = (*Octet)++;
742 
743 	/* Octet 3 */
744 	OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->NumPlanID);
745 
746 	/* Octet 4 */
747 	for (x = 0; x<sN; x++) {
748 		OBuf[(*Octet)++] = pIE->Digit[x];
749 	}
750 
751 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
752 	return rc;
753 }
754 
755 /*****************************************************************************
756 
757   Function:	 Q931Uie_CallingNum
758 
759   Parameters:   pIE[OUT]		ptr to Information Element id.
760 				IBuf[IN]		ptr to a packed ie.
761 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
762 				IOff[IN\OUT]	Input buffer offset
763 				OOff[IN\OUT]	Output buffer offset
764 
765 				Ibuf and OBuf points directly to buffers. The IOff and OOff
766 				must be updated, but are otherwise not used in the ie unpack.
767 
768   Return Value: Error Message
769 
770 *****************************************************************************/
Q931Uie_CallingNum(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)771 L3INT Q931Uie_CallingNum(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
772 {
773 	Q931ie_CallingNum *pie = (Q931ie_CallingNum*)OBuf;
774 	ie *pIE = &pMsg->CallingNum;
775 	L3INT Off = 0;
776 	L3INT Octet = 0;
777 	L3INT x;
778 	L3INT IESize;
779 
780 	*pIE = 0;
781 
782 	/* Octet 1 */
783 	pie->IEId = IBuf[Octet++];
784 
785 	/* Octet 2 */
786 	IESize = IBuf[Octet++];
787 
788 	/* Octet 3 */
789 	pie->TypNum    = (IBuf[Octet + Off] >> 4) & 0x07;
790 	pie->NumPlanID =  IBuf[Octet + Off] & 0x0f;
791 
792 	/* Octet 3a */
793 	if ((IBuf[Octet + Off] & 0x80) == 0) {
794 		Off++;
795 		pie->PresInd   = (IBuf[Octet + Off] >> 5) & 0x03;
796 		pie->ScreenInd =  IBuf[Octet + Off] & 0x03;
797 	}
798 	Octet++;
799 
800 	/* Octet 4 */
801 	x = 0;
802 	while (Q931MoreIE()) {
803 		pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
804 
805 		if ((IBuf[Octet + Off] & 0x80) != 0) {
806 			break;
807 		}
808 		Off++;
809 	}
810 	pie->Digit[x] = '\0';
811 
812 	Q931IESizeTest(Q931E_CALLINGNUM);
813 	Q931SetIE(*pIE, *OOff);
814 
815 	*IOff = (*IOff) + Octet + Off;
816 	*OOff = (*OOff) + sizeof(Q931ie_CallingNum) + x;
817 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingNum) + x);
818 
819 	return Q931E_NO_ERROR;
820 }
821 
822 /*****************************************************************************
823 
824   Function:	 Q931Pie_CallingNum
825 
826   Parameters:   IBuf[IN]		Ptr to struct.
827 				OBuf[OUT]		Ptr tp packed output buffer.
828 				Octet[IN/OUT]	Offset into OBuf.
829 
830   Return Value:	Error code, 0 = OK
831 
832 *****************************************************************************/
Q931Pie_CallingNum(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)833 L3INT Q931Pie_CallingNum(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
834 {
835 	Q931ie_CallingNum *pIE = (Q931ie_CallingNum*)IBuf;
836 	L3INT rc = 0;
837 	L3INT Beg = *Octet;
838 	L3INT li;
839 	L3INT sN = pIE->Size - sizeof(Q931ie_CallingNum);
840 	L3INT x;
841 
842 	/* Octet 1 */
843 	OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_NUMBER;
844 
845 	/* Octet 2 */
846 	li = (*Octet)++;
847 
848 	/* Octet 3 */
849 	OBuf[(*Octet)++] = 0x00 | (pIE->TypNum << 4) | (pIE->NumPlanID);
850 
851 	/* Octet 4 */
852 	OBuf[(*Octet)++] = 0x80;
853 
854 	/* Octet 5 */
855 	for (x = 0; x<sN; x++) {
856 		OBuf[(*Octet)++] = pIE->Digit[x];
857 	}
858 
859 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
860 	return rc;
861 }
862 
863 /*****************************************************************************
864 
865   Function:	 Q931Uie_CallingSub
866 
867   Parameters:   pIE[OUT]		ptr to Information Element id.
868 				IBuf[IN]		ptr to a packed ie.
869 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
870 				IOff[IN\OUT]	Input buffer offset
871 				OOff[IN\OUT]	Output buffer offset
872 
873 				Ibuf and OBuf points directly to buffers. The IOff and OOff
874 				must be updated, but are otherwise not used in the ie unpack.
875 
876   Return Value: Error Message
877 
878 *****************************************************************************/
Q931Uie_CallingSub(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)879 L3INT Q931Uie_CallingSub(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
880 {
881 	Q931ie_CallingSub *pie = (Q931ie_CallingSub*)OBuf;
882 	ie *pIE = &pMsg->CallingSub;
883 	L3INT Off = 0;
884 	L3INT Octet = 0;
885 	L3INT x;
886 	L3INT IESize;
887 
888 	*pIE = 0;
889 
890 	/* Octet 1 */
891 	pie->IEId = IBuf[Octet++];
892 
893 	/* Octet 2 */
894 	IESize = IBuf[Octet++];
895 
896 	/* Octet 3 */
897 	pie->TypNum     = (IBuf[Octet + Off] >> 4) & 0x07;
898 	pie->OddEvenInd = (IBuf[Octet + Off] >> 3) & 0x01;
899 	Octet++;
900 
901 	/* Octet 4*/
902 	x = 0;
903 	do {
904 		pie->Digit[x] = IBuf[Octet + Off] & 0x7f;
905 		Off++;
906 		x++;
907 	} while (Q931MoreIE() && x < 20);
908 
909 	Q931IESizeTest(Q931E_CALLINGSUB);
910 	Q931SetIE(*pIE, *OOff);
911 
912 	*IOff = (*IOff) + Octet + Off;
913 	*OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x -1;
914 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x -1);
915 
916 	return Q931E_NO_ERROR;
917 }
918 
919 /*****************************************************************************
920 
921   Function:	 Q931Pie_CallingSub
922 
923   Parameters:   IBuf[IN]		Ptr to struct.
924 				OBuf[OUT]		Ptr tp packed output buffer.
925 				Octet[IN/OUT]	Offset into OBuf.
926 
927   Return Value:	Error code, 0 = OK
928 
929 *****************************************************************************/
Q931Pie_CallingSub(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)930 L3INT Q931Pie_CallingSub(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
931 {
932 	Q931ie_CallingSub *pIE = (Q931ie_CallingSub*)IBuf;
933 	L3INT rc = 0;
934 	L3INT Beg = *Octet;
935 	L3INT li;
936 	L3INT sN = pIE->Size - sizeof(Q931ie_CallingSub) + 1;
937 	L3INT x;
938 
939 	/* Octet 1 */
940 	OBuf[(*Octet)++] = Q931ie_CALLING_PARTY_SUBADDRESS;
941 	li = (*Octet)++;
942 
943 	/* Octet 3 */
944 	OBuf[(*Octet)++] = 0x80 | (pIE->TypNum << 4) | (pIE->OddEvenInd << 3);
945 
946 	/* Octet 4 */
947 	for (x = 0; x<sN; x++) {
948 		OBuf[(*Octet)++] = pIE->Digit[x];
949 	}
950 
951 	OBuf[(*Octet) - 1] |= 0x80; /* Terminate bit */
952 
953 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
954 	return rc;
955 }
956 
957 /*****************************************************************************
958 
959   Function:		Q931Uie_Cause
960 
961   Parameters:   pIE[OUT]		ptr to Information Element id.
962 				IBuf[IN]		ptr to a packed ie.
963 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
964 				IOff[IN\OUT]	Input buffer offset
965 				OOff[IN\OUT]	Output buffer offset
966 
967 				Ibuf and OBuf points directly to buffers. The IOff and OOff
968 				must be updated, but are otherwise not used in the ie unpack.
969 
970   Return Value: Error Message
971 
972 *****************************************************************************/
Q931Uie_Cause(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)973 L3INT Q931Uie_Cause(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
974 {
975 	Q931ie_Cause *pie = (Q931ie_Cause*)OBuf;
976 	ie *pIE = &pMsg->Cause;
977 	L3INT Off = 0;
978 	L3INT Octet = 0;
979 	L3INT IESize;
980 
981 	*pIE = 0;
982 
983 	pie->IEId = IBuf[Octet++];
984 
985 	/* Octet 2*/
986 	IESize = IBuf[Octet++];
987 
988 	/* Octet 3*/
989 	pie->CodStand = (IBuf[Octet + Off]>>5) & 0x03;
990 	pie->Location =  IBuf[Octet + Off] & 0x0f;
991 
992 	/* Octet 3a */
993 	if ((IBuf[Octet + Off] & 0x80) == 0) {
994 		Off++;
995 		pie->Recom = IBuf[Octet + Off] & 0x7f;
996 	}
997 	Octet++;
998 
999 	/* Octet 4 */
1000 	pie->Value = IBuf[Octet + Off] & 0x7f;
1001 	Octet++;
1002 
1003 	/* Consume optional Diagnostic bytes */
1004 	while (Q931MoreIE()) {
1005 		Off++;
1006 	};
1007 
1008 	Q931IESizeTest(Q931E_CAUSE);
1009 	Q931SetIE(*pIE, *OOff);
1010 
1011 	*IOff = (*IOff) + Octet + Off;
1012 	*OOff = (*OOff) + sizeof(Q931ie_Cause);
1013 	pie->Size = sizeof(Q931ie_Cause);
1014 
1015 	return Q931E_NO_ERROR;
1016 }
1017 
1018 /*****************************************************************************
1019 
1020   Function:		Q931Pie_Cause
1021 
1022   Parameters:   IBuf[IN]		Ptr to struct.
1023 				OBuf[OUT]		Ptr tp packed output buffer.
1024 				Octet[IN/OUT]	Offset into OBuf.
1025 
1026   Return Value:	Error code, 0 = OK
1027 
1028 *****************************************************************************/
Q931Pie_Cause(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1029 L3INT Q931Pie_Cause(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1030 {
1031 	Q931ie_Cause *pIE = (Q931ie_Cause*)IBuf;
1032 	L3INT rc = 0;
1033 	L3INT Beg = *Octet;
1034 	L3INT li;
1035 
1036 	OBuf[(*Octet)++] = Q931ie_CAUSE;
1037 	li = (*Octet)++;
1038 
1039 	/* Octet 3 */
1040 	OBuf[(*Octet)++] = 0x80 | (pIE->CodStand<<5) | pIE->Location;
1041 
1042 	/* Octet 3a - currently not supported in send */
1043 
1044 	/* Octet 4 */
1045 	OBuf[(*Octet)++] = 0x80 | pIE->Value;
1046 
1047 	/* Octet 5 - diagnostics not supported in send */
1048 
1049 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1050 	return rc;
1051 }
1052 
1053 /*****************************************************************************
1054 
1055   Function:	 Q931Uie_CongLevel
1056 
1057   Parameters:   pIE[OUT]		ptr to Information Element id.
1058 				IBuf[IN]		ptr to a packed ie.
1059 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1060 				IOff[IN\OUT]	Input buffer offset
1061 				OOff[IN\OUT]	Output buffer offset
1062 
1063 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1064 				must be updated, but are otherwise not used in the ie unpack.
1065 
1066   Return Value: Error Message
1067 
1068 *****************************************************************************/
Q931Uie_CongLevel(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1069 L3INT Q931Uie_CongLevel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1070 {
1071 	Q931ie_CongLevel *pie = (Q931ie_CongLevel*)OBuf;
1072 	ie *pIE = &pMsg->CongestionLevel;
1073 	L3INT Off = 0;
1074 	L3INT Octet = 0;
1075 
1076 	*pIE = 0;
1077 
1078 	pie->IEId      = IBuf[Octet] & 0xf0;
1079 	pie->CongLevel = IBuf[Octet] & 0x0f;
1080 	Octet ++;
1081 
1082 	Q931SetIE(*pIE, *OOff);
1083 
1084 	*IOff = (*IOff) + Octet + Off;
1085 	*OOff = (*OOff) + sizeof(Q931ie_CongLevel);
1086 	pie->Size = sizeof(Q931ie_CongLevel);
1087 
1088 	return Q931E_NO_ERROR;
1089 }
1090 
1091 /*****************************************************************************
1092 
1093   Function:	 Q931Pie_CongLevel
1094 
1095   Parameters:   IBuf[IN]		Ptr to struct.
1096 				OBuf[OUT]		Ptr tp packed output buffer.
1097 				Octet[IN/OUT]	Offset into OBuf.
1098 
1099   Return Value: Error code, 0 = OK
1100 
1101 *****************************************************************************/
Q931Pie_CongLevel(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1102 L3INT Q931Pie_CongLevel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1103 {
1104 	Q931ie_CongLevel *pIE = (Q931ie_CongLevel*)IBuf;
1105 	L3INT rc = 0;
1106 	/* L3INT Beg = *Octet; */
1107 
1108 	OBuf[(*Octet)++] = Q931ie_CONGESTION_LEVEL | pIE->CongLevel;
1109 
1110 	return rc;
1111 }
1112 
1113 /*****************************************************************************
1114 
1115   Function:	 Q931Uie_ChanID
1116 
1117   Parameters:   IBuf[IN]		ptr to a packed ie.
1118 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1119 				IOff[IN\OUT]	Input buffer offset
1120 				OOff[IN\OUT]	Output buffer offset
1121 
1122 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1123 				must be updated, but are otherwise not used in the ie unpack.
1124 
1125   Return Value:	Error code, 0 = OK
1126 
1127 *****************************************************************************/
Q931Uie_ChanID(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1128 L3INT Q931Uie_ChanID(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1129 {
1130 	Q931ie_ChanID *pie = (Q931ie_ChanID*)OBuf;
1131 	ie *pIE = &pMsg->ChanID;
1132 	L3INT Off = 0;
1133 	L3INT Octet = 0;
1134 	L3INT IESize;
1135 //18 04 e1 80 83 01
1136 	*pIE = 0;
1137 
1138 	Q931Log(pTrunk, Q931_LOG_DEBUG, "Decoding ChanID IE\n");
1139 
1140 	/* Octet 1 */
1141 	pie->IEId = IBuf[Octet++];
1142 
1143 	/* Octet 2 */
1144 	IESize    = IBuf[Octet++];
1145 
1146 	/* Octet 3 */
1147 	pie->IntIDPresent = (IBuf[Octet] >> 6) & 0x01;
1148 	pie->IntType      = (IBuf[Octet] >> 5) & 0x01;
1149 	pie->PrefExcl     = (IBuf[Octet] >> 3) & 0x01;
1150 	pie->DChanInd     = (IBuf[Octet] >> 2) & 0x01;
1151 	pie->InfoChanSel  =  IBuf[Octet] & 0x03;
1152 
1153 	Off = Q931ReadExt(&IBuf[Octet++], Off);
1154 
1155 	/* Octet 3.1 */
1156 	if (pie->IntIDPresent) {
1157 		pie->InterfaceID = IBuf[Octet + Off] & 0x7f;
1158 
1159 		/* Temp fix. Interface id can be extended using the extension bit */
1160 		/* this will read the octets, but do nothing with them. this is done */
1161 		/* because the usage of this field is a little unclear */
1162 		/* 30.jan.2001/JVB */
1163 		Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1164 		Off++;
1165 	}
1166 
1167 	if ((Octet + Off - 2) != IESize) {
1168 		/* Octet 3.2 */
1169 		if (pie->IntType == 1) {        /* PRI etc */
1170 			pie->CodStand    = (IBuf[Octet + Off] >> 5) & 0x03;
1171 			pie->NumMap      = (IBuf[Octet + Off] >> 4) & 0x01;
1172 			pie->ChanMapType =  IBuf[Octet + Off] & 0x0f;
1173 			Off++;
1174 
1175 			/* Octet 3.3 */
1176 			/* Temp fix. Assume B channel. H channels not supported */
1177 			pie->ChanSlot = IBuf[Octet + Off] & 0x7f;
1178 
1179 			/* Some dialects don't follow the extension coding properly for this, but this should be safe for all */
1180 			if ((Octet + Off - 1) != IESize) {
1181 				Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1182 			}
1183 			Off++;
1184 		}
1185 	}
1186 
1187 	Q931IESizeTest(Q931E_CHANID);
1188 	Q931SetIE(*pIE, *OOff);
1189 
1190 	*IOff = (*IOff) + Octet + Off;
1191 	*OOff = (*OOff) + sizeof(Q931ie_ChanID);
1192 	pie->Size = sizeof(Q931ie_ChanID);
1193 
1194 	if (pTrunk->loglevel == Q931_LOG_DEBUG) {
1195 		const char *iface;
1196 		char tmp[100] = "";
1197 
1198 		if (!pie->IntType) {
1199 			switch (pie->InfoChanSel) {
1200 			case 0x0:
1201 				iface = "None";
1202 				break;
1203 			case 0x1:
1204 				iface = "B1";
1205 				break;
1206 			case 0x2:
1207 				iface = "B2";
1208 				break;
1209 			default:
1210 				iface = "Any Channel";
1211 			}
1212 
1213 			snprintf(tmp, sizeof(tmp)-1, "InfoChanSel: %d (%s)", pie->InfoChanSel, iface);
1214 		}
1215 
1216 		Q931Log(pTrunk, Q931_LOG_DEBUG,
1217 			"\n-------------------------- Q.931 Channel ID ------------------------\n"
1218 			"    Pref/Excl: %s, Interface Type: %s\n"
1219 			"    %s\n"
1220 			"--------------------------------------------------------------------\n\n",
1221 			((pie->PrefExcl) ? "Preferred" : "Exclusive"),
1222 			((pie->IntType) ? "PRI/Other" : "BRI"),
1223 			tmp);
1224 	}
1225 	return Q931E_NO_ERROR;
1226 }
1227 
1228 /*****************************************************************************
1229 
1230   Function:	 Q931Pie_ChanID
1231 
1232   Parameters:   IBuf[IN]		Ptr to struct.
1233 				OBuf[OUT]		Ptr tp packed output buffer.
1234 				Octet[IN/OUT]	Offset into OBuf.
1235 
1236   Return Value:	Error code, 0 = OK
1237 
1238 *****************************************************************************/
Q931Pie_ChanID(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1239 L3INT Q931Pie_ChanID(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1240 {
1241 	Q931ie_ChanID *pIE = (Q931ie_ChanID*)IBuf;
1242 	L3INT rc = Q931E_NO_ERROR;
1243 	L3INT Beg = *Octet;	/* remember current offset */
1244 	L3INT li;
1245 
1246 	OBuf[(*Octet)++] = Q931ie_CHANNEL_IDENTIFICATION;
1247 	li = (*Octet)++; /* remember length position */
1248 
1249 	/* Octet 3 flags & BRI chan # */
1250 	OBuf[(*Octet)++] = 0x80
1251 			| ((pIE->IntIDPresent << 6) & 0x40)
1252 			| ((pIE->IntType << 5) & 0x20)
1253 			| ((pIE->PrefExcl << 3) & 0x08)
1254 			|  (pIE->InfoChanSel & 0x03);
1255 
1256 	/* Octet 3.1 - Interface Identifier */
1257 	if (pIE->IntIDPresent) {
1258 		OBuf[(*Octet)++] = 0x80 | (pIE->InterfaceID & 0x7f);
1259 	}
1260 
1261 	/* Octet 3.2 & 3.3 - PRI */
1262 	if (pIE->IntType) {
1263 		OBuf[(*Octet)++]  = 0x80
1264 			| ((pIE->CodStand << 5) & 0x60)
1265 			| ((pIE->NumMap << 4) & 0x10)
1266 			|  (pIE->ChanMapType & 0x0f);		/* TODO: support all possible channel map types */
1267 
1268 		/* Octet 3.3 Channel number */
1269 		switch (pIE->ChanMapType) {
1270 		case 0x6:	/* Slot map: H0 Channel Units */	/* unsupported, Octets 3.3.1 - 3.3.3 */
1271 			return Q931E_CHANID;
1272 
1273 		case 0x8:	/* Slot map: H11 Channel Units */
1274 		case 0x9:	/* Slot map: H12 Channel Units */
1275 		default:	/* Channel number */
1276 			OBuf[(*Octet)++] = 0x80 | (pIE->ChanSlot & 0x7f);
1277 			break;
1278 		}
1279 	}
1280 
1281 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1282 	return rc;
1283 }
1284 
1285 
1286 /*****************************************************************************
1287 
1288   Function:	 Q931Uie_CRV
1289 
1290   Description:  Reading CRV.
1291 
1292 				The CRV is currently returned in the return value that
1293 				Q921Rx23 will assign to the CRV field in the unpacked
1294 				message. CRV is basically 2 bytes etc, but the spec allows
1295 				the use of longer CRV values.
1296 
1297   Parameters:   pIE[OUT]		ptr to Information Element id.
1298 				IBuf[IN]		ptr to a packed ie.
1299 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1300 				IOff[IN\OUT]	Input buffer offset
1301 				OOff[IN\OUT]	Output buffer offset
1302 
1303 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1304 				must be updated, but are otherwise not used in the ie unpack.
1305 
1306   Return Value: CRV
1307 
1308 *****************************************************************************/
Q931Uie_CRV(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1309 L3USHORT Q931Uie_CRV(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1310 {
1311 	L3USHORT CRV = 0;
1312 	L3INT Octet = *IOff;
1313 	L3INT l = IBuf[Octet++];
1314 
1315 	if (l == 1) {	/* One octet CRV */
1316 		CRV = IBuf[Octet++] & 0x7F;
1317 	}
1318 	else if (l == 2) {	/* two octet CRV */
1319 		CRV  = (IBuf[Octet++] & 0x7f) << 8;
1320 		CRV |=  IBuf[Octet++];
1321 	}
1322 	else {
1323 		/* Long CRV is not used, so we skip this */
1324 		/* TODO: is it right to set to 0 here? */
1325 		CRV = 0;
1326 		Octet += l;
1327 	}
1328 
1329 	*IOff = Octet;
1330 	return CRV;
1331 }
1332 
1333 /*****************************************************************************
1334 
1335   Function:	 Q931Uie_DateTime
1336 
1337   Parameters:   pTrunk		[IN]		Ptr to trunk information.
1338 				pIE			[OUT]       ptr to Information Element id.
1339 				IBuf		[IN]		ptr to a packed ie.
1340 				OBuf		[OUT]	   ptr to buffer for Unpacked ie.
1341 				IOff		[IN\OUT]	Input buffer offset
1342 				OOff		[IN\OUT]	Output buffer offset
1343 
1344 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1345 				must be updated, but are otherwise not used in the ie unpack.
1346 
1347   Return Value: Error Message
1348 
1349 *****************************************************************************/
Q931Uie_DateTime(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1350 L3INT Q931Uie_DateTime(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
1351 {
1352 	Q931ie_DateTime * pie = (Q931ie_DateTime*)OBuf;
1353 	ie *pIE = &pMsg->DateTime;
1354 	L3INT Off = 0;
1355 	L3INT Octet = 0;
1356 	L3INT IESize = 0;
1357 
1358 	*pIE = 0;
1359 
1360 	pie->IEId = IBuf[Octet++];
1361 
1362 	/* Octet 2 */
1363 	IESize = IBuf[Octet++];
1364 
1365 	/* Octet 3 - Year */
1366 	pie->Year = IBuf[Octet++];
1367 
1368 	/* Octet 4 - Month */
1369 	pie->Month = IBuf[Octet++];
1370 
1371 	/* Octet 5 - Day */
1372 	pie->Day = IBuf[Octet++];
1373 
1374 	/*******************************************************************
1375 		The remaining part of the IE are optioinal, but only the length
1376 		can now tell us wherever these fields are present or not
1377 		(always remember: IESize does not include ID and Size octet)
1378 	********************************************************************/
1379 	pie->Format = 0;
1380 
1381 	/* Octet 6 - Hour (optional)*/
1382 	if (IESize >= 4) {
1383 		pie->Format = 1;
1384 		pie->Hour = IBuf[Octet++];
1385 
1386 		/* Octet 7 - Minute (optional)*/
1387 		if (IESize >= 5) {
1388 			pie->Format = 2;
1389 			pie->Minute = IBuf[Octet++];
1390 
1391 			/* Octet 8 - Second (optional)*/
1392 			if (IESize >= 6) {
1393 				pie->Format = 3;
1394 				pie->Second = IBuf[Octet++];
1395 			}
1396 		}
1397 	}
1398 
1399 	Q931IESizeTest(Q931E_DATETIME);
1400 	Q931SetIE(*pIE, *OOff);
1401 
1402 	*IOff = (*IOff) + Octet + Off;
1403 	*OOff = (*OOff) + sizeof(Q931ie_DateTime);
1404 	pie->Size = sizeof(Q931ie_DateTime);
1405 
1406 	return Q931E_NO_ERROR;
1407 }
1408 
1409 /*****************************************************************************
1410 
1411   Function:	 Q931Pie_DateTime
1412 
1413   Parameters:   IBuf[IN]		Ptr to struct.
1414 				OBuf[OUT]		Ptr tp packed output buffer.
1415 				Octet[IN/OUT]	Offset into OBuf.
1416 
1417   Return Value:	Error code, 0 = OK
1418 
1419 *****************************************************************************/
Q931Pie_DateTime(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1420 L3INT Q931Pie_DateTime(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1421 {
1422 	Q931ie_DateTime *pIE = (Q931ie_DateTime*)IBuf;
1423 	L3INT rc = 0;
1424 	L3INT Beg = *Octet;
1425 	L3INT li;
1426 
1427 	OBuf[(*Octet)++] = Q931ie_DATETIME;
1428 	li = (*Octet)++;
1429 
1430 	OBuf[(*Octet)++] = pIE->Year;
1431 	OBuf[(*Octet)++] = pIE->Month;
1432 	OBuf[(*Octet)++] = pIE->Day;
1433 	if (pIE->Format >= 1) {
1434 		OBuf[(*Octet)++] = pIE->Hour;
1435 
1436 		if (pIE->Format >= 2) {
1437 			OBuf[(*Octet)++] = pIE->Minute;
1438 
1439 			if (pIE->Format >= 3) {
1440 				OBuf[(*Octet)++] = pIE->Second;
1441 			}
1442 		}
1443 	}
1444 
1445 	OBuf[li] = (L3UCHAR)((*Octet)-Beg) - 2;
1446 	return rc;
1447 }
1448 
1449 /*****************************************************************************
1450 
1451   Function:	 Q931Uie_Display
1452 
1453   Parameters:   pIE[OUT]		ptr to Information Element id.
1454 				IBuf[IN]		ptr to a packed ie.
1455 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1456 				IOff[IN\OUT]	Input buffer offset
1457 				OOff[IN\OUT]	Output buffer offset
1458 
1459 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1460 				must be updated, but are otherwise not used in the ie unpack.
1461 
1462   Return Value: Error Message
1463 
1464 *****************************************************************************/
Q931Uie_Display(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1465 L3INT Q931Uie_Display(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1466 {
1467 	Q931ie_Display *pie = (Q931ie_Display*)OBuf;
1468 	ie *pIE = &pMsg->Display;
1469 	L3INT Off = 0;
1470 	L3INT Octet = 0;
1471 	L3INT IESize;
1472 	L3INT x;
1473 
1474 	*pIE = 0;
1475 
1476 	pie->IEId = IBuf[Octet++];
1477 	IESize    = IBuf[Octet++];
1478 
1479 	for (x = 0; x<IESize; x++) {
1480 		pie->Display[x] = IBuf[Octet + Off] & 0x7f;
1481 		Off++;
1482 	}
1483 
1484 	Q931IESizeTest(Q931E_DISPLAY);
1485 	Q931SetIE(*pIE, *OOff);
1486 
1487 	*IOff = (*IOff) + Octet + Off;
1488 	*OOff = (*OOff) + sizeof(Q931ie_Display) + x - 1;
1489 	pie->Size = (L3UCHAR)(sizeof(Q931ie_Display) + x - 1);
1490 
1491 	return Q931E_NO_ERROR;
1492 }
1493 
1494 /*****************************************************************************
1495 
1496   Function:	 Q931Pie_Display
1497 
1498   Parameters:   IBuf[IN]		Ptr to struct.
1499 				OBuf[OUT]		Ptr tp packed output buffer.
1500 				Octet[IN/OUT]	Offset into OBuf.
1501 
1502   Return Value:	Error code, 0 = OK
1503 
1504 *****************************************************************************/
Q931Pie_Display(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1505 L3INT Q931Pie_Display(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1506 {
1507 	Q931ie_Display *pIE = (Q931ie_Display*)IBuf;
1508 	L3INT rc = 0;
1509 	L3INT Beg = *Octet;
1510 	L3INT li;
1511 	L3INT DSize;
1512 	L3INT x;
1513 
1514 	OBuf[(*Octet)++] = Q931ie_DISPLAY;
1515 	li = (*Octet)++;
1516 
1517 	DSize = pIE->Size - sizeof(Q931ie_Display);
1518 
1519 	for (x = 0; x< DSize; x++) {
1520 
1521 		OBuf[(*Octet)++] = pIE->Display[x];
1522 	}
1523 
1524 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1525 	return rc;
1526 }
1527 
1528 /*****************************************************************************
1529 
1530   Function:	 Q931Uie_HLComp
1531 
1532   Parameters:   pIE[OUT]		ptr to Information Element id.
1533 				IBuf[IN]		ptr to a packed ie.
1534 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1535 				IOff[IN\OUT]	Input buffer offset
1536 				OOff[IN\OUT]	Output buffer offset
1537 
1538 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1539 				must be updated, but are otherwise not used in the ie unpack.
1540 
1541   Return Value: Error Message
1542 
1543 *****************************************************************************/
Q931Uie_HLComp(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1544 L3INT Q931Uie_HLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1545 {
1546 	Q931ie_HLComp * pie = (Q931ie_HLComp*)OBuf;
1547 	ie *pIE = &pMsg->HLComp;
1548 	L3INT Off = 0;
1549 	L3INT Octet = 0;
1550 	L3INT IESize;
1551 
1552 	*pIE = 0;
1553 
1554 	pie->IEId = IBuf[Octet++];
1555 
1556 	/* Octet */
1557 	IESize = IBuf[Octet++];
1558 
1559 	/* Octet 3*/
1560 	pie->CodStand  = (IBuf[Octet + Off] >>5) & 0x03;
1561 	pie->Interpret = (IBuf[Octet + Off] >>2) & 0x07;
1562 	pie->PresMeth  =  IBuf[Octet + Off] & 0x03;
1563 	Octet++;
1564 
1565 	/* Octet 4 */
1566 	pie->HLCharID = IBuf[Octet + Off] & 0x7f;
1567 	Octet++;
1568 
1569 	/* Octet 4a*/
1570 	if ((IBuf[Octet + Off - 1] & 0x80) == 0 && Q931MoreIE()) {
1571 		if (pie->HLCharID == 0x5e || pie->HLCharID == 0x5f) {
1572 			pie->EHLCharID = IBuf[Octet + Off] & 0x7f;
1573 			Off++;
1574 		}
1575 		else if ( pie->HLCharID >= 0xc3 && pie->HLCharID <= 0xcf) {
1576 			pie->EVideoTlfCharID = IBuf[Octet + Off] & 0x7f;
1577 			Off++;
1578 		}
1579 		else {
1580 			/* error Octet 4a indicated, but invalid value in Octet 4. */
1581 			Q931SetError(pTrunk,Q931E_HLCOMP, 4, Off);
1582 			return Q931E_HLCOMP;
1583 		}
1584 		Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1585 	}
1586 
1587 	Q931IESizeTest(Q931E_HLCOMP);
1588 	Q931SetIE(*pIE, *OOff);
1589 
1590 	*IOff = (*IOff) + Octet + Off;
1591 	*OOff = (*OOff) + sizeof(Q931ie_HLComp);
1592 	pie->Size = sizeof(Q931ie_HLComp);
1593 
1594 	return Q931E_NO_ERROR;
1595 }
1596 
1597 /*****************************************************************************
1598 
1599   Function:	 Q931Pie_HLComp
1600 
1601   Parameters:   IBuf[IN]		Ptr to struct.
1602 				OBuf[OUT]		Ptr tp packed output buffer.
1603 				Octet[IN/OUT]	Offset into OBuf.
1604 
1605   Return Value:	Error code, 0 = OK
1606 
1607 *****************************************************************************/
Q931Pie_HLComp(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1608 L3INT Q931Pie_HLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1609 {
1610 	Q931ie_HLComp *pIE = (Q931ie_HLComp*)IBuf;
1611 	L3INT rc = 0;
1612 	L3INT Beg = *Octet;
1613 	L3INT li;
1614 
1615 	OBuf[(*Octet)++] = Q931ie_HIGH_LAYER_COMPATIBILITY;
1616 	li = (*Octet)++;
1617 
1618 	/* Octet 3 */
1619 	OBuf[(*Octet)++] = 0x80 | ((pIE->CodStand << 5) & 0x60) | ((pIE->Interpret << 2) & 0x1c) | (pIE->PresMeth & 0x03);
1620 
1621 	/* Octet 4 */
1622 	OBuf[(*Octet)++] = pIE->HLCharID;
1623 
1624 	/* Octet 4a */
1625 	if (pIE->HLCharID == 0x5e || pIE->HLCharID == 0x5f) {
1626 		OBuf[(*Octet)++] = 0x80 | (pIE->EHLCharID & 0x7f);
1627 	}
1628 	else if ( pIE->HLCharID >= 0xc3 && pIE->HLCharID <= 0xcf) {
1629 		OBuf[(*Octet)++] = 0x80 | (pIE->EVideoTlfCharID & 0x7f);
1630 	}
1631 	else {
1632 		OBuf[(*Octet) - 1] |= 0x80;
1633 	}
1634 
1635 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1636 	return rc;
1637 }
1638 
1639 /*****************************************************************************
1640 
1641   Function:	 Q931Uie_KeypadFac
1642 
1643   Parameters:   pIE[OUT]		ptr to Information Element id.
1644 				IBuf[IN]		ptr to a packed ie.
1645 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1646 				IOff[IN\OUT]	Input buffer offset
1647 				OOff[IN\OUT]	Output buffer offset
1648 
1649 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1650 				must be updated, but are otherwise not used in the ie unpack.
1651 
1652   Return Value: Error Message
1653 
1654 *****************************************************************************/
Q931Uie_KeypadFac(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1655 L3INT Q931Uie_KeypadFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1656 {
1657 	Q931ie_KeypadFac *pie = (Q931ie_KeypadFac*)OBuf;
1658 	ie *pIE = &pMsg->KeypadFac;
1659 	L3INT Off = 0;
1660 	L3INT Octet = 0;
1661 	L3INT IESize;
1662 	L3INT x;
1663 
1664 	*pIE = 0;
1665 
1666 	pie->IEId = IBuf[Octet++];
1667 	IESize = IBuf[Octet++];
1668 
1669 	for (x = 0; x<IESize; x++) {
1670 		pie->KeypadFac[x] = IBuf[Octet + Off] & 0x7f;
1671 		Off++;
1672 	}
1673 
1674 	Q931IESizeTest(Q931E_KEYPADFAC);
1675 	Q931SetIE(*pIE, *OOff);
1676 
1677 	*IOff = (*IOff) + Octet + Off;
1678 	*OOff = (*OOff) + sizeof(Q931ie_KeypadFac) + x - 1;
1679 	pie->Size = (L3UCHAR)(sizeof(Q931ie_KeypadFac) + x - 1);
1680 
1681 	return Q931E_NO_ERROR;
1682 }
1683 
1684 /*****************************************************************************
1685 
1686   Function:	 Q931Pie_KeypadFac
1687 
1688   Parameters:   IBuf[IN]		Ptr to struct.
1689 				OBuf[OUT]		Ptr tp packed output buffer.
1690 				Octet[IN/OUT]	Offset into OBuf.
1691 
1692   Return Value:	Error code, 0 = OK
1693 
1694 *****************************************************************************/
Q931Pie_KeypadFac(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1695 L3INT Q931Pie_KeypadFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1696 {
1697 	Q931ie_KeypadFac *pIE = (Q931ie_KeypadFac*)IBuf;
1698 	L3INT rc = 0;
1699 	L3INT Beg = *Octet;
1700 	L3INT li;
1701 	L3INT DSize;
1702 	L3INT x;
1703 
1704 	OBuf[(*Octet)++] = Q931ie_KEYPAD_FACILITY;
1705 	li = (*Octet)++;
1706 
1707 	DSize = pIE->Size - sizeof(Q931ie_KeypadFac) + 1;
1708 
1709 	for (x = 0; x< DSize; x++) {
1710 		OBuf[(*Octet)++] = pIE->KeypadFac[x];
1711 	}
1712 
1713 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
1714 	return rc;
1715 }
1716 
1717 /*****************************************************************************
1718 
1719   Function:	 Q931Uie_LLComp
1720 
1721   Parameters:   pIE[OUT]		ptr to Information Element id.
1722 				IBuf[IN]		ptr to a packed ie.
1723 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
1724 				IOff[IN\OUT]	Input buffer offset
1725 				OOff[IN\OUT]	Output buffer offset
1726 
1727 				Ibuf and OBuf points directly to buffers. The IOff and OOff
1728 				must be updated, but are otherwise not used in the ie unpack.
1729 
1730   Return Value: Error Message
1731 
1732 *****************************************************************************/
Q931Uie_LLComp(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)1733 L3INT Q931Uie_LLComp(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
1734 {
1735 	Q931ie_LLComp *pie = (Q931ie_LLComp*)OBuf;
1736 	ie *pIE = &pMsg->LLComp;
1737 	L3INT Off = 0;
1738 	L3INT Octet = 0;
1739 	L3INT IESize;
1740 
1741 	*pIE = 0;
1742 
1743 	pie->IEId = IBuf[Octet++];
1744 
1745 	/* Octet 2 */
1746 	IESize = IBuf[Octet++];
1747 
1748 	/* Octet 3 */
1749 	pie->CodStand  = (IBuf[Octet + Off] >> 5) & 0x03;
1750 	pie->ITransCap =  IBuf[Octet + Off] & 0x1f;
1751 	Octet++;
1752 
1753 	/* Octet 3a*/
1754 	if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1755 		pie->NegotInd = (IBuf[Octet + Off] >> 6) & 0x01;
1756 		Off++;
1757 	}
1758 
1759 	/* Octet 4 */
1760 	pie->TransMode = (IBuf[Octet + Off] >> 5) & 0x03;
1761 	pie->InfoRate  =  IBuf[Octet + Off] & 0x1f;
1762 
1763 	Octet++;
1764 
1765 	/* Octet 4.1 */
1766 	if (pie->InfoRate == 0x14) { /* Mutirate */
1767 		pie->RateMul = IBuf[Octet + Off] & 0x7f;
1768 		Off++;
1769 	}
1770 
1771 	/* Octet 5 - Layer 1 Ident */
1772 	if ((IBuf[Octet + Off] & 0x60) == 0x20) { /* Layer 1 Ident ? */
1773 		pie->Layer1Ident = (IBuf[Octet + Off] >> 5) & 0x03;
1774 		pie->UIL1Prot    =  IBuf[Octet + Off] & 0x1f;
1775 		Octet++;
1776 
1777 		/* Octet 5a */
1778 		if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1779 			pie->SyncAsync = (IBuf[Octet + Off] >> 6) & 0x01;
1780 			pie->Negot     = (IBuf[Octet + Off] >> 5) & 0x01;
1781 			pie->UserRate  =  IBuf[Octet + Off] & 0x1f;
1782 			Off++;
1783 
1784 			/* Octet 5b - 2 options */
1785 			if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1786 				if (pie->UIL1Prot == 0x01) { /* V.110, I.460 and X.30*/
1787 					pie->InterRate = (IBuf[Octet + Off] >> 5) & 0x03;
1788 					pie->NIConTx   = (IBuf[Octet + Off] >> 4) & 0x01;
1789 					pie->NIConRx   = (IBuf[Octet + Off] >> 3) & 0x01;
1790 					pie->FlowCtlTx = (IBuf[Octet + Off] >> 2) & 0x01;
1791 					pie->FlowCtlRx = (IBuf[Octet + Off] >> 1) & 0x01;
1792 					Off++;
1793 				}
1794 				else if (pie->UIL1Prot == 0x80) { /* V.120 */
1795 					pie->HDR        = (IBuf[Octet + Off] >> 6) & 0x01;
1796 					pie->MultiFrame = (IBuf[Octet + Off] >> 5) & 0x01;
1797 					pie->ModeL1     = (IBuf[Octet + Off] >> 4) & 0x01;
1798 					pie->NegotLLI   = (IBuf[Octet + Off] >> 3) & 0x01;
1799 					pie->Assignor   = (IBuf[Octet + Off] >> 2) & 0x01;
1800 					pie->InBandNeg  = (IBuf[Octet + Off] >> 1) & 0x01;
1801 					Off++;
1802 				}
1803 				else if (pie->UIL1Prot == 0x07) { /* non standard */
1804 					Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1805 					Off++;
1806 				}
1807 				else {
1808 					Q931SetError(pTrunk,Q931E_LLCOMP, 5,2);
1809 					return Q931E_LLCOMP;
1810 				}
1811 
1812 				/* Octet 5c */
1813 				if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1814 					pie->NumStopBits = (IBuf[Octet + Off] >> 5) & 0x03;
1815 					pie->NumDataBits = (IBuf[Octet + Off] >> 3) & 0x03;
1816 					pie->Parity      =  IBuf[Octet + Off] & 0x07;
1817 					Off++;
1818 
1819 					/* Octet 5d */
1820 					if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1821 						pie->DuplexMode	= (IBuf[Octet + Off] >> 6) & 0x01;
1822 						pie->ModemType  =  IBuf[Octet + Off] & 0x3f;
1823 						Off = Q931ReadExt(&IBuf[Octet + Off], Off);
1824 						Off++;
1825 					}
1826 				}
1827 			}
1828 		}
1829 	}
1830 
1831 	/* Octet 6 - Layer 2 Ident */
1832 	if ((IBuf[Octet + Off] & 0x60) == 0x40) { /* Layer 1 Ident ? */
1833 		pie->Layer2Ident = (IBuf[Octet + Off] >>5) & 0x03;
1834 		pie->UIL2Prot    =  IBuf[Octet + Off] & 0x1f;
1835 		Octet++;
1836 
1837 		/* Octet 6a */
1838 		if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1839 			if (pie->UIL2Prot == 0x10) { /* 2nd 6a */
1840 				pie->UsrSpcL2Prot = IBuf[Octet + Off] & 0x7f;
1841 				Off++;
1842 			}
1843 			else { /* assume 1st 6a */
1844 				pie->ModeL2  = (IBuf[Octet + Off] >> 5) & 0x03;
1845 				pie->Q933use =  IBuf[Octet + Off] & 0x03;
1846 				Off++;
1847 			}
1848 			/* Octet 6b */
1849 			if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1850 				pie->WindowSize = IBuf[Octet + Off] & 0x7f;
1851 				Off++;
1852 			}
1853 		}
1854 	}
1855 
1856 	/* Octet 7 - layer 3 Ident */
1857 	if ((IBuf[Octet + Off] & 0x60) == 0x60) { /* Layer 3 Ident ? */
1858 		pie->Layer3Ident = (IBuf[Octet + Off] >> 5) & 0x03;
1859 		pie->UIL3Prot    =  IBuf[Octet + Off] & 0x1f;
1860 		Octet++;
1861 
1862 		/* Octet 7a */
1863 		if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1864 			if (pie->UIL3Prot == 0x0b) {
1865 				/* Octet 7a + 7b AddL3Info */
1866 				pie->AddL3Info = ((IBuf[Octet + Off] << 4) & 0xf0)
1867 								| (IBuf[Octet + Off + 1] & 0x0f);
1868 				Off += 2;
1869 			}
1870 			else {
1871 				if (pie->UIL3Prot == 0x1f) {
1872 					pie->ModeL3 = (IBuf[Octet + Off] >> 5) & 0x03;
1873 					Off++;
1874 				}
1875 				else {
1876 					pie->OptL3Info = IBuf[Octet + Off] & 0x7f;
1877 					Off++;
1878 				}
1879 
1880 				/* Octet 7b*/
1881 				if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1882 					pie->DefPackSize = IBuf[Octet + Off] & 0x0f;
1883 					Off++;
1884 
1885 					/* Octet 7c */
1886 					if (IsQ931Ext(IBuf[Octet + Off - 1])) {
1887 						pie->PackWinSize= IBuf[Octet + Off] & 0x7f;
1888 					}
1889 				}
1890 			}
1891 		}
1892 	}
1893 
1894 	Q931IESizeTest(Q931E_LLCOMP);
1895 	Q931SetIE(*pIE, *OOff);
1896 
1897 	*IOff = (*IOff) + Octet + Off;
1898 	*OOff = (*OOff) + sizeof(Q931ie_LLComp);
1899 	pie->Size = sizeof(Q931ie_LLComp);
1900 
1901 	return Q931E_NO_ERROR;
1902 }
1903 
1904 /*****************************************************************************
1905 
1906   Function:	 Q931Pie_LLComp
1907 
1908   Parameters:   IBuf[IN]		Ptr to struct.
1909 				OBuf[OUT]		Ptr tp packed output buffer.
1910 				Octet[IN/OUT]	Offset into OBuf.
1911 
1912   Return Value: Error code, 0 = OK
1913 
1914 *****************************************************************************/
Q931Pie_LLComp(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)1915 L3INT Q931Pie_LLComp(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
1916 {
1917 	Q931ie_LLComp *pIE = (Q931ie_LLComp*)IBuf;
1918 	L3INT rc = 0;
1919 	L3INT Beg = *Octet;
1920 	L3INT li;
1921 
1922 	OBuf[(*Octet)++] = Q931ie_LOW_LAYER_COMPATIBILITY;
1923 	li = (*Octet)++;
1924 
1925 	/* Octet 3 */
1926 	OBuf[(*Octet)++] = (pIE->CodStand << 6) | pIE->ITransCap;
1927 
1928 	/* Octet 3a */
1929 	OBuf[(*Octet)++] = 0x80 | (pIE->NegotInd << 6);
1930 
1931 	/* Octet 4 */
1932 	OBuf[(*Octet)++] = 0x80 | (pIE->TransMode << 5) | pIE->InfoRate;
1933 
1934 	/* Octet 4.1 */
1935 	if (pIE->InfoRate == 0x18) {
1936 		OBuf[(*Octet)++] = 0x80 | pIE->RateMul;
1937 	}
1938 
1939 	/* Octet 5 */
1940 	if (pIE->Layer1Ident == 0x01) {
1941 		OBuf[(*Octet)++] = (pIE->Layer1Ident << 5) | pIE->UIL1Prot;
1942 
1943 		/* Octet 5a */
1944 		if ((pIE->ITransCap == 0x08 && (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08))
1945 			|| (pIE->ITransCap == 0x10 && (pIE->UIL1Prot == 0x02 || pIE->UIL1Prot == 0x03))) {
1946 			OBuf[(*Octet)++] = (pIE->SyncAsync<<6) | (pIE->Negot<<5) | pIE->UserRate;
1947 
1948 			/* Octet 5b*/
1949 			if (pIE->UIL1Prot == 0x01) {
1950 				OBuf[(*Octet)++] =  (pIE->InterRate << 5)
1951 							| (pIE->NIConTx << 4)
1952 							| (pIE->NIConTx << 3)
1953 							| (pIE->FlowCtlTx << 2)
1954 							| (pIE->FlowCtlRx << 1);
1955 			}
1956 			else if (pIE->UIL1Prot == 0x08) {
1957 				OBuf[(*Octet)++] =  (pIE->HDR << 6)
1958 							| (pIE->MultiFrame << 5)
1959 							| (pIE->ModeL1 << 4)
1960 							| (pIE->NegotLLI << 3)
1961 							| (pIE->Assignor << 2)
1962 							| (pIE->InBandNeg << 1);
1963 			}
1964 			else {
1965 				OBuf[(*Octet) - 1] |= 0x80;
1966 			}
1967 
1968 			/* How to detect wherever 5c and 5d is to present is not clear
1969 			 * but they have been inculded as 'standard'
1970 			 * Octet 5c
1971 			 */
1972 			if (pIE->UIL1Prot == 0x01 || pIE->UIL1Prot == 0x08) {
1973 				OBuf[(*Octet)++] = (pIE->NumStopBits << 5) | (pIE->NumDataBits << 3) | pIE->Parity ;
1974 
1975 				/* Octet 5d */
1976 				OBuf[(*Octet)++] = 0x80 | (pIE->DuplexMode << 6) | pIE->ModemType;
1977 			}
1978 		}
1979 		else {
1980 			OBuf[(*Octet) - 1] |= 0x80;
1981 		}
1982 	}
1983 
1984 	/* Octet 6 */
1985 	if (pIE->Layer2Ident == 0x02) {
1986 		OBuf[(*Octet)++] = (pIE->Layer2Ident << 5) | pIE->UIL2Prot;
1987 
1988 		/* Octet 6a*/
1989 		if (pIE->UIL2Prot == 0x02 /* Q.921/I.441 */
1990 		|| pIE->UIL2Prot == 0x06 /* X.25 link layer */
1991 		|| pIE->UIL2Prot == 0x07 /* X.25 multilink */
1992 		|| pIE->UIL2Prot == 0x09 /* HDLC ARM */
1993 		|| pIE->UIL2Prot == 0x0a /* HDLC NRM */
1994 		|| pIE->UIL2Prot == 0x0b /* HDLC ABM */
1995 		|| pIE->UIL2Prot == 0x0d /* X.75 SLP */
1996 		|| pIE->UIL2Prot == 0x0e /* Q.922 */
1997 		|| pIE->UIL2Prot == 0x11) { /* ISO/ECE 7776 DTE-DCE */
1998 			OBuf[(*Octet)++] = (pIE->ModeL2 << 5) | pIE->Q933use;
1999 
2000 			/* Octet 6b */
2001 			OBuf[(*Octet)++] = 0x80 | pIE->WindowSize;
2002 		}
2003 		else if (pIE->UIL2Prot == 0x10) { /* User Specific */
2004 			OBuf[(*Octet)++] = 0x80 | pIE->UsrSpcL2Prot;
2005 		}
2006 		else {
2007 			OBuf[(*Octet) - 1] |= 0x80;
2008 		}
2009 	}
2010 
2011 	/* Octet 7 */
2012 	if (pIE->Layer3Ident == 0x03) {
2013 		OBuf[(*Octet)++] = (pIE->Layer3Ident << 5) | pIE->UIL3Prot;
2014 
2015 		/* Octet 7a - 3 different ones */
2016 		if (pIE->UIL3Prot == 0x10) {
2017 			OBuf[(*Octet++)] = 0x80 | pIE->OptL3Info;
2018 		}
2019 		else if (pIE->UIL3Prot == 0x06
2020 			||  pIE->UIL3Prot == 0x07
2021 			||  pIE->UIL3Prot == 0x08) {
2022 			OBuf[(*Octet)++] = pIE->ModeL3 << 5;
2023 
2024 			/* Octet 7b note 7 */
2025 			OBuf[(*Octet)++] = pIE->DefPackSize;
2026 
2027 			/* Octet 7c note 7 */
2028 			OBuf[(*Octet)++] = 0x80 | pIE->PackWinSize;
2029 		}
2030 		else if (pIE->UIL3Prot == 0x0b) {
2031 			OBuf[(*Octet)++] = (pIE->AddL3Info >> 4) & 0x0f;
2032 			OBuf[(*Octet)++] = 0x80 | (pIE->AddL3Info & 0x0f);
2033 		}
2034 		else {
2035 			OBuf[(*Octet) - 1] |= 0x80;
2036 		}
2037 	}
2038 	else {
2039 		Q931SetError(pTrunk,Q931E_LLCOMP, 7,0);
2040 		rc = Q931E_LLCOMP;
2041 	}
2042 
2043 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2044 	return rc;
2045 }
2046 
2047 /*****************************************************************************
2048 
2049   Function:	 Q931Uie_NetFac
2050 
2051   Parameters:   pIE[OUT]		ptr to Information Element id.
2052 				IBuf[IN]		ptr to a packed ie.
2053 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2054 				IOff[IN\OUT]	Input buffer offset
2055 				OOff[IN\OUT]	Output buffer offset
2056 
2057 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2058 				must be updated, but are otherwise not used in the ie unpack.
2059 
2060   Return Value: Error Message
2061 
2062 *****************************************************************************/
Q931Uie_NetFac(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2063 L3INT Q931Uie_NetFac(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2064 {
2065 	Q931ie_NetFac *pie = (Q931ie_NetFac*)OBuf;
2066 	ie *pIE = &pMsg->NetFac;
2067 	L3INT Off = 0;
2068 	L3INT Octet = 0;
2069 	L3INT x = 0;
2070 	L3INT IESize;
2071 
2072 	*pIE = 0;
2073 
2074 	pie->IEId = IBuf[Octet++];
2075 
2076 	/* Octet 2 */
2077 	IESize = IBuf[Octet++];
2078 
2079 	pie->LenNetID = IBuf[Octet + Off]; /* full octet is used */
2080 	Octet++;
2081 
2082 	if (pie->LenNetID > 0) {
2083 		/* Octet 3.1 */
2084 		pie->TypeNetID = (IBuf[Octet + Off] >> 4) & 0x0f;
2085 		pie->NetIDPlan =  IBuf[Octet + Off] & 0x0f;
2086 		Off = Q931ReadExt(&IBuf[Octet], Off);
2087 		Off++;
2088 
2089 		/* Octet 3.2*/
2090 		for (x = 0; x < pie->LenNetID; x++) {
2091 			pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
2092 			Off++;
2093 		}
2094 	}
2095 
2096 	/* Octet 4*/
2097 	pie->NetFac = IBuf[Octet + Off]; /* Full Octet is used */
2098 	Octet++;
2099 
2100 	Q931IESizeTest(Q931E_NETFAC);
2101 	Q931SetIE(*pIE, *OOff);
2102 
2103 	*IOff = (*IOff) + Octet + Off;
2104 	*OOff = (*OOff) + sizeof(Q931ie_NetFac) + x - 1;
2105 	pie->Size = (L3UCHAR)(sizeof(Q931ie_NetFac) + x - 1);
2106 
2107 	return Q931E_NO_ERROR;
2108 }
2109 
2110 /*****************************************************************************
2111 
2112   Function:	 Q931Pie_NetFac
2113 
2114   Parameters:   IBuf[IN]		Ptr to struct.
2115 				OBuf[OUT]		Ptr tp packed output buffer.
2116 				Octet[IN/OUT]	Offset into OBuf.
2117 
2118   Return Value:	Error code, 0 = OK
2119 
2120 *****************************************************************************/
Q931Pie_NetFac(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2121 L3INT Q931Pie_NetFac(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2122 {
2123 	Q931ie_NetFac *pIE = (Q931ie_NetFac*)IBuf;
2124 	L3INT rc = Q931E_NO_ERROR;
2125 	L3INT Beg = *Octet;
2126 	L3INT li;
2127 	L3INT x;
2128 
2129 	OBuf[(*Octet)++] = Q931ie_NETWORK_SPECIFIC_FACILITIES;
2130 	li = (*Octet)++;
2131 
2132 	/* Octet 3 */
2133 	OBuf[(*Octet)++] = pIE->LenNetID;
2134 
2135 	if (pIE->LenNetID > 0) {
2136 		/* Octet 3.1 */
2137 		OBuf[(*Octet)++] = 0x80 | (pIE->TypeNetID << 4) | pIE->NetIDPlan;
2138 
2139 		/* Octet 3.2 */
2140 		for (x = 0; x <pIE->LenNetID; x++) {
2141 			OBuf[(*Octet)++] = pIE->NetID[x];
2142 		}
2143 	}
2144 
2145 	/* Octet 4 */
2146 	OBuf[(*Octet)++] = pIE->NetFac;
2147 
2148 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2149 	return rc;
2150 }
2151 
2152 /*****************************************************************************
2153 
2154   Function:		Q931Uie_NotifInd
2155 
2156   Parameters:   pIE[OUT]		ptr to Information Element id.
2157 				IBuf[IN]		ptr to a packed ie.
2158 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2159 				IOff[IN\OUT]	Input buffer offset
2160 				OOff[IN\OUT]	Output buffer offset
2161 
2162 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2163 				must be updated, but are otherwise not used in the ie unpack.
2164 
2165   Return Value: Error Message
2166 
2167 *****************************************************************************/
Q931Uie_NotifInd(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2168 L3INT Q931Uie_NotifInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2169 {
2170 	Q931ie_NotifInd *pie = (Q931ie_NotifInd*)OBuf;
2171 	ie *pIE = &pMsg->NotifInd;
2172 	L3INT Off = 0;
2173 	L3INT Octet = 0;
2174 	L3INT IESize;
2175 
2176 	*pIE = 0;
2177 
2178 	pie->IEId = IBuf[Octet++];
2179 
2180 	/* Octet 2*/
2181 	IESize = IBuf[Octet++];
2182 
2183 	/* Octet 3 */
2184 	pie->Notification = IBuf[Octet + Off] & 0x7f;
2185 
2186 	Off = Q931ReadExt(&IBuf[Octet], Off);
2187 	Octet++;
2188 
2189 	Q931IESizeTest(Q931E_NOTIFIND);
2190 	Q931SetIE(*pIE, *OOff);
2191 
2192 	*IOff = (*IOff) + Octet + Off;
2193 	*OOff = (*OOff) + sizeof(Q931ie_NotifInd);
2194 	pie->Size = sizeof(Q931ie_NotifInd);
2195 
2196 	return Q931E_NO_ERROR;
2197 }
2198 
2199 /*****************************************************************************
2200 
2201   Function:	 Q931Pie_NotifInd
2202 
2203   Parameters:   IBuf[IN]		Ptr to struct.
2204 				OBuf[OUT]		Ptr tp packed output buffer.
2205 				Octet[IN/OUT]	Offset into OBuf.
2206 
2207   Return Value:	Error code, 0 = OK
2208 
2209 *****************************************************************************/
Q931Pie_NotifInd(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2210 L3INT Q931Pie_NotifInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2211 {
2212 	Q931ie_NotifInd *pIE = (Q931ie_NotifInd*)IBuf;
2213 	L3INT rc = Q931E_NO_ERROR;
2214 	L3INT Beg = *Octet;
2215 	L3INT li;
2216 
2217 	OBuf[(*Octet)++] = Q931ie_NOTIFICATION_INDICATOR;
2218 	li = (*Octet)++;
2219 
2220 	/* Octet 3 */
2221 	OBuf[(*Octet)++] = pIE->Notification;
2222 
2223 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2224 	return rc;
2225 }
2226 
2227 /*****************************************************************************
2228 
2229   Function:	 Q931Uie_ProgInd
2230 
2231   Parameters:   pIE[OUT]		ptr to Information Element id.
2232 				IBuf[IN]		ptr to a packed ie.
2233 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2234 				IOff[IN\OUT]	Input buffer offset
2235 				OOff[IN\OUT]	Output buffer offset
2236 
2237 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2238 				must be updated, but are otherwise not used in the ie unpack.
2239 
2240   Return Value: Error Message
2241 
2242 *****************************************************************************/
Q931Uie_ProgInd(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2243 L3INT Q931Uie_ProgInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2244 {
2245 	Q931ie_ProgInd *pie = (Q931ie_ProgInd*)OBuf;
2246 	ie *pIE = &pMsg->ProgInd;
2247 	L3INT Off = 0;
2248 	L3INT Octet = 0;
2249 	L3INT IESize;
2250 
2251 	*pIE = 0;
2252 
2253 	pie->IEId = IBuf[Octet++];
2254 
2255 	/* Octet 2 */
2256 	IESize = IBuf[Octet++];
2257 
2258 	/* Octet 3 */
2259 	pie->CodStand = (IBuf[Octet + Off] >> 5) & 0x03;
2260 	pie->Location =  IBuf[Octet + Off] & 0x0f;
2261 
2262 	Off = Q931ReadExt(&IBuf[Octet], Off);
2263 	Octet++;
2264 
2265 	/* Octet 4 */
2266 	pie->ProgDesc = IBuf[Octet + Off] & 0x7f;
2267 	Off = Q931ReadExt(&IBuf[Octet], Off);
2268 	Octet++;
2269 
2270 	Q931IESizeTest(Q931E_PROGIND);
2271 	Q931SetIE(*pIE, *OOff);
2272 
2273 	*IOff = (*IOff) + Octet + Off;
2274 	*OOff = (*OOff) + sizeof(Q931ie_ProgInd);
2275 	pie->Size = sizeof(Q931ie_ProgInd);
2276 
2277 	return Q931E_NO_ERROR;
2278 }
2279 
2280 /*****************************************************************************
2281 
2282   Function:	 Q931Pie_ProgInd
2283 
2284   Parameters:   IBuf[IN]		Ptr to struct.
2285 				OBuf[OUT]	   Ptr tp packed output buffer.
2286 				Octet[IN/OUT]   Offset L3INTo OBuf.
2287 
2288   Return Value: Error code, 0 = OK
2289 
2290 *****************************************************************************/
Q931Pie_ProgInd(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2291 L3INT Q931Pie_ProgInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2292 {
2293 	Q931ie_ProgInd *pIE = (Q931ie_ProgInd*)IBuf;
2294 	L3INT rc = Q931E_NO_ERROR;
2295 	L3INT Beg = *Octet;
2296 	L3INT li;
2297 
2298 	OBuf[(*Octet)++] = Q931ie_PROGRESS_INDICATOR;
2299 	li = (*Octet)++;
2300 
2301 	/* Octet 3 */
2302 	OBuf[(*Octet)++] = 0x80 | (pIE->CodStand << 5) | pIE->Location;
2303 
2304 	/* Octet 4 */
2305 	OBuf[(*Octet)++] = 0x80 | pIE->ProgDesc;
2306 
2307 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2308 	return rc;
2309 }
2310 
2311 /*****************************************************************************
2312 
2313   Function:	 Q931Uie_RepeatInd
2314 
2315   Parameters:   pIE[OUT]		ptr to Information Element id.
2316 				IBuf[IN]		ptr to a packed ie.
2317 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2318 				IOff[IN\OUT]	Input buffer offset
2319 				OOff[IN\OUT]	Output buffer offset
2320 
2321 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2322 				must be updated, but are otherwise not used in the ie unpack.
2323 
2324   Return Value: Error Message
2325 
2326 *****************************************************************************/
Q931Uie_RepeatInd(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2327 L3INT Q931Uie_RepeatInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2328 {
2329 	Q931ie_RepeatInd *pie = (Q931ie_RepeatInd*)OBuf;
2330 	ie *pIE = &pMsg->RepeatInd;
2331 	L3INT Off = 0;
2332 	L3INT Octet = 0;
2333 
2334 	*pIE = 0;
2335 
2336 	pie->IEId      = IBuf[Octet] & 0xf0;
2337 	pie->RepeatInd = IBuf[Octet] & 0x0f;
2338 	Octet ++;
2339 
2340 	Q931SetIE(*pIE, *OOff);
2341 
2342 	*IOff = (*IOff) + Octet + Off;
2343 	*OOff = (*OOff) + sizeof(Q931ie_RepeatInd);
2344 	pie->Size = sizeof(Q931ie_RepeatInd);
2345 
2346 	return Q931E_NO_ERROR;
2347 }
2348 
2349 /*****************************************************************************
2350 
2351   Function:	 Q931Pie_RepeatInd
2352 
2353   Parameters:   IBuf[IN]		Ptr to struct.
2354 				OBuf[OUT]		Ptr tp packed output buffer.
2355 				Octet[IN/OUT]	Offset into OBuf.
2356 
2357   Return Value:	Error code, 0 = OK
2358 
2359 *****************************************************************************/
Q931Pie_RepeatInd(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2360 L3INT Q931Pie_RepeatInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2361 {
2362 	Q931ie_RepeatInd *pIE = (Q931ie_RepeatInd*)IBuf;
2363 	L3INT rc = 0;
2364 	/* L3INT Beg = *Octet; */
2365 
2366 	OBuf[(*Octet)++] = Q931ie_REPEAT_INDICATOR | pIE->RepeatInd;
2367 
2368 	return rc;
2369 }
2370 
2371 /*****************************************************************************
2372 
2373   Function:	 Q931Uie_RevChargeInd
2374 
2375   Parameters:   pIE[OUT]		ptr to Information Element id.
2376 				IBuf[IN]		ptr to a packed ie.
2377 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2378 				IOff[IN\OUT]	Input buffer offset
2379 				OOff[IN\OUT]	Output buffer offset
2380 
2381 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2382 				must be updated, but are otherwise not used in the ie unpack.
2383 
2384   Return Value: Error Message
2385 
2386 *****************************************************************************/
Q931Uie_RevChargeInd(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2387 L3INT Q931Uie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2388 {
2389 	ie iE;
2390 	/* ie *pIE = &pMsg->RevChargeInd; */
2391 	Q931SetIE(iE, *OOff);
2392 
2393 	return iE;
2394 }
2395 
2396 /*****************************************************************************
2397 
2398   Function:	 Q931Pie_RevChargeInd
2399 
2400   Parameters:   IBuf[IN]		Ptr to struct.
2401 				OBuf[OUT]		Ptr tp packed output buffer.
2402 				Octet[IN/OUT]	Offset into OBuf.
2403 
2404   Return Value:	Error code, 0 = OK
2405 
2406 *****************************************************************************/
Q931Pie_RevChargeInd(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2407 L3INT Q931Pie_RevChargeInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2408 {
2409 	L3BOOL RetCode = L3FALSE;
2410 
2411 	NoWarning(OBuf);
2412 	NoWarning(IBuf);
2413 
2414 	return RetCode;
2415 }
2416 
2417 /*****************************************************************************
2418 
2419   Function:	 Q931Uie_RestartInd
2420 
2421   Parameters:   pIE[OUT]		ptr to Information Element id.
2422 				IBuf[IN]		ptr to a packed ie.
2423 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2424 				IOff[IN\OUT]	Input buffer offset
2425 				OOff[IN\OUT]	Output buffer offset
2426 
2427 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2428 				must be updated, but are otherwise not used in the ie unpack.
2429 
2430   Return Value: Error Message
2431 
2432 *****************************************************************************/
Q931Uie_RestartInd(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2433 L3INT Q931Uie_RestartInd(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2434 {
2435 	Q931ie_RestartInd *pie = (Q931ie_RestartInd*)OBuf;
2436 	ie *pIE = &pMsg->RestartInd;
2437 	L3INT Off = 0;
2438 	L3INT Octet = 0;
2439 	L3INT IESize;
2440 
2441 	*pIE = 0;
2442 
2443 	pie->IEId = IBuf[Octet++];
2444 
2445 	/* Octet 2 */
2446 	IESize = IBuf[Octet++];
2447 
2448 	/* Octet 3 */
2449 	pie->Class = IBuf[Octet + Off] & 0x07;
2450 	pie->Spare = IBuf[Octet + Off] & 0x78;
2451 
2452 	Off = Q931ReadExt(&IBuf[Octet], Off);
2453 	Octet++;
2454 
2455 	Q931IESizeTest(Q931E_RESTARTIND);
2456 	Q931SetIE(*pIE, *OOff);
2457 
2458 	*IOff = (*IOff) + Octet + Off;
2459 	*OOff = (*OOff) + sizeof(Q931ie_RestartInd);
2460 	pie->Size = sizeof(Q931ie_RestartInd);
2461 
2462 
2463 	return Q931E_NO_ERROR;
2464 }
2465 
2466 /*****************************************************************************
2467 
2468   Function:	 Q931Pie_RestartInd
2469 
2470   Parameters:   IBuf[IN]		Ptr to struct.
2471 				OBuf[OUT]		Ptr tp packed output buffer.
2472 				Octet[IN/OUT]	Offset into OBuf.
2473 
2474   Return Value:	Error code, 0 = OK
2475 
2476 *****************************************************************************/
Q931Pie_RestartInd(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2477 L3INT Q931Pie_RestartInd(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2478 {
2479 	Q931ie_RestartInd *pIE = (Q931ie_RestartInd*)IBuf;
2480 	L3INT rc = Q931E_NO_ERROR;
2481 	L3INT Beg = *Octet;
2482 	L3INT li;
2483 
2484 	OBuf[(*Octet)++] = Q931ie_RESTART_INDICATOR;
2485 	li = (*Octet)++;
2486 
2487 	/* Octet 3*/
2488 	OBuf[(*Octet)++] = 0x80 | pIE->Class ;
2489 
2490 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2491 	return rc;
2492 }
2493 
2494 /*****************************************************************************
2495 
2496   Function:	 Q931Uie_Segment
2497 
2498   Parameters:   pIE[OUT]		ptr to Information Element id.
2499 				IBuf[IN]		ptr to a packed ie.
2500 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2501 				IOff[IN\OUT]	Input buffer offset
2502 				OOff[IN\OUT]	Output buffer offset
2503 
2504 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2505 				must be updated, but are otherwise not used in the ie unpack.
2506 
2507   Return Value: Error Message
2508 
2509 *****************************************************************************/
Q931Uie_Segment(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2510 L3INT Q931Uie_Segment(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2511 {
2512 	Q931ie_Segment *pie = (Q931ie_Segment*)OBuf;
2513 	ie *pIE = &pMsg->Segment;
2514 	L3INT Off = 0;
2515 	L3INT Octet = 0;
2516 	L3INT IESize;
2517 
2518 	*pIE = 0;
2519 
2520 	pie->IEId = IBuf[Octet++];
2521 	Octet++;
2522 
2523 	/* Octet 2*/
2524 	IESize = IBuf[Octet++];
2525 
2526 	/* Octet 3 */
2527 	pie->FSI       = (IBuf[Octet + Off] & 0x80) >> 7;
2528 	pie->NumSegRem =  IBuf[Octet + Off] & 0x7f;
2529 	Octet++;
2530 
2531 	/* Octet 4 */
2532 	pie->SegType = IBuf[Octet + Off] & 0x7f;
2533 	Octet++;
2534 
2535 	Q931IESizeTest(Q931E_SEGMENT);
2536 	Q931SetIE(*pIE, *OOff);
2537 
2538 	*IOff = (*IOff) + Octet + Off;
2539 	*OOff = (*OOff) + sizeof(Q931ie_Segment);
2540 	pie->Size = sizeof(Q931ie_Segment);
2541 
2542 	return Q931E_NO_ERROR;
2543 }
2544 
2545 /*****************************************************************************
2546 
2547   Function:	 Q931Pie_Segment
2548 
2549   Parameters:   IBuf[IN]		Ptr to struct.
2550 				OBuf[OUT]		Ptr tp packed output buffer.
2551 				Octet[IN/OUT]	Offset into OBuf.
2552 
2553   Return Value:	Error code, 0 = OK
2554 
2555 *****************************************************************************/
Q931Pie_Segment(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2556 L3INT Q931Pie_Segment(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2557 {
2558 	Q931ie_Segment *pIE = (Q931ie_Segment*)IBuf;
2559 	L3INT rc = Q931E_NO_ERROR;
2560 	L3INT Beg = *Octet;
2561 	L3INT li;
2562 
2563 	OBuf[(*Octet)++] = Q931ie_SEGMENTED_MESSAGE;
2564 	li = (*Octet)++;
2565 
2566 	/* Octet 3 */
2567 	OBuf[(*Octet)++] = (pIE->FSI << 7) | pIE->NumSegRem;
2568 
2569 	/* Octet 4 */
2570 	OBuf[(*Octet)++] = pIE->SegType;
2571 
2572 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2573 	return rc;
2574 }
2575 
2576 /*****************************************************************************
2577 
2578   Function:		Q931Uie_SendComplete
2579 
2580   Parameters:   pIE[OUT]		ptr to Information Element id.
2581 				IBuf[IN]		ptr to a packed ie.
2582 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2583 				IOff[IN\OUT]	Input buffer offset
2584 				OOff[IN\OUT]	Output buffer offset
2585 
2586 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2587 				must be updated, but are otherwise not used in the ie unpack.
2588 
2589   Return Value: Error Message
2590 
2591 *****************************************************************************/
Q931Uie_SendComplete(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2592 L3INT Q931Uie_SendComplete(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2593 {
2594 	Q931ie_SendComplete *pie = (Q931ie_SendComplete*)OBuf;
2595 	ie *pIE = &pMsg->SendComplete;
2596 	L3INT Off = 0;
2597 	L3INT Octet = 0;
2598 
2599 	*pIE = 0;
2600 	Octet++;
2601 
2602 	Q931SetIE(*pIE, *OOff);
2603 
2604 	*IOff = (*IOff) + Octet + Off;
2605 	*OOff = (*OOff) + sizeof(Q931ie_SendComplete);
2606 	pie->Size = sizeof(Q931ie_SendComplete);
2607 
2608 	return Q931E_NO_ERROR;
2609 }
2610 
2611 /*****************************************************************************
2612 
2613   Function:	 Q931Pie_ProgInd
2614 
2615   Parameters:   IBuf[IN]		Ptr to struct.
2616 				OBuf[OUT]	   Ptr tp packed output buffer.
2617 				Octet[IN/OUT]   Offset into OBuf.
2618 
2619   Return Value: Error code, 0 = OK
2620 
2621 *****************************************************************************/
Q931Pie_SendComplete(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2622 L3INT Q931Pie_SendComplete(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2623 {
2624 	/* Q931ie_SendComplete * pIE = (Q931ie_SendComplete*)IBuf; */
2625 	L3INT rc = Q931E_NO_ERROR;
2626 	/* L3INT Beg = *Octet; */
2627 
2628 	OBuf[(*Octet)++] = 0x80 | (L3UCHAR)Q931ie_SENDING_COMPLETE;
2629 
2630 	return rc;
2631 }
2632 
2633 /*****************************************************************************
2634 
2635   Function:	 Q931Uie_Signal
2636 
2637   Parameters:   pIE[OUT]		ptr to Information Element id.
2638 				IBuf[IN]		ptr to a packed ie.
2639 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2640 				IOff[IN\OUT]	Input buffer offset
2641 				OOff[IN\OUT]	Output buffer offset
2642 
2643 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2644 				must be updated, but are otherwise not used in the ie unpack.
2645 
2646   Return Value: Error Message
2647 
2648 *****************************************************************************/
Q931Uie_Signal(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2649 L3INT Q931Uie_Signal(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2650 {
2651 	Q931ie_Signal *pie = (Q931ie_Signal*)OBuf;
2652 	ie *pIE = &pMsg->Signal;
2653 	L3INT Off = 0;
2654 	L3INT Octet = 0;
2655 	L3INT IESize;
2656 
2657 	*pIE = 0;
2658 
2659 	pie->IEId = IBuf[Octet++];
2660 
2661 	/* Octet 2 */
2662 	IESize = IBuf[Octet++];
2663 
2664 	/* Octet 3 */
2665 	pie->Signal = IBuf[Octet + Off];
2666 	Octet++;
2667 
2668 	Q931IESizeTest(Q931E_SIGNAL);
2669 	Q931SetIE(*pIE, *OOff);
2670 
2671 	*IOff = (*IOff) + Octet + Off;
2672 	*OOff = (*OOff) + sizeof(Q931ie_Signal);
2673 	pie->Size = sizeof(Q931ie_Signal);
2674 
2675 	return Q931E_NO_ERROR;
2676 }
2677 
2678 /*****************************************************************************
2679 
2680   Function:	 Q931Pie_Signal
2681 
2682   Parameters:   IBuf[IN]		Ptr to struct.
2683 				OBuf[OUT]		Ptr tp packed output buffer.
2684 				Octet[IN/OUT]	Offset into OBuf.
2685 
2686   Return Value:	Error code, 0 = OK
2687 
2688 *****************************************************************************/
Q931Pie_Signal(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2689 L3INT Q931Pie_Signal(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2690 {
2691 	Q931ie_Signal *pIE = (Q931ie_Signal*)IBuf;
2692 	L3INT rc = Q931E_NO_ERROR;
2693 	L3INT Beg = *Octet;
2694 	L3INT li;
2695 
2696 	OBuf[(*Octet)++] = Q931ie_SIGNAL;
2697 	li = (*Octet)++;
2698 
2699 	/* Octet 3 */
2700 	OBuf[(*Octet)++] = pIE->Signal;
2701 
2702 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2703 	return rc;
2704 }
2705 
2706 /*****************************************************************************
2707 
2708   Function:	 Q931Uie_TransNetSel
2709 
2710   Parameters:   pIE[OUT]		ptr to Information Element id.
2711 				IBuf[IN]		ptr to a packed ie.
2712 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2713 				IOff[IN\OUT]	Input buffer offset
2714 				OOff[IN\OUT]	Output buffer offset
2715 
2716 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2717 				must be updated, but are otherwise not used in the ie unpack.
2718 
2719   Return Value: Error Message
2720 
2721 *****************************************************************************/
Q931Uie_TransNetSel(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2722 L3INT Q931Uie_TransNetSel(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2723 {
2724 	Q931ie_TransNetSel *pie = (Q931ie_TransNetSel*)OBuf;
2725 	ie *pIE = &pMsg->TransNetSel;
2726 	L3INT Off = 0;
2727 	L3INT Octet = 0;
2728 	L3INT x = 0;
2729 	L3INT l;
2730 
2731 	*pIE = 0;
2732 
2733 	pie->IEId = IBuf[Octet++];
2734 
2735 	/* Octet 2 */
2736 	l = IBuf[Octet++] - 3;
2737 
2738 	/* Octet 3 */
2739 	pie->Type = (IBuf[Octet + Off] >> 4) & 0x07;
2740 
2741 	Off = Q931ReadExt(&IBuf[Octet], Off);
2742 	Octet++;
2743 
2744 	for (x = 0; x < l; x++) {
2745 		pie->NetID[x] = IBuf[Octet + Off] & 0x7f;
2746 		Off++;
2747 	}
2748 
2749 	Q931SetIE(*pIE, *OOff);
2750 
2751 	*IOff = (*IOff) + Octet + Off;
2752 	*OOff = (*OOff) + sizeof(Q931ie_TransNetSel) + x - 1;
2753 	pie->Size = (L3UCHAR)(sizeof(Q931ie_TransNetSel) + x - 1);
2754 
2755 	return Q931E_NO_ERROR;
2756 }
2757 
2758 /*****************************************************************************
2759 
2760   Function:	 Q931Pie_TransNetSel
2761 
2762   Parameters:   IBuf[IN]		Ptr to struct.
2763 				OBuf[OUT]		Ptr tp packed output buffer.
2764 				Octet[IN/OUT]	Offset into OBuf.
2765 
2766   Return Value:	Error code, 0 = OK
2767 
2768 *****************************************************************************/
Q931Pie_TransNetSel(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2769 L3INT Q931Pie_TransNetSel(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2770 {
2771 	Q931ie_TransNetSel *pIE = (Q931ie_TransNetSel*)IBuf;
2772 	L3INT rc = Q931E_NO_ERROR;
2773 	L3INT Beg = *Octet;
2774 	L3INT li;
2775 	L3INT x;
2776 	L3INT l;
2777 
2778 	OBuf[(*Octet)++] = Q931ie_TRANSIT_NETWORK_SELECTION;
2779 	li = (*Octet)++;
2780 
2781 	/* Octet 3 */
2782 	OBuf[(*Octet)++] = 0x80 | (pIE->Type << 4) | pIE->NetIDPlan;
2783 
2784 	/* Octet 4 */
2785 	l = pIE->Size - sizeof(Q931ie_TransNetSel) + 1;
2786 	for (x = 0; x < l; x++) {
2787 		OBuf[(*Octet)++] = pIE->NetID[x];
2788 	}
2789 
2790 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2791 	return rc;
2792 }
2793 
2794 /*****************************************************************************
2795 
2796   Function:	 Q931Uie_UserUser
2797 
2798   Parameters:   pIE[OUT]		ptr to Information Element id.
2799 				IBuf[IN]		ptr to a packed ie.
2800 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2801 				IOff[IN\OUT]	Input buffer offset
2802 				OOff[IN\OUT]	Output buffer offset
2803 
2804 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2805 				must be updated, but are otherwise not used in the ie unpack.
2806 
2807   Return Value: Error Message
2808 
2809 *****************************************************************************/
Q931Uie_UserUser(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2810 L3INT Q931Uie_UserUser(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2811 {
2812 	Q931ie_UserUser *pie = (Q931ie_UserUser*)OBuf;
2813 	ie *pIE = &pMsg->UserUser;
2814 	L3INT Off = 0;
2815 	L3INT Octet = 0;
2816 	L3INT l;
2817 
2818 	*pIE = 0;
2819 
2820 	pie->IEId = IBuf[Octet++];
2821 
2822 	/* Octet 2 */
2823 	l = IBuf[Octet++] - 1;
2824 
2825 	/* Octet 3 */
2826 	pie->ProtDisc = IBuf[Octet++];
2827 
2828 	for (Off = 0; Off < l; Off++) {
2829 		pie->User[Off] = IBuf[Octet + Off];
2830 	}
2831 
2832 	Q931SetIE(*pIE, *OOff);
2833 
2834 	*IOff = (*IOff) + Octet + Off;
2835 	*OOff = (*OOff) + sizeof(Q931ie_UserUser) + Off - 1;
2836 	pie->Size = (L3UCHAR)(sizeof(Q931ie_UserUser) + Off - 1);
2837 
2838 	return Q931E_NO_ERROR;
2839 }
2840 
2841 /*****************************************************************************
2842 
2843   Function:	 Q931Pie_UserUser
2844 
2845   Parameters:   IBuf[IN]		Ptr to struct.
2846 				OBuf[OUT]		Ptr tp packed output buffer.
2847 				Octet[IN/OUT]	Offset into OBuf.
2848 
2849   Return Value:	Error code, 0 = OK
2850 
2851 *****************************************************************************/
Q931Pie_UserUser(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2852 L3INT Q931Pie_UserUser(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2853 {
2854 	Q931ie_UserUser *pIE = (Q931ie_UserUser*)IBuf;
2855 	L3INT rc = Q931E_NO_ERROR;
2856 	L3INT Beg = *Octet;
2857 	L3INT li;
2858 	L3INT x;
2859 	L3INT l;
2860 
2861 	OBuf[(*Octet)++] = Q931ie_USER_USER;
2862 	li = (*Octet)++;
2863 
2864 	/* Octet 3 */
2865 	OBuf[(*Octet)++] = pIE->ProtDisc;
2866 
2867 	/* Octet 4 */
2868 	l = pIE->Size - sizeof(Q931ie_UserUser) + 1;
2869 	for (x = 0; x < l; x++) {
2870 		OBuf[(*Octet)++] = pIE->User[x];
2871 	}
2872 
2873 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
2874 	return rc;
2875 }
2876 
2877 /*****************************************************************************
2878 
2879   Function:	 Q931Uie_GenericDigits
2880 
2881   Parameters:   pIE[OUT]		ptr to Information Element id.
2882 				IBuf[IN]		ptr to a packed ie.
2883 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2884 				IOff[IN\OUT]	Input buffer offset
2885 				OOff[IN\OUT]	Output buffer offset
2886 
2887 
2888 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2889 				must be updated, but are otherwise not used in the ie unpack.
2890 
2891   Return Value: Error Message
2892 
2893 *****************************************************************************/
Q931Uie_GenericDigits(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2894 L3INT Q931Uie_GenericDigits(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2895 {
2896 	Q931ie_GenericDigits *pie = (Q931ie_GenericDigits*)OBuf;
2897 	ie *pIE = &pMsg->GenericDigits;
2898 	L3INT Off = 0;
2899 	L3INT Octet = 0;
2900 	L3INT x;
2901 	L3INT IESize;
2902 
2903 	*pIE = 0;
2904 
2905 	/* Octet 1 */
2906 	pie->IEId = IBuf[Octet++];
2907 
2908 	/* Octet 2 */
2909 	IESize = IBuf[Octet++];
2910 
2911 	/* Octet 3 */
2912 	pie->Type     = (IBuf[Octet]) & 0x1F;
2913 	pie->Encoding = (IBuf[Octet] >> 5) & 0x07;
2914 	Octet++;
2915 
2916 	/* Octet 4*/
2917 	if (pie->Encoding == 0) { /* BCD Even */
2918 		x = 0;
2919 		do {
2920 			pie->Digit[x++] =  IBuf[Octet + Off] & 0x0f;
2921 			pie->Digit[x++] = (IBuf[Octet + Off] >> 4) & 0x0f;
2922 			Off++;
2923 		} while (Q931MoreIE());
2924 	} else if (pie->Encoding == 1) { /* BCD Odd */
2925 		x = 0;
2926 		do {
2927 			pie->Digit[x++] = IBuf[Octet + Off] & 0x0f;
2928 			if (Q931MoreIE()) {
2929 				pie->Digit[x] = (IBuf[Octet + Off] >> 4) & 0x0f;
2930 			}
2931 			x++;
2932 			Off++;
2933 		} while (Q931MoreIE());
2934 	} else if (pie->Encoding == 2) { /* IA5 */
2935 		x = 0;
2936 		do {
2937 			pie->Digit[x++] = IBuf[Octet + Off] & 0x7f;
2938 			Off++;
2939 		} while (Q931MoreIE());
2940 	} else {
2941 		/* Binary encoding type unkown */
2942 		Q931SetError(pTrunk, Q931E_GENERIC_DIGITS, Octet, Off);
2943 		return Q931E_GENERIC_DIGITS;
2944 	}
2945 
2946 	Q931IESizeTest(Q931E_GENERIC_DIGITS);
2947 	Q931SetIE(*pIE, *OOff);
2948 
2949 	*IOff = (*IOff) + Octet + Off;
2950 	*OOff = (*OOff) + sizeof(Q931ie_CallingSub) + x - 1;
2951 	pie->Size = (L3UCHAR)(sizeof(Q931ie_CallingSub) + x - 1);
2952 
2953 	return Q931E_NO_ERROR;
2954 }
2955 
2956 /*****************************************************************************
2957 
2958   Function:	 Q931Pie_GenericDigits
2959 
2960   Parameters:   IBuf[IN]		Ptr to struct.
2961 				OBuf[OUT]		Ptr tp packed output buffer.
2962 				Octet[IN/OUT]	Offset into OBuf.
2963 
2964   Return Value:	Error code, 0 = OK
2965 
2966 *****************************************************************************/
2967 
Q931Pie_GenericDigits(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)2968 L3INT Q931Pie_GenericDigits(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
2969 {
2970 	OBuf[(*Octet)++] = (Q931ie_GENERIC_DIGITS & 0xFF);
2971 	OBuf[(*Octet)++] = 0;
2972 
2973 	return Q931E_NO_ERROR;
2974 }
2975 
2976 /*****************************************************************************
2977 
2978   Function:	 Q931Uie_ChangeStatus
2979 
2980   Parameters:   pIE[OUT]		ptr to Information Element id.
2981 				IBuf[IN]		ptr to a packed ie.
2982 				OBuf[OUT]	   ptr to buffer for Unpacked ie.
2983 				IOff[IN\OUT]	Input buffer offset
2984 				OOff[IN\OUT]	Output buffer offset
2985 
2986 				Ibuf and OBuf points directly to buffers. The IOff and OOff
2987 				must be updated, but are otherwise not used in the ie unpack.
2988 
2989   Return Value: Error Message
2990 
2991 *****************************************************************************/
Q931Uie_ChangeStatus(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)2992 L3INT Q931Uie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR * IBuf, L3UCHAR * OBuf, L3INT *IOff, L3INT *OOff)
2993 {
2994 	Q931ie_ChangeStatus *pie = (Q931ie_ChangeStatus*)OBuf;
2995 	ie *pIE = &pMsg->ChangeStatus;
2996 	L3INT Off = 0;
2997 	L3INT Octet = 0;
2998 	L3INT IESize;
2999 
3000 	*pIE = 0;
3001 
3002 	pie->IEId = IBuf[Octet++];
3003 
3004 	/* Octet 2 */
3005 	IESize = IBuf[Octet++];
3006 
3007 	/* Octet 3 */
3008 	pie->Preference = (IBuf[Octet + Off] >> 6) & 0x01;
3009 	pie->Spare      =  IBuf[Octet + Off] & 0x38;
3010 	pie->NewStatus  =  IBuf[Octet + Off] & 0x07;
3011 	Octet++;
3012 
3013 	Q931SetIE(*pIE, *OOff);
3014 
3015 	*IOff = (*IOff) + Octet + Off;
3016 	*OOff = (*OOff) + sizeof(Q931ie_ChangeStatus);
3017 	pie->Size = sizeof(Q931ie_ChangeStatus);
3018 
3019 	return Q931E_NO_ERROR;
3020 }
3021 
3022 /*****************************************************************************
3023 
3024   Function:	 Q931Pie_ChangeStatus
3025 
3026   Parameters:   IBuf[IN]		Ptr to struct.
3027 				OBuf[OUT]		Ptr tp packed output buffer.
3028 				Octet[IN/OUT]	Offset into OBuf.
3029 
3030   Return Value:	Error code, 0 = OK
3031 
3032 *****************************************************************************/
Q931Pie_ChangeStatus(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)3033 L3INT Q931Pie_ChangeStatus(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
3034 {
3035 	Q931ie_ChangeStatus *pIE = (Q931ie_ChangeStatus*)IBuf;
3036 	L3INT rc = Q931E_NO_ERROR;
3037 	L3INT Beg = *Octet;
3038 	L3INT li;
3039 
3040 	OBuf[(*Octet)++] = Q931ie_CHANGE_STATUS;
3041 	li = (*Octet)++;
3042 
3043 	/* Octet 3 */
3044 	OBuf[(*Octet)++] = 0x80 | pIE->NewStatus | ((pIE->Preference & 0x01) << 6);
3045 
3046 	OBuf[li] = (L3UCHAR)((*Octet) - Beg) - 2;
3047 	return rc;
3048 }
3049 
3050 
3051 
Q931Uie_Generic(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * pMsg,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * IOff,L3INT * OOff)3052 L3INT Q931Uie_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *pMsg, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *IOff, L3INT *OOff)
3053 {
3054 	L3INT Octet = 0;
3055 	L3UCHAR id = 0;
3056 
3057 	/* id */
3058 	id = IBuf[Octet++];
3059 
3060 	/* Length */
3061 	Octet += IBuf[Octet];
3062 	Octet++;
3063 
3064 	Q931Log(pTrunk, Q931_LOG_DEBUG, "Discarding IE %#hhx with length %d\n", id, Octet - 2);
3065 
3066 	*IOff += Octet;
3067 	return Q931E_NO_ERROR;
3068 }
3069 
Q931Pie_Generic(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,L3UCHAR * OBuf,L3INT * Octet)3070 L3INT Q931Pie_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, L3UCHAR *OBuf, L3INT *Octet)
3071 {
3072 	/* do nothing */
3073 	return Q931E_NO_ERROR;
3074 }
3075