* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / isdn / avmb1 / capiutil.c
blob7f1a9f1adfa50fcfeede6fe8a8ce95176c9675fd
1 /*
2 * $Id: capiutil.c,v 1.9 1999/07/09 15:05:46 keil Exp $
4 * CAPI 2.0 convert capi message to capi message struct
6 * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
7 * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de)
9 * $Log: capiutil.c,v $
10 * Revision 1.9 1999/07/09 15:05:46 keil
11 * compat.h is now isdn_compat.h
13 * Revision 1.8 1999/07/01 15:26:37 calle
14 * complete new version (I love it):
15 * + new hardware independed "capi_driver" interface that will make it easy to:
16 * - support other controllers with CAPI-2.0 (i.e. USB Controller)
17 * - write a CAPI-2.0 for the passive cards
18 * - support serial link CAPI-2.0 boxes.
19 * + wrote "capi_driver" for all supported cards.
20 * + "capi_driver" (supported cards) now have to be configured with
21 * make menuconfig, in the past all supported cards where included
22 * at once.
23 * + new and better informations in /proc/capi/
24 * + new ioctl to switch trace of capi messages per controller
25 * using "avmcapictrl trace [contr] on|off|...."
26 * + complete testcircle with all supported cards and also the
27 * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
29 * Revision 1.7 1999/07/01 08:23:01 keil
30 * compatibility macros now in <linux/isdn_compat.h>
32 * Revision 1.6 1997/11/04 06:12:12 calle
33 * capi.c: new read/write in file_ops since 2.1.60
34 * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware.
35 * capiutil.c: needs config.h (CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON)
36 * compat.h: added #define LinuxVersionCode
38 * Revision 1.5 1997/10/01 09:21:19 fritz
39 * Removed old compatibility stuff for 2.0.X kernels.
40 * From now on, this code is for 2.1.X ONLY!
41 * Old stuff is still in the separate branch.
43 * Revision 1.4 1997/08/10 07:43:55 calle
44 * forgot to export symbol capi_info2str for 2.1.x
46 * Revision 1.3 1997/05/18 09:24:18 calle
47 * added verbose disconnect reason reporting to avmb1.
48 * some fixes in capi20 interface.
49 * changed info messages for B1-PCI
51 * Revision 1.2 1997/03/05 21:22:13 fritz
52 * Fix: Symbols have to be exported unconditionally.
54 * Revision 1.1 1997/03/04 21:50:34 calle
55 * Frirst version in isdn4linux
57 * Revision 2.2 1997/02/12 09:31:39 calle
58 * new version
60 * Revision 1.1 1997/01/31 10:32:20 calle
61 * Initial revision
64 #include <linux/module.h>
65 #include <linux/string.h>
66 #include <linux/ctype.h>
67 #include <linux/stddef.h>
68 #include <linux/kernel.h>
69 #include <linux/mm.h>
70 #include <asm/segment.h>
71 #include <linux/config.h>
73 #include <linux/isdn_compat.h>
74 #include "capiutil.h"
76 /* from CAPI2.0 DDK AVM Berlin GmbH */
78 #ifndef CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
79 char *capi_info2str(__u16 reason)
81 return "..";
83 #else
84 char *capi_info2str(__u16 reason)
86 switch (reason) {
88 /*-- informative values (corresponding message was processed) -----*/
89 case 0x0001:
90 return "NCPI not supported by current protocol, NCPI ignored";
91 case 0x0002:
92 return "Flags not supported by current protocol, flags ignored";
93 case 0x0003:
94 return "Alert already sent by another application";
96 /*-- error information concerning CAPI_REGISTER -----*/
97 case 0x1001:
98 return "Too many applications";
99 case 0x1002:
100 return "Logical block size to small, must be at least 128 Bytes";
101 case 0x1003:
102 return "Buffer exceeds 64 kByte";
103 case 0x1004:
104 return "Message buffer size too small, must be at least 1024 Bytes";
105 case 0x1005:
106 return "Max. number of logical connections not supported";
107 case 0x1006:
108 return "Reserved";
109 case 0x1007:
110 return "The message could not be accepted because of an internal busy condition";
111 case 0x1008:
112 return "OS resource error (no memory ?)";
113 case 0x1009:
114 return "CAPI not installed";
115 case 0x100A:
116 return "Controller does not support external equipment";
117 case 0x100B:
118 return "Controller does only support external equipment";
120 /*-- error information concerning message exchange functions -----*/
121 case 0x1101:
122 return "Illegal application number";
123 case 0x1102:
124 return "Illegal command or subcommand or message length less than 12 bytes";
125 case 0x1103:
126 return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI";
127 case 0x1104:
128 return "Queue is empty";
129 case 0x1105:
130 return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
131 case 0x1106:
132 return "Unknown notification parameter";
133 case 0x1107:
134 return "The Message could not be accepted because of an internal busy condition";
135 case 0x1108:
136 return "OS Resource error (no memory ?)";
137 case 0x1109:
138 return "CAPI not installed";
139 case 0x110A:
140 return "Controller does not support external equipment";
141 case 0x110B:
142 return "Controller does only support external equipment";
144 /*-- error information concerning resource / coding problems -----*/
145 case 0x2001:
146 return "Message not supported in current state";
147 case 0x2002:
148 return "Illegal Controller / PLCI / NCCI";
149 case 0x2003:
150 return "Out of PLCI";
151 case 0x2004:
152 return "Out of NCCI";
153 case 0x2005:
154 return "Out of LISTEN";
155 case 0x2006:
156 return "Out of FAX resources (protocol T.30)";
157 case 0x2007:
158 return "Illegal message parameter coding";
160 /*-- error information concerning requested services -----*/
161 case 0x3001:
162 return "B1 protocol not supported";
163 case 0x3002:
164 return "B2 protocol not supported";
165 case 0x3003:
166 return "B3 protocol not supported";
167 case 0x3004:
168 return "B1 protocol parameter not supported";
169 case 0x3005:
170 return "B2 protocol parameter not supported";
171 case 0x3006:
172 return "B3 protocol parameter not supported";
173 case 0x3007:
174 return "B protocol combination not supported";
175 case 0x3008:
176 return "NCPI not supported";
177 case 0x3009:
178 return "CIP Value unknown";
179 case 0x300A:
180 return "Flags not supported (reserved bits)";
181 case 0x300B:
182 return "Facility not supported";
183 case 0x300C:
184 return "Data length not supported by current protocol";
185 case 0x300D:
186 return "Reset procedure not supported by current protocol";
188 /*-- informations about the clearing of a physical connection -----*/
189 case 0x3301:
190 return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
191 case 0x3302:
192 return "Protocol error layer 2";
193 case 0x3303:
194 return "Protocol error layer 3";
195 case 0x3304:
196 return "Another application got that call";
197 /*-- T.30 specific reasons -----*/
198 case 0x3311:
199 return "Connecting not successful (remote station is no FAX G3 machine)";
200 case 0x3312:
201 return "Connecting not successful (training error)";
202 case 0x3313:
203 return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
204 case 0x3314:
205 return "Disconnected during transfer (remote abort)";
206 case 0x3315:
207 return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
208 case 0x3316:
209 return "Disconnected during transfer (local tx data underrun)";
210 case 0x3317:
211 return "Disconnected during transfer (local rx data overflow)";
212 case 0x3318:
213 return "Disconnected during transfer (local abort)";
214 case 0x3319:
215 return "Illegal parameter coding (e.g. SFF coding error)";
217 /*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/
218 case 0x3481: return "Unallocated (unassigned) number";
219 case 0x3482: return "No route to specified transit network";
220 case 0x3483: return "No route to destination";
221 case 0x3486: return "Channel unacceptable";
222 case 0x3487:
223 return "Call awarded and being delivered in an established channel";
224 case 0x3490: return "Normal call clearing";
225 case 0x3491: return "User busy";
226 case 0x3492: return "No user responding";
227 case 0x3493: return "No answer from user (user alerted)";
228 case 0x3495: return "Call rejected";
229 case 0x3496: return "Number changed";
230 case 0x349A: return "Non-selected user clearing";
231 case 0x349B: return "Destination out of order";
232 case 0x349C: return "Invalid number format";
233 case 0x349D: return "Facility rejected";
234 case 0x349E: return "Response to STATUS ENQUIRY";
235 case 0x349F: return "Normal, unspecified";
236 case 0x34A2: return "No circuit / channel available";
237 case 0x34A6: return "Network out of order";
238 case 0x34A9: return "Temporary failure";
239 case 0x34AA: return "Switching equipment congestion";
240 case 0x34AB: return "Access information discarded";
241 case 0x34AC: return "Requested circuit / channel not available";
242 case 0x34AF: return "Resources unavailable, unspecified";
243 case 0x34B1: return "Quality of service unavailable";
244 case 0x34B2: return "Requested facility not subscribed";
245 case 0x34B9: return "Bearer capability not authorized";
246 case 0x34BA: return "Bearer capability not presently available";
247 case 0x34BF: return "Service or option not available, unspecified";
248 case 0x34C1: return "Bearer capability not implemented";
249 case 0x34C2: return "Channel type not implemented";
250 case 0x34C5: return "Requested facility not implemented";
251 case 0x34C6: return "Only restricted digital information bearer capability is available";
252 case 0x34CF: return "Service or option not implemented, unspecified";
253 case 0x34D1: return "Invalid call reference value";
254 case 0x34D2: return "Identified channel does not exist";
255 case 0x34D3: return "A suspended call exists, but this call identity does not";
256 case 0x34D4: return "Call identity in use";
257 case 0x34D5: return "No call suspended";
258 case 0x34D6: return "Call having the requested call identity has been cleared";
259 case 0x34D8: return "Incompatible destination";
260 case 0x34DB: return "Invalid transit network selection";
261 case 0x34DF: return "Invalid message, unspecified";
262 case 0x34E0: return "Mandatory information element is missing";
263 case 0x34E1: return "Message type non-existent or not implemented";
264 case 0x34E2: return "Message not compatible with call state or message type non-existent or not implemented";
265 case 0x34E3: return "Information element non-existent or not implemented";
266 case 0x34E4: return "Invalid information element contents";
267 case 0x34E5: return "Message not compatible with call state";
268 case 0x34E6: return "Recovery on timer expiry";
269 case 0x34EF: return "Protocol error, unspecified";
270 case 0x34FF: return "Interworking, unspecified";
272 default: return "No additional information";
275 #endif
277 typedef struct {
278 int typ;
279 size_t off;
280 } _cdef;
282 #define _CBYTE 1
283 #define _CWORD 2
284 #define _CDWORD 3
285 #define _CSTRUCT 4
286 #define _CMSTRUCT 5
287 #define _CEND 6
289 static _cdef cdef[] =
291 /*00 */
292 {_CEND},
293 /*01 */
294 {_CEND},
295 /*02 */
296 {_CEND},
297 /*03 */
298 {_CDWORD, offsetof(_cmsg, adr.adrController)},
299 /*04 */
300 {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
301 /*05 */
302 {_CSTRUCT, offsetof(_cmsg, B1configuration)},
303 /*06 */
304 {_CWORD, offsetof(_cmsg, B1protocol)},
305 /*07 */
306 {_CSTRUCT, offsetof(_cmsg, B2configuration)},
307 /*08 */
308 {_CWORD, offsetof(_cmsg, B2protocol)},
309 /*09 */
310 {_CSTRUCT, offsetof(_cmsg, B3configuration)},
311 /*0a */
312 {_CWORD, offsetof(_cmsg, B3protocol)},
313 /*0b */
314 {_CSTRUCT, offsetof(_cmsg, BC)},
315 /*0c */
316 {_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
317 /*0d */
318 {_CMSTRUCT, offsetof(_cmsg, BProtocol)},
319 /*0e */
320 {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
321 /*0f */
322 {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
323 /*10 */
324 {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
325 /*11 */
326 {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
327 /*12 */
328 {_CDWORD, offsetof(_cmsg, CIPmask)},
329 /*13 */
330 {_CDWORD, offsetof(_cmsg, CIPmask2)},
331 /*14 */
332 {_CWORD, offsetof(_cmsg, CIPValue)},
333 /*15 */
334 {_CDWORD, offsetof(_cmsg, Class)},
335 /*16 */
336 {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
337 /*17 */
338 {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
339 /*18 */
340 {_CDWORD, offsetof(_cmsg, Data)},
341 /*19 */
342 {_CWORD, offsetof(_cmsg, DataHandle)},
343 /*1a */
344 {_CWORD, offsetof(_cmsg, DataLength)},
345 /*1b */
346 {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
347 /*1c */
348 {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
349 /*1d */
350 {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
351 /*1e */
352 {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
353 /*1f */
354 {_CWORD, offsetof(_cmsg, FacilitySelector)},
355 /*20 */
356 {_CWORD, offsetof(_cmsg, Flags)},
357 /*21 */
358 {_CDWORD, offsetof(_cmsg, Function)},
359 /*22 */
360 {_CSTRUCT, offsetof(_cmsg, HLC)},
361 /*23 */
362 {_CWORD, offsetof(_cmsg, Info)},
363 /*24 */
364 {_CSTRUCT, offsetof(_cmsg, InfoElement)},
365 /*25 */
366 {_CDWORD, offsetof(_cmsg, InfoMask)},
367 /*26 */
368 {_CWORD, offsetof(_cmsg, InfoNumber)},
369 /*27 */
370 {_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
371 /*28 */
372 {_CSTRUCT, offsetof(_cmsg, LLC)},
373 /*29 */
374 {_CSTRUCT, offsetof(_cmsg, ManuData)},
375 /*2a */
376 {_CDWORD, offsetof(_cmsg, ManuID)},
377 /*2b */
378 {_CSTRUCT, offsetof(_cmsg, NCPI)},
379 /*2c */
380 {_CWORD, offsetof(_cmsg, Reason)},
381 /*2d */
382 {_CWORD, offsetof(_cmsg, Reason_B3)},
383 /*2e */
384 {_CWORD, offsetof(_cmsg, Reject)},
385 /*2f */
386 {_CSTRUCT, offsetof(_cmsg, Useruserdata)}
389 static unsigned char *cpars[] =
391 /*00 */ 0,
392 /*01 ALERT_REQ */ (unsigned char *) "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
393 /*02 CONNECT_REQ */ (unsigned char *) "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
394 /*03 */ 0,
395 /*04 DISCONNECT_REQ */ (unsigned char *) "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
396 /*05 LISTEN_REQ */ (unsigned char *) "\x03\x25\x12\x13\x10\x11\x01",
397 /*06 */ 0,
398 /*07 */ 0,
399 /*08 INFO_REQ */ (unsigned char *) "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
400 /*09 FACILITY_REQ */ (unsigned char *) "\x03\x1f\x1e\x01",
401 /*0a SELECT_B_PROTOCOL_REQ */ (unsigned char *) "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
402 /*0b CONNECT_B3_REQ */ (unsigned char *) "\x03\x2b\x01",
403 /*0c */ 0,
404 /*0d DISCONNECT_B3_REQ */ (unsigned char *) "\x03\x2b\x01",
405 /*0e */ 0,
406 /*0f DATA_B3_REQ */ (unsigned char *) "\x03\x18\x1a\x19\x20\x01",
407 /*10 RESET_B3_REQ */ (unsigned char *) "\x03\x2b\x01",
408 /*11 */ 0,
409 /*12 */ 0,
410 /*13 ALERT_CONF */ (unsigned char *) "\x03\x23\x01",
411 /*14 CONNECT_CONF */ (unsigned char *) "\x03\x23\x01",
412 /*15 */ 0,
413 /*16 DISCONNECT_CONF */ (unsigned char *) "\x03\x23\x01",
414 /*17 LISTEN_CONF */ (unsigned char *) "\x03\x23\x01",
415 /*18 MANUFACTURER_REQ */ (unsigned char *) "\x03\x2a\x15\x21\x29\x01",
416 /*19 */ 0,
417 /*1a INFO_CONF */ (unsigned char *) "\x03\x23\x01",
418 /*1b FACILITY_CONF */ (unsigned char *) "\x03\x23\x1f\x1b\x01",
419 /*1c SELECT_B_PROTOCOL_CONF */ (unsigned char *) "\x03\x23\x01",
420 /*1d CONNECT_B3_CONF */ (unsigned char *) "\x03\x23\x01",
421 /*1e */ 0,
422 /*1f DISCONNECT_B3_CONF */ (unsigned char *) "\x03\x23\x01",
423 /*20 */ 0,
424 /*21 DATA_B3_CONF */ (unsigned char *) "\x03\x19\x23\x01",
425 /*22 RESET_B3_CONF */ (unsigned char *) "\x03\x23\x01",
426 /*23 */ 0,
427 /*24 */ 0,
428 /*25 */ 0,
429 /*26 CONNECT_IND */ (unsigned char *) "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
430 /*27 CONNECT_ACTIVE_IND */ (unsigned char *) "\x03\x16\x17\x28\x01",
431 /*28 DISCONNECT_IND */ (unsigned char *) "\x03\x2c\x01",
432 /*29 */ 0,
433 /*2a MANUFACTURER_CONF */ (unsigned char *) "\x03\x2a\x15\x21\x29\x01",
434 /*2b */ 0,
435 /*2c INFO_IND */ (unsigned char *) "\x03\x26\x24\x01",
436 /*2d FACILITY_IND */ (unsigned char *) "\x03\x1f\x1d\x01",
437 /*2e */ 0,
438 /*2f CONNECT_B3_IND */ (unsigned char *) "\x03\x2b\x01",
439 /*30 CONNECT_B3_ACTIVE_IND */ (unsigned char *) "\x03\x2b\x01",
440 /*31 DISCONNECT_B3_IND */ (unsigned char *) "\x03\x2d\x2b\x01",
441 /*32 */ 0,
442 /*33 DATA_B3_IND */ (unsigned char *) "\x03\x18\x1a\x19\x20\x01",
443 /*34 RESET_B3_IND */ (unsigned char *) "\x03\x2b\x01",
444 /*35 CONNECT_B3_T90_ACTIVE_IND */ (unsigned char *) "\x03\x2b\x01",
445 /*36 */ 0,
446 /*37 */ 0,
447 /*38 CONNECT_RESP */ (unsigned char *) "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
448 /*39 CONNECT_ACTIVE_RESP */ (unsigned char *) "\x03\x01",
449 /*3a DISCONNECT_RESP */ (unsigned char *) "\x03\x01",
450 /*3b */ 0,
451 /*3c MANUFACTURER_IND */ (unsigned char *) "\x03\x2a\x15\x21\x29\x01",
452 /*3d */ 0,
453 /*3e INFO_RESP */ (unsigned char *) "\x03\x01",
454 /*3f FACILITY_RESP */ (unsigned char *) "\x03\x1f\x01",
455 /*40 */ 0,
456 /*41 CONNECT_B3_RESP */ (unsigned char *) "\x03\x2e\x2b\x01",
457 /*42 CONNECT_B3_ACTIVE_RESP */ (unsigned char *) "\x03\x01",
458 /*43 DISCONNECT_B3_RESP */ (unsigned char *) "\x03\x01",
459 /*44 */ 0,
460 /*45 DATA_B3_RESP */ (unsigned char *) "\x03\x19\x01",
461 /*46 RESET_B3_RESP */ (unsigned char *) "\x03\x01",
462 /*47 CONNECT_B3_T90_ACTIVE_RESP */ (unsigned char *) "\x03\x01",
463 /*48 */ 0,
464 /*49 */ 0,
465 /*4a */ 0,
466 /*4b */ 0,
467 /*4c */ 0,
468 /*4d */ 0,
469 /*4e MANUFACTURER_RESP */ (unsigned char *) "\x03\x2a\x15\x21\x29\x01",
472 /*-------------------------------------------------------*/
474 #define byteTLcpy(x,y) *(__u8 *)(x)=*(__u8 *)(y);
475 #define wordTLcpy(x,y) *(__u16 *)(x)=*(__u16 *)(y);
476 #define dwordTLcpy(x,y) memcpy(x,y,4);
477 #define structTLcpy(x,y,l) memcpy (x,y,l)
478 #define structTLcpyovl(x,y,l) memmove (x,y,l)
480 #define byteTRcpy(x,y) *(__u8 *)(y)=*(__u8 *)(x);
481 #define wordTRcpy(x,y) *(__u16 *)(y)=*(__u16 *)(x);
482 #define dwordTRcpy(x,y) memcpy(y,x,4);
483 #define structTRcpy(x,y,l) memcpy (y,x,l)
484 #define structTRcpyovl(x,y,l) memmove (y,x,l)
486 /*-------------------------------------------------------*/
487 static unsigned command_2_index(unsigned c, unsigned sc)
489 if (c & 0x80)
490 c = 0x9 + (c & 0x0f);
491 else if (c <= 0x0f);
492 else if (c == 0x41)
493 c = 0x9 + 0x1;
494 else if (c == 0xff)
495 c = 0x00;
496 return (sc & 3) * (0x9 + 0x9) + c;
499 /*-------------------------------------------------------*/
500 #define TYP (cdef[cmsg->par[cmsg->p]].typ)
501 #define OFF (((__u8 *)cmsg)+cdef[cmsg->par[cmsg->p]].off)
503 static void jumpcstruct(_cmsg * cmsg)
505 unsigned layer;
506 for (cmsg->p++, layer = 1; layer;) {
507 /* $$$$$ assert (cmsg->p); */
508 cmsg->p++;
509 switch (TYP) {
510 case _CMSTRUCT:
511 layer++;
512 break;
513 case _CEND:
514 layer--;
515 break;
519 /*-------------------------------------------------------*/
520 static void pars_2_message(_cmsg * cmsg)
523 for (; TYP != _CEND; cmsg->p++) {
524 switch (TYP) {
525 case _CBYTE:
526 byteTLcpy(cmsg->m + cmsg->l, OFF);
527 cmsg->l++;
528 break;
529 case _CWORD:
530 wordTLcpy(cmsg->m + cmsg->l, OFF);
531 cmsg->l += 2;
532 break;
533 case _CDWORD:
534 dwordTLcpy(cmsg->m + cmsg->l, OFF);
535 cmsg->l += 4;
536 break;
537 case _CSTRUCT:
538 if (*(__u8 **) OFF == 0) {
539 *(cmsg->m + cmsg->l) = '\0';
540 cmsg->l++;
541 } else if (**(_cstruct *) OFF != 0xff) {
542 structTLcpy(cmsg->m + cmsg->l, *(_cstruct *) OFF, 1 + **(_cstruct *) OFF);
543 cmsg->l += 1 + **(_cstruct *) OFF;
544 } else {
545 _cstruct s = *(_cstruct *) OFF;
546 structTLcpy(cmsg->m + cmsg->l, s, 3 + *(__u16 *) (s + 1));
547 cmsg->l += 3 + *(__u16 *) (s + 1);
549 break;
550 case _CMSTRUCT:
551 /*----- Metastruktur 0 -----*/
552 if (*(_cmstruct *) OFF == CAPI_DEFAULT) {
553 *(cmsg->m + cmsg->l) = '\0';
554 cmsg->l++;
555 jumpcstruct(cmsg);
557 /*----- Metastruktur wird composed -----*/
558 else {
559 unsigned _l = cmsg->l;
560 unsigned _ls;
561 cmsg->l++;
562 cmsg->p++;
563 pars_2_message(cmsg);
564 _ls = cmsg->l - _l - 1;
565 if (_ls < 255)
566 (cmsg->m + _l)[0] = (__u8) _ls;
567 else {
568 structTLcpyovl(cmsg->m + _l + 3, cmsg->m + _l + 1, _ls);
569 (cmsg->m + _l)[0] = 0xff;
570 wordTLcpy(cmsg->m + _l + 1, &_ls);
573 break;
578 /*-------------------------------------------------------*/
579 unsigned capi_cmsg2message(_cmsg * cmsg, __u8 * msg)
581 cmsg->m = msg;
582 cmsg->l = 8;
583 cmsg->p = 0;
584 cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
586 pars_2_message(cmsg);
588 wordTLcpy(msg + 0, &cmsg->l);
589 byteTLcpy(cmsg->m + 4, &cmsg->Command);
590 byteTLcpy(cmsg->m + 5, &cmsg->Subcommand);
591 wordTLcpy(cmsg->m + 2, &cmsg->ApplId);
592 wordTLcpy(cmsg->m + 6, &cmsg->Messagenumber);
594 return 0;
597 /*-------------------------------------------------------*/
598 static void message_2_pars(_cmsg * cmsg)
600 for (; TYP != _CEND; cmsg->p++) {
602 switch (TYP) {
603 case _CBYTE:
604 byteTRcpy(cmsg->m + cmsg->l, OFF);
605 cmsg->l++;
606 break;
607 case _CWORD:
608 wordTRcpy(cmsg->m + cmsg->l, OFF);
609 cmsg->l += 2;
610 break;
611 case _CDWORD:
612 dwordTRcpy(cmsg->m + cmsg->l, OFF);
613 cmsg->l += 4;
614 break;
615 case _CSTRUCT:
616 *(__u8 **) OFF = cmsg->m + cmsg->l;
618 if (cmsg->m[cmsg->l] != 0xff)
619 cmsg->l += 1 + cmsg->m[cmsg->l];
620 else
621 cmsg->l += 3 + *(__u16 *) (cmsg->m + cmsg->l + 1);
622 break;
623 case _CMSTRUCT:
624 /*----- Metastruktur 0 -----*/
625 if (cmsg->m[cmsg->l] == '\0') {
626 *(_cmstruct *) OFF = CAPI_DEFAULT;
627 cmsg->l++;
628 jumpcstruct(cmsg);
629 } else {
630 unsigned _l = cmsg->l;
631 *(_cmstruct *) OFF = CAPI_COMPOSE;
632 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
633 cmsg->p++;
634 message_2_pars(cmsg);
636 break;
641 /*-------------------------------------------------------*/
642 unsigned capi_message2cmsg(_cmsg * cmsg, __u8 * msg)
644 memset(cmsg, 0, sizeof(_cmsg));
645 cmsg->m = msg;
646 cmsg->l = 8;
647 cmsg->p = 0;
648 byteTRcpy(cmsg->m + 4, &cmsg->Command);
649 byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
650 cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
652 message_2_pars(cmsg);
654 wordTRcpy(msg + 0, &cmsg->l);
655 wordTRcpy(cmsg->m + 2, &cmsg->ApplId);
656 wordTRcpy(cmsg->m + 6, &cmsg->Messagenumber);
658 return 0;
661 /*-------------------------------------------------------*/
662 unsigned capi_cmsg_header(_cmsg * cmsg, __u16 _ApplId,
663 __u8 _Command, __u8 _Subcommand,
664 __u16 _Messagenumber, __u32 _Controller)
666 memset(cmsg, 0, sizeof(_cmsg));
667 cmsg->ApplId = _ApplId;
668 cmsg->Command = _Command;
669 cmsg->Subcommand = _Subcommand;
670 cmsg->Messagenumber = _Messagenumber;
671 cmsg->adr.adrController = _Controller;
672 return 0;
675 /*-------------------------------------------------------*/
677 static char *mnames[] =
680 "ALERT_REQ",
681 "CONNECT_REQ",
683 "DISCONNECT_REQ",
684 "LISTEN_REQ",
687 "INFO_REQ",
688 "FACILITY_REQ",
689 "SELECT_B_PROTOCOL_REQ",
690 "CONNECT_B3_REQ",
692 "DISCONNECT_B3_REQ",
694 "DATA_B3_REQ",
695 "RESET_B3_REQ",
698 "ALERT_CONF",
699 "CONNECT_CONF",
701 "DISCONNECT_CONF",
702 "LISTEN_CONF",
703 "MANUFACTURER_REQ",
705 "INFO_CONF",
706 "FACILITY_CONF",
707 "SELECT_B_PROTOCOL_CONF",
708 "CONNECT_B3_CONF",
710 "DISCONNECT_B3_CONF",
712 "DATA_B3_CONF",
713 "RESET_B3_CONF",
717 "CONNECT_IND",
718 "CONNECT_ACTIVE_IND",
719 "DISCONNECT_IND",
721 "MANUFACTURER_CONF",
723 "INFO_IND",
724 "FACILITY_IND",
726 "CONNECT_B3_IND",
727 "CONNECT_B3_ACTIVE_IND",
728 "DISCONNECT_B3_IND",
730 "DATA_B3_IND",
731 "RESET_B3_IND",
732 "CONNECT_B3_T90_ACTIVE_IND",
735 "CONNECT_RESP",
736 "CONNECT_ACTIVE_RESP",
737 "DISCONNECT_RESP",
739 "MANUFACTURER_IND",
741 "INFO_RESP",
742 "FACILITY_RESP",
744 "CONNECT_B3_RESP",
745 "CONNECT_B3_ACTIVE_RESP",
746 "DISCONNECT_B3_RESP",
748 "DATA_B3_RESP",
749 "RESET_B3_RESP",
750 "CONNECT_B3_T90_ACTIVE_RESP",
757 "MANUFACTURER_RESP"
760 char *capi_cmd2str(__u8 cmd, __u8 subcmd)
762 return mnames[command_2_index(cmd, subcmd)];
766 /*-------------------------------------------------------*/
767 /*-------------------------------------------------------*/
769 static char *pnames[] =
771 /*00 */ 0,
772 /*01 */ 0,
773 /*02 */ 0,
774 /*03 */ "Controller/PLCI/NCCI",
775 /*04 */ "AdditionalInfo",
776 /*05 */ "B1configuration",
777 /*06 */ "B1protocol",
778 /*07 */ "B2configuration",
779 /*08 */ "B2protocol",
780 /*09 */ "B3configuration",
781 /*0a */ "B3protocol",
782 /*0b */ "BC",
783 /*0c */ "BChannelinformation",
784 /*0d */ "BProtocol",
785 /*0e */ "CalledPartyNumber",
786 /*0f */ "CalledPartySubaddress",
787 /*10 */ "CallingPartyNumber",
788 /*11 */ "CallingPartySubaddress",
789 /*12 */ "CIPmask",
790 /*13 */ "CIPmask2",
791 /*14 */ "CIPValue",
792 /*15 */ "Class",
793 /*16 */ "ConnectedNumber",
794 /*17 */ "ConnectedSubaddress",
795 /*18 */ "Data",
796 /*19 */ "DataHandle",
797 /*1a */ "DataLength",
798 /*1b */ "FacilityConfirmationParameter",
799 /*1c */ "Facilitydataarray",
800 /*1d */ "FacilityIndicationParameter",
801 /*1e */ "FacilityRequestParameter",
802 /*1f */ "FacilitySelector",
803 /*20 */ "Flags",
804 /*21 */ "Function",
805 /*22 */ "HLC",
806 /*23 */ "Info",
807 /*24 */ "InfoElement",
808 /*25 */ "InfoMask",
809 /*26 */ "InfoNumber",
810 /*27 */ "Keypadfacility",
811 /*28 */ "LLC",
812 /*29 */ "ManuData",
813 /*2a */ "ManuID",
814 /*2b */ "NCPI",
815 /*2c */ "Reason",
816 /*2d */ "Reason_B3",
817 /*2e */ "Reject",
818 /*2f */ "Useruserdata"
822 static char buf[8192];
823 static char *p = 0;
825 #include <stdarg.h>
827 /*-------------------------------------------------------*/
828 static void bufprint(char *fmt,...)
830 va_list f;
831 va_start(f, fmt);
832 vsprintf(p, fmt, f);
833 va_end(f);
834 p += strlen(p);
837 static void printstructlen(__u8 * m, unsigned len)
839 unsigned hex = 0;
840 for (; len; len--, m++)
841 if (isalnum(*m) || *m == ' ') {
842 if (hex)
843 bufprint(">");
844 bufprint("%c", *m);
845 hex = 0;
846 } else {
847 if (!hex)
848 bufprint("<%02x", *m);
849 else
850 bufprint(" %02x", *m);
851 hex = 1;
853 if (hex)
854 bufprint(">");
857 static void printstruct(__u8 * m)
859 unsigned len;
860 if (m[0] != 0xff) {
861 len = m[0];
862 m += 1;
863 } else {
864 len = ((__u16 *) (m + 1))[0];
865 m += 3;
867 printstructlen(m, len);
870 /*-------------------------------------------------------*/
871 #define NAME (pnames[cmsg->par[cmsg->p]])
873 static void protocol_message_2_pars(_cmsg * cmsg, int level)
875 for (; TYP != _CEND; cmsg->p++) {
876 int slen = 29 + 3 - level;
877 int i;
879 bufprint(" ");
880 for (i = 0; i < level - 1; i++)
881 bufprint(" ");
883 switch (TYP) {
884 case _CBYTE:
885 bufprint("%-*s = 0x%x\n", slen, NAME, *(__u8 *) (cmsg->m + cmsg->l));
886 cmsg->l++;
887 break;
888 case _CWORD:
889 bufprint("%-*s = 0x%x\n", slen, NAME, *(__u16 *) (cmsg->m + cmsg->l));
890 cmsg->l += 2;
891 break;
892 case _CDWORD:
893 if (strcmp(NAME, "Data") == 0) {
894 bufprint("%-*s = ", slen, NAME);
895 printstructlen((__u8 *) * (__u32 *) (cmsg->m + cmsg->l),
896 *(__u16 *) (cmsg->m + cmsg->l + sizeof(__u32)));
897 bufprint("\n");
898 } else
899 bufprint("%-*s = 0x%lx\n", slen, NAME, *(__u32 *) (cmsg->m + cmsg->l));
900 cmsg->l += 4;
901 break;
902 case _CSTRUCT:
903 bufprint("%-*s = ", slen, NAME);
904 if (cmsg->m[cmsg->l] == '\0')
905 bufprint("default");
906 else
907 printstruct(cmsg->m + cmsg->l);
908 bufprint("\n");
909 if (cmsg->m[cmsg->l] != 0xff)
910 cmsg->l += 1 + cmsg->m[cmsg->l];
911 else
912 cmsg->l += 3 + *(__u16 *) (cmsg->m + cmsg->l + 1);
914 break;
916 case _CMSTRUCT:
917 /*----- Metastruktur 0 -----*/
918 if (cmsg->m[cmsg->l] == '\0') {
919 bufprint("%-*s = default\n", slen, NAME);
920 cmsg->l++;
921 jumpcstruct(cmsg);
922 } else {
923 char *name = NAME;
924 unsigned _l = cmsg->l;
925 bufprint("%-*s\n", slen, name);
926 cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
927 cmsg->p++;
928 protocol_message_2_pars(cmsg, level + 1);
930 break;
934 /*-------------------------------------------------------*/
935 char *capi_message2str(__u8 * msg)
938 _cmsg cmsg;
939 p = buf;
940 p[0] = 0;
942 cmsg.m = msg;
943 cmsg.l = 8;
944 cmsg.p = 0;
945 byteTRcpy(cmsg.m + 4, &cmsg.Command);
946 byteTRcpy(cmsg.m + 5, &cmsg.Subcommand);
947 cmsg.par = cpars[command_2_index(cmsg.Command, cmsg.Subcommand)];
949 bufprint("%-26s ID=%03d #0x%04x LEN=%04d\n",
950 mnames[command_2_index(cmsg.Command, cmsg.Subcommand)],
951 ((unsigned short *) msg)[1],
952 ((unsigned short *) msg)[3],
953 ((unsigned short *) msg)[0]);
955 protocol_message_2_pars(&cmsg, 1);
956 return buf;
959 char *capi_cmsg2str(_cmsg * cmsg)
961 p = buf;
962 p[0] = 0;
963 cmsg->l = 8;
964 cmsg->p = 0;
965 bufprint("%s ID=%03d #0x%04x LEN=%04d\n",
966 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
967 ((__u16 *) cmsg->m)[1],
968 ((__u16 *) cmsg->m)[3],
969 ((__u16 *) cmsg->m)[0]);
970 protocol_message_2_pars(cmsg, 1);
971 return buf;
975 EXPORT_SYMBOL(capi_cmsg2message);
976 EXPORT_SYMBOL(capi_message2cmsg);
977 EXPORT_SYMBOL(capi_cmsg_header);
978 EXPORT_SYMBOL(capi_cmd2str);
979 EXPORT_SYMBOL(capi_cmsg2str);
980 EXPORT_SYMBOL(capi_message2str);
981 EXPORT_SYMBOL(capi_info2str);
983 #ifdef MODULE
985 int init_module(void)
987 return 0;
990 void cleanup_module(void)
994 #endif