callbacks.c 8.1 KB

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