00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <linux/skbuff.h>
00027 #include <linux/if.h>
00028 #include <linux/if_ether.h>
00029 #include <linux/netdevice.h>
00030 #include <linux/irda.h>
00031
00032 #include <net/pkt_sched.h>
00033 #include <net/sock.h>
00034
00035 #include <asm/byteorder.h>
00036
00037 #include <net/irda/irda.h>
00038 #include <net/irda/irda_device.h>
00039 #include <net/irda/irlap.h>
00040 #include <net/irda/wrapper.h>
00041 #include <net/irda/timer.h>
00042 #include <net/irda/irlap_frame.h>
00043 #include <net/irda/qos.h>
00044
00045
00046
00047
00048
00049
00050
00051
00052 static inline void irlap_insert_info(struct irlap_cb *self,
00053 struct sk_buff *skb)
00054 {
00055 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
00056
00057
00058
00059
00060
00061 cb->magic = LAP_MAGIC;
00062 cb->mtt = self->mtt_required;
00063 cb->speed = self->speed;
00064
00065
00066 self->mtt_required = 0;
00067
00068
00069
00070
00071
00072 cb->xbofs = self->bofs_count+self->xbofs_delay;
00073
00074
00075 self->xbofs_delay = 0;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
00085 {
00086
00087 skb->dev = self->netdev;
00088 skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
00089 skb->protocol = htons(ETH_P_IRDA);
00090 skb->priority = TC_PRIO_BESTEFFORT;
00091
00092 irlap_insert_info(self, skb);
00093
00094 dev_queue_xmit(skb);
00095 }
00096
00097
00098
00099
00100
00101
00102 void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
00103 {
00104 struct sk_buff *skb;
00105 struct snrm_frame *frame;
00106 int ret;
00107
00108 ASSERT(self != NULL, return;);
00109 ASSERT(self->magic == LAP_MAGIC, return;);
00110
00111
00112 skb = dev_alloc_skb(64);
00113 if (!skb)
00114 return;
00115
00116 frame = (struct snrm_frame *) skb_put(skb, 2);
00117
00118
00119 if (qos)
00120 frame->caddr = CMD_FRAME | CBROADCAST;
00121 else
00122 frame->caddr = CMD_FRAME | self->caddr;
00123
00124
00125 frame->control = SNRM_CMD | PF_BIT;
00126
00127
00128
00129
00130 if (qos) {
00131 skb_put(skb, 9);
00132 frame->saddr = cpu_to_le32(self->saddr);
00133 frame->daddr = cpu_to_le32(self->daddr);
00134
00135 frame->ncaddr = self->caddr;
00136
00137 ret = irlap_insert_qos_negotiation_params(self, skb);
00138 if (ret < 0) {
00139 dev_kfree_skb(skb);
00140 return;
00141 }
00142 }
00143 irlap_queue_xmit(self, skb);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
00153 struct irlap_info *info)
00154 {
00155 struct snrm_frame *frame;
00156
00157 frame = (struct snrm_frame *) skb->data;
00158
00159 if (skb->len >= sizeof(struct snrm_frame)) {
00160
00161 info->caddr = frame->ncaddr;
00162
00163
00164 if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
00165 IRDA_DEBUG(3, __FUNCTION__
00166 "(), invalid connection address!\n");
00167 dev_kfree_skb(skb);
00168 return;
00169 }
00170
00171
00172 info->daddr = le32_to_cpu(frame->saddr);
00173 info->saddr = le32_to_cpu(frame->daddr);
00174
00175
00176 if (info->saddr != self->saddr) {
00177 IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n");
00178 dev_kfree_skb(skb);
00179 return;
00180 }
00181 irlap_do_event(self, RECV_SNRM_CMD, skb, info);
00182 } else
00183
00184 irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
00194 {
00195 struct sk_buff *skb;
00196 struct ua_frame *frame;
00197 int ret;
00198
00199 IRDA_DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies);
00200
00201 ASSERT(self != NULL, return;);
00202 ASSERT(self->magic == LAP_MAGIC, return;);
00203
00204 skb = NULL;
00205
00206
00207 skb = dev_alloc_skb(64);
00208 if (!skb)
00209 return;
00210
00211 frame = (struct ua_frame *) skb_put(skb, 10);
00212
00213
00214 frame->caddr = self->caddr;
00215 frame->control = UA_RSP | PF_BIT;
00216
00217 frame->saddr = cpu_to_le32(self->saddr);
00218 frame->daddr = cpu_to_le32(self->daddr);
00219
00220
00221 if (qos) {
00222 ret = irlap_insert_qos_negotiation_params(self, skb);
00223 if (ret < 0) {
00224 dev_kfree_skb(skb);
00225 return;
00226 }
00227 }
00228
00229 irlap_queue_xmit(self, skb);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 void irlap_send_dm_frame( struct irlap_cb *self)
00240 {
00241 struct sk_buff *skb = NULL;
00242 __u8 *frame;
00243
00244 ASSERT(self != NULL, return;);
00245 ASSERT(self->magic == LAP_MAGIC, return;);
00246
00247 skb = dev_alloc_skb(32);
00248 if (!skb)
00249 return;
00250
00251 frame = skb_put( skb, 2);
00252
00253 if (self->state == LAP_NDM)
00254 frame[0] = CBROADCAST;
00255 else
00256 frame[0] = self->caddr;
00257
00258 frame[1] = DM_RSP | PF_BIT;
00259
00260 irlap_queue_xmit(self, skb);
00261 }
00262
00263
00264
00265
00266
00267
00268
00269 void irlap_send_disc_frame(struct irlap_cb *self)
00270 {
00271 struct sk_buff *skb = NULL;
00272 __u8 *frame;
00273
00274 IRDA_DEBUG(3, __FUNCTION__ "()\n");
00275
00276 ASSERT(self != NULL, return;);
00277 ASSERT(self->magic == LAP_MAGIC, return;);
00278
00279 skb = dev_alloc_skb(16);
00280 if (!skb)
00281 return;
00282
00283 frame = skb_put(skb, 2);
00284
00285 frame[0] = self->caddr | CMD_FRAME;
00286 frame[1] = DISC_CMD | PF_BIT;
00287
00288 irlap_queue_xmit(self, skb);
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
00298 __u8 command, discovery_t *discovery)
00299 {
00300 struct sk_buff *skb = NULL;
00301 struct xid_frame *frame;
00302 __u32 bcast = BROADCAST;
00303 __u8 *info;
00304
00305 IRDA_DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S,
00306 command);
00307
00308 ASSERT(self != NULL, return;);
00309 ASSERT(self->magic == LAP_MAGIC, return;);
00310 ASSERT(discovery != NULL, return;);
00311
00312 skb = dev_alloc_skb(64);
00313 if (!skb)
00314 return;
00315
00316 skb_put(skb, 14);
00317 frame = (struct xid_frame *) skb->data;
00318
00319 if (command) {
00320 frame->caddr = CBROADCAST | CMD_FRAME;
00321 frame->control = XID_CMD | PF_BIT;
00322 } else {
00323 frame->caddr = CBROADCAST;
00324 frame->control = XID_RSP | PF_BIT;
00325 }
00326 frame->ident = XID_FORMAT;
00327
00328 frame->saddr = cpu_to_le32(self->saddr);
00329
00330 if (command)
00331 frame->daddr = cpu_to_le32(bcast);
00332 else
00333 frame->daddr = cpu_to_le32(discovery->daddr);
00334
00335 switch (S) {
00336 case 1:
00337 frame->flags = 0x00;
00338 break;
00339 case 6:
00340 frame->flags = 0x01;
00341 break;
00342 case 8:
00343 frame->flags = 0x02;
00344 break;
00345 case 16:
00346 frame->flags = 0x03;
00347 break;
00348 default:
00349 frame->flags = 0x02;
00350 break;
00351 }
00352
00353 frame->slotnr = s;
00354 frame->version = 0x00;
00355
00356
00357
00358
00359
00360
00361 if (!command || (frame->slotnr == 0xff)) {
00362 int len;
00363
00364 if (discovery->hints.byte[0] & HINT_EXTENSION) {
00365 info = skb_put(skb, 2);
00366 info[0] = discovery->hints.byte[0];
00367 info[1] = discovery->hints.byte[1];
00368 } else {
00369 info = skb_put(skb, 1);
00370 info[0] = discovery->hints.byte[0];
00371 }
00372 info = skb_put(skb, 1);
00373 info[0] = discovery->charset;
00374
00375 len = IRDA_MIN(discovery->name_len, skb_tailroom(skb));
00376 info = skb_put(skb, len);
00377 memcpy(info, discovery->nickname, len);
00378 }
00379 irlap_queue_xmit(self, skb);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
00389 struct sk_buff *skb,
00390 struct irlap_info *info)
00391 {
00392 struct xid_frame *xid;
00393 discovery_t *discovery = NULL;
00394 __u8 *discovery_info;
00395 char *text;
00396
00397 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00398
00399 ASSERT(self != NULL, return;);
00400 ASSERT(self->magic == LAP_MAGIC, return;);
00401
00402 xid = (struct xid_frame *) skb->data;
00403
00404 info->daddr = le32_to_cpu(xid->saddr);
00405 info->saddr = le32_to_cpu(xid->daddr);
00406
00407
00408 if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
00409 IRDA_DEBUG(0, __FUNCTION__
00410 "(), frame is not addressed to us!\n");
00411 dev_kfree_skb(skb);
00412 return;
00413 }
00414
00415 if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
00416 WARNING(__FUNCTION__ "(), kmalloc failed!\n");
00417 dev_kfree_skb(skb);
00418 return;
00419 }
00420 memset(discovery, 0, sizeof(discovery_t));
00421
00422 discovery->daddr = info->daddr;
00423 discovery->saddr = self->saddr;
00424 discovery->timestamp = jiffies;
00425
00426 IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", discovery->daddr);
00427
00428 discovery_info = skb_pull(skb, sizeof(struct xid_frame));
00429
00430
00431 discovery->hints.byte[0] = discovery_info[0];
00432 if (discovery_info[0] & HINT_EXTENSION) {
00433 IRDA_DEBUG(4, "EXTENSION\n");
00434 discovery->hints.byte[1] = discovery_info[1];
00435 discovery->charset = discovery_info[2];
00436 text = (char *) &discovery_info[3];
00437 } else {
00438 discovery->hints.byte[1] = 0;
00439 discovery->charset = discovery_info[1];
00440 text = (char *) &discovery_info[2];
00441 }
00442
00443
00444
00445
00446 skb->data[skb->len] = '\0';
00447 strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
00448 discovery->name_len = strlen(discovery->nickname);
00449
00450 info->discovery = discovery;
00451
00452 irlap_do_event(self, RECV_DISCOVERY_XID_RSP, skb, info);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461 static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
00462 struct sk_buff *skb,
00463 struct irlap_info *info)
00464 {
00465 struct xid_frame *xid;
00466 discovery_t *discovery = NULL;
00467 __u8 *discovery_info;
00468 char *text;
00469
00470 xid = (struct xid_frame *) skb->data;
00471
00472 info->daddr = le32_to_cpu(xid->saddr);
00473 info->saddr = le32_to_cpu(xid->daddr);
00474
00475
00476 if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
00477 IRDA_DEBUG(0, __FUNCTION__
00478 "(), frame is not addressed to us!\n");
00479 dev_kfree_skb(skb);
00480 return;
00481 }
00482
00483 switch (xid->flags & 0x03) {
00484 case 0x00:
00485 info->S = 1;
00486 break;
00487 case 0x01:
00488 info->S = 6;
00489 break;
00490 case 0x02:
00491 info->S = 8;
00492 break;
00493 case 0x03:
00494 info->S = 16;
00495 break;
00496 default:
00497
00498 dev_kfree_skb(skb);
00499 return;
00500 }
00501 info->s = xid->slotnr;
00502
00503 discovery_info = skb_pull(skb, sizeof(struct xid_frame));
00504
00505
00506
00507
00508 if (info->s == 0xff) {
00509
00510
00511
00512 discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
00513 if (!discovery) {
00514 WARNING(__FUNCTION__ "(), unable to malloc!\n");
00515 dev_kfree_skb(skb);
00516 return;
00517 }
00518
00519 discovery->daddr = info->daddr;
00520 discovery->saddr = self->saddr;
00521 discovery->timestamp = jiffies;
00522
00523 discovery->hints.byte[0] = discovery_info[0];
00524 if (discovery_info[0] & HINT_EXTENSION) {
00525 discovery->hints.byte[1] = discovery_info[1];
00526 discovery->charset = discovery_info[2];
00527 text = (char *) &discovery_info[3];
00528 } else {
00529 discovery->hints.byte[1] = 0;
00530 discovery->charset = discovery_info[1];
00531 text = (char *) &discovery_info[2];
00532 }
00533
00534
00535
00536
00537 skb->data[skb->len] = '\0';
00538 strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
00539 discovery->name_len = strlen(discovery->nickname);
00540
00541 info->discovery = discovery;
00542 } else
00543 info->discovery = NULL;
00544
00545 irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
00546 }
00547
00548
00549
00550
00551
00552
00553
00554 void irlap_send_rr_frame(struct irlap_cb *self, int command)
00555 {
00556 struct sk_buff *skb;
00557 __u8 *frame;
00558
00559 skb = dev_alloc_skb(16);
00560 if (!skb)
00561 return;
00562
00563 frame = skb_put(skb, 2);
00564
00565 frame[0] = self->caddr;
00566 frame[0] |= (command) ? CMD_FRAME : 0;
00567
00568 frame[1] = RR | PF_BIT | (self->vr << 5);
00569
00570 irlap_queue_xmit(self, skb);
00571 }
00572
00573
00574
00575
00576
00577
00578
00579 void irlap_send_rd_frame(struct irlap_cb *self)
00580 {
00581 struct sk_buff *skb;
00582 __u8 *frame;
00583
00584 skb = dev_alloc_skb(16);
00585 if (!skb)
00586 return;
00587
00588 frame = skb_put(skb, 2);
00589
00590 frame[0] = self->caddr;
00591 frame[1] = RD_RSP | PF_BIT;
00592
00593 irlap_queue_xmit(self, skb);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603 static inline void irlap_recv_rr_frame(struct irlap_cb *self,
00604 struct sk_buff *skb,
00605 struct irlap_info *info, int command)
00606 {
00607 info->nr = skb->data[1] >> 5;
00608
00609
00610 if (command)
00611 irlap_do_event(self, RECV_RR_CMD, skb, info);
00612 else
00613 irlap_do_event(self, RECV_RR_RSP, skb, info);
00614 }
00615
00616 void irlap_send_frmr_frame( struct irlap_cb *self, int command)
00617 {
00618 struct sk_buff *skb = NULL;
00619 __u8 *frame;
00620
00621 ASSERT( self != NULL, return;);
00622 ASSERT( self->magic == LAP_MAGIC, return;);
00623
00624 skb = dev_alloc_skb( 32);
00625 if (!skb)
00626 return;
00627
00628 frame = skb_put( skb, 2);
00629
00630 frame[0] = self->caddr;
00631 frame[0] |= (command) ? CMD_FRAME : 0;
00632
00633 frame[1] = (self->vs << 1);
00634 frame[1] |= PF_BIT;
00635 frame[1] |= (self->vr << 5);
00636
00637 frame[2] = 0;
00638
00639 IRDA_DEBUG(4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies);
00640
00641 irlap_queue_xmit(self, skb);
00642 }
00643
00644
00645
00646
00647
00648
00649
00650 static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
00651 struct irlap_info *info, int command)
00652 {
00653 info->nr = skb->data[1] >> 5;
00654
00655 IRDA_DEBUG(4, __FUNCTION__ "(), nr=%d, %ld\n", info->nr, jiffies);
00656
00657 if (command)
00658 irlap_do_event(self, RECV_RNR_CMD, skb, info);
00659 else
00660 irlap_do_event(self, RECV_RNR_RSP, skb, info);
00661 }
00662
00663 static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
00664 struct irlap_info *info, int command)
00665 {
00666 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00667
00668 info->nr = skb->data[1] >> 5;
00669
00670
00671 if (command)
00672 irlap_do_event(self, RECV_REJ_CMD, skb, info);
00673 else
00674 irlap_do_event(self, RECV_REJ_RSP, skb, info);
00675 }
00676
00677 static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
00678 struct irlap_info *info, int command)
00679 {
00680 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00681
00682 info->nr = skb->data[1] >> 5;
00683
00684
00685 if (command)
00686 irlap_do_event(self, RECV_SREJ_CMD, skb, info);
00687 else
00688 irlap_do_event(self, RECV_SREJ_RSP, skb, info);
00689 }
00690
00691 static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
00692 struct irlap_info *info, int command)
00693 {
00694 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00695
00696
00697 if (command)
00698 irlap_do_event(self, RECV_DISC_CMD, skb, info);
00699 else
00700 irlap_do_event(self, RECV_RD_RSP, skb, info);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709 static inline void irlap_recv_ua_frame(struct irlap_cb *self,
00710 struct sk_buff *skb,
00711 struct irlap_info *info)
00712 {
00713 irlap_do_event(self, RECV_UA_RSP, skb, info);
00714 }
00715
00716
00717
00718
00719
00720
00721
00722 void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
00723 {
00724 struct sk_buff *tx_skb;
00725
00726 if (skb->data[1] == I_FRAME) {
00727
00728
00729
00730
00731
00732 skb->data[1] = I_FRAME | (self->vs << 1);
00733
00734
00735 tx_skb = skb_clone(skb, GFP_ATOMIC);
00736 if (tx_skb == NULL) {
00737 dev_kfree_skb(skb);
00738 return;
00739 }
00740
00741
00742
00743
00744 if (skb->sk != NULL)
00745 skb_set_owner_w(tx_skb, skb->sk);
00746
00747
00748
00749
00750 skb_queue_tail(&self->wx_list, skb);
00751
00752 self->vs = (self->vs + 1) % 8;
00753 self->ack_required = FALSE;
00754 self->window -= 1;
00755
00756 irlap_send_i_frame( self, tx_skb, CMD_FRAME);
00757 } else {
00758 IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
00759 irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
00760 self->window -= 1;
00761 }
00762 }
00763
00764
00765
00766
00767
00768 void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
00769 {
00770 struct sk_buff *tx_skb;
00771
00772
00773 if (skb->data[1] == I_FRAME) {
00774
00775
00776
00777
00778
00779 skb->data[1] = I_FRAME | (self->vs << 1);
00780
00781
00782 tx_skb = skb_clone(skb, GFP_ATOMIC);
00783 if (tx_skb == NULL) {
00784 dev_kfree_skb(skb);
00785 return;
00786 }
00787
00788
00789
00790
00791 if (skb->sk != NULL)
00792 skb_set_owner_w(tx_skb, skb->sk);
00793
00794
00795
00796
00797 skb_queue_tail(&self->wx_list, skb);
00798
00799
00800
00801
00802
00803
00804
00805 del_timer(&self->poll_timer);
00806
00807 tx_skb->data[1] |= PF_BIT;
00808
00809 self->vs = (self->vs + 1) % 8;
00810 self->ack_required = FALSE;
00811 self->window = self->window_size;
00812
00813 irlap_start_final_timer(self, self->final_timeout);
00814
00815 irlap_send_i_frame(self, tx_skb, CMD_FRAME);
00816 } else {
00817 IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
00818
00819 del_timer(&self->poll_timer);
00820
00821 if (self->ack_required) {
00822 irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
00823 irlap_send_rr_frame(self, CMD_FRAME);
00824 self->ack_required = FALSE;
00825 } else {
00826 skb->data[1] |= PF_BIT;
00827 irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
00828 }
00829 self->window = self->window_size;
00830 irlap_start_final_timer(self, self->final_timeout);
00831 }
00832 }
00833
00834
00835
00836
00837
00838
00839
00840 void irlap_send_data_secondary_final(struct irlap_cb *self,
00841 struct sk_buff *skb)
00842 {
00843 struct sk_buff *tx_skb = NULL;
00844
00845 ASSERT(self != NULL, return;);
00846 ASSERT(self->magic == LAP_MAGIC, return;);
00847 ASSERT(skb != NULL, return;);
00848
00849
00850 if (skb->data[1] == I_FRAME) {
00851
00852
00853
00854
00855
00856 skb->data[1] = I_FRAME | (self->vs << 1);
00857
00858 tx_skb = skb_clone(skb, GFP_ATOMIC);
00859 if (tx_skb == NULL) {
00860 dev_kfree_skb(skb);
00861 return;
00862 }
00863
00864 if (skb->sk != NULL)
00865 skb_set_owner_w(tx_skb, skb->sk);
00866
00867
00868 skb_queue_tail(&self->wx_list, skb);
00869
00870 tx_skb->data[1] |= PF_BIT;
00871
00872 self->vs = (self->vs + 1) % 8;
00873 self->window = self->window_size;
00874 self->ack_required = FALSE;
00875
00876 irlap_start_wd_timer(self, self->wd_timeout);
00877
00878 irlap_send_i_frame(self, tx_skb, RSP_FRAME);
00879 } else {
00880 if (self->ack_required) {
00881 irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
00882 irlap_send_rr_frame(self, RSP_FRAME);
00883 self->ack_required = FALSE;
00884 } else {
00885 skb->data[1] |= PF_BIT;
00886 irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
00887 }
00888 self->window = self->window_size;
00889
00890 irlap_start_wd_timer(self, self->wd_timeout);
00891 }
00892 }
00893
00894
00895
00896
00897
00898
00899
00900 void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
00901 {
00902 struct sk_buff *tx_skb = NULL;
00903
00904
00905 if (skb->data[1] == I_FRAME) {
00906
00907
00908
00909
00910
00911 skb->data[1] = I_FRAME | (self->vs << 1);
00912
00913 tx_skb = skb_clone(skb, GFP_ATOMIC);
00914 if (tx_skb == NULL) {
00915 dev_kfree_skb(skb);
00916 return;
00917 }
00918
00919 if (skb->sk != NULL)
00920 skb_set_owner_w(tx_skb, skb->sk);
00921
00922
00923 skb_queue_tail(&self->wx_list, skb);
00924
00925 self->vs = (self->vs + 1) % 8;
00926 self->ack_required = FALSE;
00927 self->window -= 1;
00928
00929 irlap_send_i_frame(self, tx_skb, RSP_FRAME);
00930 } else {
00931 irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
00932 self->window -= 1;
00933 }
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943 void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
00944 {
00945 struct sk_buff *tx_skb;
00946 struct sk_buff *skb;
00947 int count;
00948
00949 ASSERT(self != NULL, return;);
00950 ASSERT(self->magic == LAP_MAGIC, return;);
00951
00952
00953 skb = tx_skb = NULL;
00954
00955 count = skb_queue_len(&self->wx_list);
00956
00957
00958 skb = skb_peek(&self->wx_list);
00959 while (skb != NULL) {
00960 irlap_wait_min_turn_around(self, &self->qos_tx);
00961
00962
00963
00964
00965
00966 tx_skb = skb_copy(skb, GFP_ATOMIC);
00967 if (!tx_skb) {
00968 IRDA_DEBUG(0, __FUNCTION__ "(), unable to copy\n");
00969 return;
00970 }
00971
00972 tx_skb->next = tx_skb->prev = NULL;
00973 tx_skb->list = NULL;
00974
00975
00976
00977
00978 if (skb->sk != NULL)
00979 skb_set_owner_w(tx_skb, skb->sk);
00980
00981
00982 tx_skb->data[1] &= 0x0f;
00983
00984
00985
00986
00987 if (count-- == 1)
00988 tx_skb->data[1] |= PF_BIT;
00989 else
00990 tx_skb->data[1] &= ~PF_BIT;
00991
00992 irlap_send_i_frame(self, tx_skb, command);
00993
00994
00995
00996
00997
00998 if (skb == skb_peek_tail(&self->wx_list))
00999 skb = NULL;
01000 else
01001 skb = skb->next;
01002 }
01003 #if 0
01004
01005
01006
01007 while (skb_queue_len( &self->txq) > 0) {
01008
01009 IRDA_DEBUG(0, __FUNCTION__ "(), sending additional frames!\n");
01010 if ((skb_queue_len( &self->txq) > 0) &&
01011 (self->window > 0)) {
01012 skb = skb_dequeue( &self->txq);
01013 ASSERT(skb != NULL, return;);
01014
01015
01016
01017
01018
01019 if ((self->window > 1) &&
01020 skb_queue_len(&self->txq) > 0)
01021 {
01022 irlap_send_data_primary(self, skb);
01023 } else {
01024 irlap_send_data_primary_poll(self, skb);
01025 }
01026 }
01027 }
01028 #endif
01029 }
01030
01031 void irlap_resend_rejected_frame(struct irlap_cb *self, int command)
01032 {
01033 struct sk_buff *tx_skb;
01034 struct sk_buff *skb;
01035
01036 ASSERT(self != NULL, return;);
01037 ASSERT(self->magic == LAP_MAGIC, return;);
01038
01039
01040 skb = tx_skb = NULL;
01041
01042
01043 skb = skb_peek(&self->wx_list);
01044 if (skb != NULL) {
01045 irlap_wait_min_turn_around(self, &self->qos_tx);
01046
01047
01048
01049
01050
01051 tx_skb = skb_copy(skb, GFP_ATOMIC);
01052 if (!tx_skb) {
01053 IRDA_DEBUG(0, __FUNCTION__ "(), unable to copy\n");
01054 return;
01055 }
01056
01057 tx_skb->next = tx_skb->prev = NULL;
01058 tx_skb->list = NULL;
01059
01060
01061
01062
01063 if (skb->sk != NULL)
01064 skb_set_owner_w(tx_skb, skb->sk);
01065
01066
01067 tx_skb->data[1] &= 0x0f;
01068
01069
01070 tx_skb->data[1] |= PF_BIT;
01071
01072 irlap_send_i_frame(self, tx_skb, command);
01073 }
01074 }
01075
01076
01077
01078
01079
01080
01081
01082 void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
01083 __u8 caddr, int command)
01084 {
01085 IRDA_DEBUG(4, __FUNCTION__ "()\n");
01086
01087 ASSERT(self != NULL, return;);
01088 ASSERT(self->magic == LAP_MAGIC, return;);
01089 ASSERT(skb != NULL, return;);
01090
01091
01092 skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
01093
01094 irlap_queue_xmit(self, skb);
01095 }
01096
01097
01098
01099
01100
01101
01102 void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
01103 int command)
01104 {
01105
01106 skb->data[0] = self->caddr;
01107 skb->data[0] |= (command) ? CMD_FRAME : 0;
01108
01109
01110 skb->data[1] |= (self->vr << 5);
01111
01112 irlap_queue_xmit(self, skb);
01113 }
01114
01115
01116
01117
01118
01119
01120
01121 static inline void irlap_recv_i_frame(struct irlap_cb *self,
01122 struct sk_buff *skb,
01123 struct irlap_info *info, int command)
01124 {
01125 info->nr = skb->data[1] >> 5;
01126 info->pf = skb->data[1] & PF_BIT;
01127 info->ns = (skb->data[1] >> 1) & 0x07;
01128
01129
01130 if (command)
01131 irlap_do_event(self, RECV_I_CMD, skb, info);
01132 else
01133 irlap_do_event(self, RECV_I_RSP, skb, info);
01134 }
01135
01136
01137
01138
01139
01140
01141
01142 static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
01143 struct irlap_info *info)
01144 {
01145 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
01146
01147 info->pf = skb->data[1] & PF_BIT;
01148
01149 irlap_do_event(self, RECV_UI_FRAME, skb, info);
01150 }
01151
01152
01153
01154
01155
01156
01157
01158 static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
01159 struct irlap_info *info)
01160 {
01161 __u8 *frame;
01162 int w, x, y, z;
01163
01164 IRDA_DEBUG(0, __FUNCTION__ "()\n");
01165
01166 ASSERT(self != NULL, return;);
01167 ASSERT(self->magic == LAP_MAGIC, return;);
01168 ASSERT(skb != NULL, return;);
01169 ASSERT(info != NULL, return;);
01170
01171 frame = skb->data;
01172
01173 info->nr = frame[2] >> 5;
01174 info->pf = frame[2] & PF_BIT;
01175 info->ns = (frame[2] >> 1) & 0x07;
01176
01177 w = frame[3] & 0x01;
01178 x = frame[3] & 0x02;
01179 y = frame[3] & 0x04;
01180 z = frame[3] & 0x08;
01181
01182 if (w) {
01183 IRDA_DEBUG(0, "Rejected control field is undefined or not "
01184 "implemented.\n");
01185 }
01186 if (x) {
01187 IRDA_DEBUG(0, "Rejected control field was invalid because it "
01188 "contained a non permitted I field.\n");
01189 }
01190 if (y) {
01191 IRDA_DEBUG(0, "Received I field exceeded the maximum negotiated "
01192 "for the existing connection or exceeded the maximum "
01193 "this station supports if no connection exists.\n");
01194 }
01195 if (z) {
01196 IRDA_DEBUG(0, "Rejected control field control field contained an "
01197 "invalid Nr count.\n");
01198 }
01199 irlap_do_event(self, RECV_FRMR_RSP, skb, info);
01200 }
01201
01202
01203
01204
01205
01206
01207
01208 void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
01209 struct sk_buff *cmd)
01210 {
01211 struct sk_buff *skb;
01212 struct test_frame *frame;
01213 __u8 *info;
01214
01215 skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame));
01216 if (!skb)
01217 return;
01218
01219
01220 if (caddr == CBROADCAST) {
01221 frame = (struct test_frame *)
01222 skb_put(skb, sizeof(struct test_frame));
01223
01224
01225 frame->saddr = cpu_to_le32(self->saddr);
01226 frame->daddr = cpu_to_le32(daddr);
01227 } else
01228 frame = (struct test_frame *) skb_put(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
01229
01230 frame->caddr = caddr;
01231 frame->control = TEST_RSP | PF_BIT;
01232
01233
01234 info = skb_put(skb, cmd->len);
01235 memcpy(info, cmd->data, cmd->len);
01236
01237
01238 irlap_wait_min_turn_around(self, &self->qos_tx);
01239 irlap_queue_xmit(self, skb);
01240 }
01241
01242
01243
01244
01245
01246
01247
01248 static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
01249 struct irlap_info *info, int command)
01250 {
01251 struct test_frame *frame;
01252
01253 IRDA_DEBUG(2, __FUNCTION__ "()\n");
01254
01255 frame = (struct test_frame *) skb->data;
01256
01257
01258 if (info->caddr == CBROADCAST) {
01259 if (skb->len < sizeof(struct test_frame)) {
01260 IRDA_DEBUG(0, __FUNCTION__
01261 "() test frame to short!\n");
01262 dev_kfree_skb(skb);
01263 return;
01264 }
01265
01266
01267 info->daddr = le32_to_cpu(frame->saddr);
01268 info->saddr = le32_to_cpu(frame->daddr);
01269
01270
01271 if ((info->saddr != self->saddr) &&
01272 (info->saddr != BROADCAST)) {
01273 dev_kfree_skb(skb);
01274 return;
01275 }
01276 }
01277
01278 if (command)
01279 irlap_do_event(self, RECV_TEST_CMD, skb, info);
01280 else
01281 irlap_do_event(self, RECV_TEST_RSP, skb, info);
01282 }
01283
01284
01285
01286
01287
01288
01289
01290
01291 int irlap_driver_rcv(struct sk_buff *skb, struct device *dev,
01292 struct packet_type *ptype)
01293 {
01294 struct irlap_info info;
01295 struct irlap_cb *self;
01296 int command;
01297 __u8 control;
01298
01299
01300 self = (struct irlap_cb *) dev->atalk_ptr;
01301
01302
01303 if (!self || self->magic != LAP_MAGIC) {
01304 dev_kfree_skb(skb);
01305 return -1;
01306 }
01307
01308
01309 if (skb->len < 2) {
01310 ERROR(__FUNCTION__ "(), frame to short!\n");
01311 dev_kfree_skb(skb);
01312 return -1;
01313 }
01314
01315 command = skb->data[0] & CMD_FRAME;
01316 info.caddr = skb->data[0] & CBROADCAST;
01317
01318 info.pf = skb->data[1] & PF_BIT;
01319 info.control = skb->data[1] & ~PF_BIT;
01320
01321 control = info.control;
01322
01323
01324 if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
01325 IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n");
01326 dev_kfree_skb(skb);
01327 return 0;
01328 }
01329
01330
01331
01332
01333 if (~control & 0x01) {
01334