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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Callbacks for the FSM
  3.  *
  4.  * Copyright (C) 1996 Universidade de Lisboa
  5.  * 
  6.  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  7.  *
  8.  * This software may be used and distributed according to the terms of 
  9.  * the GNU General Public License, incorporated herein by reference.
  10.  */
  11. /*
  12.  * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
  13.  * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN 
  14.  * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
  15.  */
  16. #include <linux/sched.h>
  17. #include <linux/string.h>
  18. #include <linux/kernel.h>
  19. #include <linux/types.h>
  20. #include <linux/slab.h>
  21. #include <linux/mm.h>
  22. #include <linux/tqueue.h>
  23. #include <linux/skbuff.h>
  24. #include <asm/io.h>
  25. #include <linux/isdnif.h>
  26. #include "pcbit.h"
  27. #include "layer2.h"
  28. #include "edss1.h"
  29. #include "callbacks.h"
  30. #include "capi.h"
  31. ushort last_ref_num = 1;
  32. /*
  33.  *  send_conn_req
  34.  *
  35.  */
  36. void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  37.       struct callb_data *cbdata) 
  38. {
  39. struct sk_buff *skb;
  40. int len;
  41.         ushort refnum;
  42. #ifdef DEBUG
  43.         printk(KERN_DEBUG "Called Party Number: %sn", 
  44.                cbdata->data.setup.CalledPN);
  45. #endif
  46.         /*
  47.          * hdr - kmalloc in capi_conn_req
  48.          *     - kfree   when msg has been sent
  49.          */
  50.         if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb, 
  51.  chan->proto)) < 0)
  52.         {
  53.                 printk("capi_conn_req failedn");
  54.                 return;
  55.         }
  56.         refnum = last_ref_num++ & 0x7fffU;
  57.         chan->callref = 0;
  58.         chan->layer2link = 0;
  59.         chan->snum = 0;
  60.         chan->s_refnum = refnum;
  61.         pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
  62. }
  63. /*
  64.  *  rcv CONNECT
  65.  *  will go into ACTIVE state
  66.  *  send CONN_ACTIVE_RESP
  67.  *  send Select protocol request 
  68.  */
  69. void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  70.       struct callb_data *data) 
  71. {
  72.         isdn_ctrl ictl;
  73.   struct sk_buff *skb;
  74. int len;
  75.         ushort refnum;
  76.         if ((len=capi_conn_active_resp(chan, &skb)) < 0)
  77.         {
  78.                 printk("capi_conn_active_req failedn");
  79.                 return;
  80.         }
  81.         refnum = last_ref_num++ & 0x7fffU;
  82.         chan->s_refnum = refnum;
  83.         pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
  84.         ictl.command = ISDN_STAT_DCONN;
  85.         ictl.driver=dev->id;
  86.         ictl.arg=chan->id;
  87.         dev->dev_if->statcallb(&ictl);
  88.         /* ACTIVE D-channel */
  89.         /* Select protocol  */
  90.         if ((len=capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) { 
  91.                 printk("capi_select_proto_req failedn");
  92.                 return;
  93.         }
  94.         refnum = last_ref_num++ & 0x7fffU;
  95.         chan->s_refnum = refnum;
  96.         pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
  97. }
  98. /*
  99.  * Disconnect received (actually RELEASE COMPLETE) 
  100.  * This means we were not able to establish connection with remote
  101.  * Inform the big boss above
  102.  */
  103. void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
  104.       struct callb_data *data) 
  105. {
  106.         isdn_ctrl ictl;
  107.         ictl.command = ISDN_STAT_DHUP;
  108.         ictl.driver=dev->id;
  109.         ictl.arg=chan->id;
  110.         dev->dev_if->statcallb(&ictl);
  111. }
  112. /*
  113.  * Incoming call received
  114.  * inform user
  115.  */
  116. void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
  117.      struct callb_data *cbdata) 
  118. {
  119.         isdn_ctrl ictl;
  120.         unsigned short refnum;
  121.   struct sk_buff *skb;
  122. int len;
  123.         ictl.command = ISDN_STAT_ICALL;
  124.         ictl.driver=dev->id;
  125.         ictl.arg=chan->id;
  126.         
  127.         /*
  128.          *  ictl.num >= strlen() + strlen() + 5
  129.          */
  130. if (cbdata->data.setup.CallingPN == NULL) {
  131. printk(KERN_DEBUG "NULL CallingPN to phone; using 0n");
  132. strcpy(ictl.parm.setup.phone, "0");
  133. }
  134. else {
  135. strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
  136. }
  137. if (cbdata->data.setup.CalledPN == NULL) {
  138. printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0n");
  139. strcpy(ictl.parm.setup.eazmsn, "0");
  140. }
  141. else {
  142. strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
  143. }
  144. ictl.parm.setup.si1 = 7;
  145. ictl.parm.setup.si2 = 0;
  146. ictl.parm.setup.plan = 0;
  147. ictl.parm.setup.screen = 0;
  148. #ifdef DEBUG
  149. printk(KERN_DEBUG "statstr: %sn", ictl.num);
  150. #endif
  151.         dev->dev_if->statcallb(&ictl);
  152.         
  153.         if ((len=capi_conn_resp(chan, &skb)) < 0) {
  154.                 printk(KERN_DEBUG "capi_conn_resp failedn");
  155.                 return;
  156. }
  157.         refnum = last_ref_num++ & 0x7fffU;
  158.         chan->s_refnum = refnum;
  159.         pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
  160. }
  161. /*
  162.  * user has replied
  163.  * open the channel
  164.  * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
  165.  */
  166. void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  167.      struct callb_data *data)
  168. {
  169.         unsigned short refnum;
  170. struct sk_buff *skb;
  171.         int len;
  172.         
  173.         if ((len = capi_conn_active_req(chan, &skb)) < 0) {        
  174.                 printk(KERN_DEBUG "capi_conn_active_req failedn");
  175.                 return;
  176.         }
  177.         refnum = last_ref_num++ & 0x7fffU;
  178.         chan->s_refnum = refnum;
  179. printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQn");
  180.         pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
  181. }
  182. /*
  183.  * CONN_ACK arrived
  184.  * start b-proto selection
  185.  *
  186.  */
  187. void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  188.      struct callb_data *data)
  189. {
  190.         unsigned short refnum;
  191.   struct sk_buff *skb;
  192. int len;
  193.         
  194.         if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
  195.         {
  196.                 printk("capi_select_proto_req failedn");
  197.                 return;
  198.         }
  199.         refnum = last_ref_num++ & 0x7fffU;
  200.         chan->s_refnum = refnum;
  201.         pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
  202. }
  203. /*
  204.  * Received disconnect ind on active state
  205.  * send disconnect resp
  206.  * send msg to user
  207.  */
  208. void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  209.        struct callb_data *data)
  210. {
  211.   struct sk_buff *skb;
  212. int len;
  213.         ushort refnum;
  214.         isdn_ctrl ictl;
  215.   
  216.         if ((len = capi_disc_resp(chan, &skb)) < 0) {
  217.                 printk("capi_disc_resp failedn");
  218.                 return;
  219.         }
  220.         refnum = last_ref_num++ & 0x7fffU;
  221.         chan->s_refnum = refnum;
  222.         pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);    
  223.         ictl.command = ISDN_STAT_BHUP;
  224.         ictl.driver=dev->id;
  225.         ictl.arg=chan->id;
  226.         dev->dev_if->statcallb(&ictl);
  227. }
  228.         
  229. /*
  230.  *  User HANGUP on active/call proceeding state
  231.  *  send disc.req
  232.  */
  233. void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  234.        struct callb_data *data)
  235. {
  236.   struct sk_buff *skb;
  237. int len;
  238.         ushort refnum;
  239.         if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
  240.         {
  241.                 printk("capi_disc_req failedn");
  242.                 return;
  243.         }
  244.         refnum = last_ref_num++ & 0x7fffU;
  245.         chan->s_refnum = refnum;
  246.         pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);  
  247. }
  248. /*
  249.  *  Disc confirm received send BHUP
  250.  *  Problem: when the HL driver sends the disc req itself
  251.  *           LL receives BHUP
  252.  */
  253. void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  254.        struct callb_data *data)
  255. {
  256.         isdn_ctrl ictl;
  257.         ictl.command = ISDN_STAT_BHUP;
  258.         ictl.driver=dev->id;
  259.         ictl.arg=chan->id;
  260.         dev->dev_if->statcallb(&ictl);
  261. }
  262. void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  263. struct callb_data *data)
  264. {
  265. }
  266. /*
  267.  * send activate b-chan protocol
  268.  */
  269. void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  270.        struct callb_data *data) 
  271. {
  272.   struct sk_buff *skb;
  273. int len;
  274.         ushort refnum;
  275.         if ((len = capi_activate_transp_req(chan, &skb)) < 0)
  276.         {
  277.                 printk("capi_conn_activate_transp_req failedn");
  278.                 return;
  279.         }
  280.         refnum = last_ref_num++ & 0x7fffU;
  281.         chan->s_refnum = refnum;
  282.         pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
  283. }
  284. /*
  285.  *  Inform User that the B-channel is available
  286.  */
  287. void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan, 
  288.      struct callb_data *data) 
  289. {
  290.         isdn_ctrl ictl;
  291.         ictl.command = ISDN_STAT_BCONN;
  292.         ictl.driver=dev->id;
  293.         ictl.arg=chan->id;
  294.         dev->dev_if->statcallb(&ictl);
  295. }