callbacks.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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/string.h>
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <linux/mm.h>
  20. #include <linux/skbuff.h>
  21. #include <asm/io.h>
  22. #include <linux/isdnif.h>
  23. #include "pcbit.h"
  24. #include "layer2.h"
  25. #include "edss1.h"
  26. #include "callbacks.h"
  27. #include "capi.h"
  28. ushort last_ref_num = 1;
  29. /*
  30. * send_conn_req
  31. *
  32. */
  33. void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
  34. struct callb_data *cbdata)
  35. {
  36. struct sk_buff *skb;
  37. int len;
  38. ushort refnum;
  39. #ifdef DEBUG
  40. printk(KERN_DEBUG "Called Party Number: %s\n",
  41. cbdata->data.setup.CalledPN);
  42. #endif
  43. /*
  44. * hdr - kmalloc in capi_conn_req
  45. * - kfree when msg has been sent
  46. */
  47. if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
  48. chan->proto)) < 0)
  49. {
  50. printk("capi_conn_req failed\n");
  51. return;
  52. }
  53. refnum = last_ref_num++ & 0x7fffU;
  54. chan->callref = 0;
  55. chan->layer2link = 0;
  56. chan->snum = 0;
  57. chan->s_refnum = refnum;
  58. pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
  59. }
  60. /*
  61. * rcv CONNECT
  62. * will go into ACTIVE state
  63. * send CONN_ACTIVE_RESP
  64. * send Select protocol request
  65. */
  66. void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
  67. struct callb_data *data)
  68. {
  69. isdn_ctrl ictl;
  70. struct sk_buff *skb;
  71. int len;
  72. ushort refnum;
  73. if ((len = capi_conn_active_resp(chan, &skb)) < 0)
  74. {
  75. printk("capi_conn_active_req failed\n");
  76. return;
  77. }
  78. refnum = last_ref_num++ & 0x7fffU;
  79. chan->s_refnum = refnum;
  80. pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
  81. ictl.command = ISDN_STAT_DCONN;
  82. ictl.driver = dev->id;
  83. ictl.arg = chan->id;
  84. dev->dev_if->statcallb(&ictl);
  85. /* ACTIVE D-channel */
  86. /* Select protocol */
  87. if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
  88. printk("capi_select_proto_req failed\n");
  89. return;
  90. }
  91. refnum = last_ref_num++ & 0x7fffU;
  92. chan->s_refnum = refnum;
  93. pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
  94. }
  95. /*
  96. * Incoming call received
  97. * inform user
  98. */
  99. void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
  100. struct callb_data *cbdata)
  101. {
  102. isdn_ctrl ictl;
  103. unsigned short refnum;
  104. struct sk_buff *skb;
  105. int len;
  106. ictl.command = ISDN_STAT_ICALL;
  107. ictl.driver = dev->id;
  108. ictl.arg = chan->id;
  109. /*
  110. * ictl.num >= strlen() + strlen() + 5
  111. */
  112. if (cbdata->data.setup.CallingPN == NULL) {
  113. printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
  114. strcpy(ictl.parm.setup.phone, "0");
  115. }
  116. else {
  117. strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
  118. }
  119. if (cbdata->data.setup.CalledPN == NULL) {
  120. printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
  121. strcpy(ictl.parm.setup.eazmsn, "0");
  122. }
  123. else {
  124. strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
  125. }
  126. ictl.parm.setup.si1 = 7;
  127. ictl.parm.setup.si2 = 0;
  128. ictl.parm.setup.plan = 0;
  129. ictl.parm.setup.screen = 0;
  130. #ifdef DEBUG
  131. printk(KERN_DEBUG "statstr: %s\n", ictl.num);
  132. #endif
  133. dev->dev_if->statcallb(&ictl);
  134. if ((len = capi_conn_resp(chan, &skb)) < 0) {
  135. printk(KERN_DEBUG "capi_conn_resp failed\n");
  136. return;
  137. }
  138. refnum = last_ref_num++ & 0x7fffU;
  139. chan->s_refnum = refnum;
  140. pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
  141. }
  142. /*
  143. * user has replied
  144. * open the channel
  145. * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
  146. */
  147. void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
  148. struct callb_data *data)
  149. {
  150. unsigned short refnum;
  151. struct sk_buff *skb;
  152. int len;
  153. if ((len = capi_conn_active_req(chan, &skb)) < 0) {
  154. printk(KERN_DEBUG "capi_conn_active_req failed\n");
  155. return;
  156. }
  157. refnum = last_ref_num++ & 0x7fffU;
  158. chan->s_refnum = refnum;
  159. printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
  160. pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
  161. }
  162. /*
  163. * CONN_ACK arrived
  164. * start b-proto selection
  165. *
  166. */
  167. void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
  168. struct callb_data *data)
  169. {
  170. unsigned short refnum;
  171. struct sk_buff *skb;
  172. int len;
  173. if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
  174. {
  175. printk("capi_select_proto_req failed\n");
  176. return;
  177. }
  178. refnum = last_ref_num++ & 0x7fffU;
  179. chan->s_refnum = refnum;
  180. pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
  181. }
  182. /*
  183. * Received disconnect ind on active state
  184. * send disconnect resp
  185. * send msg to user
  186. */
  187. void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
  188. struct callb_data *data)
  189. {
  190. struct sk_buff *skb;
  191. int len;
  192. ushort refnum;
  193. isdn_ctrl ictl;
  194. if ((len = capi_disc_resp(chan, &skb)) < 0) {
  195. printk("capi_disc_resp failed\n");
  196. return;
  197. }
  198. refnum = last_ref_num++ & 0x7fffU;
  199. chan->s_refnum = refnum;
  200. pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
  201. ictl.command = ISDN_STAT_BHUP;
  202. ictl.driver = dev->id;
  203. ictl.arg = chan->id;
  204. dev->dev_if->statcallb(&ictl);
  205. }
  206. /*
  207. * User HANGUP on active/call proceeding state
  208. * send disc.req
  209. */
  210. void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
  211. struct callb_data *data)
  212. {
  213. struct sk_buff *skb;
  214. int len;
  215. ushort refnum;
  216. if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
  217. {
  218. printk("capi_disc_req failed\n");
  219. return;
  220. }
  221. refnum = last_ref_num++ & 0x7fffU;
  222. chan->s_refnum = refnum;
  223. pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
  224. }
  225. /*
  226. * Disc confirm received send BHUP
  227. * Problem: when the HL driver sends the disc req itself
  228. * LL receives BHUP
  229. */
  230. void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
  231. struct callb_data *data)
  232. {
  233. isdn_ctrl ictl;
  234. ictl.command = ISDN_STAT_BHUP;
  235. ictl.driver = dev->id;
  236. ictl.arg = chan->id;
  237. dev->dev_if->statcallb(&ictl);
  238. }
  239. void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
  240. struct callb_data *data)
  241. {
  242. }
  243. /*
  244. * send activate b-chan protocol
  245. */
  246. void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
  247. struct callb_data *data)
  248. {
  249. struct sk_buff *skb;
  250. int len;
  251. ushort refnum;
  252. if ((len = capi_activate_transp_req(chan, &skb)) < 0)
  253. {
  254. printk("capi_conn_activate_transp_req failed\n");
  255. return;
  256. }
  257. refnum = last_ref_num++ & 0x7fffU;
  258. chan->s_refnum = refnum;
  259. pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
  260. }
  261. /*
  262. * Inform User that the B-channel is available
  263. */
  264. void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
  265. struct callb_data *data)
  266. {
  267. isdn_ctrl ictl;
  268. ictl.command = ISDN_STAT_BCONN;
  269. ictl.driver = dev->id;
  270. ictl.arg = chan->id;
  271. dev->dev_if->statcallb(&ictl);
  272. }