Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

irlap_frame.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                
00003  * Filename:      irlap_frame.c
00004  * Version:       1.0
00005  * Description:   Build and transmit IrLAP frames
00006  * Status:        Stable
00007  * Author:        Dag Brattli <dagb@cs.uit.no>
00008  * Created at:    Tue Aug 19 10:27:26 1997
00009  * Modified at:   Thu Apr 13 02:40:49 2000
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * 
00012  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
00013  *     All Rights Reserved.
00014  *     
00015  *     This program is free software; you can redistribute it and/or 
00016  *     modify it under the terms of the GNU General Public License as 
00017  *     published by the Free Software Foundation; either version 2 of 
00018  *     the License, or (at your option) any later version.
00019  *
00020  *     Neither Dag Brattli nor University of Tromsų admit liability nor
00021  *     provide warranty for any of this software. This material is 
00022  *     provided "AS-IS" and at no charge.
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  * Function irlap_insert_info (self, skb)
00047  *
00048  *    Insert minimum turnaround time and speed information into the skb. We 
00049  *    need to do this since it's per packet relevant information. Safe to
00050  *    have this function inlined since it's only called from one place
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          * Insert MTT (min. turn time) and speed into skb, so that the
00059          * device driver knows which settings to use 
00060          */
00061         cb->magic = LAP_MAGIC;
00062         cb->mtt = self->mtt_required;
00063         cb->speed = self->speed;
00064 
00065         /* Reset */
00066         self->mtt_required = 0;
00067         
00068         /* 
00069          * Delay equals negotiated BOFs count, plus the number of BOFs to 
00070          * force the negotiated minimum turnaround time 
00071          */
00072         cb->xbofs = self->bofs_count+self->xbofs_delay;
00073         
00074         /* Reset XBOF's delay (used only for getting min turn time) */
00075         self->xbofs_delay = 0;
00076 }
00077 
00078 /*
00079  * Function irlap_queue_xmit (self, skb)
00080  *
00081  *    A little wrapper for dev_queue_xmit, so we can insert some common
00082  *    code into it.
00083  */
00084 void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
00085 {
00086         /* Some common init stuff */
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  * Function irlap_send_snrm_cmd (void)
00099  *
00100  *    Transmits a connect SNRM command frame
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         /* Allocate frame */
00112         skb = dev_alloc_skb(64);
00113         if (!skb)
00114                 return;
00115 
00116         frame = (struct snrm_frame *) skb_put(skb, 2); 
00117 
00118         /* Insert connection address field */
00119         if (qos)
00120                 frame->caddr = CMD_FRAME | CBROADCAST;
00121         else
00122                 frame->caddr = CMD_FRAME | self->caddr;
00123 
00124         /* Insert control field */
00125         frame->control = SNRM_CMD | PF_BIT;
00126         
00127         /*
00128          *  If we are establishing a connection then insert QoS paramerters 
00129          */
00130         if (qos) {
00131                 skb_put(skb, 9); /* 21 left */
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  * Function irlap_recv_snrm_cmd (skb, info)
00148  *
00149  *    Received SNRM (Set Normal Response Mode) command frame
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                 /* Copy the new connection address */
00161                 info->caddr = frame->ncaddr;
00162 
00163                 /* Check if the new connection address is valid */
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                 /* Copy peer device address */
00172                 info->daddr = le32_to_cpu(frame->saddr);
00173                 info->saddr = le32_to_cpu(frame->daddr);
00174                 
00175                 /* Only accept if addressed directly to us */
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                 /* Signal that this SNRM frame does not contain and I-field */
00184                 irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
00185 }
00186 
00187 /*
00188  * Function irlap_send_ua_response_frame (qos)
00189  *
00190  *    Send UA (Unnumbered Acknowledgement) frame
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         /* Allocate frame */
00207         skb = dev_alloc_skb(64);
00208         if (!skb)
00209                 return;
00210 
00211         frame = (struct ua_frame *) skb_put(skb, 10);
00212         
00213         /* Build UA response */
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         /* Should we send QoS negotiation parameters? */
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  * Function irlap_send_dm_frame (void)
00235  *
00236  *    Send disconnected mode (DM) frame
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  * Function irlap_send_disc_frame (void)
00265  *
00266  *    Send disconnect (DISC) frame
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  * Function irlap_send_discovery_xid_frame (S, s, command)
00293  *
00294  *    Build and transmit a XID (eXchange station IDentifier) discovery
00295  *    frame. 
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          *  Provide info for final slot only in commands, and for all
00358          *  responses. Send the second byte of the hint only if the
00359          *  EXTENSION bit is set in the first byte.
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  * Function irlap_recv_discovery_xid_rsp (skb, info)
00384  *
00385  *    Received a XID discovery response
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         /* Make sure frame is addressed to us */
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         /* Get info returned from peer */
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          *  Terminate info string, should be safe since this is where the 
00444          *  FCS bytes resides.
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  * Function irlap_recv_discovery_xid_cmd (skb, info)
00457  *
00458  *    Received a XID discovery command
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         /* Make sure frame is addressed to us */
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                 /* Error!! */
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          *  Check if last frame 
00507          */
00508         if (info->s == 0xff) {
00509                 /*
00510                  *  We now have some discovery info to deliver!
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                  *  Terminate string, should be safe since this is where the 
00535                  *  FCS bytes resides.
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  * Function irlap_send_rr_frame (self, command)
00550  *
00551  *    Build and transmit RR (Receive Ready) frame. Notice that it is currently
00552  *    only possible to send RR frames with the poll bit set.
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  * Function irlap_send_rd_frame (self)
00575  *
00576  *    Request disconnect. Used by a secondary station to request the 
00577  *    disconnection of the link.
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  * Function irlap_recv_rr_frame (skb, info)
00598  *
00599  *    Received RR (Receive Ready) frame from peer station, no harm in
00600  *    making it inline since its called only from one single place
00601  *    (irlap_driver_rcv).
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         /* Check if this is a command or a response frame */
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  * Function irlap_recv_rnr_frame (self, skb, info)
00646  *
00647  *    Received RNR (Receive Not Ready) frame from peer station
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         /* Check if this is a command or a response frame */
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         /* Check if this is a command or a response frame */
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         /* Check if this is a command or a response frame */
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  * Function irlap_recv_ua_frame (skb, frame)
00705  *
00706  *    Received UA (Unnumbered Acknowledgement) frame
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  * Function irlap_send_data_primary(self, skb)
00718  *
00719  *    Send I-frames as the primary station but without the poll bit set
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                  *  Insert frame sequence number (Vs) in control field before
00730                  *  inserting into transmit window queue.
00731                  */
00732                 skb->data[1] = I_FRAME | (self->vs << 1);
00733                 
00734                 /* Copy buffer */
00735                 tx_skb = skb_clone(skb, GFP_ATOMIC);
00736                 if (tx_skb == NULL) {
00737                         dev_kfree_skb(skb);
00738                         return;
00739                 }
00740                 
00741                 /*
00742                  *  make sure the skb->sk accounting of memory usage is sane
00743                  */
00744                 if (skb->sk != NULL)
00745                         skb_set_owner_w(tx_skb, skb->sk);
00746                 
00747                 /* 
00748                  *  Insert frame in store, in case of retransmissions 
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  * Function irlap_send_data_primary_poll (self, skb)
00765  *
00766  *    Send I(nformation) frame as primary with poll bit set
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         /* Is this reliable or unreliable data? */
00773         if (skb->data[1] == I_FRAME) {
00774                 
00775                 /*  
00776                  *  Insert frame sequence number (Vs) in control field before
00777                  *  inserting into transmit window queue.
00778                  */
00779                 skb->data[1] = I_FRAME | (self->vs << 1);
00780                 
00781                 /* Copy buffer */
00782                 tx_skb = skb_clone(skb, GFP_ATOMIC);
00783                 if (tx_skb == NULL) {
00784                         dev_kfree_skb(skb);
00785                         return;
00786                 }
00787                 
00788                 /*
00789                  *  make sure the skb->sk accounting of memory usage is sane
00790                  */
00791                 if (skb->sk != NULL)
00792                         skb_set_owner_w(tx_skb, skb->sk);
00793                 
00794                 /* 
00795                  *  Insert frame in store, in case of retransmissions 
00796                  */
00797                 skb_queue_tail(&self->wx_list, skb);
00798                 
00799                 /*  
00800                  *  Set poll bit if necessary. We do this to the copied
00801                  *  skb, since retransmitted need to set or clear the poll
00802                  *  bit depending on when they are sent.  
00803                  */
00804                 /* Stop P timer */
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  * Function irlap_send_data_secondary_final (self, skb)
00836  *
00837  *    Send I(nformation) frame as secondary with final bit set
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         /* Is this reliable or unreliable data? */
00850         if (skb->data[1] == I_FRAME) {
00851 
00852                 /*  
00853                  *  Insert frame sequence number (Vs) in control field before
00854                  *  inserting into transmit window queue.
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                 /* Insert frame in store */
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  * Function irlap_send_data_secondary (self, skb)
00896  *
00897  *    Send I(nformation) frame as secondary without final bit set
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         /* Is this reliable or unreliable data? */
00905         if (skb->data[1] == I_FRAME) {
00906                 
00907                 /*  
00908                  *  Insert frame sequence number (Vs) in control field before
00909                  *  inserting into transmit window queue.
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                 /* Insert frame in store */
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  * Function irlap_resend_rejected_frames (nr)
00938  *
00939  *    Resend frames which has not been acknowledged. Should be safe to 
00940  *    traverse the list without locking it since this function will only be 
00941  *    called from interrupt context (BH)
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         /* Initialize variables */
00953         skb = tx_skb = NULL;
00954 
00955         count = skb_queue_len(&self->wx_list);
00956 
00957         /*  Resend unacknowledged frame(s) */
00958         skb = skb_peek(&self->wx_list);
00959         while (skb != NULL) {
00960                 irlap_wait_min_turn_around(self, &self->qos_tx);
00961 
00962                 /* We copy the skb to be retransmitted since we will have to 
00963                  * modify it. Cloning will confuse packet sniffers 
00964                  */
00965                 /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
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                 /* Unlink tx_skb from list */
00972                 tx_skb->next = tx_skb->prev = NULL;
00973                 tx_skb->list = NULL;
00974 
00975                 /*
00976                  *  make sure the skb->sk accounting of memory usage is sane
00977                  */
00978                 if (skb->sk != NULL)
00979                         skb_set_owner_w(tx_skb, skb->sk);
00980 
00981                 /* Clear old Nr field + poll bit */
00982                 tx_skb->data[1] &= 0x0f;
00983 
00984                 /* 
00985                  *  Set poll bit on the last frame retransmitted
00986                  */
00987                 if (count-- == 1)
00988                         tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
00989                 else
00990                         tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
00991                 
00992                 irlap_send_i_frame(self, tx_skb, command);
00993 
00994                 /* 
00995                  *  If our skb is the last buffer in the list, then
00996                  *  we are finished, if not, move to the next sk-buffer
00997                  */
00998                 if (skb == skb_peek_tail(&self->wx_list))
00999                         skb = NULL;
01000                 else
01001                         skb = skb->next;
01002         }
01003 #if 0 /* Not yet */
01004         /* 
01005          *  We can now fill the window with additinal data frames
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                          *  If send window > 1 then send frame with pf 
01017                          *  bit cleared
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         /* Initialize variables */
01040         skb = tx_skb = NULL;
01041 
01042         /*  Resend unacknowledged frame(s) */
01043         skb = skb_peek(&self->wx_list);
01044         if (skb != NULL) {
01045                 irlap_wait_min_turn_around(self, &self->qos_tx);
01046 
01047                 /* We copy the skb to be retransmitted since we will have to 
01048                  * modify it. Cloning will confuse packet sniffers 
01049                  */
01050                 /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
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                 /* Unlink tx_skb from list */
01057                 tx_skb->next = tx_skb->prev = NULL;
01058                 tx_skb->list = NULL;
01059 
01060                 /*
01061                  *  make sure the skb->sk accounting of memory usage is sane
01062                  */
01063                 if (skb->sk != NULL)
01064                         skb_set_owner_w(tx_skb, skb->sk);
01065 
01066                 /* Clear old Nr field + poll bit */
01067                 tx_skb->data[1] &= 0x0f;
01068 
01069                 /*  Set poll/final bit */
01070                 tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
01071                 
01072                 irlap_send_i_frame(self, tx_skb, command);
01073         }
01074 }
01075 
01076 /*
01077  * Function irlap_send_ui_frame (self, skb, command)
01078  *
01079  *    Contruct and transmit an Unnumbered Information (UI) frame
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         /* Insert connection address */
01092         skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
01093 
01094         irlap_queue_xmit(self, skb);
01095 }
01096 
01097 /*
01098  * Function irlap_send_i_frame (skb)
01099  *
01100  *    Contruct and transmit Information (I) frame
01101  */
01102 void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb, 
01103                         int command) 
01104 {
01105         /* Insert connection address */
01106         skb->data[0] = self->caddr;
01107         skb->data[0] |= (command) ? CMD_FRAME : 0;
01108         
01109         /* Insert next to receive (Vr) */
01110         skb->data[1] |= (self->vr << 5);  /* insert nr */
01111 
01112         irlap_queue_xmit(self, skb);
01113 }
01114 
01115 /*
01116  * Function irlap_recv_i_frame (skb, frame)
01117  *
01118  *    Receive and parse an I (Information) frame, no harm in making it inline
01119  *    since it's called only from one single place (irlap_driver_rcv).
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;          /* Next to receive */
01126         info->pf = skb->data[1] & PF_BIT;      /* Final bit */
01127         info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
01128 
01129         /* Check if this is a command or a response frame */
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  * Function irlap_recv_ui_frame (self, skb, info)
01138  *
01139  *    Receive and parse an Unnumbered Information (UI) frame
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;      /* Final bit */
01148 
01149         irlap_do_event(self, RECV_UI_FRAME, skb, info);
01150 }
01151 
01152 /*
01153  * Function irlap_recv_frmr_frame (skb, frame)
01154  *
01155  *    Received Frame Reject response.
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;          /* Next to receive */
01174         info->pf = frame[2] & PF_BIT;      /* Final bit */
01175         info->ns = (frame[2] >> 1) & 0x07; /* Next to send */
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  * Function irlap_send_test_frame (self, daddr)
01204  *
01205  *    Send a test frame response
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         /* Broadcast frames must include saddr and daddr fields */
01220         if (caddr == CBROADCAST) {
01221                 frame = (struct test_frame *) 
01222                         skb_put(skb, sizeof(struct test_frame));
01223 
01224                 /* Insert the swapped addresses */
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         /* Copy info */
01234         info = skb_put(skb, cmd->len);
01235         memcpy(info, cmd->data, cmd->len);
01236 
01237         /* Return to sender */
01238         irlap_wait_min_turn_around(self, &self->qos_tx);
01239         irlap_queue_xmit(self, skb);
01240 }
01241 
01242 /*
01243  * Function irlap_recv_test_frame (self, skb)
01244  *
01245  *    Receive a test frame
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         /* Broadcast frames must carry saddr and daddr fields */
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                 /* Read and swap addresses */
01267                 info->daddr = le32_to_cpu(frame->saddr);
01268                 info->saddr = le32_to_cpu(frame->daddr);
01269 
01270                 /* Make sure frame is addressed to us */
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  * Function irlap_driver_rcv (skb, netdev, ptype)
01286  *
01287  *    Called when a frame is received. Dispatches the right receive function 
01288  *    for processing of the frame.
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         /* FIXME: should we get our own field? */
01300         self = (struct irlap_cb *) dev->atalk_ptr;
01301 
01302         /* If the net device is down, then IrLAP is gone! */
01303         if (!self || self->magic != LAP_MAGIC) {
01304                 dev_kfree_skb(skb);
01305                 return -1;
01306         }
01307 
01308         /* Check if frame is large enough for parsing */
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; /* Mask away poll/final bit */
01320 
01321         control = info.control;
01322 
01323         /*  First we check if this frame has a valid connection address */
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          *  Optimize for the common case and check if the frame is an
01331          *  I(nformation) frame. Only I-frames have bit 0 set to 0
01332          */
01333         if (~control & 0x01) {
01334