//---------------------------------------------------------------------------
struct rb_entity *nasmt_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos)
{
  //---------------------------------------------------------------------------
  struct rb_entity *rb;
#ifdef NAS_DEBUG_CLASS
  printk("nasmt_COMMON_add_rb - begin for rab_id %d , qos %d\n", rab_id, qos );
#endif

  if (cx==NULL) {
    printk("nasmt_COMMON_add_rb - input parameter cx is NULL \n");
    return NULL;
  }

  rb=nasmt_COMMON_search_rb(cx, rab_id);

  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);
#ifdef NAS_DEBUG_DC
      printk("nasmt_COMMON_add_rb: rb rab_id=%u, rab_id=%u, mt_id=%u\n",rb->rab_id,rab_id, cx->lcr);
#endif
      rb->qos=qos;
      rb->sapi=NAS_DRB_INPUT_SAPI;
      // LG force the use of only one rt-fifo rb->sapi=NAS_BA_INPUT_SAPI;
      rb->state=NAS_IDLE;
      rb->next=cx->rb;
      cx->rb=rb;
      ++cx->num_rb;
    } else
      printk("nasmt_COMMON_add_rb: no memory\n");
  }

#ifdef NAS_DEBUG_CLASS
  printk("nasmt_COMMON_add_rb - end \n" );
#endif
  return rb;
}
예제 #2
0
파일: nasmt_common.c 프로젝트: a4a881d4/oai
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc){
//---------------------------------------------------------------------------
	struct pdcp_data_req     pdcph;
// Start debug information
#ifdef GRAAL_DEBUG_SEND
	printk("nasmt_COMMON_QOS_send - begin \n");
#endif
//	if (cx->state!=GRAAL_STATE_CONNECTED) // <--- A REVOIR
//	{
//		gpriv->stats.tx_dropped ++;
//		printk("GRAAL_QOS_SEND: No connected, so message are dropped \n");
//		return;
//	}
  if (skb==NULL){
 	  printk("nasmt_COMMON_QOS_send - input parameter skb is NULL \n");
    return;
  }
  if (gc==NULL){
 	  printk("nasmt_COMMON_QOS_send - input parameter gc is NULL \n");
    return;
  }
  if (cx==NULL){
 	  printk("nasmt_COMMON_QOS_send - input parameter cx is NULL \n");
    return;
  }
// End debug information
	if (gc->rb==NULL){
		gc->rb = nasmt_COMMON_search_rb(cx, gc->rab_id);
		if (gc->rb==NULL){
			++gpriv->stats.tx_dropped;
			printk("nasmt_COMMON_QOS_send: No corresponding Radio Bearer, so message are dropped, rab_id=%u \n", gc->rab_id);
			return;
		}
	}
#ifdef GRAAL_DEBUG_SEND
	printk("nasmt_COMMON_QOS_send #1 :");
	printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id);
  nasmt_TOOL_print_classifier(gc);
#endif
	pdcph.data_size  = skb->len;
	pdcph.rb_id      = (gc->rb)->rab_id+(32*cx->lcr);
	bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE);
	if (bytes_wrote != NAS_PDCPH_SIZE){
		printk("nasmt_COMMON_QOS_send: problem while writing PDCP's header\n");
		printk("rb_id %d, SAP index %d, Wrote %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS_PDCPH_SIZE);
		return;
	}
	bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len);
	if (bytes_wrote != skb->len+NAS_PDCPH_SIZE){
		printk("nasmt_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion
		return;
	}
#ifdef GRAAL_DEBUG_SEND
	printk("nasmt_COMMON_QOS_send - %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id,gpriv->sap[(gc->rb)->sapi]);
#endif
	gpriv->stats.tx_bytes   += skb->len;
	gpriv->stats.tx_packets ++;
#ifdef GRAAL_DEBUG_SEND
	printk("nasmt_COMMON_QOS_send - end \n");
#endif
}
//---------------------------------------------------------------------------
// Request the transfer of data (QoS SAP)
void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
{
  //---------------------------------------------------------------------------
  //struct pdcp_data_req     pdcph;
  struct pdcp_data_req_header_t     pdcph;
  int bytes_wrote = 0;

  // Start debug information
#ifdef NAS_DEBUG_SEND
  printk("nasmt_COMMON_QOS_send - begin \n");
#endif

  //  if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR
  //  {
  //    gpriv->stats.tx_dropped ++;
  //    printk("NAS_QOS_SEND: No connected, so message are dropped \n");
  //    return;
  //  }
  if (!skb || !gc || !cx) {
    printk("nasmt_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n");
    return;
  }

  // End debug information

  if (gc->rb==NULL) {
    gc->rb = nasmt_COMMON_search_rb(cx, gc->rab_id);

    if (gc->rb==NULL) {
      ++gpriv->stats.tx_dropped;
      printk("nasmt_COMMON_QOS_send: No corresponding Radio Bearer, so message is dropped, rab_id=%u \n", gc->rab_id);
      return;
    }
  }

#ifdef NAS_DEBUG_SEND
  printk("nasmt_COMMON_QOS_send #1 :");
  printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id);
  nasmt_TOOL_print_classifier(gc);
#endif

  pdcph.data_size  = skb->len;
  pdcph.rb_id      = ((gc->rb)->rab_id+(32*cx->lcr))-NAS_SIG_NUM_SRB;
  pdcph.inst       = 0;

#ifdef PDCP_USE_NETLINK
  bytes_wrote = nasmt_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP);
  //printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len);
#else
  //bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE);
  bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE);
  //printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len);
#endif //PDCP_USE_NETLINK

  if (bytes_wrote != NAS_PDCPH_SIZE) {
    printk("nasmt_COMMON_QOS_send: problem while writing PDCP's header\n");
    printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
    gpriv->stats.tx_dropped ++;
    return;
  }

#ifdef  PDCP_USE_NETLINK
  bytes_wrote += nasmt_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP);
#else
  //bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len);
  bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len);
#endif //PDCP_USE_NETLINK

  if (bytes_wrote != skb->len + NAS_PDCPH_SIZE) {
    printk("nasmt_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion
    printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE);
    gpriv->stats.tx_dropped ++;
    return;
  }

#ifdef NAS_DEBUG_SEND
  printk("nasmt_COMMON_QOS_send - %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id,NAS2PDCP_FIFO);
#endif
  gpriv->stats.tx_bytes   += skb->len;
  gpriv->stats.tx_packets ++;
#ifdef NAS_DEBUG_SEND
  printk("nasmt_COMMON_QOS_send - end \n");
#endif
}
///////////////////////////////////////////////////////////////////////////////
// Request the addition of a classifier rule
//---------------------------------------------------------------------------
void nasmt_set_msg_class_add_reply(struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq)
{
  //---------------------------------------------------------------------------
  struct classifier_entity *gc;

  if (msgreq->dscp>NAS_DSCP_DEFAULT) {
    printk("nasmt_set_msg_class_add_reply: Incoherent parameter value\n");
    msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
    return;
  }

  if (msgreq->dir==NAS_DIRECTION_SEND) {
    struct cx_entity *cx;
    cx=nasmt_COMMON_search_cx(msgreq->lcr);

    if (cx!=NULL) {
      printk("nasmt_set_msg_class_add_reply: DSCP %d, Classref %d\n",msgreq->dscp, msgreq->classref );
      gc=nasmt_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref);
      printk("nasmt_set_msg_class_add_reply: %p %p\n" , msgreq, gc);

      if (gc==NULL) {
        msgrep->status=-NAS_ERROR_NOMEMORY;
        return;
      }
    } else {
      msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
      return;
    }

    gc->rab_id=msgreq->rab_id;
    gc->rb=nasmt_COMMON_search_rb(cx, gc->rab_id);
  } else {
    if (msgreq->dir==NAS_DIRECTION_RECEIVE) {
      gc=nasmt_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref);

      if (gc==NULL) {
        msgrep->status=-NAS_ERROR_NOMEMORY;
        return;
      }
    } else {
      msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
      return;
    }
  }

  nasmt_TOOL_fct(gc, msgreq->fct);
  gc->version=msgreq->version;

  switch(gc->version) {
  case 4:
    gc->saddr.ipv4=msgreq->saddr.ipv4;
    gc->daddr.ipv4=msgreq->daddr.ipv4;
    gc->splen=msgreq->splen;
    gc->dplen=msgreq->dplen;
    break;

  case 6:
    gc->saddr.ipv6=msgreq->saddr.ipv6;
    gc->daddr.ipv6=msgreq->daddr.ipv6;
    gc->splen=msgreq->splen;
    gc->dplen=msgreq->dplen;
    break;

  case 0:
    gc->saddr.ipv6.s6_addr32[0]=0;
    gc->daddr.ipv6.s6_addr32[1]=0;
    gc->saddr.ipv6.s6_addr32[2]=0;
    gc->daddr.ipv6.s6_addr32[3]=0;
    gc->splen=0;
    gc->dplen=0;
    break;

  default:
    msgrep->status=-NAS_ERROR_NOTCORRECTVERSION;
    kfree(gc);
    return;
  }

  gc->protocol=msgreq->protocol;
  gc->sport=htons(msgreq->sport);
  gc->dport=htons(msgreq->dport);
  msgrep->status=0;
}