linux-old/net/irda/irlap_frame.c
<<
>>
Prefs
   1/*********************************************************************
   2 *                
   3 * Filename:      irlap_frame.c
   4 * Version:       1.0
   5 * Description:   Build and transmit IrLAP frames
   6 * Status:        Stable
   7 * Author:        Dag Brattli <dagb@cs.uit.no>
   8 * Created at:    Tue Aug 19 10:27:26 1997
   9 * Modified at:   Wed Jan  5 08:59:04 2000
  10 * Modified by:   Dag Brattli <dagb@cs.uit.no>
  11 * 
  12 *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
  13 *     All Rights Reserved.
  14 *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
  15 *     
  16 *     This program is free software; you can redistribute it and/or 
  17 *     modify it under the terms of the GNU General Public License as 
  18 *     published by the Free Software Foundation; either version 2 of 
  19 *     the License, or (at your option) any later version.
  20 *
  21 *     Neither Dag Brattli nor University of Tromsø admit liability nor
  22 *     provide warranty for any of this software. This material is 
  23 *     provided "AS-IS" and at no charge.
  24 *
  25 ********************************************************************/
  26
  27#include <linux/skbuff.h>
  28#include <linux/if.h>
  29#include <linux/if_ether.h>
  30#include <linux/netdevice.h>
  31#include <linux/irda.h>
  32 
  33#include <net/pkt_sched.h>
  34#include <net/sock.h>
  35 
  36#include <asm/byteorder.h>
  37
  38#include <net/irda/irda.h>
  39#include <net/irda/irda_device.h>
  40#include <net/irda/irlap.h>
  41#include <net/irda/wrapper.h>
  42#include <net/irda/timer.h>
  43#include <net/irda/irlap_frame.h>
  44#include <net/irda/qos.h>
  45
  46/*
  47 * Function irlap_insert_info (self, skb)
  48 *
  49 *    Insert minimum turnaround time and speed information into the skb. We 
  50 *    need to do this since it's per packet relevant information. Safe to
  51 *    have this function inlined since it's only called from one place
  52 */
  53static inline void irlap_insert_info(struct irlap_cb *self, 
  54                                     struct sk_buff *skb)
  55{
  56        struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
  57
  58        /*  
  59         * Insert MTT (min. turn time) and speed into skb, so that the
  60         * device driver knows which settings to use 
  61         */
  62        cb->magic = LAP_MAGIC;
  63        cb->mtt = self->mtt_required;
  64        cb->next_speed = self->speed;
  65
  66        /* Reset */
  67        self->mtt_required = 0;
  68        
  69        /* 
  70         * Delay equals negotiated BOFs count, plus the number of BOFs to 
  71         * force the negotiated minimum turnaround time 
  72         */
  73        cb->xbofs = self->bofs_count;
  74        cb->next_xbofs = self->next_bofs;
  75        cb->xbofs_delay = self->xbofs_delay;
  76        
  77        /* Reset XBOF's delay (used only for getting min turn time) */
  78        self->xbofs_delay = 0;
  79        /* Put the correct xbofs value for the next packet */
  80        self->bofs_count = self->next_bofs;
  81}
  82
  83/*
  84 * Function irlap_queue_xmit (self, skb)
  85 *
  86 *    A little wrapper for dev_queue_xmit, so we can insert some common
  87 *    code into it.
  88 */
  89void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
  90{
  91        /* Some common init stuff */
  92        skb->dev = self->netdev;
  93        skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
  94        skb->protocol = htons(ETH_P_IRDA);
  95        skb->priority = TC_PRIO_BESTEFFORT;
  96
  97        irlap_insert_info(self, skb);
  98
  99        dev_queue_xmit(skb);
 100}
 101
 102/*
 103 * Function irlap_send_snrm_cmd (void)
 104 *
 105 *    Transmits a connect SNRM command frame
 106 */
 107void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) 
 108{
 109        struct sk_buff *skb;
 110        struct snrm_frame *frame;
 111        int ret;
 112
 113        ASSERT(self != NULL, return;);
 114        ASSERT(self->magic == LAP_MAGIC, return;);
 115
 116        /* Allocate frame */
 117        skb = dev_alloc_skb(64);
 118        if (!skb)
 119                return;
 120
 121        frame = (struct snrm_frame *) skb_put(skb, 2); 
 122
 123        /* Insert connection address field */
 124        if (qos)
 125                frame->caddr = CMD_FRAME | CBROADCAST;
 126        else
 127                frame->caddr = CMD_FRAME | self->caddr;
 128
 129        /* Insert control field */
 130        frame->control = SNRM_CMD | PF_BIT;
 131        
 132        /*
 133         *  If we are establishing a connection then insert QoS paramerters 
 134         */
 135        if (qos) {
 136                skb_put(skb, 9); /* 21 left */
 137                frame->saddr = cpu_to_le32(self->saddr);
 138                frame->daddr = cpu_to_le32(self->daddr);
 139
 140                frame->ncaddr = self->caddr;
 141                                
 142                ret = irlap_insert_qos_negotiation_params(self, skb);
 143                if (ret < 0) {
 144                        dev_kfree_skb(skb);
 145                        return;
 146                }
 147        }
 148        irlap_queue_xmit(self, skb);
 149}
 150
 151/*
 152 * Function irlap_recv_snrm_cmd (skb, info)
 153 *
 154 *    Received SNRM (Set Normal Response Mode) command frame
 155 *
 156 */
 157static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, 
 158                                struct irlap_info *info) 
 159{
 160        struct snrm_frame *frame;
 161
 162        frame = (struct snrm_frame *) skb->data;
 163        
 164        if (skb->len >= sizeof(struct snrm_frame)) {
 165                /* Copy the new connection address ignoring the C/R bit */
 166                info->caddr = frame->ncaddr & 0xFE;
 167
 168                /* Check if the new connection address is valid */
 169                if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
 170                        IRDA_DEBUG(3, "%s(), invalid connection address!\n", __FUNCTION__);
 171                        return;
 172                }
 173                
 174                /* Copy peer device address */
 175                info->daddr = le32_to_cpu(frame->saddr);
 176                info->saddr = le32_to_cpu(frame->daddr);
 177                
 178                /* Only accept if addressed directly to us */
 179                if (info->saddr != self->saddr) {
 180                        IRDA_DEBUG(2, "%s(), not addressed to us!\n", __FUNCTION__);
 181                        return;
 182                }
 183                irlap_do_event(self, RECV_SNRM_CMD, skb, info);
 184        } else {
 185                /* Signal that this SNRM frame does not contain and I-field */
 186                irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
 187        }
 188}
 189
 190/*
 191 * Function irlap_send_ua_response_frame (qos)
 192 *
 193 *    Send UA (Unnumbered Acknowledgement) frame
 194 *
 195 */
 196void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
 197{
 198        struct sk_buff *skb;
 199        struct ua_frame *frame;
 200        int ret;
 201        
 202        IRDA_DEBUG(2, "%s() <%ld>\n", __FUNCTION__, jiffies);
 203        
 204        ASSERT(self != NULL, return;);
 205        ASSERT(self->magic == LAP_MAGIC, return;);
 206
 207        skb = NULL;
 208
 209        /* Allocate frame */
 210        skb = dev_alloc_skb(64);
 211        if (!skb)
 212                return;
 213
 214        frame = (struct ua_frame *) skb_put(skb, 10);
 215        
 216        /* Build UA response */
 217        frame->caddr = self->caddr;
 218        frame->control = UA_RSP | PF_BIT;
 219
 220        frame->saddr = cpu_to_le32(self->saddr);
 221        frame->daddr = cpu_to_le32(self->daddr);
 222
 223        /* Should we send QoS negotiation parameters? */
 224        if (qos) {
 225                ret = irlap_insert_qos_negotiation_params(self, skb);
 226                if (ret < 0) {
 227                        dev_kfree_skb(skb);
 228                        return;
 229                }
 230        }
 231
 232        irlap_queue_xmit(self, skb);
 233}
 234
 235
 236/*
 237 * Function irlap_send_dm_frame (void)
 238 *
 239 *    Send disconnected mode (DM) frame
 240 *
 241 */
 242void irlap_send_dm_frame( struct irlap_cb *self)
 243{
 244        struct sk_buff *skb = NULL;
 245        __u8 *frame;
 246        
 247        ASSERT(self != NULL, return;);
 248        ASSERT(self->magic == LAP_MAGIC, return;);
 249
 250        skb = dev_alloc_skb(32);
 251        if (!skb)
 252                return;
 253
 254        frame = skb_put( skb, 2);
 255        
 256        if (self->state == LAP_NDM)
 257                frame[0] = CBROADCAST;
 258        else
 259                frame[0] = self->caddr;
 260
 261        frame[1] = DM_RSP | PF_BIT;
 262
 263        irlap_queue_xmit(self, skb);    
 264}
 265
 266/*
 267 * Function irlap_send_disc_frame (void)
 268 *
 269 *    Send disconnect (DISC) frame
 270 *
 271 */
 272void irlap_send_disc_frame(struct irlap_cb *self) 
 273{
 274        struct sk_buff *skb = NULL;
 275        __u8 *frame;
 276        
 277        IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 278
 279        ASSERT(self != NULL, return;);
 280        ASSERT(self->magic == LAP_MAGIC, return;);
 281
 282        skb = dev_alloc_skb(16);
 283        if (!skb)
 284                return;
 285
 286        frame = skb_put(skb, 2);
 287        
 288        frame[0] = self->caddr | CMD_FRAME;
 289        frame[1] = DISC_CMD | PF_BIT;
 290
 291        irlap_queue_xmit(self, skb);
 292}
 293
 294/*
 295 * Function irlap_send_discovery_xid_frame (S, s, command)
 296 *
 297 *    Build and transmit a XID (eXchange station IDentifier) discovery
 298 *    frame. 
 299 */
 300void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s, 
 301                                    __u8 command, discovery_t *discovery) 
 302{
 303        struct sk_buff *skb = NULL;
 304        struct xid_frame *frame;
 305        __u32 bcast = BROADCAST;
 306        __u8 *info;
 307
 308        IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__, s, S, 
 309                   command);
 310
 311        ASSERT(self != NULL, return;);
 312        ASSERT(self->magic == LAP_MAGIC, return;);
 313        ASSERT(discovery != NULL, return;);
 314
 315        skb = dev_alloc_skb(64);
 316        if (!skb)
 317                return;
 318
 319        skb_put(skb, 14);
 320        frame = (struct xid_frame *) skb->data;
 321
 322        if (command) {
 323                frame->caddr = CBROADCAST | CMD_FRAME;
 324                frame->control =  XID_CMD | PF_BIT;
 325        } else {
 326                frame->caddr = CBROADCAST;
 327                frame->control =  XID_RSP | PF_BIT;
 328        }
 329        frame->ident = XID_FORMAT;
 330
 331        frame->saddr = cpu_to_le32(self->saddr);
 332
 333        if (command)
 334                frame->daddr = cpu_to_le32(bcast);
 335        else
 336                frame->daddr = cpu_to_le32(discovery->daddr);
 337        
 338        switch (S) {
 339        case 1:
 340                frame->flags = 0x00;
 341                break;
 342        case 6:
 343                frame->flags = 0x01;
 344                break;
 345        case 8:
 346                frame->flags = 0x02;
 347                break;
 348        case 16:
 349                frame->flags = 0x03;
 350                break;
 351        default:
 352                frame->flags = 0x02;
 353                break;
 354        }
 355
 356        frame->slotnr = s; 
 357        frame->version = 0x00;
 358
 359        /*  
 360         *  Provide info for final slot only in commands, and for all
 361         *  responses. Send the second byte of the hint only if the
 362         *  EXTENSION bit is set in the first byte.
 363         */
 364        if (!command || (frame->slotnr == 0xff)) {
 365                int len;
 366
 367                if (discovery->hints.byte[0] & HINT_EXTENSION) {
 368                        info = skb_put(skb, 2);         
 369                        info[0] = discovery->hints.byte[0];
 370                        info[1] = discovery->hints.byte[1];
 371                } else {
 372                        info = skb_put(skb, 1);
 373                        info[0] = discovery->hints.byte[0];
 374                }
 375                info = skb_put(skb, 1);
 376                info[0] = discovery->charset;
 377
 378                len = IRDA_MIN(discovery->name_len, skb_tailroom(skb));
 379                info = skb_put(skb, len);
 380                memcpy(info, discovery->nickname, len);
 381        } 
 382        irlap_queue_xmit(self, skb);
 383}
 384
 385/*
 386 * Function irlap_recv_discovery_xid_rsp (skb, info)
 387 *
 388 *    Received a XID discovery response
 389 *
 390 */
 391static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, 
 392                                         struct sk_buff *skb, 
 393                                         struct irlap_info *info) 
 394{
 395        struct xid_frame *xid;
 396        discovery_t *discovery = NULL;
 397        __u8 *discovery_info;
 398        char *text;
 399
 400        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
 401
 402        ASSERT(self != NULL, return;);
 403        ASSERT(self->magic == LAP_MAGIC, return;);
 404
 405        xid = (struct xid_frame *) skb->data;
 406
 407        info->daddr = le32_to_cpu(xid->saddr);
 408        info->saddr = le32_to_cpu(xid->daddr);
 409
 410        /* Make sure frame is addressed to us */
 411        if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
 412                IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n", __FUNCTION__);
 413                return;
 414        }
 415
 416        if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
 417                WARNING("%s(), kmalloc failed!\n", __FUNCTION__);
 418                return;
 419        }
 420        memset(discovery, 0, sizeof(discovery_t));
 421
 422        discovery->daddr = info->daddr;
 423        discovery->saddr = self->saddr;
 424        discovery->timestamp = jiffies;
 425
 426        IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__, discovery->daddr);
 427
 428        discovery_info = skb_pull(skb, sizeof(struct xid_frame));
 429
 430        /* Get info returned from peer */
 431        discovery->hints.byte[0] = discovery_info[0];
 432        if (discovery_info[0] & HINT_EXTENSION) {
 433                IRDA_DEBUG(4, "EXTENSION\n");
 434                discovery->hints.byte[1] = discovery_info[1];
 435                discovery->charset = discovery_info[2];
 436                text = (char *) &discovery_info[3];
 437        } else {
 438                discovery->hints.byte[1] = 0;
 439                discovery->charset = discovery_info[1];
 440                text = (char *) &discovery_info[2];
 441        }
 442        /* 
 443         *  Terminate info string, should be safe since this is where the 
 444         *  FCS bytes resides.
 445         */
 446        skb->data[skb->len] = '\0'; 
 447        strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
 448        discovery->name_len = strlen(discovery->nickname);
 449
 450        info->discovery = discovery;
 451
 452        irlap_do_event(self, RECV_DISCOVERY_XID_RSP, skb, info);
 453}
 454
 455/*
 456 * Function irlap_recv_discovery_xid_cmd (skb, info)
 457 *
 458 *    Received a XID discovery command
 459 *
 460 */
 461static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, 
 462                                         struct sk_buff *skb, 
 463                                         struct irlap_info *info) 
 464{
 465        struct xid_frame *xid;
 466        discovery_t *discovery = NULL;
 467        __u8 *discovery_info;
 468        char *text;
 469
 470        xid = (struct xid_frame *) skb->data;
 471
 472        info->daddr = le32_to_cpu(xid->saddr);
 473        info->saddr = le32_to_cpu(xid->daddr);
 474
 475        /* Make sure frame is addressed to us */
 476        if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
 477                IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n", __FUNCTION__);
 478                return;
 479        }
 480
 481        switch (xid->flags & 0x03) {
 482        case 0x00:
 483                info->S = 1;
 484                break;
 485        case 0x01:
 486                info->S = 6;
 487                break;
 488        case 0x02:
 489                info->S = 8;
 490                break;
 491        case 0x03:
 492                info->S = 16;
 493                break;
 494        default:
 495                /* Error!! */
 496                dev_kfree_skb(skb);
 497                return;
 498        }
 499        info->s = xid->slotnr;
 500        
 501        discovery_info = skb_pull(skb, sizeof(struct xid_frame));
 502
 503        /* 
 504         *  Check if last frame 
 505         */
 506        if (info->s == 0xff) {
 507                /* Check if things are sane at this point... */
 508                if((discovery_info == NULL) || (skb->len < 3)) {
 509                        ERROR("%s(), discovery frame to short!\n", __FUNCTION__);
 510                        return;
 511                }
 512
 513                /*
 514                 *  We now have some discovery info to deliver!
 515                 */
 516                discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
 517                if (!discovery) {
 518                        WARNING("%s(), unable to malloc!\n", __FUNCTION__);
 519                        return;
 520                }
 521              
 522                discovery->daddr = info->daddr;
 523                discovery->saddr = self->saddr;
 524                discovery->timestamp = jiffies;
 525
 526                discovery->hints.byte[0] = discovery_info[0];
 527                if (discovery_info[0] & HINT_EXTENSION) {
 528                        discovery->hints.byte[1] = discovery_info[1];
 529                        discovery->charset = discovery_info[2];
 530                        text = (char *) &discovery_info[3];
 531                } else {
 532                        discovery->hints.byte[1] = 0;
 533                        discovery->charset = discovery_info[1];
 534                        text = (char *) &discovery_info[2];
 535                }
 536                /* 
 537                 *  Terminate string, should be safe since this is where the 
 538                 *  FCS bytes resides.
 539                 */
 540                skb->data[skb->len] = '\0'; 
 541                strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
 542                discovery->name_len = strlen(discovery->nickname);
 543
 544                info->discovery = discovery;
 545        } else
 546                info->discovery = NULL;
 547
 548        irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
 549}
 550
 551/*
 552 * Function irlap_send_rr_frame (self, command)
 553 *
 554 *    Build and transmit RR (Receive Ready) frame. Notice that it is currently
 555 *    only possible to send RR frames with the poll bit set.
 556 */
 557void irlap_send_rr_frame(struct irlap_cb *self, int command) 
 558{
 559        struct sk_buff *skb;
 560        __u8 *frame;
 561
 562        skb = dev_alloc_skb(16);
 563        if (!skb)
 564                return;
 565        
 566        frame = skb_put(skb, 2);
 567        
 568        frame[0] = self->caddr;
 569        frame[0] |= (command) ? CMD_FRAME : 0;
 570
 571        frame[1] = RR | PF_BIT | (self->vr << 5);
 572
 573        irlap_queue_xmit(self, skb);
 574}
 575
 576/*
 577 * Function irlap_send_rd_frame (self)
 578 *
 579 *    Request disconnect. Used by a secondary station to request the 
 580 *    disconnection of the link.
 581 */
 582void irlap_send_rd_frame(struct irlap_cb *self)
 583{
 584        struct sk_buff *skb;
 585        __u8 *frame;
 586
 587        skb = dev_alloc_skb(16);
 588        if (!skb)
 589                return;
 590        
 591        frame = skb_put(skb, 2);
 592        
 593        frame[0] = self->caddr;
 594        frame[1] = RD_RSP | PF_BIT;
 595
 596        irlap_queue_xmit(self, skb);
 597}
 598
 599/*
 600 * Function irlap_recv_rr_frame (skb, info)
 601 *
 602 *    Received RR (Receive Ready) frame from peer station, no harm in
 603 *    making it inline since its called only from one single place
 604 *    (irlap_driver_rcv).
 605 */
 606static inline void irlap_recv_rr_frame(struct irlap_cb *self, 
 607                                       struct sk_buff *skb, 
 608                                       struct irlap_info *info, int command)
 609{
 610        info->nr = skb->data[1] >> 5;
 611
 612        /* Check if this is a command or a response frame */
 613        if (command)
 614                irlap_do_event(self, RECV_RR_CMD, skb, info);
 615        else
 616                irlap_do_event(self, RECV_RR_RSP, skb, info);
 617}
 618
 619void irlap_send_frmr_frame( struct irlap_cb *self, int command)
 620{
 621        struct sk_buff *skb = NULL;
 622        __u8 *frame;
 623        
 624        ASSERT( self != NULL, return;);
 625        ASSERT( self->magic == LAP_MAGIC, return;);
 626
 627        skb = dev_alloc_skb( 32);
 628        if (!skb)
 629                return;
 630
 631        frame = skb_put( skb, 2);
 632        
 633        frame[0] = self->caddr;
 634        frame[0] |= (command) ? CMD_FRAME : 0;
 635
 636        frame[1]  = (self->vs << 1);
 637        frame[1] |= PF_BIT;
 638        frame[1] |= (self->vr << 5);
 639
 640        frame[2] = 0;
 641
 642        IRDA_DEBUG(4, "%s(), vr=%d, %ld\n", __FUNCTION__, self->vr, jiffies); 
 643
 644        irlap_queue_xmit(self, skb);
 645}
 646
 647/*
 648 * Function irlap_recv_rnr_frame (self, skb, info)
 649 *
 650 *    Received RNR (Receive Not Ready) frame from peer station
 651 *
 652 */
 653static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb, 
 654                                 struct irlap_info *info, int command) 
 655{
 656        info->nr = skb->data[1] >> 5;
 657
 658        IRDA_DEBUG(4, "%s(), nr=%d, %ld\n", __FUNCTION__, info->nr, jiffies);
 659
 660        if (command)
 661                irlap_do_event(self, RECV_RNR_CMD, skb, info);
 662        else
 663                irlap_do_event(self, RECV_RNR_RSP, skb, info);
 664}
 665
 666static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb, 
 667                                 struct irlap_info *info, int command)
 668{
 669        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 670
 671        info->nr = skb->data[1] >> 5;
 672        
 673        /* Check if this is a command or a response frame */
 674        if (command)
 675                irlap_do_event(self, RECV_REJ_CMD, skb, info);
 676        else
 677                irlap_do_event(self, RECV_REJ_RSP, skb, info);
 678}
 679
 680static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb, 
 681                                  struct irlap_info *info, int command)
 682{
 683        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 684
 685        info->nr = skb->data[1] >> 5;
 686        
 687        /* Check if this is a command or a response frame */
 688        if (command)
 689                irlap_do_event(self, RECV_SREJ_CMD, skb, info);
 690        else
 691                irlap_do_event(self, RECV_SREJ_RSP, skb, info);
 692}
 693
 694static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb, 
 695                                  struct irlap_info *info, int command)
 696{
 697        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 698
 699        /* Check if this is a command or a response frame */
 700        if (command)
 701                irlap_do_event(self, RECV_DISC_CMD, skb, info);
 702        else
 703                irlap_do_event(self, RECV_RD_RSP, skb, info);
 704}
 705
 706/*
 707 * Function irlap_recv_ua_frame (skb, frame)
 708 *
 709 *    Received UA (Unnumbered Acknowledgement) frame
 710 *
 711 */
 712static inline void irlap_recv_ua_frame(struct irlap_cb *self, 
 713                                       struct sk_buff *skb, 
 714                                       struct irlap_info *info) 
 715{
 716        irlap_do_event(self, RECV_UA_RSP, skb, info);
 717}
 718
 719/*
 720 * Function irlap_send_data_primary(self, skb)
 721 *
 722 *    Send I-frames as the primary station but without the poll bit set
 723 *
 724 */
 725void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
 726{
 727        struct sk_buff *tx_skb;
 728
 729        if (skb->data[1] == I_FRAME) {
 730
 731                /*  
 732                 *  Insert frame sequence number (Vs) in control field before
 733                 *  inserting into transmit window queue.
 734                 */
 735                skb->data[1] = I_FRAME | (self->vs << 1);
 736                
 737                /* Copy buffer */
 738                tx_skb = skb_clone(skb, GFP_ATOMIC);
 739                if (tx_skb == NULL) {
 740                        return;
 741                }
 742                
 743                /* 
 744                 *  Insert frame in store, in case of retransmissions 
 745                 */
 746                skb_queue_tail(&self->wx_list, skb_get(skb));
 747                
 748                self->vs = (self->vs + 1) % 8;
 749                self->ack_required = FALSE;             
 750                self->window -= 1;
 751
 752                irlap_send_i_frame( self, tx_skb, CMD_FRAME);
 753        } else {
 754                IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
 755                irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 756                self->window -= 1;
 757        }
 758}
 759/*
 760 * Function irlap_send_data_primary_poll (self, skb)
 761 *
 762 *    Send I(nformation) frame as primary with poll bit set
 763 */
 764void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) 
 765{
 766        struct sk_buff *tx_skb;
 767
 768        /* Stop P timer */
 769        del_timer(&self->poll_timer);
 770                
 771        /* Is this reliable or unreliable data? */
 772        if (skb->data[1] == I_FRAME) {
 773                
 774                /*  
 775                 *  Insert frame sequence number (Vs) in control field before
 776                 *  inserting into transmit window queue.
 777                 */
 778                skb->data[1] = I_FRAME | (self->vs << 1);
 779                
 780                /* Copy buffer */
 781                tx_skb = skb_clone(skb, GFP_ATOMIC);
 782                if (tx_skb == NULL) {
 783                        return;
 784                }
 785                
 786                /* 
 787                 *  Insert frame in store, in case of retransmissions 
 788                 */
 789                skb_queue_tail(&self->wx_list, skb_get(skb));
 790                
 791                /*  
 792                 *  Set poll bit if necessary. We do this to the copied
 793                 *  skb, since retransmitted need to set or clear the poll
 794                 *  bit depending on when they are sent.  
 795                 */
 796                tx_skb->data[1] |= PF_BIT;
 797                
 798                self->vs = (self->vs + 1) % 8;
 799                self->ack_required = FALSE;
 800
 801                irlap_send_i_frame(self, tx_skb, CMD_FRAME);
 802        } else {
 803                IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
 804
 805                if (self->ack_required) {
 806                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 807                        irlap_send_rr_frame(self, CMD_FRAME);
 808                        self->ack_required = FALSE;
 809                } else {
 810                        skb->data[1] |= PF_BIT;
 811                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
 812                }
 813        }
 814
 815        self->window = self->window_size;
 816#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 817        /* We are allowed to transmit a maximum number of bytes again. */
 818        self->bytes_left = self->line_capacity;
 819#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 820
 821        irlap_start_final_timer(self, self->final_timeout);
 822}
 823
 824/*
 825 * Function irlap_send_data_secondary_final (self, skb)
 826 *
 827 *    Send I(nformation) frame as secondary with final bit set
 828 *
 829 */
 830void irlap_send_data_secondary_final(struct irlap_cb *self, 
 831                                     struct sk_buff *skb) 
 832{
 833        struct sk_buff *tx_skb = NULL;
 834
 835        ASSERT(self != NULL, return;);
 836        ASSERT(self->magic == LAP_MAGIC, return;);
 837        ASSERT(skb != NULL, return;);
 838
 839        /* Is this reliable or unreliable data? */
 840        if (skb->data[1] == I_FRAME) {
 841
 842                /*  
 843                 *  Insert frame sequence number (Vs) in control field before
 844                 *  inserting into transmit window queue.
 845                 */
 846                skb->data[1] = I_FRAME | (self->vs << 1);
 847                
 848                tx_skb = skb_clone(skb, GFP_ATOMIC);
 849                if (tx_skb == NULL) {
 850                        return;
 851                }               
 852
 853                /* Insert frame in store */
 854                skb_queue_tail(&self->wx_list, skb_get(skb));
 855                
 856                tx_skb->data[1] |= PF_BIT;
 857                
 858                self->vs = (self->vs + 1) % 8; 
 859                self->ack_required = FALSE;
 860                
 861                irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
 862        } else {
 863                if (self->ack_required) {
 864                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
 865                        irlap_send_rr_frame(self, RSP_FRAME);
 866                        self->ack_required = FALSE;
 867                } else {
 868                        skb->data[1] |= PF_BIT;
 869                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
 870                }
 871        }
 872
 873        self->window = self->window_size;
 874#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
 875        /* We are allowed to transmit a maximum number of bytes again. */
 876        self->bytes_left = self->line_capacity;
 877#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 878
 879        irlap_start_wd_timer(self, self->wd_timeout);
 880}
 881
 882/*
 883 * Function irlap_send_data_secondary (self, skb)
 884 *
 885 *    Send I(nformation) frame as secondary without final bit set
 886 *
 887 */
 888void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb) 
 889{
 890        struct sk_buff *tx_skb = NULL;
 891
 892        /* Is this reliable or unreliable data? */
 893        if (skb->data[1] == I_FRAME) {
 894                
 895                /*  
 896                 *  Insert frame sequence number (Vs) in control field before
 897                 *  inserting into transmit window queue.
 898                 */
 899                skb->data[1] = I_FRAME | (self->vs << 1);
 900                
 901                tx_skb = skb_clone(skb, GFP_ATOMIC);
 902                if (tx_skb == NULL) {
 903                        return;
 904                }               
 905                
 906                /* Insert frame in store */
 907                skb_queue_tail(&self->wx_list, skb_get(skb));
 908                
 909                self->vs = (self->vs + 1) % 8;
 910                self->ack_required = FALSE;             
 911                self->window -= 1;
 912
 913                irlap_send_i_frame(self, tx_skb, RSP_FRAME); 
 914        } else {
 915                irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
 916                self->window -= 1;
 917        }
 918}
 919
 920/*
 921 * Function irlap_resend_rejected_frames (nr)
 922 *
 923 *    Resend frames which has not been acknowledged. Should be safe to 
 924 *    traverse the list without locking it since this function will only be 
 925 *    called from interrupt context (BH)
 926 */
 927void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
 928{
 929        struct sk_buff *tx_skb;
 930        struct sk_buff *skb;
 931        int count;
 932
 933        ASSERT(self != NULL, return;);
 934        ASSERT(self->magic == LAP_MAGIC, return;);
 935
 936        /* Initialize variables */
 937        skb = tx_skb = NULL;
 938
 939        count = skb_queue_len(&self->wx_list);
 940
 941        /*  Resend unacknowledged frame(s) */
 942        skb = skb_peek(&self->wx_list);
 943        while (skb != NULL) {
 944                irlap_wait_min_turn_around(self, &self->qos_tx);
 945
 946                /* We copy the skb to be retransmitted since we will have to 
 947                 * modify it. Cloning will confuse packet sniffers 
 948                 */
 949                /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
 950                tx_skb = skb_copy(skb, GFP_ATOMIC);
 951                if (!tx_skb) {
 952                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
 953                        return;
 954                }
 955                /* Unlink tx_skb from list */
 956                tx_skb->next = tx_skb->prev = NULL;
 957                tx_skb->list = NULL;
 958
 959                /* Clear old Nr field + poll bit */
 960                tx_skb->data[1] &= 0x0f;
 961
 962                /* 
 963                 *  Set poll bit on the last frame retransmitted
 964                 */
 965                if (count-- == 1)
 966                        tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
 967                else
 968                        tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
 969                
 970                irlap_send_i_frame(self, tx_skb, command);
 971
 972                /* 
 973                 *  If our skb is the last buffer in the list, then
 974                 *  we are finished, if not, move to the next sk-buffer
 975                 */
 976                if (skb == skb_peek_tail(&self->wx_list))
 977                        skb = NULL;
 978                else
 979                        skb = skb->next;
 980        }
 981#if 0 /* Not yet */
 982        /* 
 983         *  We can now fill the window with additinal data frames
 984         */
 985        while (skb_queue_len( &self->txq) > 0) {
 986                
 987                IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
 988                if ((skb_queue_len( &self->txq) > 0) && 
 989                    (self->window > 0)) {
 990                        skb = skb_dequeue( &self->txq); 
 991                        ASSERT(skb != NULL, return;);
 992
 993                        /*
 994                         *  If send window > 1 then send frame with pf 
 995                         *  bit cleared
 996                         */ 
 997                        if ((self->window > 1) && 
 998                            skb_queue_len(&self->txq) > 0) 
 999                        {
1000                                irlap_send_data_primary(self, skb);
1001                        } else {
1002                                irlap_send_data_primary_poll(self, skb);
1003                        }
1004                        kfree_skb(skb);
1005                }
1006        }
1007#endif
1008}
1009
1010void irlap_resend_rejected_frame(struct irlap_cb *self, int command)
1011{
1012        struct sk_buff *tx_skb;
1013        struct sk_buff *skb;
1014
1015        ASSERT(self != NULL, return;);
1016        ASSERT(self->magic == LAP_MAGIC, return;);
1017
1018        /* Initialize variables */
1019        skb = tx_skb = NULL;
1020
1021        /*  Resend unacknowledged frame(s) */
1022        skb = skb_peek(&self->wx_list);
1023        if (skb != NULL) {
1024                irlap_wait_min_turn_around(self, &self->qos_tx);
1025
1026                /* We copy the skb to be retransmitted since we will have to 
1027                 * modify it. Cloning will confuse packet sniffers 
1028                 */
1029                /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
1030                tx_skb = skb_copy(skb, GFP_ATOMIC);
1031                if (!tx_skb) {
1032                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
1033                        return; 
1034                }
1035                /* Unlink tx_skb from list */
1036                tx_skb->next = tx_skb->prev = NULL;
1037                tx_skb->list = NULL;
1038
1039                /* Clear old Nr field + poll bit */
1040                tx_skb->data[1] &= 0x0f;
1041
1042                /*  Set poll/final bit */
1043                tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
1044                
1045                irlap_send_i_frame(self, tx_skb, command);
1046        }
1047}
1048
1049/*
1050 * Function irlap_send_ui_frame (self, skb, command)
1051 *
1052 *    Contruct and transmit an Unnumbered Information (UI) frame
1053 *
1054 */
1055void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb, 
1056                         __u8 caddr, int command)
1057{
1058        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1059        
1060        ASSERT(self != NULL, return;);
1061        ASSERT(self->magic == LAP_MAGIC, return;);
1062        ASSERT(skb != NULL, return;);
1063        
1064        /* Insert connection address */
1065        skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
1066
1067        irlap_queue_xmit(self, skb);
1068}
1069
1070/*
1071 * Function irlap_send_i_frame (skb)
1072 *
1073 *    Contruct and transmit Information (I) frame
1074 */
1075void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb, 
1076                        int command) 
1077{
1078        /* Insert connection address */
1079        skb->data[0] = self->caddr;
1080        skb->data[0] |= (command) ? CMD_FRAME : 0;
1081        
1082        /* Insert next to receive (Vr) */
1083        skb->data[1] |= (self->vr << 5);  /* insert nr */
1084
1085        irlap_queue_xmit(self, skb);
1086}
1087
1088/*
1089 * Function irlap_recv_i_frame (skb, frame)
1090 *
1091 *    Receive and parse an I (Information) frame, no harm in making it inline
1092 *    since it's called only from one single place (irlap_driver_rcv).
1093 */
1094static inline void irlap_recv_i_frame(struct irlap_cb *self, 
1095                                      struct sk_buff *skb, 
1096                                      struct irlap_info *info, int command) 
1097{
1098        info->nr = skb->data[1] >> 5;          /* Next to receive */
1099        info->pf = skb->data[1] & PF_BIT;      /* Final bit */
1100        info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
1101
1102        /* Check if this is a command or a response frame */
1103        if (command)
1104                irlap_do_event(self, RECV_I_CMD, skb, info);
1105        else
1106                irlap_do_event(self, RECV_I_RSP, skb, info);
1107}
1108
1109/*
1110 * Function irlap_recv_ui_frame (self, skb, info)
1111 *
1112 *    Receive and parse an Unnumbered Information (UI) frame
1113 *
1114 */
1115static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb, 
1116                                struct irlap_info *info)
1117{
1118        IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
1119
1120        info->pf = skb->data[1] & PF_BIT;      /* Final bit */
1121
1122        irlap_do_event(self, RECV_UI_FRAME, skb, info);
1123}
1124
1125/*
1126 * Function irlap_recv_frmr_frame (skb, frame)
1127 *
1128 *    Received Frame Reject response.
1129 *
1130 */
1131static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, 
1132                                  struct irlap_info *info) 
1133{
1134        __u8 *frame;
1135        int w, x, y, z;
1136
1137        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
1138        
1139        ASSERT(self != NULL, return;);
1140        ASSERT(self->magic == LAP_MAGIC, return;);
1141        ASSERT(skb != NULL, return;);
1142        ASSERT(info != NULL, return;);
1143        
1144        frame = skb->data;
1145
1146        info->nr = frame[2] >> 5;          /* Next to receive */
1147        info->pf = frame[2] & PF_BIT;      /* Final bit */
1148        info->ns = (frame[2] >> 1) & 0x07; /* Next to send */
1149
1150        w = frame[3] & 0x01;
1151        x = frame[3] & 0x02;
1152        y = frame[3] & 0x04;
1153        z = frame[3] & 0x08;
1154        
1155        if (w) {
1156                IRDA_DEBUG(0, "Rejected control field is undefined or not "
1157                      "implemented.\n");
1158        } 
1159        if (x) {
1160                IRDA_DEBUG(0, "Rejected control field was invalid because it "
1161                      "contained a non permitted I field.\n");
1162        }
1163        if (y) {
1164                IRDA_DEBUG(0, "Received I field exceeded the maximum negotiated "
1165                      "for the existing connection or exceeded the maximum "
1166                      "this station supports if no connection exists.\n");
1167        }
1168        if (z) {
1169                IRDA_DEBUG(0, "Rejected control field control field contained an "
1170                      "invalid Nr count.\n");
1171        }
1172        irlap_do_event(self, RECV_FRMR_RSP, skb, info);
1173}
1174
1175/*
1176 * Function irlap_send_test_frame (self, daddr)
1177 *
1178 *    Send a test frame response
1179 *
1180 */
1181void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, 
1182                           struct sk_buff *cmd)
1183{
1184        struct sk_buff *skb;
1185        struct test_frame *frame;
1186        __u8 *info;
1187
1188        skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame));
1189        if (!skb)
1190                return;
1191
1192        /* Broadcast frames must include saddr and daddr fields */
1193        if (caddr == CBROADCAST) {
1194                frame = (struct test_frame *) 
1195                        skb_put(skb, sizeof(struct test_frame));
1196
1197                /* Insert the swapped addresses */
1198                frame->saddr = cpu_to_le32(self->saddr);
1199                frame->daddr = cpu_to_le32(daddr);
1200        } else
1201                frame = (struct test_frame *) skb_put(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
1202
1203        frame->caddr = caddr;
1204        frame->control = TEST_RSP | PF_BIT;
1205
1206        /* Copy info */
1207        info = skb_put(skb, cmd->len);
1208        memcpy(info, cmd->data, cmd->len);
1209
1210        /* Return to sender */
1211        irlap_wait_min_turn_around(self, &self->qos_tx);
1212        irlap_queue_xmit(self, skb);
1213}
1214
1215/*
1216 * Function irlap_recv_test_frame (self, skb)
1217 *
1218 *    Receive a test frame
1219 *
1220 */
1221static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, 
1222                                  struct irlap_info *info, int command)
1223{
1224        struct test_frame *frame;
1225
1226        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
1227        
1228        frame = (struct test_frame *) skb->data;
1229                
1230        /* Broadcast frames must carry saddr and daddr fields */
1231        if (info->caddr == CBROADCAST) {
1232                if (skb->len < sizeof(struct test_frame)) {
1233                        IRDA_DEBUG(0, "%s() test frame to short!\n", __FUNCTION__);
1234                        return;
1235                }
1236                
1237                /* Read and swap addresses */
1238                info->daddr = le32_to_cpu(frame->saddr);
1239                info->saddr = le32_to_cpu(frame->daddr);
1240
1241                /* Make sure frame is addressed to us */
1242                if ((info->saddr != self->saddr) && 
1243                    (info->saddr != BROADCAST)) {
1244                        return;
1245                }
1246        }
1247
1248        if (command)
1249                irlap_do_event(self, RECV_TEST_CMD, skb, info);
1250        else
1251                irlap_do_event(self, RECV_TEST_RSP, skb, info);
1252}
1253
1254/*
1255 * Function irlap_driver_rcv (skb, netdev, ptype)
1256 *
1257 *    Called when a frame is received. Dispatches the right receive function 
1258 *    for processing of the frame.
1259 *
1260 */
1261int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, 
1262                     struct packet_type *ptype)
1263{
1264        struct irlap_info info;
1265        struct irlap_cb *self;
1266        int command;
1267        __u8 control;
1268        
1269        /* FIXME: should we get our own field? */
1270        self = (struct irlap_cb *) dev->atalk_ptr;
1271
1272        /* If the net device is down, then IrLAP is gone! */
1273        if (!self || self->magic != LAP_MAGIC) {
1274                dev_kfree_skb(skb);
1275                return -1;
1276        }
1277
1278        /* Check if frame is large enough for parsing */
1279        if (skb->len < 2) {
1280                ERROR("%s(), frame to short!\n", __FUNCTION__);
1281                dev_kfree_skb(skb);
1282                return -1;
1283        }
1284        
1285        command    = skb->data[0] & CMD_FRAME;
1286        info.caddr = skb->data[0] & CBROADCAST;
1287        
1288        info.pf      = skb->data[1] &  PF_BIT;
1289        info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
1290
1291        control = info.control;
1292
1293        /*  First we check if this frame has a valid connection address */
1294        if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
1295                IRDA_DEBUG(0, "%s(), wrong connection address!\n", __FUNCTION__);
1296                goto out;
1297        }
1298        /*  
1299         *  Optimize for the common case and check if the frame is an
1300         *  I(nformation) frame. Only I-frames have bit 0 set to 0
1301         */
1302        if (~control & 0x01) {
1303                irlap_recv_i_frame(self, skb, &info, command);
1304                goto out;
1305        }
1306        /*
1307         *  We now check is the frame is an S(upervisory) frame. Only 
1308         *  S-frames have bit 0 set to 1 and bit 1 set to 0
1309         */
1310        if (~control & 0x02) {
1311                /* 
1312                 *  Received S(upervisory) frame, check which frame type it is
1313                 *  only the first nibble is of interest
1314                 */
1315                switch (control & 0x0f) {
1316                case RR:
1317                        irlap_recv_rr_frame(self, skb, &info, command);
1318                        break;
1319                case RNR:
1320                        irlap_recv_rnr_frame(self, skb, &info, command);
1321                        break;
1322                case REJ:
1323                        irlap_recv_rej_frame(self, skb, &info, command);
1324                        break;
1325                case SREJ:
1326                        irlap_recv_srej_frame(self, skb, &info, command);
1327                        break;
1328                default:
1329                        WARNING("%s() Unknown S-frame %02x received!\n", __FUNCTION__,
1330                                info.control);
1331                        break;
1332                }
1333                goto out;
1334        }
1335        /* 
1336         *  This must be a C(ontrol) frame 
1337         */
1338        switch (control) {
1339        case XID_RSP:
1340                irlap_recv_discovery_xid_rsp(self, skb, &info);
1341                break;
1342        case XID_CMD:
1343                irlap_recv_discovery_xid_cmd(self, skb, &info);
1344                break;
1345        case SNRM_CMD:
1346                irlap_recv_snrm_cmd(self, skb, &info);
1347                break;
1348        case DM_RSP:
1349                irlap_do_event(self, RECV_DM_RSP, skb, &info);
1350                break;
1351        case DISC_CMD: /* And RD_RSP since they have the same value */
1352                irlap_recv_disc_frame(self, skb, &info, command);
1353                break;
1354        case TEST_CMD:
1355                irlap_recv_test_frame(self, skb, &info, command);
1356                break;
1357        case UA_RSP:
1358                irlap_recv_ua_frame(self, skb, &info);
1359                break;
1360        case FRMR_RSP:
1361                irlap_recv_frmr_frame(self, skb, &info);
1362                break;
1363        case UI_FRAME:
1364                irlap_recv_ui_frame(self, skb, &info);
1365                break;
1366        default:
1367                WARNING("%s(), Unknown frame %02x received!\n", __FUNCTION__,
1368                        info.control);
1369                break;
1370        }
1371out:
1372        dev_kfree_skb(skb); 
1373        return 0;
1374}
1375
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.