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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*********************************************************************
  2.  *                
  3.  * Filename:      ircomm_event.c
  4.  * Version:       1.0
  5.  * Description:   IrCOMM layer state machine
  6.  * Status:        Stable
  7.  * Author:        Dag Brattli <dagb@cs.uit.no>
  8.  * Created at:    Sun Jun  6 20:33:11 1999
  9.  * Modified at:   Sun Dec 12 13:44:32 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/proc_fs.h>
  32. #include <linux/init.h>
  33. #include <net/irda/irda.h>
  34. #include <net/irda/irlmp.h>
  35. #include <net/irda/iriap.h>
  36. #include <net/irda/irttp.h>
  37. #include <net/irda/irias_object.h>
  38. #include <net/irda/ircomm_core.h>
  39. #include <net/irda/ircomm_event.h>
  40. static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, 
  41.      struct sk_buff *skb, struct ircomm_info *info);
  42. static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, 
  43.       struct sk_buff *skb, struct ircomm_info *info);
  44. static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, 
  45.       struct sk_buff *skb, struct ircomm_info *info);
  46. static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, 
  47.      struct sk_buff *skb, struct ircomm_info *info);
  48. char *ircomm_state[] = {
  49. "IRCOMM_IDLE",
  50. "IRCOMM_WAITI",
  51. "IRCOMM_WAITR",
  52. "IRCOMM_CONN",
  53. };
  54. char *ircomm_event[] = {
  55. "IRCOMM_CONNECT_REQUEST",
  56.         "IRCOMM_CONNECT_RESPONSE",
  57.         "IRCOMM_TTP_CONNECT_INDICATION",
  58. "IRCOMM_LMP_CONNECT_INDICATION",
  59.         "IRCOMM_TTP_CONNECT_CONFIRM",
  60. "IRCOMM_LMP_CONNECT_CONFIRM",
  61.         "IRCOMM_LMP_DISCONNECT_INDICATION",
  62. "IRCOMM_TTP_DISCONNECT_INDICATION",
  63.         "IRCOMM_DISCONNECT_REQUEST",
  64.         "IRCOMM_TTP_DATA_INDICATION",
  65. "IRCOMM_LMP_DATA_INDICATION",
  66.         "IRCOMM_DATA_REQUEST",
  67.         "IRCOMM_CONTROL_REQUEST",
  68.         "IRCOMM_CONTROL_INDICATION",
  69. };
  70. static int (*state[])(struct ircomm_cb *self, IRCOMM_EVENT event,
  71.       struct sk_buff *skb, struct ircomm_info *info) = 
  72. {
  73. ircomm_state_idle,
  74. ircomm_state_waiti,
  75. ircomm_state_waitr,
  76. ircomm_state_conn,
  77. };
  78. /*
  79.  * Function ircomm_state_idle (self, event, skb)
  80.  *
  81.  *    IrCOMM is currently idle
  82.  *
  83.  */
  84. static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event, 
  85.      struct sk_buff *skb, struct ircomm_info *info)
  86. {
  87. int ret = 0;
  88. switch (event) {
  89. case IRCOMM_CONNECT_REQUEST:
  90. ircomm_next_state(self, IRCOMM_WAITI);
  91. ret = self->issue.connect_request(self, skb, info);
  92. break;
  93. case IRCOMM_TTP_CONNECT_INDICATION:
  94. case IRCOMM_LMP_CONNECT_INDICATION:
  95. ircomm_next_state(self, IRCOMM_WAITR);
  96. ircomm_connect_indication(self, skb, info);
  97. break;
  98. default:
  99. IRDA_DEBUG(4, __FUNCTION__"(), unknown event: %sn",
  100.    ircomm_event[event]);
  101. if (skb)
  102. dev_kfree_skb(skb);
  103. return -EINVAL;
  104. }
  105. return ret;
  106. }
  107. /*
  108.  * Function ircomm_state_waiti (self, event, skb)
  109.  *
  110.  *    The IrCOMM user has requested an IrCOMM connection to the remote 
  111.  *    device and is awaiting confirmation
  112.  */
  113. static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event, 
  114.       struct sk_buff *skb, struct ircomm_info *info)
  115. {
  116. int ret = 0;
  117. switch (event) {
  118. case IRCOMM_TTP_CONNECT_CONFIRM:
  119. case IRCOMM_LMP_CONNECT_CONFIRM:
  120. ircomm_next_state(self, IRCOMM_CONN);
  121. ircomm_connect_confirm(self, skb, info);
  122. break;
  123. case IRCOMM_TTP_DISCONNECT_INDICATION:
  124. case IRCOMM_LMP_DISCONNECT_INDICATION:
  125. ircomm_next_state(self, IRCOMM_IDLE);
  126. ircomm_disconnect_indication(self, skb, info);
  127. break;
  128. default:
  129. IRDA_DEBUG(0, __FUNCTION__"(), unknown event: %sn",
  130.    ircomm_event[event]);
  131. if (skb)
  132. dev_kfree_skb(skb);
  133. ret = -EINVAL;
  134. }
  135. return ret;
  136. }
  137. /*
  138.  * Function ircomm_state_waitr (self, event, skb)
  139.  *
  140.  *    IrCOMM has received an incoming connection request and is awaiting
  141.  *    response from the user
  142.  */
  143. static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event, 
  144.       struct sk_buff *skb, struct ircomm_info *info) 
  145. {
  146. int ret = 0;
  147. switch (event) {
  148. case IRCOMM_CONNECT_RESPONSE:
  149. ircomm_next_state(self, IRCOMM_CONN);
  150. ret = self->issue.connect_response(self, skb);
  151. break;
  152. case IRCOMM_DISCONNECT_REQUEST:
  153. ircomm_next_state(self, IRCOMM_IDLE);
  154. ret = self->issue.disconnect_request(self, skb, info);
  155. break;
  156. case IRCOMM_TTP_DISCONNECT_INDICATION:
  157. case IRCOMM_LMP_DISCONNECT_INDICATION:
  158. ircomm_next_state(self, IRCOMM_IDLE);
  159. ircomm_disconnect_indication(self, skb, info);
  160. break;
  161. default:
  162. IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %sn",
  163.    ircomm_event[event]);
  164. if (skb)
  165. dev_kfree_skb(skb);
  166. ret = -EINVAL;
  167. }
  168. return ret;
  169. }
  170. /*
  171.  * Function ircomm_state_conn (self, event, skb)
  172.  *
  173.  *    IrCOMM is connected to the peer IrCOMM device
  174.  *
  175.  */
  176. static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, 
  177.      struct sk_buff *skb, struct ircomm_info *info)
  178. {
  179. int ret = 0;
  180. switch (event) {
  181. case IRCOMM_DATA_REQUEST:
  182. ret = self->issue.data_request(self, skb, 0);
  183. break;
  184. case IRCOMM_TTP_DATA_INDICATION:
  185. ircomm_process_data(self, skb);
  186. break;
  187. case IRCOMM_LMP_DATA_INDICATION:
  188. ircomm_data_indication(self, skb);
  189. break;
  190. case IRCOMM_CONTROL_REQUEST:
  191. /* Just send a separate frame for now */
  192. ret = self->issue.data_request(self, skb, skb->len);
  193. break;
  194. case IRCOMM_TTP_DISCONNECT_INDICATION:
  195. case IRCOMM_LMP_DISCONNECT_INDICATION:
  196. ircomm_next_state(self, IRCOMM_IDLE);
  197. ircomm_disconnect_indication(self, skb, info);
  198. break;
  199. case IRCOMM_DISCONNECT_REQUEST:
  200. ircomm_next_state(self, IRCOMM_IDLE);
  201. ret = self->issue.disconnect_request(self, skb, info);
  202. break;
  203. default:
  204. IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %sn",
  205.    ircomm_event[event]);
  206. if (skb)
  207. dev_kfree_skb(skb);
  208. ret = -EINVAL;
  209. }
  210. return ret;
  211. }
  212. /*
  213.  * Function ircomm_do_event (self, event, skb)
  214.  *
  215.  *    Process event
  216.  *
  217.  */
  218. int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
  219.     struct sk_buff *skb, struct ircomm_info *info) 
  220. {
  221. IRDA_DEBUG(4, __FUNCTION__": state=%s, event=%sn",
  222.    ircomm_state[self->state], ircomm_event[event]);
  223. return (*state[self->state])(self, event, skb, info);
  224. }
  225. /*
  226.  * Function ircomm_next_state (self, state)
  227.  *
  228.  *    Switch state
  229.  *
  230.  */
  231. void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state)
  232. {
  233. self->state = state;
  234. IRDA_DEBUG(4, __FUNCTION__": next state=%s, service type=%dn", 
  235.    ircomm_state[self->state], self->service_type);
  236. }