1 /*****************************************************************************
2
3 FileName: 5ESSmes.c
4
5 Contents: Pack/Unpack functions. These functions will unpack a 5ESS ISDN
6 message from the bit packed original format into structs
7 that contains variables sized by the user. It will also pack
8 the struct back into a Q.931 message as required.
9
10 See 5ESS.h for description.
11
12 License/Copyright:
13
14 Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
15 email:janvb@caselaboratories.com
16
17 Copyright (c) 2007, Michael Jerris. All rights reserved.
18 email:mike@jerris.com
19
20 Copyright (c) 2007, Michael S. Collins, All rights reserved.
21 email:mcollins@fcnetwork.com
22
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions are
25 met:
26
27 * Redistributions of source code must retain the above copyright notice,
28 this list of conditions and the following disclaimer.
29 * Redistributions in binary form must reproduce the above copyright notice,
30 this list of conditions and the following disclaimer in the documentation
31 and/or other materials provided with the distribution.
32 * Neither the name of the Case Labs, Ltd nor the names of its contributors
33 may be used to endorse or promote products derived from this software
34 without specific prior written permission.
35
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
40 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 POSSIBILITY OF SUCH DAMAGE.
47
48 *****************************************************************************/
49
50 #include "5ESS.h"
51
52 /*****************************************************************************
53
54 Function: ATT5ESSUmes_Setup
55
56 *****************************************************************************/
ATT5ESSUmes_Setup(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,Q931mes_Generic * mes,L3INT IOff,L3INT Size)57 L3INT ATT5ESSUmes_Setup(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size)
58 {
59 L3INT ir = 0;
60 L3INT OOff = 0;
61 L3INT rc = Q931E_NO_ERROR;
62 L3UCHAR last_codeset = 0, codeset = 0;
63 L3UCHAR shift_nolock = 1;
64
65 while (IOff < Size) {
66
67 if (shift_nolock) {
68 codeset = last_codeset;
69 }
70
71 if ((IBuf[IOff] & 0xF0) == Q931ie_SHIFT) {
72 shift_nolock = (IBuf[IOff] & 0x08);
73 if (shift_nolock) {
74 last_codeset = codeset;
75 }
76 codeset = ((IBuf[IOff] & 0x07));
77 IOff++;
78 }
79
80 if (codeset == 0) {
81 switch (IBuf[IOff])
82 {
83 case Q931ie_SENDING_COMPLETE:
84 case Q931ie_BEARER_CAPABILITY:
85 case Q931ie_CHANNEL_IDENTIFICATION:
86 case Q931ie_PROGRESS_INDICATOR:
87 case Q931ie_NETWORK_SPECIFIC_FACILITIES:
88 case Q931ie_DISPLAY:
89 case Q931ie_DATETIME:
90 case Q931ie_KEYPAD_FACILITY:
91 case Q931ie_SIGNAL:
92 case Q931ie_CALLING_PARTY_NUMBER:
93 case Q931ie_CALLING_PARTY_SUBADDRESS:
94 case Q931ie_CALLED_PARTY_NUMBER:
95 case Q931ie_CALLED_PARTY_SUBADDRESS:
96 case Q931ie_TRANSIT_NETWORK_SELECTION:
97 case Q931ie_LOW_LAYER_COMPATIBILITY:
98 case Q931ie_HIGH_LAYER_COMPATIBILITY:
99 case Q931ie_FACILITY:
100 rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
101 if (rc != Q931E_NO_ERROR)
102 return rc;
103 break;
104 case Q931ie_REPEAT_INDICATOR:
105 if (ir < 2) {
106 rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
107 ir++;
108 } else {
109 return Q931E_ILLEGAL_IE;
110 }
111 break;
112 default:
113 return Q931E_ILLEGAL_IE;
114 break;
115 }
116 } else if (codeset == 6) {
117 switch (IBuf[IOff])
118 {
119 case Q931ie_GENERIC_DIGITS:
120 rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
121 if (rc != Q931E_NO_ERROR)
122 return rc;
123 break;
124 default:
125 return Q931E_ILLEGAL_IE;
126 break;
127 }
128 } else if (codeset == 7) {
129 switch (IBuf[IOff])
130 {
131 case Q931ie_DISPLAY:
132 rc = Q931Uie[pTrunk->Dialect][IBuf[IOff]](pTrunk, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
133 if (rc != Q931E_NO_ERROR)
134 return rc;
135 break;
136 default:
137 return Q931E_ILLEGAL_IE;
138 break;
139 }
140 } else {
141 return Q931E_ILLEGAL_IE;
142 }
143 }
144 mes->Size = sizeof(Q931mes_Generic) - 1 + OOff;
145 return Q931E_NO_ERROR;
146 }
147
148 /*****************************************************************************
149
150 Function: ATT5ESSPmes_Setup
151
152 Decription: Pack a Q931mes_Generic into a real Q.931 message. The user will
153 set up a SETUP message and issue this to the stack where it
154 is processed by Q931ProcSetup that processes and validates
155 it before it actually sends it out. This function is called
156 to compute the real Q.931 message.
157
158 Parameters: IBuf[IN] Ptr to un-packed struct
159 ISize[IN] Size of input buffer (unpacked message).
160 OBuf[OUT] Ptr to packed 'octet' wise message.
161 OSize[OUT] Size of packed message.
162
163 Called By: Q931ProcSetup
164
165 *****************************************************************************/
ATT5ESSPmes_Setup(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * IBuf,L3INT ISize,L3UCHAR * OBuf,L3INT * OSize)166 L3INT ATT5ESSPmes_Setup(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
167 {
168 L3INT rc = Q931E_NO_ERROR;
169 Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf;
170 L3INT Octet = 0;
171
172 /* Q931 Message Header */
173 Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet);
174
175 /* Sending Complete */
176 if (Q931IsIEPresent(pMes->SendComplete)) {
177 OBuf[Octet++] = (L3UCHAR)(pMes->SendComplete & 0x00ff);
178 }
179
180 /* Repeat Indicator */
181 if (Q931IsIEPresent(pMes->RepeatInd)) {
182 OBuf[Octet++] = (L3UCHAR)(pMes->RepeatInd & 0x00ff);
183 }
184
185 /* Bearer capability */
186 if (Q931IsIEPresent(pMes->BearerCap)) {
187 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_BEARER_CAPABILITY](pTrunk, Q931GetIEPtr(pMes->BearerCap,pMes->buf), OBuf, &Octet))!=0)
188 return rc;
189 } else {
190 rc = Q931E_BEARERCAP;
191 }
192
193 /* Channel Identification */
194 if (Q931IsIEPresent(pMes->ChanID)) {
195 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CHANNEL_IDENTIFICATION](pTrunk, Q931GetIEPtr(pMes->ChanID,pMes->buf), OBuf, &Octet))!=0)
196 return rc;
197 }
198
199 /* Progress indicator */
200 if (Q931IsIEPresent(pMes->ProgInd)) {
201 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_PROGRESS_INDICATOR](pTrunk, Q931GetIEPtr(pMes->ProgInd,pMes->buf), OBuf, &Octet))!=0)
202 return rc;
203 }
204
205 /* Network specific facilities */
206 if (Q931IsIEPresent(pMes->NetFac)) {
207 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_NETWORK_SPECIFIC_FACILITIES](pTrunk, Q931GetIEPtr(pMes->NetFac,pMes->buf), OBuf, &Octet))!=0)
208 return rc;
209 }
210
211 /* Display */
212 if (Q931IsIEPresent(pMes->Display)) {
213 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DISPLAY](pTrunk, Q931GetIEPtr(pMes->Display,pMes->buf), OBuf, &Octet))!=0)
214 return rc;
215 }
216
217 /* Date/Time */
218 if (Q931IsIEPresent(pMes->DateTime)) {
219 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_DATETIME](pTrunk, Q931GetIEPtr(pMes->DateTime,pMes->buf), OBuf, &Octet))!=0)
220 return rc;
221 }
222
223 /* Keypad Facility */
224 if (Q931IsIEPresent(pMes->KeypadFac)) {
225 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_KEYPAD_FACILITY](pTrunk, Q931GetIEPtr(pMes->KeypadFac,pMes->buf), OBuf, &Octet))!=0)
226 return rc;
227 }
228
229 /* Signal */
230 if (Q931IsIEPresent(pMes->Signal)) {
231 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_SIGNAL](pTrunk, Q931GetIEPtr(pMes->Signal,pMes->buf), OBuf, &Octet))!=0)
232 return rc;
233 }
234
235 /* Calling Party Number */
236 if (Q931IsIEPresent(pMes->CallingNum)) {
237 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CallingNum,pMes->buf), OBuf, &Octet))!=0)
238 return rc;
239 }
240
241 /* Calling Party Subaddress */
242 if (Q931IsIEPresent(pMes->CallingSub)) {
243 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLING_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CallingSub,pMes->buf), OBuf, &Octet))!=0)
244 return rc;
245 }
246
247 /* Called Party number */
248 if (Q931IsIEPresent(pMes->CalledNum)) {
249 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_NUMBER](pTrunk, Q931GetIEPtr(pMes->CalledNum,pMes->buf), OBuf, &Octet))!=0)
250 return rc;
251 }
252
253 /* Called party subaddress */
254 if (Q931IsIEPresent(pMes->CalledSub)) {
255 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_CALLED_PARTY_SUBADDRESS](pTrunk, Q931GetIEPtr(pMes->CalledSub,pMes->buf), OBuf, &Octet))!=0)
256 return rc;
257 }
258
259 /* Transit network selection */
260 if (Q931IsIEPresent(pMes->TransNetSel)) {
261 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_TRANSIT_NETWORK_SELECTION](pTrunk, Q931GetIEPtr(pMes->TransNetSel,pMes->buf), OBuf, &Octet))!=0)
262 return rc;
263 }
264
265 /* Repeat Indicator */
266 if (Q931IsIEPresent(pMes->LLRepeatInd)) {
267 rc = Q931E_UNKNOWN_IE;/* TODO */
268 }
269
270 /* Low Layer Compatibility */
271 if (Q931IsIEPresent(pMes->LLComp)) {
272 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_LOW_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->LLComp,pMes->buf), OBuf, &Octet))!=0)
273 return rc;
274 }
275
276 /* High Layer Compatibility */
277 if (Q931IsIEPresent(pMes->HLComp)) {
278 if ((rc = Q931Pie[pTrunk->Dialect][Q931ie_HIGH_LAYER_COMPATIBILITY](pTrunk, Q931GetIEPtr(pMes->HLComp,pMes->buf), OBuf, &Octet))!=0)
279 return rc;
280 }
281
282 *OSize = Octet;
283 return rc;
284 }
285
286
287 /*****************************************************************************
288
289 Function: ATT5ESSUmes_0x0f
290
291 *****************************************************************************/
ATT5ESSUmes_0x0f(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,Q931mes_Generic * mes,L3INT IOff,L3INT Size)292 L3INT ATT5ESSUmes_0x0f(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size)
293 {
294 if (mes->ProtDisc == 8) {
295 return Q931Umes_ConnectAck(pTrunk, IBuf, mes, IOff, Size);
296 }
297
298 if (mes->ProtDisc == 3) {
299 return Q931Umes_Service(pTrunk, IBuf, mes, IOff, Size);
300 }
301
302 return Q931E_UNKNOWN_MESSAGE;
303 }
304
305 /*****************************************************************************
306
307 Function: ATT5ESSPmes_0x0f
308
309 *****************************************************************************/
ATT5ESSPmes_0x0f(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * IBuf,L3INT ISize,L3UCHAR * OBuf,L3INT * OSize)310 L3INT ATT5ESSPmes_0x0f(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
311 {
312 Q931mes_Generic *mes = (Q931mes_Generic *)IBuf;
313
314 if (mes->ProtDisc == 8) {
315 return Q931Pmes_ConnectAck(pTrunk, IBuf, ISize, OBuf, OSize);
316 }
317
318 if (mes->ProtDisc == 3) {
319 return Q931Pmes_Service(pTrunk, IBuf, ISize, OBuf, OSize);
320 }
321
322 return Q931E_UNKNOWN_MESSAGE;
323 }
324
325 /*****************************************************************************
326
327 Function: ATT5ESSUmes_0x07
328
329 *****************************************************************************/
ATT5ESSUmes_0x07(Q931_TrunkInfo_t * pTrunk,L3UCHAR * IBuf,Q931mes_Generic * mes,L3INT IOff,L3INT Size)330 L3INT ATT5ESSUmes_0x07(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size)
331 {
332 if (mes->ProtDisc == 8) {
333 return Q931Umes_Connect(pTrunk, IBuf, mes, IOff, Size);
334 }
335
336 if (mes->ProtDisc == 3) {
337 return Q931Umes_ServiceAck(pTrunk, IBuf, mes, IOff, Size);
338 }
339
340 return Q931E_UNKNOWN_MESSAGE;
341 }
342
343 /*****************************************************************************
344
345 Function: ATT5ESSPmes_0x07
346
347 *****************************************************************************/
ATT5ESSPmes_0x07(Q931_TrunkInfo_t * pTrunk,Q931mes_Generic * IBuf,L3INT ISize,L3UCHAR * OBuf,L3INT * OSize)348 L3INT ATT5ESSPmes_0x07(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
349 {
350 Q931mes_Generic *mes = (Q931mes_Generic *)IBuf;
351
352 if (mes->ProtDisc == 8) {
353 return Q931Pmes_Connect(pTrunk, IBuf, ISize, OBuf, OSize);
354 }
355
356 if (mes->ProtDisc == 3) {
357 return Q931Pmes_ServiceAck(pTrunk, IBuf, ISize, OBuf, OSize);
358 }
359
360 return Q931E_UNKNOWN_MESSAGE;
361 }
362