capiutil.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:26k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: capiutil.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  2.  *
  3.  * CAPI 2.0 convert capi message to capi message struct
  4.  *
  5.  * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
  6.  * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de>
  7.  *
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  */
  12. #include <linux/module.h>
  13. #include <linux/string.h>
  14. #include <linux/ctype.h>
  15. #include <linux/stddef.h>
  16. #include <linux/kernel.h>
  17. #include <linux/mm.h>
  18. #include <linux/init.h>
  19. #include <asm/segment.h>
  20. #include <linux/config.h>
  21. #include "capiutil.h"
  22. MODULE_DESCRIPTION("CAPI4Linux: CAPI message conversion support");
  23. MODULE_AUTHOR("Carsten Paeth");
  24. MODULE_LICENSE("GPL");
  25. /* from CAPI2.0 DDK AVM Berlin GmbH */
  26. #ifndef CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
  27. char *capi_info2str(__u16 reason)
  28. {
  29.     return "..";
  30. }
  31. #else
  32. char *capi_info2str(__u16 reason)
  33. {
  34.     switch (reason) {
  35. /*-- informative values (corresponding message was processed) -----*/
  36. case 0x0001:
  37.    return "NCPI not supported by current protocol, NCPI ignored";
  38. case 0x0002:
  39.    return "Flags not supported by current protocol, flags ignored";
  40. case 0x0003:
  41.    return "Alert already sent by another application";
  42. /*-- error information concerning CAPI_REGISTER -----*/
  43. case 0x1001:
  44.    return "Too many applications";
  45. case 0x1002:
  46.    return "Logical block size too small, must be at least 128 Bytes";
  47. case 0x1003:
  48.    return "Buffer exceeds 64 kByte";
  49. case 0x1004:
  50.    return "Message buffer size too small, must be at least 1024 Bytes";
  51. case 0x1005:
  52.    return "Max. number of logical connections not supported";
  53. case 0x1006:
  54.    return "Reserved";
  55. case 0x1007:
  56.    return "The message could not be accepted because of an internal busy condition";
  57. case 0x1008:
  58.    return "OS resource error (no memory ?)";
  59. case 0x1009:
  60.    return "CAPI not installed";
  61. case 0x100A:
  62.    return "Controller does not support external equipment";
  63. case 0x100B:
  64.    return "Controller does only support external equipment";
  65. /*-- error information concerning message exchange functions -----*/
  66. case 0x1101:
  67.    return "Illegal application number";
  68. case 0x1102:
  69.    return "Illegal command or subcommand or message length less than 12 bytes";
  70. case 0x1103:
  71.    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";
  72. case 0x1104:
  73.    return "Queue is empty";
  74. case 0x1105:
  75.    return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
  76. case 0x1106:
  77.    return "Unknown notification parameter";
  78. case 0x1107:
  79.    return "The Message could not be accepted because of an internal busy condition";
  80. case 0x1108:
  81.    return "OS Resource error (no memory ?)";
  82. case 0x1109:
  83.    return "CAPI not installed";
  84. case 0x110A:
  85.    return "Controller does not support external equipment";
  86. case 0x110B:
  87.    return "Controller does only support external equipment";
  88. /*-- error information concerning resource / coding problems -----*/
  89. case 0x2001:
  90.    return "Message not supported in current state";
  91. case 0x2002:
  92.    return "Illegal Controller / PLCI / NCCI";
  93. case 0x2003:
  94.    return "Out of PLCI";
  95. case 0x2004:
  96.    return "Out of NCCI";
  97. case 0x2005:
  98.    return "Out of LISTEN";
  99. case 0x2006:
  100.    return "Out of FAX resources (protocol T.30)";
  101. case 0x2007:
  102.    return "Illegal message parameter coding";
  103. /*-- error information concerning requested services  -----*/
  104. case 0x3001:
  105.    return "B1 protocol not supported";
  106. case 0x3002: 
  107.    return "B2 protocol not supported";
  108. case 0x3003: 
  109.    return "B3 protocol not supported";
  110. case 0x3004: 
  111.    return "B1 protocol parameter not supported";
  112. case 0x3005: 
  113.    return "B2 protocol parameter not supported";
  114. case 0x3006: 
  115.    return "B3 protocol parameter not supported";
  116. case 0x3007: 
  117.    return "B protocol combination not supported";
  118. case 0x3008: 
  119.    return "NCPI not supported";
  120. case 0x3009: 
  121.    return "CIP Value unknown";
  122. case 0x300A: 
  123.    return "Flags not supported (reserved bits)";
  124. case 0x300B: 
  125.    return "Facility not supported";
  126. case 0x300C: 
  127.    return "Data length not supported by current protocol";
  128. case 0x300D: 
  129.    return "Reset procedure not supported by current protocol";
  130. /*-- informations about the clearing of a physical connection -----*/
  131. case 0x3301: 
  132.    return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
  133. case 0x3302: 
  134.    return "Protocol error layer 2";
  135. case 0x3303: 
  136.    return "Protocol error layer 3";
  137. case 0x3304: 
  138.    return "Another application got that call";
  139. /*-- T.30 specific reasons -----*/
  140. case 0x3311: 
  141.    return "Connecting not successful (remote station is no FAX G3 machine)";
  142. case 0x3312: 
  143.    return "Connecting not successful (training error)";
  144. case 0x3313: 
  145.    return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
  146. case 0x3314: 
  147.    return "Disconnected during transfer (remote abort)";
  148. case 0x3315: 
  149.    return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
  150. case 0x3316: 
  151.    return "Disconnected during transfer (local tx data underrun)";
  152. case 0x3317: 
  153.    return "Disconnected during transfer (local rx data overflow)";
  154. case 0x3318: 
  155.    return "Disconnected during transfer (local abort)";
  156. case 0x3319: 
  157.    return "Illegal parameter coding (e.g. SFF coding error)";
  158. /*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/
  159. case 0x3481: return "Unallocated (unassigned) number";
  160. case 0x3482: return "No route to specified transit network";
  161. case 0x3483: return "No route to destination";
  162. case 0x3486: return "Channel unacceptable";
  163. case 0x3487: 
  164.    return "Call awarded and being delivered in an established channel";
  165. case 0x3490: return "Normal call clearing";
  166. case 0x3491: return "User busy";
  167. case 0x3492: return "No user responding";
  168. case 0x3493: return "No answer from user (user alerted)";
  169. case 0x3495: return "Call rejected";
  170. case 0x3496: return "Number changed";
  171. case 0x349A: return "Non-selected user clearing";
  172. case 0x349B: return "Destination out of order";
  173. case 0x349C: return "Invalid number format";
  174. case 0x349D: return "Facility rejected";
  175. case 0x349E: return "Response to STATUS ENQUIRY";
  176. case 0x349F: return "Normal, unspecified";
  177. case 0x34A2: return "No circuit / channel available";
  178. case 0x34A6: return "Network out of order";
  179. case 0x34A9: return "Temporary failure";
  180. case 0x34AA: return "Switching equipment congestion";
  181. case 0x34AB: return "Access information discarded";
  182. case 0x34AC: return "Requested circuit / channel not available";
  183. case 0x34AF: return "Resources unavailable, unspecified";
  184. case 0x34B1: return "Quality of service unavailable";
  185. case 0x34B2: return "Requested facility not subscribed";
  186. case 0x34B9: return "Bearer capability not authorized";
  187. case 0x34BA: return "Bearer capability not presently available";
  188. case 0x34BF: return "Service or option not available, unspecified";
  189. case 0x34C1: return "Bearer capability not implemented";
  190. case 0x34C2: return "Channel type not implemented";
  191. case 0x34C5: return "Requested facility not implemented";
  192. case 0x34C6: return "Only restricted digital information bearer capability is available";
  193. case 0x34CF: return "Service or option not implemented, unspecified";
  194. case 0x34D1: return "Invalid call reference value";
  195. case 0x34D2: return "Identified channel does not exist";
  196. case 0x34D3: return "A suspended call exists, but this call identity does not";
  197. case 0x34D4: return "Call identity in use";
  198. case 0x34D5: return "No call suspended";
  199. case 0x34D6: return "Call having the requested call identity has been cleared";
  200. case 0x34D8: return "Incompatible destination";
  201. case 0x34DB: return "Invalid transit network selection";
  202. case 0x34DF: return "Invalid message, unspecified";
  203. case 0x34E0: return "Mandatory information element is missing";
  204. case 0x34E1: return "Message type non-existent or not implemented";
  205. case 0x34E2: return "Message not compatible with call state or message type non-existent or not implemented";
  206. case 0x34E3: return "Information element non-existent or not implemented";
  207. case 0x34E4: return "Invalid information element contents";
  208. case 0x34E5: return "Message not compatible with call state";
  209. case 0x34E6: return "Recovery on timer expiry";
  210. case 0x34EF: return "Protocol error, unspecified";
  211. case 0x34FF: return "Interworking, unspecified";
  212. default: return "No additional information";
  213.     }
  214. }
  215. #endif
  216. typedef struct {
  217. int typ;
  218. size_t off;
  219. } _cdef;
  220. #define _CBYTE        1
  221. #define _CWORD        2
  222. #define _CDWORD        3
  223. #define _CSTRUCT       4
  224. #define _CMSTRUCT      5
  225. #define _CEND        6
  226. static _cdef cdef[] =
  227. {
  228.     /*00 */ 
  229.  {_CEND},
  230.     /*01 */ 
  231.  {_CEND},
  232.     /*02 */ 
  233.  {_CEND},
  234.     /*03 */ 
  235.  {_CDWORD, offsetof(_cmsg, adr.adrController)},
  236.     /*04 */ 
  237.  {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
  238.     /*05 */ 
  239.  {_CSTRUCT, offsetof(_cmsg, B1configuration)},
  240.     /*06 */ 
  241.  {_CWORD, offsetof(_cmsg, B1protocol)},
  242.     /*07 */ 
  243.  {_CSTRUCT, offsetof(_cmsg, B2configuration)},
  244.     /*08 */ 
  245.  {_CWORD, offsetof(_cmsg, B2protocol)},
  246.     /*09 */ 
  247.  {_CSTRUCT, offsetof(_cmsg, B3configuration)},
  248.     /*0a */ 
  249.  {_CWORD, offsetof(_cmsg, B3protocol)},
  250.     /*0b */ 
  251.  {_CSTRUCT, offsetof(_cmsg, BC)},
  252.     /*0c */ 
  253.  {_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
  254.     /*0d */ 
  255.  {_CMSTRUCT, offsetof(_cmsg, BProtocol)},
  256.     /*0e */ 
  257.  {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
  258.     /*0f */ 
  259.  {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
  260.     /*10 */ 
  261.  {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
  262.     /*11 */ 
  263.  {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
  264.     /*12 */ 
  265.  {_CDWORD, offsetof(_cmsg, CIPmask)},
  266.     /*13 */ 
  267.  {_CDWORD, offsetof(_cmsg, CIPmask2)},
  268.     /*14 */ 
  269.  {_CWORD, offsetof(_cmsg, CIPValue)},
  270.     /*15 */ 
  271.  {_CDWORD, offsetof(_cmsg, Class)},
  272.     /*16 */ 
  273.  {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
  274.     /*17 */ 
  275.  {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
  276.     /*18 */ 
  277.  {_CDWORD, offsetof(_cmsg, Data)},
  278.     /*19 */ 
  279.  {_CWORD, offsetof(_cmsg, DataHandle)},
  280.     /*1a */ 
  281.  {_CWORD, offsetof(_cmsg, DataLength)},
  282.     /*1b */ 
  283.  {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
  284.     /*1c */ 
  285.  {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
  286.     /*1d */ 
  287.  {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
  288.     /*1e */ 
  289.  {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
  290.     /*1f */ 
  291.  {_CWORD, offsetof(_cmsg, FacilitySelector)},
  292.     /*20 */ 
  293.  {_CWORD, offsetof(_cmsg, Flags)},
  294.     /*21 */ 
  295.  {_CDWORD, offsetof(_cmsg, Function)},
  296.     /*22 */ 
  297.  {_CSTRUCT, offsetof(_cmsg, HLC)},
  298.     /*23 */ 
  299.  {_CWORD, offsetof(_cmsg, Info)},
  300.     /*24 */ 
  301.  {_CSTRUCT, offsetof(_cmsg, InfoElement)},
  302.     /*25 */ 
  303.  {_CDWORD, offsetof(_cmsg, InfoMask)},
  304.     /*26 */ 
  305.  {_CWORD, offsetof(_cmsg, InfoNumber)},
  306.     /*27 */ 
  307.  {_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
  308.     /*28 */ 
  309.  {_CSTRUCT, offsetof(_cmsg, LLC)},
  310.     /*29 */ 
  311.  {_CSTRUCT, offsetof(_cmsg, ManuData)},
  312.     /*2a */ 
  313.  {_CDWORD, offsetof(_cmsg, ManuID)},
  314.     /*2b */ 
  315.  {_CSTRUCT, offsetof(_cmsg, NCPI)},
  316.     /*2c */ 
  317.  {_CWORD, offsetof(_cmsg, Reason)},
  318.     /*2d */ 
  319.  {_CWORD, offsetof(_cmsg, Reason_B3)},
  320.     /*2e */ 
  321.  {_CWORD, offsetof(_cmsg, Reject)},
  322.     /*2f */ 
  323.  {_CSTRUCT, offsetof(_cmsg, Useruserdata)}
  324. };
  325. static unsigned char *cpars[] =
  326. {
  327.     /*00 */ 0,
  328.     /*01 ALERT_REQ */ (unsigned char *) "x03x04x0cx27x2fx1cx01x01",
  329.     /*02 CONNECT_REQ */ (unsigned char *) "x03x14x0ex10x0fx11x0dx06x08x0ax05x07x09x01x0bx28x22x04x0cx27x2fx1cx01x01",
  330.     /*03 */ 0,
  331.     /*04 DISCONNECT_REQ */ (unsigned char *) "x03x04x0cx27x2fx1cx01x01",
  332.     /*05 LISTEN_REQ */ (unsigned char *) "x03x25x12x13x10x11x01",
  333.     /*06 */ 0,
  334.     /*07 */ 0,
  335.     /*08 INFO_REQ */ (unsigned char *) "x03x0ex04x0cx27x2fx1cx01x01",
  336.     /*09 FACILITY_REQ */ (unsigned char *) "x03x1fx1ex01",
  337.     /*0a SELECT_B_PROTOCOL_REQ */ (unsigned char *) "x03x0dx06x08x0ax05x07x09x01x01",
  338.     /*0b CONNECT_B3_REQ */ (unsigned char *) "x03x2bx01",
  339.     /*0c */ 0,
  340.     /*0d DISCONNECT_B3_REQ */ (unsigned char *) "x03x2bx01",
  341.     /*0e */ 0,
  342.     /*0f DATA_B3_REQ */ (unsigned char *) "x03x18x1ax19x20x01",
  343.     /*10 RESET_B3_REQ */ (unsigned char *) "x03x2bx01",
  344.     /*11 */ 0,
  345.     /*12 */ 0,
  346.     /*13 ALERT_CONF */ (unsigned char *) "x03x23x01",
  347.     /*14 CONNECT_CONF */ (unsigned char *) "x03x23x01",
  348.     /*15 */ 0,
  349.     /*16 DISCONNECT_CONF */ (unsigned char *) "x03x23x01",
  350.     /*17 LISTEN_CONF */ (unsigned char *) "x03x23x01",
  351.     /*18 MANUFACTURER_REQ */ (unsigned char *) "x03x2ax15x21x29x01",
  352.     /*19 */ 0,
  353.     /*1a INFO_CONF */ (unsigned char *) "x03x23x01",
  354.     /*1b FACILITY_CONF */ (unsigned char *) "x03x23x1fx1bx01",
  355.     /*1c SELECT_B_PROTOCOL_CONF */ (unsigned char *) "x03x23x01",
  356.     /*1d CONNECT_B3_CONF */ (unsigned char *) "x03x23x01",
  357.     /*1e */ 0,
  358.     /*1f DISCONNECT_B3_CONF */ (unsigned char *) "x03x23x01",
  359.     /*20 */ 0,
  360.     /*21 DATA_B3_CONF */ (unsigned char *) "x03x19x23x01",
  361.     /*22 RESET_B3_CONF */ (unsigned char *) "x03x23x01",
  362.     /*23 */ 0,
  363.     /*24 */ 0,
  364.     /*25 */ 0,
  365.     /*26 CONNECT_IND */ (unsigned char *) "x03x14x0ex10x0fx11x0bx28x22x04x0cx27x2fx1cx01x01",
  366.     /*27 CONNECT_ACTIVE_IND */ (unsigned char *) "x03x16x17x28x01",
  367.     /*28 DISCONNECT_IND */ (unsigned char *) "x03x2cx01",
  368.     /*29 */ 0,
  369.     /*2a MANUFACTURER_CONF */ (unsigned char *) "x03x2ax15x21x29x01",
  370.     /*2b */ 0,
  371.     /*2c INFO_IND */ (unsigned char *) "x03x26x24x01",
  372.     /*2d FACILITY_IND */ (unsigned char *) "x03x1fx1dx01",
  373.     /*2e */ 0,
  374.     /*2f CONNECT_B3_IND */ (unsigned char *) "x03x2bx01",
  375.     /*30 CONNECT_B3_ACTIVE_IND */ (unsigned char *) "x03x2bx01",
  376.     /*31 DISCONNECT_B3_IND */ (unsigned char *) "x03x2dx2bx01",
  377.     /*32 */ 0,
  378.     /*33 DATA_B3_IND */ (unsigned char *) "x03x18x1ax19x20x01",
  379.     /*34 RESET_B3_IND */ (unsigned char *) "x03x2bx01",
  380.     /*35 CONNECT_B3_T90_ACTIVE_IND */ (unsigned char *) "x03x2bx01",
  381.     /*36 */ 0,
  382.     /*37 */ 0,
  383.     /*38 CONNECT_RESP */ (unsigned char *) "x03x2ex0dx06x08x0ax05x07x09x01x16x17x28x04x0cx27x2fx1cx01x01",
  384.     /*39 CONNECT_ACTIVE_RESP */ (unsigned char *) "x03x01",
  385.     /*3a DISCONNECT_RESP */ (unsigned char *) "x03x01",
  386.     /*3b */ 0,
  387.     /*3c MANUFACTURER_IND */ (unsigned char *) "x03x2ax15x21x29x01",
  388.     /*3d */ 0,
  389.     /*3e INFO_RESP */ (unsigned char *) "x03x01",
  390.     /*3f FACILITY_RESP */ (unsigned char *) "x03x1fx01",
  391.     /*40 */ 0,
  392.     /*41 CONNECT_B3_RESP */ (unsigned char *) "x03x2ex2bx01",
  393.     /*42 CONNECT_B3_ACTIVE_RESP */ (unsigned char *) "x03x01",
  394.     /*43 DISCONNECT_B3_RESP */ (unsigned char *) "x03x01",
  395.     /*44 */ 0,
  396.     /*45 DATA_B3_RESP */ (unsigned char *) "x03x19x01",
  397.     /*46 RESET_B3_RESP */ (unsigned char *) "x03x01",
  398.     /*47 CONNECT_B3_T90_ACTIVE_RESP */ (unsigned char *) "x03x01",
  399.     /*48 */ 0,
  400.     /*49 */ 0,
  401.     /*4a */ 0,
  402.     /*4b */ 0,
  403.     /*4c */ 0,
  404.     /*4d */ 0,
  405.     /*4e MANUFACTURER_RESP */ (unsigned char *) "x03x2ax15x21x29x01",
  406. };
  407. /*-------------------------------------------------------*/
  408. #define byteTLcpy(x,y)        *(__u8 *)(x)=*(__u8 *)(y);
  409. #define wordTLcpy(x,y)        *(__u16 *)(x)=*(__u16 *)(y);
  410. #define dwordTLcpy(x,y)       memcpy(x,y,4);
  411. #define structTLcpy(x,y,l)    memcpy (x,y,l)
  412. #define structTLcpyovl(x,y,l) memmove (x,y,l)
  413. #define byteTRcpy(x,y)        *(__u8 *)(y)=*(__u8 *)(x);
  414. #define wordTRcpy(x,y)        *(__u16 *)(y)=*(__u16 *)(x);
  415. #define dwordTRcpy(x,y)       memcpy(y,x,4);
  416. #define structTRcpy(x,y,l)    memcpy (y,x,l)
  417. #define structTRcpyovl(x,y,l) memmove (y,x,l)
  418. /*-------------------------------------------------------*/
  419. static unsigned command_2_index(unsigned c, unsigned sc)
  420. {
  421. if (c & 0x80)
  422. c = 0x9 + (c & 0x0f);
  423. else if (c <= 0x0f);
  424. else if (c == 0x41)
  425. c = 0x9 + 0x1;
  426. else if (c == 0xff)
  427. c = 0x00;
  428. return (sc & 3) * (0x9 + 0x9) + c;
  429. }
  430. /*-------------------------------------------------------*/
  431. #define TYP (cdef[cmsg->par[cmsg->p]].typ)
  432. #define OFF (((__u8 *)cmsg)+cdef[cmsg->par[cmsg->p]].off)
  433. static void jumpcstruct(_cmsg * cmsg)
  434. {
  435. unsigned layer;
  436. for (cmsg->p++, layer = 1; layer;) {
  437. /* $$$$$ assert (cmsg->p); */
  438. cmsg->p++;
  439. switch (TYP) {
  440. case _CMSTRUCT:
  441. layer++;
  442. break;
  443. case _CEND:
  444. layer--;
  445. break;
  446. }
  447. }
  448. }
  449. /*-------------------------------------------------------*/
  450. static void pars_2_message(_cmsg * cmsg)
  451. {
  452. for (; TYP != _CEND; cmsg->p++) {
  453. switch (TYP) {
  454. case _CBYTE:
  455. byteTLcpy(cmsg->m + cmsg->l, OFF);
  456. cmsg->l++;
  457. break;
  458. case _CWORD:
  459. wordTLcpy(cmsg->m + cmsg->l, OFF);
  460. cmsg->l += 2;
  461. break;
  462. case _CDWORD:
  463. dwordTLcpy(cmsg->m + cmsg->l, OFF);
  464. cmsg->l += 4;
  465. break;
  466. case _CSTRUCT:
  467. if (*(__u8 **) OFF == 0) {
  468. *(cmsg->m + cmsg->l) = '';
  469. cmsg->l++;
  470. } else if (**(_cstruct *) OFF != 0xff) {
  471. structTLcpy(cmsg->m + cmsg->l, *(_cstruct *) OFF, 1 + **(_cstruct *) OFF);
  472. cmsg->l += 1 + **(_cstruct *) OFF;
  473. } else {
  474. _cstruct s = *(_cstruct *) OFF;
  475. structTLcpy(cmsg->m + cmsg->l, s, 3 + *(__u16 *) (s + 1));
  476. cmsg->l += 3 + *(__u16 *) (s + 1);
  477. }
  478. break;
  479. case _CMSTRUCT:
  480. /*----- Metastruktur 0 -----*/
  481. if (*(_cmstruct *) OFF == CAPI_DEFAULT) {
  482. *(cmsg->m + cmsg->l) = '';
  483. cmsg->l++;
  484. jumpcstruct(cmsg);
  485. }
  486. /*----- Metastruktur wird composed -----*/
  487. else {
  488. unsigned _l = cmsg->l;
  489. unsigned _ls;
  490. cmsg->l++;
  491. cmsg->p++;
  492. pars_2_message(cmsg);
  493. _ls = cmsg->l - _l - 1;
  494. if (_ls < 255)
  495. (cmsg->m + _l)[0] = (__u8) _ls;
  496. else {
  497. structTLcpyovl(cmsg->m + _l + 3, cmsg->m + _l + 1, _ls);
  498. (cmsg->m + _l)[0] = 0xff;
  499. wordTLcpy(cmsg->m + _l + 1, &_ls);
  500. }
  501. }
  502. break;
  503. }
  504. }
  505. }
  506. /*-------------------------------------------------------*/
  507. unsigned capi_cmsg2message(_cmsg * cmsg, __u8 * msg)
  508. {
  509. cmsg->m = msg;
  510. cmsg->l = 8;
  511. cmsg->p = 0;
  512. cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
  513. pars_2_message(cmsg);
  514. wordTLcpy(msg + 0, &cmsg->l);
  515. byteTLcpy(cmsg->m + 4, &cmsg->Command);
  516. byteTLcpy(cmsg->m + 5, &cmsg->Subcommand);
  517. wordTLcpy(cmsg->m + 2, &cmsg->ApplId);
  518. wordTLcpy(cmsg->m + 6, &cmsg->Messagenumber);
  519. return 0;
  520. }
  521. /*-------------------------------------------------------*/
  522. static void message_2_pars(_cmsg * cmsg)
  523. {
  524. for (; TYP != _CEND; cmsg->p++) {
  525. switch (TYP) {
  526. case _CBYTE:
  527. byteTRcpy(cmsg->m + cmsg->l, OFF);
  528. cmsg->l++;
  529. break;
  530. case _CWORD:
  531. wordTRcpy(cmsg->m + cmsg->l, OFF);
  532. cmsg->l += 2;
  533. break;
  534. case _CDWORD:
  535. dwordTRcpy(cmsg->m + cmsg->l, OFF);
  536. cmsg->l += 4;
  537. break;
  538. case _CSTRUCT:
  539. *(__u8 **) OFF = cmsg->m + cmsg->l;
  540. if (cmsg->m[cmsg->l] != 0xff)
  541. cmsg->l += 1 + cmsg->m[cmsg->l];
  542. else
  543. cmsg->l += 3 + *(__u16 *) (cmsg->m + cmsg->l + 1);
  544. break;
  545. case _CMSTRUCT:
  546. /*----- Metastruktur 0 -----*/
  547. if (cmsg->m[cmsg->l] == '') {
  548. *(_cmstruct *) OFF = CAPI_DEFAULT;
  549. cmsg->l++;
  550. jumpcstruct(cmsg);
  551. } else {
  552. unsigned _l = cmsg->l;
  553. *(_cmstruct *) OFF = CAPI_COMPOSE;
  554. cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
  555. cmsg->p++;
  556. message_2_pars(cmsg);
  557. }
  558. break;
  559. }
  560. }
  561. }
  562. /*-------------------------------------------------------*/
  563. unsigned capi_message2cmsg(_cmsg * cmsg, __u8 * msg)
  564. {
  565. memset(cmsg, 0, sizeof(_cmsg));
  566. cmsg->m = msg;
  567. cmsg->l = 8;
  568. cmsg->p = 0;
  569. byteTRcpy(cmsg->m + 4, &cmsg->Command);
  570. byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
  571. cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
  572. message_2_pars(cmsg);
  573. wordTRcpy(msg + 0, &cmsg->l);
  574. wordTRcpy(cmsg->m + 2, &cmsg->ApplId);
  575. wordTRcpy(cmsg->m + 6, &cmsg->Messagenumber);
  576. return 0;
  577. }
  578. /*-------------------------------------------------------*/
  579. unsigned capi_cmsg_header(_cmsg * cmsg, __u16 _ApplId,
  580.   __u8 _Command, __u8 _Subcommand,
  581.   __u16 _Messagenumber, __u32 _Controller)
  582. {
  583. memset(cmsg, 0, sizeof(_cmsg));
  584. cmsg->ApplId = _ApplId;
  585. cmsg->Command = _Command;
  586. cmsg->Subcommand = _Subcommand;
  587. cmsg->Messagenumber = _Messagenumber;
  588. cmsg->adr.adrController = _Controller;
  589. return 0;
  590. }
  591. /*-------------------------------------------------------*/
  592. static char *mnames[] =
  593. {
  594. 0,
  595. "ALERT_REQ",
  596. "CONNECT_REQ",
  597. 0,
  598. "DISCONNECT_REQ",
  599. "LISTEN_REQ",
  600. 0,
  601. 0,
  602. "INFO_REQ",
  603. "FACILITY_REQ",
  604. "SELECT_B_PROTOCOL_REQ",
  605. "CONNECT_B3_REQ",
  606. 0,
  607. "DISCONNECT_B3_REQ",
  608. 0,
  609. "DATA_B3_REQ",
  610. "RESET_B3_REQ",
  611. 0,
  612. 0,
  613. "ALERT_CONF",
  614. "CONNECT_CONF",
  615. 0,
  616. "DISCONNECT_CONF",
  617. "LISTEN_CONF",
  618. "MANUFACTURER_REQ",
  619. 0,
  620. "INFO_CONF",
  621. "FACILITY_CONF",
  622. "SELECT_B_PROTOCOL_CONF",
  623. "CONNECT_B3_CONF",
  624. 0,
  625. "DISCONNECT_B3_CONF",
  626. 0,
  627. "DATA_B3_CONF",
  628. "RESET_B3_CONF",
  629. 0,
  630. 0,
  631. 0,
  632. "CONNECT_IND",
  633. "CONNECT_ACTIVE_IND",
  634. "DISCONNECT_IND",
  635. 0,
  636. "MANUFACTURER_CONF",
  637. 0,
  638. "INFO_IND",
  639. "FACILITY_IND",
  640. 0,
  641. "CONNECT_B3_IND",
  642. "CONNECT_B3_ACTIVE_IND",
  643. "DISCONNECT_B3_IND",
  644. 0,
  645. "DATA_B3_IND",
  646. "RESET_B3_IND",
  647. "CONNECT_B3_T90_ACTIVE_IND",
  648. 0,
  649. 0,
  650. "CONNECT_RESP",
  651. "CONNECT_ACTIVE_RESP",
  652. "DISCONNECT_RESP",
  653. 0,
  654. "MANUFACTURER_IND",
  655. 0,
  656. "INFO_RESP",
  657. "FACILITY_RESP",
  658. 0,
  659. "CONNECT_B3_RESP",
  660. "CONNECT_B3_ACTIVE_RESP",
  661. "DISCONNECT_B3_RESP",
  662. 0,
  663. "DATA_B3_RESP",
  664. "RESET_B3_RESP",
  665. "CONNECT_B3_T90_ACTIVE_RESP",
  666. 0,
  667. 0,
  668. 0,
  669. 0,
  670. 0,
  671. 0,
  672. "MANUFACTURER_RESP"
  673. };
  674. char *capi_cmd2str(__u8 cmd, __u8 subcmd)
  675. {
  676. return mnames[command_2_index(cmd, subcmd)];
  677. }
  678. /*-------------------------------------------------------*/
  679. /*-------------------------------------------------------*/
  680. static char *pnames[] =
  681. {
  682.     /*00 */ 0,
  683.     /*01 */ 0,
  684.     /*02 */ 0,
  685.     /*03 */ "Controller/PLCI/NCCI",
  686.     /*04 */ "AdditionalInfo",
  687.     /*05 */ "B1configuration",
  688.     /*06 */ "B1protocol",
  689.     /*07 */ "B2configuration",
  690.     /*08 */ "B2protocol",
  691.     /*09 */ "B3configuration",
  692.     /*0a */ "B3protocol",
  693.     /*0b */ "BC",
  694.     /*0c */ "BChannelinformation",
  695.     /*0d */ "BProtocol",
  696.     /*0e */ "CalledPartyNumber",
  697.     /*0f */ "CalledPartySubaddress",
  698.     /*10 */ "CallingPartyNumber",
  699.     /*11 */ "CallingPartySubaddress",
  700.     /*12 */ "CIPmask",
  701.     /*13 */ "CIPmask2",
  702.     /*14 */ "CIPValue",
  703.     /*15 */ "Class",
  704.     /*16 */ "ConnectedNumber",
  705.     /*17 */ "ConnectedSubaddress",
  706.     /*18 */ "Data32",
  707.     /*19 */ "DataHandle",
  708.     /*1a */ "DataLength",
  709.     /*1b */ "FacilityConfirmationParameter",
  710.     /*1c */ "Facilitydataarray",
  711.     /*1d */ "FacilityIndicationParameter",
  712.     /*1e */ "FacilityRequestParameter",
  713.     /*1f */ "FacilitySelector",
  714.     /*20 */ "Flags",
  715.     /*21 */ "Function",
  716.     /*22 */ "HLC",
  717.     /*23 */ "Info",
  718.     /*24 */ "InfoElement",
  719.     /*25 */ "InfoMask",
  720.     /*26 */ "InfoNumber",
  721.     /*27 */ "Keypadfacility",
  722.     /*28 */ "LLC",
  723.     /*29 */ "ManuData",
  724.     /*2a */ "ManuID",
  725.     /*2b */ "NCPI",
  726.     /*2c */ "Reason",
  727.     /*2d */ "Reason_B3",
  728.     /*2e */ "Reject",
  729.     /*2f */ "Useruserdata"
  730. };
  731. static char buf[8192];
  732. static char *p = 0;
  733. #include <stdarg.h>
  734. /*-------------------------------------------------------*/
  735. static void bufprint(char *fmt,...)
  736. {
  737. va_list f;
  738. va_start(f, fmt);
  739. vsprintf(p, fmt, f);
  740. va_end(f);
  741. p += strlen(p);
  742. }
  743. static void printstructlen(__u8 * m, unsigned len)
  744. {
  745. unsigned hex = 0;
  746. for (; len; len--, m++)
  747. if (isalnum(*m) || *m == ' ') {
  748. if (hex)
  749. bufprint(">");
  750. bufprint("%c", *m);
  751. hex = 0;
  752. } else {
  753. if (!hex)
  754. bufprint("<%02x", *m);
  755. else
  756. bufprint(" %02x", *m);
  757. hex = 1;
  758. }
  759. if (hex)
  760. bufprint(">");
  761. }
  762. static void printstruct(__u8 * m)
  763. {
  764. unsigned len;
  765. if (m[0] != 0xff) {
  766. len = m[0];
  767. m += 1;
  768. } else {
  769. len = ((__u16 *) (m + 1))[0];
  770. m += 3;
  771. }
  772. printstructlen(m, len);
  773. }
  774. /*-------------------------------------------------------*/
  775. #define NAME (pnames[cmsg->par[cmsg->p]])
  776. static void protocol_message_2_pars(_cmsg * cmsg, int level)
  777. {
  778. for (; TYP != _CEND; cmsg->p++) {
  779. int slen = 29 + 3 - level;
  780. int i;
  781. bufprint("  ");
  782. for (i = 0; i < level - 1; i++)
  783. bufprint(" ");
  784. switch (TYP) {
  785. case _CBYTE:
  786. bufprint("%-*s = 0x%xn", slen, NAME, *(__u8 *) (cmsg->m + cmsg->l));
  787. cmsg->l++;
  788. break;
  789. case _CWORD:
  790. bufprint("%-*s = 0x%xn", slen, NAME, *(__u16 *) (cmsg->m + cmsg->l));
  791. cmsg->l += 2;
  792. break;
  793. case _CDWORD:
  794. bufprint("%-*s = 0x%lxn", slen, NAME, *(__u32 *) (cmsg->m + cmsg->l));
  795. cmsg->l += 4;
  796. break;
  797. case _CSTRUCT:
  798. bufprint("%-*s = ", slen, NAME);
  799. if (cmsg->m[cmsg->l] == '')
  800. bufprint("default");
  801. else
  802. printstruct(cmsg->m + cmsg->l);
  803. bufprint("n");
  804. if (cmsg->m[cmsg->l] != 0xff)
  805. cmsg->l += 1 + cmsg->m[cmsg->l];
  806. else
  807. cmsg->l += 3 + *(__u16 *) (cmsg->m + cmsg->l + 1);
  808. break;
  809. case _CMSTRUCT:
  810. /*----- Metastruktur 0 -----*/
  811. if (cmsg->m[cmsg->l] == '') {
  812. bufprint("%-*s = defaultn", slen, NAME);
  813. cmsg->l++;
  814. jumpcstruct(cmsg);
  815. } else {
  816. char *name = NAME;
  817. unsigned _l = cmsg->l;
  818. bufprint("%-*sn", slen, name);
  819. cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1;
  820. cmsg->p++;
  821. protocol_message_2_pars(cmsg, level + 1);
  822. }
  823. break;
  824. }
  825. }
  826. }
  827. /*-------------------------------------------------------*/
  828. char *capi_message2str(__u8 * msg)
  829. {
  830. _cmsg cmsg;
  831. p = buf;
  832. p[0] = 0;
  833. cmsg.m = msg;
  834. cmsg.l = 8;
  835. cmsg.p = 0;
  836. byteTRcpy(cmsg.m + 4, &cmsg.Command);
  837. byteTRcpy(cmsg.m + 5, &cmsg.Subcommand);
  838. cmsg.par = cpars[command_2_index(cmsg.Command, cmsg.Subcommand)];
  839. bufprint("%-26s ID=%03d #0x%04x LEN=%04dn",
  840.  mnames[command_2_index(cmsg.Command, cmsg.Subcommand)],
  841.  ((unsigned short *) msg)[1],
  842.  ((unsigned short *) msg)[3],
  843.  ((unsigned short *) msg)[0]);
  844. protocol_message_2_pars(&cmsg, 1);
  845. return buf;
  846. }
  847. char *capi_cmsg2str(_cmsg * cmsg)
  848. {
  849. p = buf;
  850. p[0] = 0;
  851. cmsg->l = 8;
  852. cmsg->p = 0;
  853. bufprint("%s ID=%03d #0x%04x LEN=%04dn",
  854.  mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
  855.  ((__u16 *) cmsg->m)[1],
  856.  ((__u16 *) cmsg->m)[3],
  857.  ((__u16 *) cmsg->m)[0]);
  858. protocol_message_2_pars(cmsg, 1);
  859. return buf;
  860. }
  861. EXPORT_SYMBOL(capi_cmsg2message);
  862. EXPORT_SYMBOL(capi_message2cmsg);
  863. EXPORT_SYMBOL(capi_cmsg_header);
  864. EXPORT_SYMBOL(capi_cmd2str);
  865. EXPORT_SYMBOL(capi_cmsg2str);
  866. EXPORT_SYMBOL(capi_message2str);
  867. EXPORT_SYMBOL(capi_info2str);
  868. static int __init capiutil_init(void)
  869. return 0; 
  870. }
  871. static void __exit capiutil_exit(void)
  872. {
  873. }
  874. module_init(capiutil_init);
  875. module_exit(capiutil_exit);