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