common.c 20.7 KB
Newer Older
1
2
3
4
5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

nikaeinn's avatar
nikaeinn committed
22
23
24
/*! \file common.c
* \brief implementation of emultor tx and rx
* \author Navid Nikaein, Lionel GAUTHIER, and Raymomd Knopp
25
* \date 2011
nikaeinn's avatar
nikaeinn committed
26
* \version 1.0
27
* \company Eurecom
nikaeinn's avatar
nikaeinn committed
28
29
* \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#include "local.h"
#include "proto_extern.h"

//#define NAS_DEBUG_RECEIVE 1
//#define NAS_DEBUG_SEND 1
//#define NAS_DEBUG_CLASS 1
//#define NAS_ADDRESS_FIX 1

#include <linux/inetdevice.h>

#include <net/tcp.h>
#include <net/udp.h>


45
46
47
48
49
50
void nas_COMMON_receive(uint16_t dlen,
                        void *pdcp_sdu,
                        int inst,
                        struct classifier_entity *rclass,
                        nasRadioBearerId_t rb_id)
{
51
52
53
54
55

  //---------------------------------------------------------------------------
  struct sk_buff *skb;
  struct ipversion *ipv;
  struct nas_priv *gpriv=netdev_priv(nasdev[inst]);
gauthier's avatar
gauthier committed
56
  uint32_t odaddr,osaddr;
57

Cedric Roux's avatar
Cedric Roux committed
58
  //int i;
59
60
61

  unsigned char protocol;

Cedric Roux's avatar
Cedric Roux committed
62
  unsigned char /**addr,*/ *daddr,*saddr,*ifaddr /*,sn*/;
63

Cedric Roux's avatar
Cedric Roux committed
64
65
  //struct udphdr *uh;
  //struct tcphdr *th;
gauthier's avatar
gauthier committed
66
  uint16_t *cksum,check;
67

68
  struct iphdr *network_header;
69
70
71
72
73
74

#ifdef NAS_DEBUG_RECEIVE

  printk("NAS_COMMON_RECEIVE: begin RB %d Inst %d Length %d bytes\n",rb_id,inst,dlen);
#endif
  skb = dev_alloc_skb( dlen + 2 );
75
76
77
78
79
80
81

  if(!skb) {
    printk("NAS_COMMON_RECEIVE: low on memory\n");
    ++gpriv->stats.rx_dropped;
    return;
  }

82
83
84
85
  skb_reserve(skb,2);
  memcpy(skb_put(skb, dlen), pdcp_sdu,dlen);

  skb->dev = nasdev[inst];
86

87
  skb_reset_mac_header(skb);
88
  //printk("[NAC_COMMIN_RECEIVE]: Packet Type %d (%d,%d)",skb->pkt_type,PACKET_HOST,PACKET_BROADCAST);
89
90
91
92
93
94
95
96
  skb->pkt_type = PACKET_HOST;

  if (rclass->version != NAS_MPLS_VERSION_CODE) {  // This is an IP packet

    skb->ip_summed = CHECKSUM_NONE;


    ipv = (struct ipversion *)skb->data;
97
98
99

    switch (ipv->version) {
    case 6:
100
#ifdef NAS_DEBUG_RECEIVE
101
      printk("NAS_COMMON_RECEIVE: receive IPv6 message\n");
102
103
104
#endif


105
106
107
108
      skb_reset_network_header(skb);

      skb->protocol = htons(ETH_P_IPV6);
      //  printk("Writing packet with protocol %x\n",ntohs(skb->protocol));
109

110
      break;
111

112
    case 4:
113
#ifdef NAS_ADDRESS_FIX
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
      // Make the third byte of both the source and destination equal to the fourth of the destination



      daddr = (unsigned char *)&((struct iphdr *)skb->data)->daddr;
      odaddr = ((struct iphdr *)skb->data)->daddr;
      //    sn = addr[3];
      saddr = (unsigned char *)&((struct iphdr *)skb->data)->saddr;
      osaddr = ((struct iphdr *)skb->data)->saddr;

      if (daddr[0] == saddr[0]) {// same network
        daddr[2] = daddr[3]; // set third byte of destination to that of local machine so that local IP stack accepts the packet
        saddr[2] = daddr[3]; // set third byte of source to that of local machine so that local IP stack accepts the packet
      } else { // get the 3rd byte from device address in net_device structure
        ifaddr = (unsigned char *)(&(((struct in_device *)((nasdev[inst])->ip_ptr))->ifa_list->ifa_local));

        if (saddr[0] == ifaddr[0]) { // source is in same network as local machine
          daddr[0] += saddr[3];        // fix address of remote destination to undo change at source
          saddr[2] =  ifaddr[2];       // set third byte to that of local machine so that local IP stack accepts the packet
        } else {                       // source is remote machine from outside network
          saddr[0] -= daddr[3];        // fix address of remote source to be understood by destination
          daddr[2] =  daddr[3];        // fix 3rd byte of local address to be understood by IP stack of
          // destination
        }
      }

140
141
#endif //NAS_ADDRESS_FIX
#ifdef NAS_DEBUG_RECEIVE
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
      //    printk("NAS_TOOL_RECEIVE: receive IPv4 message\n");
      addr = (unsigned char *)&((struct iphdr *)skb->data)->saddr;

      if (addr) {
        //      addr[2]^=0x01;
        printk("[NAS][COMMON][RECEIVE] Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
      }

      addr = (unsigned char *)&((struct iphdr *)skb->data)->daddr;

      if (addr) {
        //      addr[2]^=0x01;
        printk("[NAS][COMMON][RECEIVE] Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);
      }

      printk("[NAS][COMMON][RECEIVE] protocol  %d\n",((struct iphdr *)skb->data)->protocol);

#endif

      skb_reset_network_header(skb);
      network_header = (struct iphdr *)skb_network_header(skb);
      protocol = network_header->protocol;
164
165

#ifdef NAS_DEBUG_RECEIVE
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

      switch (protocol) {
      case IPPROTO_IP:
        printk("[NAS][COMMON][RECEIVE] Received Raw IPv4 packet\n");
        break;

      case IPPROTO_IPV6:
        printk("[NAS][COMMON][RECEIVE] Received Raw IPv6 packet\n");
        break;

      case IPPROTO_ICMP:
        printk("[NAS][COMMON][RECEIVE] Received Raw ICMP packet\n");
        break;

      case IPPROTO_TCP:
        printk("[NAS][COMMON][RECEIVE] Received TCP packet\n");
        break;

      case IPPROTO_UDP:
        printk("[NAS][COMMON][RECEIVE] Received UDP packet\n");
        break;

      default:
        break;
      }

#endif

194
195
196
#ifdef NAS_ADDRESS_FIX

#ifdef NAS_DEBUG_RECEIVE
Cedric Roux's avatar
Cedric Roux committed
197
      printk("NAS_COMMON_RECEIVE: dumping the packet before the csum recalculation (len %d)\n",skb->len);
198
199
200
201
202

      for (i=0; i<skb->len; i++)
        printk("%2x ",((unsigned char *)(skb->data))[i]);

      printk("\n");
203
204
205
#endif //NAS_DEBUG_RECEIVE


206
207
208
      network_header->check = 0;
      network_header->check = ip_fast_csum((unsigned char *) network_header,
                                           network_header->ihl);
209
#ifdef NAS_DEBUG_RECEIVE
210
      printk("[NAS][COMMON][RECEIVE] IP Fast Checksum %x \n", network_header->check);
211
212
#endif

213
214
      //    if (!(skb->nh.iph->frag_off & htons(IP_OFFSET))) {

215
216


217
218
219
220
221

      switch(protocol) {

      case IPPROTO_TCP:

222
        cksum  = (uint16_t*)&(((struct tcphdr*)(((char *)network_header + (network_header->ihl<<2))))->check);
223
        //check  = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, tcp_hdrlen(skb), IPPROTO_TCP, ~(*cksum));
224
225

#ifdef NAS_DEBUG_RECEIVE
226
227
228
229
230
231
232
233
234
235
236
237
        printk("[NAS][COMMON] Inst %d TCP packet calculated CS %x, CS = %x (before), SA (%x)%x, DA (%x)%x\n",
               inst,
               network_header->check,
               *cksum,
               osaddr,
               ((struct iphdr *)skb->data)->saddr,
               odaddr,
               ((struct iphdr *)skb->data)->daddr);
#endif
        check  = csum_tcpudp_magic(((struct iphdr *)skb->data)->saddr, ((struct iphdr *)skb->data)->daddr,0,0, ~(*cksum));
        *cksum = csum_tcpudp_magic(~osaddr, ~odaddr, 0, 0, ~check);

238
#ifdef NAS_DEBUG_RECEIVE
239
240
241
        printk("[NAS][COMMON] Inst %d TCP packet NEW CS %x\n",
               inst,
               *cksum);
242
#endif
243
        break;
244

245
246
      case IPPROTO_UDP:

247
        cksum  = (uint16_t*)&(((struct udphdr*)(((char *)network_header + (network_header->ihl<<2))))->check);
248
        // check = csum_tcpudp_magic(((struct iphdr *)network_header)->saddr, ((struct iphdr *)network_header)->daddr, udp_hdr(skb)->len, IPPROTO_UDP, ~(*cksum));
249
#ifdef NAS_DEBUG_RECEIVE
250
251
252
253
254
255
256
257
258
259
260
        printk("[NAS][COMMON] Inst %d UDP packet CS = %x (before), SA (%x)%x, DA (%x)%x\n",
               inst,
               *cksum,
               osaddr,
               ((struct iphdr *)skb->data)->saddr,
               odaddr,
               ((struct iphdr *)skb->data)->daddr);
#endif
        check = csum_tcpudp_magic(((struct iphdr *)skb->data)->saddr, ((struct iphdr *)skb->data)->daddr, 0,0, ~(*cksum));
        *cksum= csum_tcpudp_magic(~osaddr, ~odaddr,0,0, ~check);
        //*cksum= csum_tcpudp_magic(~osaddr, ~odaddr,udp_hdr(skb)->len, IPPROTO_UDP, ~check);
261
262

#ifdef NAS_DEBUG_RECEIVE
263
264
265
266
267
268
        printk("[NAS][COMMON] Inst %d UDP packet NEW CS %x\n",
               inst,
               *cksum);
#endif
        //    if ((check = *cksum) != 0) {
        // src, dst, len, proto, sum
269
270


271
272
273
274
        //    }

        break;

275
      default:
276
        break;
277
      }
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

      //    }

#endif //NAS_ADDRESS_FIX

      skb->protocol = htons(ETH_P_IP);
      //  printk("[NAS][COMMON] Writing packet with protocol %x\n",ntohs(skb->protocol));
      break;

    default:
      printk("NAS_COMMON_RECEIVE: begin RB %d Inst %d Length %d bytes\n",rb_id,inst,dlen);

      printk("[NAS][COMMON] Inst %d: receive unknown message (version=%d)\n",inst,ipv->version);

    }
  } else { // This is an MPLS packet
294
295
296
297
298
299
300

#ifdef NAS_DEBUG_RECEIVE
    printk("NAS_COMMON_RECEIVE: Received an MPLS packet on RB %d\n",rb_id);
#endif
    skb->protocol = htons(ETH_P_MPLS_UC);

  }
301

302
303
304
305
  ++gpriv->stats.rx_packets;
  gpriv->stats.rx_bytes += dlen;
#ifdef NAS_DEBUG_RECEIVE
  printk("NAS_COMMON_RECEIVE: sending packet of size %d to kernel\n",skb->len);
306
307
308
309

  for (i=0; i<skb->len; i++)
    printk("%2x ",((unsigned char *)(skb->data))[i]);

310
311
  printk("\n");
#endif //NAS_DEBUG_RECEIVE
312
  netif_rx_ni(skb);
313
314
315
316
317
318
319
#ifdef NAS_DEBUG_RECEIVE
  printk("NAS_COMMON_RECEIVE: end\n");
#endif
}

//---------------------------------------------------------------------------
// Delete the data
Cedric Roux's avatar
Cedric Roux committed
320
void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp,int inst,struct nas_priv *gpriv)
321
{
322
323
324
325
326
327
328
329
  struct nas_priv *priv=netdev_priv(nasdev[inst]);
  //---------------------------------------------------------------------------
  ++priv->stats.tx_dropped;
}

//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)

Cedric Roux's avatar
Cedric Roux committed
330
void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv)
331
{
332
  //---------------------------------------------------------------------------
gauthier's avatar
gauthier committed
333
  struct pdcp_data_req_header_s     pdcph;
334
335
336
337
338
  struct nas_priv *priv=netdev_priv(nasdev[inst]);
#ifdef LOOPBACK_TEST
  int i;
#endif
  unsigned int bytes_wrote;
Cedric Roux's avatar
Cedric Roux committed
339
  //unsigned char j;
340
341
342
343
  // Start debug information
#ifdef NAS_DEBUG_SEND
  printk("NAS_COMMON_QOS_SEND - inst %d begin \n",inst);
#endif
344
345
346
347
348
349
350
351

  //  if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
  //  {
  //    priv->stats.tx_dropped ++;
  //    printk("NAS_QOS_SEND: No connected, so message are dropped \n");
  //    return;
  //  }
  if (skb==NULL) {
352
353
354
355
356
#ifdef NAS_DEBUG_SEND
    printk("NAS_COMMON_QOS_SEND - input parameter skb is NULL \n");
#endif
    return;
  }
357
358

  if (gc==NULL) {
359
360
361
362
363
#ifdef NAS_DEBUG_SEND
    printk("NAS_COMMON_QOS_SEND - input parameter gc is NULL \n");
#endif
    return;
  }
364
365

  if (cx==NULL) {
366
367
368
369
370
#ifdef NAS_DEBUG_SEND
    printk("NAS_COMMON_QOS_SEND - input parameter cx is NULL \n");
#endif
    return;
  }
371

372
  // End debug information
373
374
375
376
377
378
379
  if (gc->rb==NULL) {
    gc->rb=nas_COMMON_search_rb(cx, gc->rab_id);

    if (gc->rb==NULL) {
      ++priv->stats.tx_dropped;
      printk("NAS_COMMON_QOS_SEND: No corresponding Radio Bearer, so message are dropped, rab_id=%u \n", gc->rab_id);
      return;
380
    }
381
382
  }

383
384
385
386
387
388
389
390
391
392
#ifdef NAS_DEBUG_SEND
  printk("NAS_COMMON_QOS_SEND #1 :");
  printk("lcr %u, rab_id %u, rab_id %u, skb_len %d\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id,skb->len);
  nas_print_classifier(gc);
#endif
  pdcph.data_size  = skb->len;
  pdcph.rb_id      = (gc->rb)->rab_id;
  pdcph.inst       = inst;


393
#ifdef PDCP_USE_NETLINK
394
395
396
  bytes_wrote = nas_netlink_send((char *)&pdcph,NAS_PDCPH_SIZE);
#ifdef NAS_DEBUG_SEND
  printk("[NAS] Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n",
397
         bytes_wrote,skb->len);
398
399
400
401
402
#endif
#else
  bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE);
#ifdef NAS_DEBUG_SEND
  printk("[NAS] Wrote %d bytes (header for %d byte skb) to PDCP fifo\n",
403
         bytes_wrote,skb->len);
404
#endif
405
#endif //PDCP_USE_NETLINK
406
407
408
409

  if (bytes_wrote != NAS_PDCPH_SIZE) {
    printk("NAS_COMMON_QOS_SEND: problem while writing PDCP's header (bytes wrote = %d )\n",bytes_wrote);
    printk("rb_id %d, Wrote %d, Header Size %lu\n", pdcph.rb_id , bytes_wrote, NAS_PDCPH_SIZE);
410
#ifndef PDCP_USE_NETLINK
411
    rtf_reset(NAS2PDCP_FIFO);
412
#endif //PDCP_USE_NETLINK
413
414
415
    return;
  }

416
#ifdef  PDCP_USE_NETLINK
417
418
419
  bytes_wrote += nas_netlink_send((char *)skb->data,skb->len);
#else
  bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len);
420
#endif //PDCP_USE_NETLINK
421

422
423
424
425
426
427
428
  if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) {
    printk("NAS_COMMON_QOS_SEND: Inst %d, RB_ID %d: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %lu\n",
           inst,
           pdcph.rb_id,
           bytes_wrote,
           skb->len,
           NAS_PDCPH_SIZE); // congestion
429
#ifndef PDCP_USE_NETLINK
430
    rtf_reset(NAS2PDCP_FIFO);
431
#endif //PDCP_USE_NETLINK
432
433
434
    return;
  }

435
436
#ifdef NAS_DEBUG_SEND
  printk("NAS_SEND: Sending packet of size %d to PDCP \n",skb->len);
437
438
439
440

  for (j=0; j<skb->len; j++)
    printk("%2x ",((unsigned char *)(skb->data))[j]);

441
442
443
444
445
446
447
448
449
450
  printk("\n");
#endif

  priv->stats.tx_bytes   += skb->len;
  priv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND
  printk("NAS_COMMON_QOS_SEND - end \n");
#endif
}

451
#ifndef PDCP_USE_NETLINK
452
//---------------------------------------------------------------------------
453
454
void nas_COMMON_QOS_receive()
{
455
  //---------------------------------------------------------------------------
gauthier's avatar
gauthier committed
456
  uint8_t sapi;
gauthier's avatar
gauthier committed
457
  struct pdcp_data_ind_header_s     pdcph;
458
459
460
461
462
463
464
465
466
  unsigned char data_buffer[2048];
  struct classifier_entity *rclass;
  struct nas_priv *priv;
  int bytes_read;

  // Start debug information
#ifdef NAS_DEBUG_RECEIVE
  printk("NAS_COMMON_QOS_RECEIVE - begin \n");
#endif
467

468
  // End debug information
469

470
  bytes_read =  rtf_get(PDCP2PDCP_USE_RT_FIFO,&pdcph, NAS_PDCPH_SIZE);
471

472
  while (bytes_read>0) {
473
474
475
476
477
    if (bytes_read != NAS_PDCPH_SIZE) {
      printk("NAS_COMMON_QOS_RECEIVE: problem while reading PDCP header\n");
      return;
    }

478
479
    priv=netdev_priv(nasdev[pdcph.inst]);
    rclass = nas_COMMON_search_class_for_rb(pdcph.rb_id,priv);
480

481
    bytes_read+= rtf_get(PDCP2PDCP_USE_RT_FIFO,
482
483
484
                         data_buffer,
                         pdcph.data_size);

485
486
#ifdef NAS_DEBUG_RECEIVE
    printk("NAS_COMMON_QOS_RECEIVE - Got header for RB %d, Inst %d \n",
487
488
           pdcph.rb_id,
           pdcph.inst);
489
#endif
490

491
492
493
494
    if (rclass) {
#ifdef NAS_DEBUG_RECEIVE
      printk("[NAS][COMMON] Found corresponding connection in classifier for RAB\n");
#endif //NAS_DEBUG_RECEIVE
495
496
497
498
499
500

      nas_COMMON_receive(pdcph.data_size,
                         (void *)data_buffer,
                         pdcph.inst,
                         rclass,
                         pdcph.rb_id);
501
    }
502

503
    bytes_read =  rtf_get(PDCP2PDCP_USE_RT_FIFO, &pdcph, NAS_PDCPH_SIZE);
504
  }
505
506
507



508
509
510
511
512
513
514
515
516
#ifdef NAS_DEBUG_RECEIVE
  printk("NAS_COMMON_QOS_RECEIVE - end \n");
#endif
}

#else
void nas_COMMON_QOS_receive(struct nlmsghdr *nlh)
{

gauthier's avatar
gauthier committed
517
  struct pdcp_data_ind_header_s     *pdcph = (struct pdcp_data_ind_header_s *)NLMSG_DATA(nlh);
518
519
520
521
522
523
524
525
  struct classifier_entity *rclass;
  struct nas_priv *priv;

  priv = netdev_priv(nasdev[pdcph->inst]);


#ifdef NAS_DEBUG_RECEIVE
  printk("[NAS][COMMON][NETLINK] QOS receive from PDCP, size %d, rab %d, inst %d\n",
526
         pdcph->data_size,pdcph->rb_id,pdcph->inst);
527
528
529
530
531
532
533
534
#endif //NAS_DEBUG_RECEIVE

  rclass = nas_COMMON_search_class_for_rb(pdcph->rb_id,priv);

  if (rclass) {
#ifdef NAS_DEBUG_RECEIVE
    printk("[NAS][COMMON][NETLINK] Found corresponding connection in classifier for RAB\n");
#endif //NAS_DEBUG_RECEIVE
535
536
537
538
539
540
541

    nas_COMMON_receive(pdcph->data_size,
                       (unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE,
                       pdcph->inst,
                       rclass,
                       pdcph->rb_id);
  }
542
543

}
544
#endif //PDCP_USE_NETLINK
545
546

//---------------------------------------------------------------------------
547
548
struct cx_entity *nas_COMMON_search_cx(nasLocalConnectionRef_t lcr,struct nas_priv *priv)
{
549
550
551
552
  //---------------------------------------------------------------------------
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_SEARCH_CX - lcr %d\n",lcr);
#endif
553

554
555
556
557
558
559
560
561
  if (lcr<NAS_CX_MAX)
    return priv->cx+lcr;
  else
    return NULL;
}

//---------------------------------------------------------------------------
// Search a Radio Bearer
562
563
struct rb_entity *nas_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id)
{
564
565
566
567
568
  //---------------------------------------------------------------------------
  struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_SEARCH_RB - rab_id %d\n", rab_id);
#endif
569

570
571
  for (rb=cx->rb; rb!=NULL; rb=rb->next) {
#ifdef NAS_DEBUG_CLASS
572
    printk("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");
Cedric Roux's avatar
Cedric Roux committed
573
574
575
576
577
578
    printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.rab_id %u \n", rb->rab_id, rab_id);
    //printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.sapi %u \n", rb->sapi);
    //printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.qos %u \n", rb->qos);
    //printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.state %u \n", rb->state);
    //printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.retry %u \n", rb->retry);
    //printk("NAS_COMMON_SEARCH_RB - rab_id %d Comparing  rb_entity.countimer %u \n\n", rb->countimer);
579
580
581
582
#endif

                                if (rb->rab_id==rab_id)
                                return rb;
583
  }
584
585

                     return NULL;
586
587
}

588
589
              //
              // Search for a classifier with corresponding radio bearer
590

591
592
              struct classifier_entity *nas_COMMON_search_class_for_rb(nasRadioBearerId_t rab_id,struct nas_priv *priv)
{
593

Cedric Roux's avatar
Cedric Roux committed
594
  //struct rb_entity *rb;
595
596
597
598
599
600
601
  int dscp;
  struct classifier_entity *rclass;

#ifdef NAS_DEBUG_CLASS
  printk("[NAS][COMMON] NAS_COMMON_SEARCH_CLASS_FOR_RB - rab_id %d\n", rab_id);
#endif

602
603
604
  for (dscp=0; dscp<NAS_DSCP_MAX; dscp++) {

    //      printk("[NAS][COMMON] priv->rclassifier[%d] = %p\n",dscp,priv->rclassifier[dscp]);
605
606
607
608
    for (rclass=priv->rclassifier[dscp]; rclass!=NULL; rclass=rclass->next) {
#ifdef NAS_DEBUG_CLASS
      printk("[NAS][COMMON] NAS_COMMON_SEARCH_CLASS_FOR_RB - dscp %d, rb %d\n", dscp,rclass->rab_id);
#endif
609

610
      if (rclass->rab_id==rab_id)
611
        return rclass;
612
613
    }
  }
614

615
  return NULL;
616

617
618
619
}

//---------------------------------------------------------------------------
620
621
struct rb_entity *nas_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos)
{
622
623
624
625
626
  //--------------------------------------------------------------------------
  struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_ADD_RB - begin for rab_id %d , qos %d\n", rab_id, qos );
#endif
627
628

  if (cx==NULL) {
629
630
631
632
633
#ifdef NAS_DEBUG_CLASS
    printk("NAS_COMMON_ADD_RB - input parameter cx is NULL \n");
#endif
    return NULL;
  }
634

635
  rb=nas_COMMON_search_rb(cx, rab_id);
636
637
638
639
640
641
642
643
644

  if (rb==NULL) {
    rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL);

    if (rb!=NULL) {
      rb->retry=0;
      rb->countimer=NAS_TIMER_IDLE;
      rb->rab_id=rab_id;
      //      rb->rab_id=rab_id+(32*cx->lcr);
645
#ifdef NAS_DEBUG_DC
646
647
648
649
650
651
652
653
654
655
656
657
      printk("NAS_COMMON_ADD_RB: rab_id=%u, mt_id=%u\n",rb->rab_id, cx->lcr);
#endif
      rb->qos=qos;
      rb->sapi=NAS_RAB_INPUT_SAPI;
      rb->state=NAS_IDLE;
      rb->next=cx->rb;
      cx->rb=rb;
      ++cx->num_rb;
    } else
      printk("NAS_ADD_CTL_RB: no memory\n");
  }

658
659
660
661
662
663
664
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_ADD_RB - end \n" );
#endif
  return rb;
}

//---------------------------------------------------------------------------
665
666
void nas_COMMON_flush_rb(struct cx_entity *cx)
{
667
668
669
  //---------------------------------------------------------------------------
  struct rb_entity *rb;
  struct classifier_entity *gc;
gauthier's avatar
gauthier committed
670
  uint8_t dscp;
671
672
673
674
  // End debug information
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_FLUSH_RB - begin\n");
#endif
675
676

  if (cx==NULL) {
677
678
679
680
681
#ifdef NAS_DEBUG_CLASS
    printk("NAS_COMMON_FLUSH_RB - input parameter cx is NULL \n");
#endif
    return;
  }
682

683
  // End debug information
684
  for (rb=cx->rb; rb!=NULL; rb=cx->rb) {
685
686
687
688
    printk("NAS_COMMON_FLUSH_RB: del rab_id %u\n", rb->rab_id);
    cx->rb=rb->next;
    kfree(rb);
  }
689

690
691
  cx->num_rb=0;
  cx->rb=NULL;
692
693
694
695
696
697

  for(dscp=0; dscp<NAS_DSCP_MAX; ++dscp) {
    for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next)
      gc->rb=NULL;
  }

698
699
700
701
#ifdef NAS_DEBUG_CLASS
  printk("NAS_COMMON_FLUSH_RB - end\n");
#endif
}