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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*********************************************************************
  2.  *                
  3.  * Filename:      ircomm_ttp.c
  4.  * Version:       1.0
  5.  * Description:   Interface between IrCOMM and IrTTP
  6.  * Status:        Stable
  7.  * Author:        Dag Brattli <dagb@cs.uit.no>
  8.  * Created at:    Sun Jun  6 20:48:27 1999
  9.  * Modified at:   Mon Dec 13 11:35:13 1999
  10.  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  11.  * 
  12.  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
  13.  *     
  14.  *     This program is free software; you can redistribute it and/or 
  15.  *     modify it under the terms of the GNU General Public License as 
  16.  *     published by the Free Software Foundation; either version 2 of 
  17.  *     the License, or (at your option) any later version.
  18.  * 
  19.  *     This program is distributed in the hope that it will be useful,
  20.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22.  *     GNU General Public License for more details.
  23.  * 
  24.  *     You should have received a copy of the GNU General Public License 
  25.  *     along with this program; if not, write to the Free Software 
  26.  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
  27.  *     MA 02111-1307 USA
  28.  *     
  29.  ********************************************************************/
  30. #include <linux/sched.h>
  31. #include <linux/init.h>
  32. #include <net/irda/irda.h>
  33. #include <net/irda/irlmp.h>
  34. #include <net/irda/iriap.h>
  35. #include <net/irda/irttp.h>
  36. #include <net/irda/ircomm_event.h>
  37. #include <net/irda/ircomm_ttp.h>
  38. /*
  39.  * Function ircomm_open_tsap (self)
  40.  *
  41.  *    
  42.  *
  43.  */
  44. int ircomm_open_tsap(struct ircomm_cb *self)
  45. {
  46. notify_t notify;
  47. IRDA_DEBUG(4, __FUNCTION__ "()n");
  48. /* Register callbacks */
  49. irda_notify_init(&notify);
  50. notify.data_indication       = ircomm_ttp_data_indication;
  51. notify.connect_confirm       = ircomm_ttp_connect_confirm;
  52. notify.connect_indication    = ircomm_ttp_connect_indication;
  53. notify.flow_indication       = ircomm_ttp_flow_indication;
  54. notify.disconnect_indication = ircomm_ttp_disconnect_indication;
  55. notify.instance = self;
  56. strncpy(notify.name, "IrCOMM", NOTIFY_MAX_NAME);
  57. self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
  58.      &notify);
  59. if (!self->tsap) {
  60. IRDA_DEBUG(0, __FUNCTION__"failed to allocate tsapn");
  61. return -1;
  62. }
  63. self->slsap_sel = self->tsap->stsap_sel;
  64. /*
  65.  *  Initialize the call-table for issuing commands
  66.  */
  67. self->issue.data_request       = ircomm_ttp_data_request;
  68. self->issue.connect_request    = ircomm_ttp_connect_request;
  69. self->issue.connect_response   = ircomm_ttp_connect_response;
  70. self->issue.disconnect_request = ircomm_ttp_disconnect_request;
  71. return 0;
  72. }
  73. /*
  74.  * Function ircomm_ttp_connect_request (self, userdata)
  75.  *
  76.  *    
  77.  *
  78.  */
  79. int ircomm_ttp_connect_request(struct ircomm_cb *self, 
  80.        struct sk_buff *userdata, 
  81.        struct ircomm_info *info)
  82. {
  83. int ret = 0;
  84. IRDA_DEBUG(4, __FUNCTION__ "()n");
  85. ret = irttp_connect_request(self->tsap, info->dlsap_sel,
  86.     info->saddr, info->daddr, NULL, 
  87.     TTP_SAR_DISABLE, userdata); 
  88. return ret;
  89. }
  90. /*
  91.  * Function ircomm_ttp_connect_response (self, skb)
  92.  *
  93.  *    
  94.  *
  95.  */
  96. int ircomm_ttp_connect_response(struct ircomm_cb *self, struct sk_buff *skb)
  97. {
  98. int ret;
  99. IRDA_DEBUG(4, __FUNCTION__"()n");
  100. ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, skb);
  101. return ret;
  102. }
  103. /*
  104.  * Function ircomm_ttp_data_request (self, userdata)
  105.  *
  106.  *    Send IrCOMM data to IrTTP layer. Currently we do not try to combine 
  107.  *    control data with pure data, so they will be sent as separate frames. 
  108.  *    Should not be a big problem though, since control frames are rare. But
  109.  *    some of them are sent after connection establishment, so this can 
  110.  *    increase the latency a bit.
  111.  */
  112. int ircomm_ttp_data_request(struct ircomm_cb *self, struct sk_buff *skb, 
  113.     int clen)
  114. {
  115. int ret;
  116. ASSERT(skb != NULL, return -1;);
  117. IRDA_DEBUG(2, __FUNCTION__"(), clen=%dn", clen);
  118. /* 
  119.  * Insert clen field, currently we either send data only, or control
  120.  * only frames, to make things easier and avoid queueing
  121.  */
  122. ASSERT(skb_headroom(skb) >= IRCOMM_HEADER_SIZE, return -1;);
  123. skb_push(skb, IRCOMM_HEADER_SIZE);
  124. skb->data[0] = clen;
  125. ret = irttp_data_request(self->tsap, skb);
  126. if (ret) {
  127. ERROR(__FUNCTION__ "(), failedn");
  128. dev_kfree_skb(skb);
  129. }
  130. return ret;
  131. }
  132. /*
  133.  * Function ircomm_ttp_data_indication (instance, sap, skb)
  134.  *
  135.  *    Incoming data
  136.  *
  137.  */
  138. int ircomm_ttp_data_indication(void *instance, void *sap,
  139.        struct sk_buff *skb)
  140. {
  141. struct ircomm_cb *self = (struct ircomm_cb *) instance;
  142. IRDA_DEBUG(4, __FUNCTION__"()n");
  143. ASSERT(self != NULL, return -1;);
  144. ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
  145. ASSERT(skb != NULL, return -1;);
  146. ircomm_do_event(self, IRCOMM_TTP_DATA_INDICATION, skb, NULL);
  147. return 0;
  148. }
  149. void ircomm_ttp_connect_confirm(void *instance, void *sap,
  150. struct qos_info *qos, 
  151. __u32 max_sdu_size, 
  152. __u8 max_header_size,
  153. struct sk_buff *skb)
  154. {
  155. struct ircomm_cb *self = (struct ircomm_cb *) instance;
  156. struct ircomm_info info;
  157. IRDA_DEBUG(4, __FUNCTION__"()n");
  158. ASSERT(self != NULL, return;);
  159. ASSERT(self->magic == IRCOMM_MAGIC, return;);
  160. ASSERT(skb != NULL, return;);
  161. ASSERT(qos != NULL, return;);
  162. if (max_sdu_size != TTP_SAR_DISABLE) {
  163. ERROR(__FUNCTION__ "(), SAR not allowed for IrCOMM!n");
  164. dev_kfree_skb(skb);
  165. return;
  166. }
  167. info.max_data_size = irttp_get_max_seg_size(self->tsap)
  168. - IRCOMM_HEADER_SIZE;
  169. info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
  170. info.qos = qos;
  171. ircomm_do_event(self, IRCOMM_TTP_CONNECT_CONFIRM, skb, &info);
  172. }
  173. /*
  174.  * Function ircomm_ttp_connect_indication (instance, sap, qos, max_sdu_size,
  175.  *                                         max_header_size, skb)
  176.  *
  177.  *    
  178.  *
  179.  */
  180. void ircomm_ttp_connect_indication(void *instance, void *sap,
  181.    struct qos_info *qos,
  182.    __u32 max_sdu_size,
  183.    __u8 max_header_size,
  184.    struct sk_buff *skb)
  185. {
  186. struct ircomm_cb *self = (struct ircomm_cb *)instance;
  187. struct ircomm_info info;
  188. IRDA_DEBUG(4, __FUNCTION__"()n");
  189. ASSERT(self != NULL, return;);
  190. ASSERT(self->magic == IRCOMM_MAGIC, return;);
  191. ASSERT(skb != NULL, return;);
  192. ASSERT(qos != NULL, return;);
  193. if (max_sdu_size != TTP_SAR_DISABLE) {
  194. ERROR(__FUNCTION__ "(), SAR not allowed for IrCOMM!n");
  195. dev_kfree_skb(skb);
  196. return;
  197. }
  198. info.max_data_size = irttp_get_max_seg_size(self->tsap)
  199. - IRCOMM_HEADER_SIZE;
  200. info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
  201. info.qos = qos;
  202. ircomm_do_event(self, IRCOMM_TTP_CONNECT_INDICATION, skb, &info);
  203. }
  204. /*
  205.  * Function ircomm_ttp_disconnect_request (self, userdata, info)
  206.  *
  207.  *    
  208.  *
  209.  */
  210. int ircomm_ttp_disconnect_request(struct ircomm_cb *self, 
  211.   struct sk_buff *userdata, 
  212.   struct ircomm_info *info)
  213. {
  214. int ret;
  215. ret = irttp_disconnect_request(self->tsap, userdata, P_NORMAL);
  216. return ret;
  217. }
  218. /*
  219.  * Function ircomm_ttp_disconnect_indication (instance, sap, reason, skb)
  220.  *
  221.  *    
  222.  *
  223.  */
  224. void ircomm_ttp_disconnect_indication(void *instance, void *sap, 
  225.       LM_REASON reason,
  226.       struct sk_buff *skb)
  227. {
  228. struct ircomm_cb *self = (struct ircomm_cb *) instance;
  229. struct ircomm_info info;
  230. IRDA_DEBUG(2, __FUNCTION__"()n");
  231. ASSERT(self != NULL, return;);
  232. ASSERT(self->magic == IRCOMM_MAGIC, return;);
  233. info.reason = reason;
  234. ircomm_do_event(self, IRCOMM_TTP_DISCONNECT_INDICATION, skb, &info);
  235. }
  236. /*
  237.  * Function ircomm_ttp_flow_indication (instance, sap, cmd)
  238.  *
  239.  *    Layer below is telling us to start or stop the flow of data
  240.  *
  241.  */
  242. void ircomm_ttp_flow_indication(void *instance, void *sap, LOCAL_FLOW cmd)
  243. {
  244. struct ircomm_cb *self = (struct ircomm_cb *) instance;
  245. IRDA_DEBUG(4, __FUNCTION__ "()n");
  246. ASSERT(self != NULL, return;);
  247. ASSERT(self->magic == IRCOMM_MAGIC, return;);
  248. if (self->notify.flow_indication)
  249. self->notify.flow_indication(self->notify.instance, self, cmd);
  250. }