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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * CAPI encoder/decoder for
  3.  * Portugal Telecom CAPI 2.0
  4.  *
  5.  * Copyright (C) 1996 Universidade de Lisboa
  6.  * 
  7.  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  8.  *
  9.  * This software may be used and distributed according to the terms of 
  10.  * the GNU General Public License, incorporated herein by reference.
  11.  *
  12.  * Not compatible with the AVM Gmbh. CAPI 2.0
  13.  *
  14.  */
  15. /*
  16.  *        Documentation:
  17.  *        - "Common ISDN API - Perfil Portugu阺 - Vers鉶 2.1",
  18.  *           Telecom Portugal, Fev 1992.
  19.  *        - "Common ISDN API - Especifica玢o de protocolos para 
  20.  *           acesso aos canais B", Inesc, Jan 1994.
  21.  */
  22. /*
  23.  *        TODO: better decoding of Information Elements
  24.  *              for debug purposes mainly
  25.  *              encode our number in CallerPN and ConnectedPN
  26.  */
  27. #include <linux/sched.h>
  28. #include <linux/string.h>
  29. #include <linux/kernel.h>
  30. #include <linux/types.h>
  31. #include <linux/slab.h>
  32. #include <linux/mm.h>
  33. #include <linux/tqueue.h>
  34. #include <linux/skbuff.h>
  35. #include <asm/io.h>
  36. #include <asm/string.h>
  37. #include <linux/isdnif.h>
  38. #include "pcbit.h"
  39. #include "edss1.h"
  40. #include "capi.h"
  41. /*
  42.  *  Encoding of CAPI messages
  43.  *
  44.  */
  45. int capi_conn_req(const char * calledPN, struct sk_buff **skb, int proto)
  46. {
  47.         ushort len;
  48.         /*
  49.          * length
  50.          *   AppInfoMask - 2
  51.          *   BC0         - 3
  52.          *   BC1         - 1
  53.          *   Chan        - 2
  54.          *   Keypad      - 1
  55.          *   CPN         - 1
  56.          *   CPSA        - 1
  57.          *   CalledPN    - 2 + strlen
  58.          *   CalledPSA   - 1
  59.          *   rest...     - 4
  60.          *   ----------------
  61.          *   Total        18 + strlen
  62.          */
  63.         len = 18 + strlen(calledPN);
  64. if (proto == ISDN_PROTO_L2_TRANS)
  65. len++;
  66. if ((*skb = dev_alloc_skb(len)) == NULL) {
  67.     
  68.         printk(KERN_WARNING "capi_conn_req: alloc_skb failedn");
  69. return -1;
  70. }
  71.         /* InfoElmMask */
  72.         *((ushort*) skb_put(*skb, 2)) = AppInfoMask; 
  73. if (proto == ISDN_PROTO_L2_TRANS)
  74. {
  75. /* Bearer Capability - Mandatory*/
  76. *(skb_put(*skb, 1)) = 3;        /* BC0.Length */
  77. *(skb_put(*skb, 1)) = 0x80;     /* Speech */
  78. *(skb_put(*skb, 1)) = 0x10;     /* Circuit Mode */
  79. *(skb_put(*skb, 1)) = 0x23;     /* A-law */
  80. }
  81. else
  82. {
  83. /* Bearer Capability - Mandatory*/
  84. *(skb_put(*skb, 1)) = 2;        /* BC0.Length */
  85. *(skb_put(*skb, 1)) = 0x88;     /* Digital Information */
  86. *(skb_put(*skb, 1)) = 0x90;     /* BC0.Octect4 */
  87. }
  88.         /* Bearer Capability - Optional*/
  89.         *(skb_put(*skb, 1)) = 0;        /* BC1.Length = 0                    */
  90.         *(skb_put(*skb, 1)) = 1;        /* ChannelID.Length = 1              */
  91.         *(skb_put(*skb, 1)) = 0x83;     /* Basic Interface - Any Channel     */
  92.         *(skb_put(*skb, 1)) = 0;        /* Keypad.Length = 0                 */
  93.                   
  94.         *(skb_put(*skb, 1)) = 0;        /* CallingPN.Length = 0              */
  95.         *(skb_put(*skb, 1)) = 0;        /* CallingPSA.Length = 0             */
  96.         /* Called Party Number */
  97.         *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
  98.         *(skb_put(*skb, 1)) = 0x81;
  99.         memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
  100.         /* '#' */
  101.         *(skb_put(*skb, 1)) = 0;       /* CalledPSA.Length = 0     */
  102.         /* LLC.Length  = 0; */
  103.         /* HLC0.Length = 0; */
  104.         /* HLC1.Length = 0; */ 
  105.         /* UTUS.Length = 0; */
  106.         memset(skb_put(*skb, 4), 0, 4);
  107.         return len;
  108. }
  109. int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb)
  110. {
  111.         
  112. if ((*skb = dev_alloc_skb(5)) == NULL) {
  113.     
  114. printk(KERN_WARNING "capi_conn_resp: alloc_skb failedn");
  115. return -1;
  116. }
  117.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  118.         *(skb_put(*skb, 1)) = 0x01;  /* ACCEPT_CALL */
  119.         *(skb_put(*skb, 1)) = 0;
  120.         *(skb_put(*skb, 1)) = 0;
  121.         return 5;
  122. }
  123. int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb)
  124. {
  125.         /*
  126.          * 8 bytes
  127.          */
  128.         
  129. if ((*skb = dev_alloc_skb(8)) == NULL) {
  130.     
  131. printk(KERN_WARNING "capi_conn_active_req: alloc_skb failedn");
  132. return -1;
  133. }
  134.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  135. #ifdef DEBUG
  136. printk(KERN_DEBUG "Call Reference: %04xn", chan->callref); 
  137. #endif
  138.         *(skb_put(*skb, 1)) = 0;       /*  BC.Length = 0;          */
  139.         *(skb_put(*skb, 1)) = 0;       /*  ConnectedPN.Length = 0  */
  140.         *(skb_put(*skb, 1)) = 0;       /*  PSA.Length              */
  141.         *(skb_put(*skb, 1)) = 0;       /*  LLC.Length = 0;         */
  142.         *(skb_put(*skb, 1)) = 0;       /*  HLC.Length = 0;         */
  143.         *(skb_put(*skb, 1)) = 0;       /*  UTUS.Length = 0;        */
  144. return 8;
  145. }
  146. int capi_conn_active_resp(struct pcbit_chan* chan, struct sk_buff **skb)
  147. {
  148.         /*
  149.          * 2 bytes
  150.          */
  151.   
  152. if ((*skb = dev_alloc_skb(2)) == NULL) {
  153.     
  154. printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failedn");
  155. return -1;
  156. }
  157.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  158.         return 2;
  159. }
  160. int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, 
  161.                           int outgoing)
  162. {
  163.         /*
  164.          * 18 bytes
  165.          */
  166. if ((*skb = dev_alloc_skb(18)) == NULL) {
  167.     
  168. printk(KERN_WARNING "capi_select_proto_req: alloc_skb failedn");
  169. return -1;
  170. }
  171.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  172.         /* Layer2 protocol */
  173.         switch (chan->proto) {
  174.         case ISDN_PROTO_L2_X75I: 
  175.                 *(skb_put(*skb, 1)) = 0x05;            /* LAPB */
  176.                 break;
  177.         case ISDN_PROTO_L2_HDLC:
  178.                 *(skb_put(*skb, 1)) = 0x02;
  179.                 break;
  180. case ISDN_PROTO_L2_TRANS:
  181. /* 
  182.  * Voice (a-law)
  183.  */
  184. *(skb_put(*skb, 1)) = 0x06;
  185. break;
  186.         default:
  187. #ifdef DEBUG 
  188.                 printk(KERN_DEBUG "Transparentn");
  189. #endif
  190.                 *(skb_put(*skb, 1)) = 0x03;
  191.                 break;
  192.         }
  193.         *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);    /* Don't ask */
  194.         *(skb_put(*skb, 1)) = 0x00;
  195.   
  196.         *((ushort *) skb_put(*skb, 2)) = MRU;
  197.  
  198.         *(skb_put(*skb, 1)) = 0x08;           /* Modulo */
  199.         *(skb_put(*skb, 1)) = 0x07;           /* Max Window */
  200.   
  201.         *(skb_put(*skb, 1)) = 0x01;           /* No Layer3 Protocol */
  202.         /*
  203.          * 2 - layer3 MTU       [10]
  204.          *   - Modulo           [12]
  205.          *   - Window           
  206.          *   - layer1 proto     [14]
  207.          *   - bitrate
  208.          *   - sub-channel      [16]
  209.          *   - layer1dataformat [17]
  210.          */
  211.         memset(skb_put(*skb, 8), 0, 8);
  212.         return 18;
  213. }
  214. int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
  215. {
  216. if ((*skb = dev_alloc_skb(7)) == NULL) {
  217.     
  218. printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failedn");
  219. return -1;
  220. }
  221.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  222.         
  223.         *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
  224.         *(skb_put(*skb, 1)) = 0x00;             /* Transmit by default */
  225.         *((ushort *) skb_put(*skb, 2)) = MRU;
  226.         *(skb_put(*skb, 1)) = 0x01;             /* Enables reception*/
  227.         return 7;
  228. }
  229. int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb)
  230. {
  231. ushort data_len;
  232. /*  
  233.  * callref      - 2  
  234.  * layer2link   - 1
  235.  * wBlockLength - 2 
  236.  * data         - 4
  237.  * sernum       - 1
  238.  */
  239. data_len = skb->len;
  240. if(skb_headroom(skb) < 10)
  241. {
  242. printk(KERN_CRIT "No headspace (%u) on headroom %p for capi headern", skb_headroom(skb), skb);
  243. }
  244. else
  245. {
  246. skb_push(skb, 10);
  247. }
  248. *((u16 *) (skb->data)) = chan->callref;
  249. skb->data[2] = chan->layer2link;
  250. *((u16 *) (skb->data + 3)) = data_len;
  251. chan->s_refnum = (chan->s_refnum + 1) % 8;
  252. *((u32 *) (skb->data + 5)) = chan->s_refnum;
  253. skb->data[9] = 0;                           /* HDLC frame number */
  254. return 10;
  255. }
  256. int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb)
  257.     
  258. {
  259. if ((*skb = dev_alloc_skb(4)) == NULL) {
  260.     
  261. printk(KERN_WARNING "capi_tdata_resp: alloc_skb failedn");
  262. return -1;
  263. }
  264.         *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
  265.         *(skb_put(*skb, 1)) = chan->layer2link;
  266.         *(skb_put(*skb, 1)) = chan->r_refnum;
  267.         return (*skb)->len;
  268. }
  269. int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
  270. {
  271. if ((*skb = dev_alloc_skb(6)) == NULL) {
  272.     
  273. printk(KERN_WARNING "capi_disc_req: alloc_skb failedn");
  274. return -1;
  275. }
  276.         *((ushort*) skb_put(*skb, 2) ) = callref;  
  277.         *(skb_put(*skb, 1)) = 2;                  /* Cause.Length = 2; */
  278.         *(skb_put(*skb, 1)) = 0x80;
  279.         *(skb_put(*skb, 1)) = 0x80 | cause;           
  280.         /* 
  281.          * Change it: we should send 'Sic transit gloria Mundi' here ;-) 
  282.          */
  283.         *(skb_put(*skb, 1)) = 0;                   /* UTUS.Length = 0;  */
  284.         return 6;
  285. }
  286. int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
  287. {
  288. if ((*skb = dev_alloc_skb(2)) == NULL) {
  289.     
  290. printk(KERN_WARNING "capi_disc_resp: alloc_skb failedn");
  291. return -1;
  292. }
  293.         *((ushort*) skb_put(*skb, 2)) = chan->callref;  
  294.         return 2;
  295. }
  296. /*
  297.  *  Decoding of CAPI messages
  298.  *
  299.  */
  300. int capi_decode_conn_ind(struct pcbit_chan * chan, 
  301.                          struct sk_buff *skb,
  302.                          struct callb_data *info) 
  303. {
  304.         int CIlen, len;
  305.         /* Call Reference [CAPI] */
  306.         chan->callref = *((ushort*) skb->data);
  307.         skb_pull(skb, 2);
  308. #ifdef DEBUG
  309. printk(KERN_DEBUG "Call Reference: %04xn", chan->callref); 
  310. #endif
  311.         /* Channel Identification */
  312.         /* Expect  
  313.            Len = 1 
  314.            Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
  315.            */
  316.         CIlen = skb->data[0];
  317. #ifdef DEBUG
  318.         if (CIlen == 1) {
  319.                 if ( ((skb->data[1]) & 0xFC) == 0x48 )
  320.                         printk(KERN_DEBUG "decode_conn_ind: chan okn");
  321.                 printk(KERN_DEBUG "phyChan = %dn", skb->data[1] & 0x03); 
  322.         }
  323. else
  324. printk(KERN_DEBUG "conn_ind: CIlen = %dn", CIlen);
  325. #endif
  326.         skb_pull(skb, CIlen + 1);
  327.         /* Calling Party Number */
  328.         /* An "additional service" as far as Portugal Telecom is concerned */
  329.         len = skb->data[0];
  330. if (len > 0) {
  331. int count = 1;
  332. #ifdef DEBUG
  333. printk(KERN_DEBUG "CPN: Octect 3 %02xn", skb->data[1]);
  334. #endif
  335. if ((skb->data[1] & 0x80) == 0)
  336. count = 2;
  337. if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
  338. return -1;
  339.        
  340. memcpy(info->data.setup.CallingPN, skb->data + count + 1, 
  341.        len - count);
  342. info->data.setup.CallingPN[len - count] = 0;
  343. }
  344. else {
  345. info->data.setup.CallingPN = NULL;
  346. printk(KERN_DEBUG "NULL CallingPNn");
  347. }
  348. skb_pull(skb, len + 1);
  349.         /* Calling Party Subaddress */
  350.         skb_pull(skb, skb->data[0] + 1);
  351.         /* Called Party Number */
  352.         len = skb->data[0];
  353. if (len > 0) {
  354. int count = 1;
  355. if ((skb->data[1] & 0x80) == 0)
  356. count = 2;
  357.         
  358. if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
  359. return -1;
  360.         
  361. memcpy(info->data.setup.CalledPN, skb->data + count + 1, 
  362.        len - count); 
  363. info->data.setup.CalledPN[len - count] = 0;
  364. }
  365. else {
  366. info->data.setup.CalledPN = NULL;
  367. printk(KERN_DEBUG "NULL CalledPNn");
  368. }
  369. skb_pull(skb, len + 1);
  370.         /* Called Party Subaddress */
  371.         skb_pull(skb, skb->data[0] + 1);
  372.         /* LLC */
  373.         skb_pull(skb, skb->data[0] + 1);
  374.         /* HLC */
  375.         skb_pull(skb, skb->data[0] + 1);
  376.         /* U2U */
  377.         skb_pull(skb, skb->data[0] + 1);
  378.         return 0;
  379. }
  380. /*
  381.  *  returns errcode
  382.  */
  383. int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
  384.   int *complete) 
  385. {
  386.         int errcode;
  387.   
  388.         chan->callref = *((ushort *) skb->data);     /* Update CallReference */
  389.         skb_pull(skb, 2);
  390.         errcode = *((ushort *) skb->data);   /* read errcode */
  391.         skb_pull(skb, 2);
  392.         *complete = *(skb->data);
  393.         skb_pull(skb, 1);
  394.         /* FIX ME */
  395.         /* This is actually a firmware bug */
  396.         if (!*complete)
  397.         {
  398.                 printk(KERN_DEBUG "complete=%02xn", *complete);
  399.                 *complete = 1;
  400.         }
  401.         /* Optional Bearer Capability */
  402.         skb_pull(skb, *(skb->data) + 1);
  403.         
  404.         /* Channel Identification */
  405.         skb_pull(skb, *(skb->data) + 1);
  406.         /* High Layer Compatibility follows */
  407.         skb_pull(skb, *(skb->data) + 1);
  408.         return errcode;
  409. }
  410. int capi_decode_conn_actv_ind(struct pcbit_chan * chan, struct sk_buff *skb)
  411. {
  412.         ushort len;
  413. #ifdef DEBUG
  414.         char str[32];
  415. #endif
  416.         /* Yet Another Bearer Capability */
  417.         skb_pull(skb, *(skb->data) + 1);
  418.   
  419.         /* Connected Party Number */
  420.         len=*(skb->data);
  421. #ifdef DEBUG
  422. if (len > 1 && len < 31) {
  423. memcpy(str, skb->data + 2, len - 1);
  424. str[len] = 0;
  425. printk(KERN_DEBUG "Connected Party Number: %sn", str);
  426. }
  427. else
  428. printk(KERN_DEBUG "actv_ind CPN len = %dn", len);
  429. #endif
  430.         skb_pull(skb, len + 1);
  431.         /* Connected Subaddress */
  432.         skb_pull(skb, *(skb->data) + 1);
  433.         /* Low Layer Capability */
  434.         skb_pull(skb, *(skb->data) + 1);
  435.         /* High Layer Capability */
  436.         skb_pull(skb, *(skb->data) + 1);
  437.         return 0;
  438. }
  439. int capi_decode_conn_actv_conf(struct pcbit_chan * chan, struct sk_buff *skb)
  440. {
  441.         ushort errcode;
  442.         errcode = *((ushort*) skb->data);
  443.         skb_pull(skb, 2);
  444.         
  445.         /* Channel Identification 
  446.         skb_pull(skb, skb->data[0] + 1);
  447.         */
  448.         return errcode;
  449. }
  450. int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
  451. {
  452.         ushort errcode;
  453.         
  454.         chan->layer2link = *(skb->data);
  455.         skb_pull(skb, 1);
  456.         errcode = *((ushort*) skb->data);
  457.         skb_pull(skb, 2);
  458.         return errcode;
  459. }
  460. int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
  461. {
  462.         ushort errcode;
  463.         if (chan->layer2link != *(skb->data) )
  464.                 printk("capi_decode_actv_trans_conf: layer2link doesn't matchn");
  465.         skb_pull(skb, 1);
  466.         errcode = *((ushort*) skb->data);
  467.         skb_pull(skb, 2);
  468.         return errcode;        
  469. }
  470. int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
  471. {
  472.         ushort len;
  473. #ifdef DEBUG
  474.         int i;
  475. #endif
  476.         /* Cause */
  477.         
  478.         len = *(skb->data);
  479.         skb_pull(skb, 1);
  480. #ifdef DEBUG
  481.         for (i=0; i<len; i++)
  482.                 printk(KERN_DEBUG "Cause Octect %d: %02xn", i+3, 
  483.                        *(skb->data + i));
  484. #endif
  485.         skb_pull(skb, len);
  486.         return 0;
  487. }
  488. int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb)
  489. {
  490.         ushort errcode;
  491.         errcode = *((ushort*) skb->data);
  492.         skb_pull(skb, 2);
  493.         return errcode;                
  494. }
  495. #ifdef DEBUG
  496. int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
  497. {
  498.         char str[64];
  499.         int len;
  500.         
  501.         len = hdr[0];
  502.         if (len < 64 && len == hdrlen - 1) {        
  503.                 memcpy(str, hdr + 1, hdrlen - 1);
  504.                 str[hdrlen - 1] = 0;
  505.                 printk("%sn", str);
  506.         }
  507.         else
  508.                 printk("debug message incorrectn");
  509.         return 0;
  510. }
  511. #endif