callbacks.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. * Incoming call received
  99. * inform user
  100. */
  101. void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
  102. struct callb_data *cbdata)
  103. {
  104. isdn_ctrl ictl;
  105. unsigned short refnum;
  106. struct sk_buff *skb;
  107. int len;
  108. ictl.command = ISDN_STAT_ICALL;
  109. ictl.driver=dev->id;
  110. ictl.arg=chan->id;
  111. /*
  112. * ictl.num >= strlen() + strlen() + 5
  113. */
  114. if (cbdata->data.setup.CallingPN == NULL) {
  115. printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
  116. strcpy(ictl.parm.setup.phone, "0");
  117. }
  118. else {
  119. strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
  120. }
  121. if (cbdata->data.setup.CalledPN == NULL) {
  122. printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
  123. strcpy(ictl.parm.setup.eazmsn, "0");
  124. }
  125. else {
  126. strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
  127. }
  128. ictl.parm.setup.si1 = 7;
  129. ictl.parm.setup.si2 = 0;
  130. ictl.parm.setup.plan = 0;
  131. ictl.parm.setup.screen = 0;
  132. #ifdef DEBUG
  133. printk(KERN_DEBUG "statstr: %s\n", ictl.num);
  134. #endif
  135. dev->dev_if->statcallb(&ictl);
  136. if ((len=capi_conn_resp(chan, &skb)) < 0) {
  137. printk(KERN_DEBUG "capi_conn_resp failed\n");
  138. return;
  139. }
  140. refnum = last_ref_num++ & 0x7fffU;
  141. chan->s_refnum = refnum;
  142. pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
  143. }
  144. /*
  145. * user has replied
  146. * open the channel
  147. * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
  148. */
  149. void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  150. struct callb_data *data)
  151. {
  152. unsigned short refnum;
  153. struct sk_buff *skb;
  154. int len;
  155. if ((len = capi_conn_active_req(chan, &skb)) < 0) {
  156. printk(KERN_DEBUG "capi_conn_active_req failed\n");
  157. return;
  158. }
  159. refnum = last_ref_num++ & 0x7fffU;
  160. chan->s_refnum = refnum;
  161. printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
  162. pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
  163. }
  164. /*
  165. * CONN_ACK arrived
  166. * start b-proto selection
  167. *
  168. */
  169. void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
  170. struct callb_data *data)
  171. {
  172. unsigned short refnum;
  173. struct sk_buff *skb;
  174. int len;
  175. if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
  176. {
  177. printk("capi_select_proto_req failed\n");
  178. return;
  179. }
  180. refnum = last_ref_num++ & 0x7fffU;
  181. chan->s_refnum = refnum;
  182. pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
  183. }
  184. /*
  185. * Received disconnect ind on active state
  186. * send disconnect resp
  187. * send msg to user
  188. */
  189. void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
  190. struct callb_data *data)
  191. {
  192. struct sk_buff *skb;
  193. int len;
  194. ushort refnum;
  195. isdn_ctrl ictl;
  196. if ((len = capi_disc_resp(chan, &skb)) < 0) {
  197. printk("capi_disc_resp failed\n");
  198. return;
  199. }
  200. refnum = last_ref_num++ & 0x7fffU;
  201. chan->s_refnum = refnum;
  202. pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
  203. ictl.command = ISDN_STAT_BHUP;
  204. ictl.driver=dev->id;
  205. ictl.arg=chan->id;
  206. dev->dev_if->statcallb(&ictl);
  207. }
  208. /*
  209. * User HANGUP on active/call proceeding state
  210. * send disc.req
  211. */
  212. void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  213. struct callb_data *data)
  214. {
  215. struct sk_buff *skb;
  216. int len;
  217. ushort refnum;
  218. if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
  219. {
  220. printk("capi_disc_req failed\n");
  221. return;
  222. }
  223. refnum = last_ref_num++ & 0x7fffU;
  224. chan->s_refnum = refnum;
  225. pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
  226. }
  227. /*
  228. * Disc confirm received send BHUP
  229. * Problem: when the HL driver sends the disc req itself
  230. * LL receives BHUP
  231. */
  232. void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
  233. struct callb_data *data)
  234. {
  235. isdn_ctrl ictl;
  236. ictl.command = ISDN_STAT_BHUP;
  237. ictl.driver=dev->id;
  238. ictl.arg=chan->id;
  239. dev->dev_if->statcallb(&ictl);
  240. }
  241. void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan,
  242. struct callb_data *data)
  243. {
  244. }
  245. /*
  246. * send activate b-chan protocol
  247. */
  248. void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
  249. struct callb_data *data)
  250. {
  251. struct sk_buff *skb;
  252. int len;
  253. ushort refnum;
  254. if ((len = capi_activate_transp_req(chan, &skb)) < 0)
  255. {
  256. printk("capi_conn_activate_transp_req failed\n");
  257. return;
  258. }
  259. refnum = last_ref_num++ & 0x7fffU;
  260. chan->s_refnum = refnum;
  261. pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
  262. }
  263. /*
  264. * Inform User that the B-channel is available
  265. */
  266. void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan,
  267. struct callb_data *data)
  268. {
  269. isdn_ctrl ictl;
  270. ictl.command = ISDN_STAT_BCONN;
  271. ictl.driver=dev->id;
  272. ictl.arg=chan->id;
  273. dev->dev_if->statcallb(&ictl);
  274. }