callbacks.c 7.7 KB

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