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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * LAPB release 002
  3.  *
  4.  * This code REQUIRES 2.1.15 or higher/ NET3.038
  5.  *
  6.  * This module:
  7.  * This module is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version
  10.  * 2 of the License, or (at your option) any later version.
  11.  *
  12.  * History
  13.  * LAPB 001 Jonathan Naylor Started Coding
  14.  * LAPB 002 Jonathan Naylor New timer architecture.
  15.  */
  16. #include <linux/errno.h>
  17. #include <linux/types.h>
  18. #include <linux/socket.h>
  19. #include <linux/in.h>
  20. #include <linux/kernel.h>
  21. #include <linux/sched.h>
  22. #include <linux/timer.h>
  23. #include <linux/string.h>
  24. #include <linux/sockios.h>
  25. #include <linux/net.h>
  26. #include <linux/inet.h>
  27. #include <linux/skbuff.h>
  28. #include <net/sock.h>
  29. #include <asm/uaccess.h>
  30. #include <asm/system.h>
  31. #include <linux/fcntl.h>
  32. #include <linux/mm.h>
  33. #include <linux/interrupt.h>
  34. #include <net/lapb.h>
  35. /* 
  36.  *  This procedure is passed a buffer descriptor for an iframe. It builds
  37.  *  the rest of the control part of the frame and then writes it out.
  38.  */
  39. static void lapb_send_iframe(lapb_cb *lapb, struct sk_buff *skb, int poll_bit)
  40. {
  41. unsigned char *frame;
  42. if (skb == NULL)
  43. return;
  44. if (lapb->mode & LAPB_EXTENDED) {
  45. frame = skb_push(skb, 2);
  46. frame[0] = LAPB_I;
  47. frame[0] |= (lapb->vs << 1);
  48. frame[1] = (poll_bit) ? LAPB_EPF : 0;
  49. frame[1] |= (lapb->vr << 1);
  50. } else {
  51. frame = skb_push(skb, 1);
  52. *frame = LAPB_I;
  53. *frame |= (poll_bit) ? LAPB_SPF : 0;
  54. *frame |= (lapb->vr << 5);
  55. *frame |= (lapb->vs << 1);
  56. }
  57. #if LAPB_DEBUG > 1
  58. printk(KERN_DEBUG "lapb: (%p) S%d TX I(%d) S%d R%dn", lapb->token, lapb->state, poll_bit, lapb->vs, lapb->vr);
  59. #endif
  60. lapb_transmit_buffer(lapb, skb, LAPB_COMMAND);
  61. }
  62. void lapb_kick(lapb_cb *lapb)
  63. {
  64. struct sk_buff *skb, *skbn;
  65. unsigned short modulus, start, end;
  66. modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
  67. start = (skb_peek(&lapb->ack_queue) == NULL) ? lapb->va : lapb->vs;
  68. end   = (lapb->va + lapb->window) % modulus;
  69. if (!(lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) &&
  70.     start != end                                &&
  71.     skb_peek(&lapb->write_queue) != NULL) {
  72. lapb->vs = start;
  73. /*
  74.  * Dequeue the frame and copy it.
  75.  */
  76. skb  = skb_dequeue(&lapb->write_queue);
  77. do {
  78. if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
  79. skb_queue_head(&lapb->write_queue, skb);
  80. break;
  81. }
  82. if (skb->sk != NULL)
  83. skb_set_owner_w(skbn, skb->sk);
  84. /*
  85.  * Transmit the frame copy.
  86.  */
  87. lapb_send_iframe(lapb, skbn, LAPB_POLLOFF);
  88. lapb->vs = (lapb->vs + 1) % modulus;
  89. /*
  90.  * Requeue the original data frame.
  91.  */
  92. skb_queue_tail(&lapb->ack_queue, skb);
  93. } while (lapb->vs != end && (skb = skb_dequeue(&lapb->write_queue)) != NULL);
  94. lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
  95. if (!lapb_t1timer_running(lapb))
  96. lapb_start_t1timer(lapb);
  97. }
  98. }
  99. void lapb_transmit_buffer(lapb_cb *lapb, struct sk_buff *skb, int type)
  100. {
  101. unsigned char *ptr;
  102. ptr = skb_push(skb, 1);
  103. if (lapb->mode & LAPB_MLP) {
  104. if (lapb->mode & LAPB_DCE) {
  105. if (type == LAPB_COMMAND)
  106. *ptr = LAPB_ADDR_C;
  107. if (type == LAPB_RESPONSE)
  108. *ptr = LAPB_ADDR_D;
  109. } else {
  110. if (type == LAPB_COMMAND)
  111. *ptr = LAPB_ADDR_D;
  112. if (type == LAPB_RESPONSE)
  113. *ptr = LAPB_ADDR_C;
  114. }
  115. } else {
  116. if (lapb->mode & LAPB_DCE) {
  117. if (type == LAPB_COMMAND)
  118. *ptr = LAPB_ADDR_A;
  119. if (type == LAPB_RESPONSE)
  120. *ptr = LAPB_ADDR_B;
  121. } else {
  122. if (type == LAPB_COMMAND)
  123. *ptr = LAPB_ADDR_B;
  124. if (type == LAPB_RESPONSE)
  125. *ptr = LAPB_ADDR_A;
  126. }
  127. }
  128. #if LAPB_DEBUG > 2
  129. printk(KERN_DEBUG "lapb: (%p) S%d TX %02X %02X %02Xn", lapb->token, lapb->state, skb->data[0], skb->data[1], skb->data[2]);
  130. #endif
  131. if (!lapb_data_transmit(lapb, skb))
  132. kfree_skb(skb);
  133. }
  134. void lapb_establish_data_link(lapb_cb *lapb)
  135. {
  136. lapb->condition = 0x00;
  137. lapb->n2count   = 0;
  138. if (lapb->mode & LAPB_EXTENDED) {
  139. #if LAPB_DEBUG > 1
  140. printk(KERN_DEBUG "lapb: (%p) S%d TX SABME(1)n", lapb->token, lapb->state);
  141. #endif
  142. lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
  143. } else {
  144. #if LAPB_DEBUG > 1
  145. printk(KERN_DEBUG "lapb: (%p) S%d TX SABM(1)n", lapb->token, lapb->state);
  146. #endif
  147. lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
  148. }
  149. lapb_start_t1timer(lapb);
  150. lapb_stop_t2timer(lapb);
  151. }
  152. void lapb_enquiry_response(lapb_cb *lapb)
  153. {
  154. #if LAPB_DEBUG > 1
  155. printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%dn", lapb->token, lapb->state, lapb->vr);
  156. #endif
  157. lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
  158. lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
  159. }
  160. void lapb_timeout_response(lapb_cb *lapb)
  161. {
  162. #if LAPB_DEBUG > 1
  163. printk(KERN_DEBUG "lapb: (%p) S%d TX RR(0) R%dn", lapb->token, lapb->state, lapb->vr);
  164. #endif
  165. lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE);
  166. lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
  167. }
  168. void lapb_check_iframes_acked(lapb_cb *lapb, unsigned short nr)
  169. {
  170. if (lapb->vs == nr) {
  171. lapb_frames_acked(lapb, nr);
  172. lapb_stop_t1timer(lapb);
  173. lapb->n2count = 0;
  174. } else {
  175. if (lapb->va != nr) {
  176. lapb_frames_acked(lapb, nr);
  177. lapb_start_t1timer(lapb);
  178. }
  179. }
  180. }
  181. void lapb_check_need_response(lapb_cb *lapb, int type, int pf)
  182. {
  183. if (type == LAPB_COMMAND && pf)
  184. lapb_enquiry_response(lapb);
  185. }