git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7117 818b1a75-f10b-46b9-bf7c-635c3b92a50f
1504 lines
54 KiB
C
Executable File
1504 lines
54 KiB
C
Executable File
/***************************************************************************
|
|
nasrg_ascontrol.c - description
|
|
***************************************************************************
|
|
Access Stratum Control features for eNodeB
|
|
***************************************************************************
|
|
Eurecom OpenAirInterface 2
|
|
Copyright(c) 1999 - 2013 Eurecom
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
under the terms and conditions of the GNU General Public License,
|
|
version 2, as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
The full GNU General Public License is included in this distribution in
|
|
the file called "COPYING".
|
|
|
|
Contact Information
|
|
Openair Admin: openair_admin@eurecom.fr
|
|
Openair Tech : openair_tech@eurecom.fr
|
|
Forums : http://forums.eurecom.fsr/openairinterface
|
|
Address : Eurecom, 450 route des Chappes, 06410 Biot Sophia Antipolis, France
|
|
*******************************************************************************/
|
|
/*! \file nasrg_ascontrol.c
|
|
* \brief Access Stratum Control functions for OpenAirInterface CELLULAR version - RG
|
|
* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier
|
|
* \company Eurecom
|
|
* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
|
|
*/
|
|
/*******************************************************************************/
|
|
#ifdef NODE_RG
|
|
#include "nasrg_variables.h"
|
|
#include "nasrg_proto.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
void nasrg_ASCTL_init(void)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int cxi, i;
|
|
|
|
gpriv->next_sclassref = NASRG_DEFAULTRAB_CLASSREF;
|
|
|
|
// Initialize MBMS services list in MT
|
|
for (cxi=0; cxi<NAS_CX_MAX ; ++cxi) {
|
|
for (i = 0; i<NASRG_MBMS_SVCES_MAX; i++) {
|
|
gpriv->cx[cxi].requested_joined_services[i]= -1;
|
|
gpriv->cx[cxi].requested_left_services[i]= -1;
|
|
gpriv->cx[cxi].joined_services[i]= -1;
|
|
}
|
|
}
|
|
|
|
printk("nasrg_ASCTL_init Complete\n");
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nasrg_ASCTL_write(int sap, unsigned char *data_buffer, unsigned int data_length)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int bytes_wrote = 0;
|
|
#ifdef PDCP_USE_NETLINK
|
|
unsigned char xmit_buffer [NAS_MESSAGE_MAXLEN];
|
|
|
|
//write SAP_Id
|
|
switch (sap) {
|
|
case RRC_DEVICE_GC:
|
|
xmit_buffer[0] = RRC_NAS_GC_IN;
|
|
break;
|
|
|
|
case RRC_DEVICE_NT:
|
|
xmit_buffer[0] = RRC_NAS_NT_IN;
|
|
break;
|
|
|
|
case RRC_DEVICE_DC_INPUT0:
|
|
xmit_buffer[0] = RRC_NAS_DC0_IN;
|
|
break;
|
|
|
|
case RRC_DEVICE_DC_INPUT1:
|
|
xmit_buffer[0] = RRC_NAS_DC1_IN;
|
|
//case RRC_DEVICE_DC_INPUT2:
|
|
//xmit_buffer[0] = RRC_NAS_DC2_IN;
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_write - ERROR - Invalid SAP %d\n", sap);
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
memcpy (&((char*)xmit_buffer)[1], data_buffer, data_length);
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_write - Sending data to RRC, sap %d, length %d (including NETLINK SAP value)\n", sap, data_length+1);
|
|
nasrg_TOOL_print_buffer(xmit_buffer,data_length+1);
|
|
#endif
|
|
bytes_wrote = nasrg_netlink_send(xmit_buffer,data_length+1, NASNL_DEST_RRC);
|
|
#else
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version
|
|
bytes_wrote = rtf_put(sap, data_buffer, data_length+1);
|
|
#endif //PDCP_USE_NETLINK
|
|
return bytes_wrote-1;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//For demo, add automatically a radio bearer
|
|
//Equivalent to rb add send 0 5 2
|
|
void nasrg_ASCTL_start_default_rb(struct cx_entity *cx)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
#ifdef DEMO_3GSM
|
|
struct rb_entity *rb;
|
|
int status;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_start_default_rb - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_start_default_rb - input parameter cx is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
|
|
rb = nasrg_COMMON_add_rb(cx, NASRG_DEFAULTRAB_RBID, NASRG_DEFAULTRAB_QoS);
|
|
|
|
if (rb!=NULL) {
|
|
rb->cnxid = (NAS_RB_MAX_NUM * cx->lcr)+1;
|
|
//rb->default_rab =1;
|
|
rb->dscp = NASRG_DEFAULTRAB_DSCP;
|
|
rb->dscp_ul = NASRG_DEFAULTRAB_DSCP;
|
|
status=nasrg_ASCTL_DC_send_rb_establish_request(cx, rb);
|
|
} else
|
|
status=-NAS_ERROR_NOMEMORY;
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_start_default_rb - end %d \n",status);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------
|
|
//For demo, add automatically a classifier
|
|
//Equivalent to class add send 0 -f qos <x> -cr 0
|
|
void nasrg_ASCTL_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *rb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct classifier_entity *gc;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_default_sclassifier - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !rb) {
|
|
printk("nasrg_ASCTL_start_default_sclassifier - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
gc=nasrg_CLASS_add_sclassifier(cx, NAS_DSCP_DEFAULT, gpriv->next_sclassref);
|
|
|
|
if (gc==NULL) {
|
|
printk("nasrg_ASCTL_start_default_sclassifier - Classifier pointer is null : not added \n");
|
|
return;
|
|
}
|
|
|
|
gc->fct = nasrg_COMMON_QOS_send;
|
|
gc->rab_id =rb->rab_id;
|
|
gc->rb= rb;
|
|
gc->version = NASRG_DEFAULTRAB_IPVERSION;
|
|
gc->protocol= NAS_PROTOCOL_DEFAULT;
|
|
gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH;
|
|
// copy locator part of address into the gc structure
|
|
//gc->daddr.ipv6.s6_addr32[0] = 0;
|
|
//gc->daddr.ipv6.s6_addr32[1] = 0;
|
|
//gc->daddr.ipv6.s6_addr32[2] = 0;
|
|
//gc->daddr.ipv6.s6_addr32[3] = 0;
|
|
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_default_sclassifier - end \n");
|
|
nasrg_TOOL_print_classifier(gc);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//Add automatically a classifier on DSCP
|
|
//Equivalent to class add send 0 -f qos <x> -cr 0
|
|
void nasrg_ASCTL_start_sclassifier(struct cx_entity *cx,struct rb_entity *rb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct classifier_entity *gc;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_sclassifier - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !rb) {
|
|
printk("nasrg_ASCTL_start_sclassifier - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
gc=nasrg_CLASS_add_sclassifier(cx, rb->dscp, gpriv->next_sclassref);
|
|
|
|
if (gc==NULL) {
|
|
printk("nasrg_ASCTL_start_sclassifier - Classifier pointer is null : not added \n");
|
|
return;
|
|
}
|
|
|
|
gc->fct = nasrg_COMMON_QOS_send;
|
|
gc->rab_id =rb->rab_id;
|
|
gc->rb= rb;
|
|
gc->version = NASRG_DEFAULTRAB_IPVERSION;
|
|
gc->protocol= NAS_PROTOCOL_DEFAULT;
|
|
gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH;
|
|
// copy locator part of address into the gc structure
|
|
gc->daddr.ipv6.s6_addr32[2] = cx->iid6[0];
|
|
gc->daddr.ipv6.s6_addr32[3] = cx->iid6[1];
|
|
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_sclassifier - end \n");
|
|
nasrg_TOOL_print_classifier(gc);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//Add automatically a classifier for mbms
|
|
void nasrg_ASCTL_start_mbmsclassifier(int mbms_ix,struct rb_entity *mbms_rb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct classifier_entity *gc;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_mbmsclassifier - begin \n");
|
|
#endif
|
|
|
|
if (!mbms_rb) {
|
|
printk("nasrg_ASCTL_start_mbmsclassifier - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
//
|
|
// gc=nasrg_CLASS_add_mbmsclassifier(mbms_ix, gpriv->next_mbmsclassref);
|
|
gc=nasrg_CLASS_add_mbmsclassifier(mbms_ix, gpriv->next_sclassref++);
|
|
|
|
if (gc==NULL) {
|
|
printk("nasrg_ASCTL_start_mbmsclassifier - Classifier pointer is null : not added \n");
|
|
return;
|
|
}
|
|
|
|
gc->fct = nasrg_COMMON_QOS_send;
|
|
gc->rab_id =mbms_rb->mbms_rbId;
|
|
gc->rb= mbms_rb;
|
|
gc->version = NASRG_DEFAULTRAB_IPVERSION;
|
|
gc->protocol= NAS_PROTOCOL_DEFAULT;
|
|
#ifdef NAS_DEBUG_CLASS
|
|
printk("nasrg_ASCTL_start_mbmsclassifier - end \n");
|
|
nasrg_TOOL_print_classifier(gc);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//Notifies automatically UE on default MBMS service
|
|
void nasrg_ASCTL_start_default_ue_notification(struct cx_entity *cx)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_start_default_ue_notification - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("\nERROR nasrg_ASCTL_start_default_ue_notification - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
// set value for default MBMS service
|
|
cx->requested_joined_services[0] = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1;
|
|
nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//Notifies automatically UE on default MBMS service
|
|
void nasrg_ASCTL_start_default_mbms_service(void)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int mbms_ix=0; // should allocate index based on Service_id /cnxid / MC IP address
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_start_default_mbms_service - begin \n");
|
|
#endif
|
|
|
|
// Establish MBMS bearer if not already done
|
|
if ((gpriv->mbms_rb[mbms_ix].state != NAS_CX_DCH)&&(gpriv->mbms_rb[mbms_ix].state != NAS_RB_ESTABLISHING)) {
|
|
gpriv->mbms_rb[mbms_ix].cnxid = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1;
|
|
gpriv->mbms_rb[mbms_ix].serviceId = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1;
|
|
gpriv->mbms_rb[mbms_ix].sessionId = NASRG_TEMP_MBMS_SESSION_ID; //Temp hard coded
|
|
gpriv->mbms_rb[mbms_ix].mbms_rbId = NASRG_DEFAULTRAB_RBID;
|
|
gpriv->mbms_rb[mbms_ix].sapi = NAS_DC_INPUT_SAPI;
|
|
#ifdef NAS_DEBUG_MBMS_PROT
|
|
gpriv->mbms_rb[mbms_ix].sapi = NAS_DRB_INPUT_SAPI; //Only one RT-FIFO is used
|
|
#endif
|
|
gpriv->mbms_rb[mbms_ix].qos = 20; //from first version of MBMS traces
|
|
gpriv->mbms_rb[mbms_ix].dscp = 0; //maybe 7
|
|
gpriv->mbms_rb[mbms_ix].duration = NASRG_TEMP_MBMS_DURATION; //Temp hard coded
|
|
//memcpy ((char *)&(gpriv->mbms_rb[mbms_ix].mcast_address),(char *)&(msgreq->mcast_group), 16);
|
|
gpriv->mbms_rb[mbms_ix].mcast_address[0] = 0xFF;
|
|
gpriv->mbms_rb[mbms_ix].mcast_address[1] = 0x0E;
|
|
nasrg_ASCTL_GC_send_mbms_bearer_establish_req(mbms_ix);
|
|
} else {
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_start_default_mbms_service - skipped, mbms_rb.state = %d \n", gpriv->mbms_rb[mbms_ix].state);
|
|
#endif
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void nasrg_ASCTL_timer(unsigned long data)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
uint8_t cxi;
|
|
struct cx_entity *cx;
|
|
struct rb_entity *rb;
|
|
spin_lock(&gpriv->lock);
|
|
#ifdef NAS_DEBUG_TIMER
|
|
printk("nasrg_ASCTL_timer - begin \n");
|
|
#endif
|
|
(gpriv->timer).function = nasrg_ASCTL_timer;
|
|
(gpriv->timer).expires=jiffies+NAS_TIMER_TICK;
|
|
(gpriv->timer).data=0L;
|
|
|
|
for (cxi=0; cxi<NAS_CX_MAX ; ++cxi) {
|
|
cx=gpriv->cx+cxi;
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_timer - No pointer for connection %d \n", cxi);
|
|
continue;
|
|
}
|
|
|
|
for (rb=cx->rb; rb!=NULL; rb=rb->next) {
|
|
if (rb->countimer!=NAS_TIMER_IDLE) {
|
|
#ifdef NAS_DEBUG_TIMER
|
|
printk("nasrg_ASCTL_timer : rb countimer %d, rb state %d\n", rb->countimer, rb->state);
|
|
#endif
|
|
|
|
if (rb->countimer==0) {
|
|
switch (rb->state) {
|
|
case NAS_CX_CONNECTING:
|
|
case NAS_CX_CONNECTING_FAILURE: // MW - 15/01/07 Useless, currently no retry if failure
|
|
if (rb->retry<gpriv->retry_limit) {
|
|
printk("nasrg_ASCTL_timer: Retry RB establishment %d\n", rb->retry);
|
|
nasrg_ASCTL_DC_send_rb_establish_request(cx, rb);
|
|
} else {
|
|
printk("nasrg_ASCTL_timer: RB Establishment failure\n");
|
|
rb->state=NAS_IDLE;
|
|
rb->countimer=NAS_TIMER_IDLE;
|
|
}
|
|
|
|
break;
|
|
|
|
case NAS_CX_DCH:
|
|
#ifdef DEMO_3GSM
|
|
if (cx->num_rb == 1) {
|
|
nasrg_ASCTL_start_default_sclassifier(cx, rb);
|
|
}
|
|
|
|
#endif
|
|
nasrg_ASCTL_start_sclassifier(cx, rb);
|
|
rb->countimer=NAS_TIMER_IDLE;
|
|
break;
|
|
|
|
case NAS_CX_RELEASING_FAILURE:
|
|
nasrg_ASCTL_DC_send_rb_release_request(cx, rb);
|
|
break;
|
|
|
|
default:
|
|
rb->countimer=NAS_TIMER_IDLE;
|
|
}
|
|
} else {
|
|
--rb->countimer;
|
|
printk("nasrg_ASCTL_timer : rb countimer-- %d, rb state %d\n", rb->countimer, rb->state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
add_timer(&gpriv->timer);
|
|
#ifdef NAS_DEBUG_TIMER
|
|
printk("nasrg_ASCTL_timer - end \n");
|
|
#endif
|
|
spin_unlock(&gpriv->lock);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
Transmission side
|
|
***************************************************************************/
|
|
//---------------------------------------------------------------------------
|
|
// Encode INFO_BROADCAST_REQ message
|
|
int nasrg_ASCTL_GC_send_broadcast_request(uint8_t category)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
char *xmit_data = "TESTING BROADCASTING ROUTER ADVERTISEMENT. TESTING BROADCASTING ROUTER ADVERTISEMENT. BROADCASTING ROUTER.\0";
|
|
int bytes_wrote = 0;
|
|
#ifdef PDCP_USE_NETLINK
|
|
unsigned char xbuffer[NAS_MESSAGE_MAXLEN];
|
|
int count=0;
|
|
#endif
|
|
|
|
struct nas_rg_gc_element *p;
|
|
p= (struct nas_rg_gc_element *)(gpriv->xbuffer);
|
|
p->type = INFO_BROADCAST_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASInfoBroadcastReq);
|
|
//
|
|
p->nasRGGCPrimitive.broadcast_req.period = 0;
|
|
p->nasRGGCPrimitive.broadcast_req.category = category;
|
|
p->nasRGGCPrimitive.broadcast_req.nasDataLength = strlen(xmit_data)+1; // TBD
|
|
|
|
//bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); //original version
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(xbuffer,(unsigned char *)p, p->length);
|
|
count = p->length;
|
|
bytes_wrote = count;
|
|
#else
|
|
bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length);
|
|
#endif
|
|
//printk("nasrg_ASCTL_GC_send_broadcast_request - Wrote %d bytes to RRC NAS_GC_SAPII\n", bytes_wrote);
|
|
|
|
//bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength);
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(&(xbuffer[count]),(unsigned char *)xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength);
|
|
count += p->nasRGGCPrimitive.broadcast_req.nasDataLength;
|
|
bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], xbuffer, count);
|
|
#else
|
|
bytes_wrote += nasrg_ASCTL_write((gpriv->sap[NAS_GC_SAPI], xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength);
|
|
#endif
|
|
|
|
if (bytes_wrote==p->length+p->nasRGGCPrimitive.broadcast_req.nasDataLength) {
|
|
#ifdef NAS_DEBUG_GC
|
|
printk("nasrg_ASCTL_GC_send_broadcast: INFO_BROADCAST_REQ primitive sent successfully in GC-FIFO\n");
|
|
#endif
|
|
} else {
|
|
printk("nasrg_ASCTL_GC_send_broadcast: Message sent failure in GC-FIFO\n");
|
|
}
|
|
return bytes_wrote;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Encode INFO_BROADCAST_REQ message for RRC SIB1
|
|
int nasrg_ASCTL_GC_send_SIB1_broadcast_request(struct sk_buff *skb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_gc_element *p;
|
|
char sib1_flag; // will be used for reception in nas_ue
|
|
int bytes_wrote = 0;
|
|
#ifdef PDCP_USE_NETLINK
|
|
unsigned char xbuffer[NAS_MESSAGE_MAXLEN];
|
|
int count=0;
|
|
#endif
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_GC
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - begin \n");
|
|
#endif
|
|
|
|
if (!skb) {
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - input parameter is NULL \n");
|
|
return 0;
|
|
}
|
|
|
|
// End debug information
|
|
p= (struct nas_rg_gc_element *)(gpriv->xbuffer);
|
|
p->type = INFO_BROADCAST_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASInfoBroadcastReq);
|
|
//
|
|
p->nasRGGCPrimitive.broadcast_req.period = 10; // to be checked
|
|
p->nasRGGCPrimitive.broadcast_req.category = 1;
|
|
p->nasRGGCPrimitive.broadcast_req.nasDataLength = skb->len+1; // TBD
|
|
sib1_flag = 1;
|
|
// send header
|
|
//bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); //original version
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(xbuffer,(unsigned char *)p, p->length);
|
|
count = p->length;
|
|
bytes_wrote = count;
|
|
#else
|
|
bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length);
|
|
#endif
|
|
//printk("nasrg_ASCTL_GC_send_broadcast_request - Wrote %d bytes to RRC NAS_GC_SAPII\n", bytes_wrote);
|
|
|
|
|
|
if (bytes_wrote!=p->length) {
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: Header send failure in GC-FIFO\n");
|
|
return bytes_wrote;
|
|
}
|
|
|
|
// send sib1_flag
|
|
//bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], &sib1_flag, 1);
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(&(xbuffer[count]),(unsigned char *)&sib1_flag, 1);
|
|
count += 1;
|
|
bytes_wrote = count;
|
|
#else
|
|
bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)&sib1_flag, 1);
|
|
#endif
|
|
|
|
if (bytes_wrote!=p->length+1) {
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: sib1_flag send failure in GC-FIFO\n");
|
|
return bytes_wrote;
|
|
}
|
|
|
|
// send data
|
|
//bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], skb->data, skb->len);
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(&(xbuffer[count]),skb->data, skb->len);
|
|
count += skb->len;
|
|
bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], xbuffer, count);
|
|
#else
|
|
bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], skb->data, skb->len);
|
|
#endif
|
|
|
|
|
|
if (bytes_wrote!=p->length+skb->len+1) {
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: Data send failure in GC-FIFO\n");
|
|
return bytes_wrote;
|
|
}
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - end \n");
|
|
#endif
|
|
return bytes_wrote;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Encode MBMS_BEARER_ESTABLISH_REQ message
|
|
int nasrg_ASCTL_GC_send_mbms_bearer_establish_req(int mbms_ix )
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
struct nas_rg_gc_element *p;
|
|
int bytes_wrote = 0;
|
|
|
|
p= (struct nas_rg_gc_element *)(gpriv->xbuffer);
|
|
p->type = MBMS_BEARER_ESTABLISH_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASMBMSBearerEstablishReq);
|
|
//
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId = gpriv->mbms_rb[mbms_ix].serviceId;
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_sessionId = gpriv->mbms_rb[mbms_ix].sessionId;
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId = gpriv->mbms_rb[mbms_ix].mbms_rbId;
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_sapId = gpriv->mbms_rb[mbms_ix].sapi;
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_QoSclass = gpriv->mbms_rb[mbms_ix].qos;
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_duration = gpriv->mbms_rb[mbms_ix].duration;
|
|
gpriv->mbms_rb[mbms_ix].state = NAS_RB_ESTABLISHING;
|
|
//
|
|
//bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
#ifdef NAS_DEBUG_GC
|
|
printk(" nasrg_ASCTL_GC_send_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_REQ primitive sent successfully in GC-FIFO\n");
|
|
printk(" ServiceId %d, RB_Id %d , qos class %d \n",
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId,
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId,
|
|
p->nasRGGCPrimitive.mbms_establish_req.mbms_QoSclass);
|
|
#endif
|
|
} else {
|
|
printk("nasrg_ASCTL_GC_send_mbms_bearer_establish: Message sent failure in GC-FIFO\n");
|
|
}
|
|
|
|
return bytes_wrote;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// HNN - Encode MBMS_BEARER_RELEASE_REQ message
|
|
int nasrg_ASCTL_GC_send_mbms_bearer_release_req(int mbms_ix)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
struct nas_rg_gc_element *p;
|
|
uint16_t classref=0;
|
|
int bytes_wrote = 0;
|
|
|
|
p= (struct nas_rg_gc_element *)(gpriv->xbuffer);
|
|
|
|
p->type = MBMS_BEARER_RELEASE_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASMBMSBearerReleaseReq);
|
|
//
|
|
p->nasRGGCPrimitive.mbms_release_req.mbms_serviceId = gpriv->mbms_rb[mbms_ix].serviceId;
|
|
p->nasRGGCPrimitive.mbms_release_req.mbms_sessionId = gpriv->mbms_rb[mbms_ix].sessionId;
|
|
p->nasRGGCPrimitive.mbms_release_req.mbms_rbId = gpriv->mbms_rb[mbms_ix].mbms_rbId;
|
|
//gpriv->mbms_rb[mbms_ix].state = NAS_RB_RELEASING;
|
|
//
|
|
//bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
#ifdef NAS_DEBUG_GC
|
|
printk(" nasrg_ASCTL_GC_send_mbms_bearer_release: MBMS_BEARER_RELEASE_REQ primitive sent successfully in GC-FIFO\n");
|
|
printk(" ServiceId %d, RB_Id %d \n", p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId, p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId);
|
|
#endif
|
|
// clean NASRG private structures
|
|
classref = (gpriv->mbmsclassifier[mbms_ix])->classref;
|
|
nasrg_CLASS_del_mbmsclassifier(mbms_ix, classref);
|
|
//nasrg_CLASS_flush_mbmsclassifier();
|
|
//gpriv->mbms_rb[mbms_ix].state = NAS_IDLE;
|
|
memset (&(gpriv->mbms_rb[mbms_ix]),0,sizeof (struct rb_entity));
|
|
} else {
|
|
printk("nasrg_ASCTL_GC_send_mbms_bearer_release: Message sent failure in GC-FIFO\n");
|
|
}
|
|
|
|
return bytes_wrote;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Confirm the establishment of a connection (DC channel)
|
|
int nasrg_ASCTL_DC_send_cx_establish_confirm(struct cx_entity *cx, uint8_t response)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int bytes_wrote = 0;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_cx_establish - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_DC_send_cx_establish - input parameter cx is NULL \n");
|
|
return NAS_ERROR_NOTCORRECTVALUE;
|
|
}
|
|
|
|
// End debug information
|
|
p= (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = CONN_ESTABLISH_CNF;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASConnEstablishConf);
|
|
p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef = cx->lcr;
|
|
p->nasRGDCPrimitive.conn_establish_conf.status = response; // can be ACCEPTED or FAILURE
|
|
p->nasRGDCPrimitive.conn_establish_conf.num_RBs = 0; // Hard coded in first step
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_cx_establish: CONN_ESTABLISH_CNF primitive sent successfully in DC-FIFO\n");
|
|
printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef);
|
|
printk(" Status %u\n",p->nasRGDCPrimitive.conn_establish_conf.status);
|
|
#endif
|
|
} else
|
|
printk("nasrg_ASCTL_DC_send_cx_establish: Message transmission failure to DC-FIFO\n");
|
|
|
|
return bytes_wrote;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Request the establishment of a radio bearer
|
|
int nasrg_ASCTL_DC_send_rb_establish_request(struct cx_entity *cx, struct rb_entity *rb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int bytes_wrote = 0;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_rb_establish - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !rb) {
|
|
printk("nasrg_ASCTL_DC_send_rb_establish - input parameter is NULL \n");
|
|
return NAS_ERROR_NOTCORRECTVALUE;
|
|
}
|
|
|
|
// End debug information
|
|
switch(rb->state) {
|
|
case NAS_CX_CONNECTING:
|
|
case NAS_CX_CONNECTING_FAILURE:
|
|
case NAS_IDLE:
|
|
++rb->retry;
|
|
rb->countimer=gpriv->timer_establishment;
|
|
|
|
if (cx->state==NAS_CX_DCH) {
|
|
p= (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = RB_ESTABLISH_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASrbEstablishReq);
|
|
p->nasRGDCPrimitive.rb_establish_req.localConnectionRef = cx->lcr;
|
|
p->nasRGDCPrimitive.rb_establish_req.rbId = rb->rab_id + (NAS_RB_MAX_NUM * cx->lcr);
|
|
p->nasRGDCPrimitive.rb_establish_req.QoSclass = rb->qos;
|
|
p->nasRGDCPrimitive.rb_establish_req.dscp = rb->dscp_ul;
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
rb->state=NAS_CX_CONNECTING;
|
|
#ifdef NAS_DEBUG_DC
|
|
printk(" nasrg_ASCTL_DC_send_rb_establish: RB_ESTABLISH_REQ primitive sent successfully in DC-FIFO\n");
|
|
printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.rb_establish_req.localConnectionRef);
|
|
printk(" Radio Bearer identification %u\n",p->nasRGDCPrimitive.rb_establish_req.rbId);
|
|
printk(" QoS %u\n",p->nasRGDCPrimitive.rb_establish_req.QoSclass);
|
|
#endif
|
|
} else {
|
|
rb->state=NAS_CX_CONNECTING_FAILURE;
|
|
printk("nasrg_ASCTL_DC_send_rb_establish: Message sent failure in DC-FIFO\n");
|
|
}
|
|
|
|
return bytes_wrote;
|
|
} else {
|
|
rb->state=NAS_CX_CONNECTING_FAILURE;
|
|
printk("nasrg_ASCTL_DC_send_rb_establish: Failure \n");
|
|
return 0;
|
|
}
|
|
|
|
default:
|
|
return -NAS_ERROR_NOTIDLE;
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Request the release of a radio bearer
|
|
int nasrg_ASCTL_DC_send_rb_release_request(struct cx_entity *cx, struct rb_entity *rb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int bytes_wrote = 0;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_rb_release - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !rb) {
|
|
printk("nasrg_ASCTL_DC_send_rb_release - input parameter is NULL \n");
|
|
return NAS_ERROR_NOTCORRECTVALUE;
|
|
}
|
|
|
|
// End debug information
|
|
switch (rb->state) {
|
|
case NAS_CX_RELEASING_FAILURE:
|
|
case NAS_CX_DCH:
|
|
p= (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = RB_RELEASE_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASrbReleaseReq);
|
|
p->nasRGDCPrimitive.rb_release_req.localConnectionRef = cx->lcr;
|
|
p->nasRGDCPrimitive.rb_release_req.rbId = rb->rab_id + (NAS_RB_MAX_NUM * cx->lcr);
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote) {
|
|
rb->state=NAS_IDLE;
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_rb_release: RB_RELEASE_REQ primitive sent successfully in DC-FIFO\n");
|
|
#endif
|
|
} else {
|
|
++rb->retry;
|
|
rb->countimer=gpriv->timer_release;
|
|
rb->state=NAS_CX_RELEASING_FAILURE;
|
|
printk("nasrg_ASCTL_DC_send_rb_release: Message sent failure in DC-FIFO\n");
|
|
}
|
|
|
|
return bytes_wrote;
|
|
|
|
default:
|
|
return -NAS_ERROR_NOTCONNECTED;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Request the notification of a UE to joined or left services
|
|
int nasrg_ASCTL_DC_send_mbms_ue_notify_req(struct cx_entity *cx)
|
|
{
|
|
//-----------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int i;
|
|
int bytes_wrote = 0;
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req - input parameter is NULL \n");
|
|
return NAS_ERROR_NOTCORRECTVALUE;
|
|
}
|
|
|
|
// End debug information
|
|
p= (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = MBMS_UE_NOTIFY_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASMBMSUENotifyReq);
|
|
//
|
|
p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef = cx->lcr;
|
|
|
|
// joined/left services are lists of MAX_MBMS_SERVICES
|
|
// -1 means the end of the list
|
|
for (i = 0; i < MAX_MBMS_SERVICES; i++) {
|
|
p->nasRGDCPrimitive.mbms_ue_notify_req.joined_services[i].mbms_serviceId = (nasMBMSServiceId_t)cx->requested_joined_services[i];
|
|
p->nasRGDCPrimitive.mbms_ue_notify_req.left_services[i].mbms_serviceId = (nasMBMSServiceId_t)cx->requested_left_services[i];
|
|
}
|
|
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req: MBMS_UE_NOTIFY_REQ primitive sent successfully in DC-FIFO\n");
|
|
printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef);
|
|
printk(" joined service %d, left service %d\n",cx->requested_joined_services[0], cx->requested_left_services[0] );
|
|
#endif
|
|
} else
|
|
printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req: Message transmission failure to DC-FIFO\n");
|
|
|
|
return bytes_wrote;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Request the transfer of data (DC SAP)
|
|
void nasrg_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int bytes_wrote = 0;
|
|
#ifdef PDCP_USE_NETLINK
|
|
unsigned char xbuffer[NAS_MESSAGE_MAXLEN];
|
|
int count=0;
|
|
#endif
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_sig_data - begin \n");
|
|
#endif
|
|
|
|
if (!skb || !gc || !cx) {
|
|
printk("nasrg_ASCTL_DC_send_sig_data - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
if (cx->state!=NAS_CX_DCH) {
|
|
printk("nasrg_ASCTL_DC_send_sig_data: Not connected, so the message is dropped\n");
|
|
++gpriv->stats.tx_dropped;
|
|
return;
|
|
}
|
|
|
|
p = (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = DATA_TRANSFER_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASDataReq);
|
|
p->nasRGDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr;
|
|
p->nasRGDCPrimitive.data_transfer_req.priority = NAS_SIG_SRB3;
|
|
p->nasRGDCPrimitive.data_transfer_req.nasDataLength = skb->len;
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(xbuffer,(unsigned char *)p, p->length);
|
|
count = p->length;
|
|
bytes_wrote = count;
|
|
#else
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
#endif
|
|
|
|
if (bytes_wrote!=p->length) {
|
|
printk("nasrg_ASCTL_DC_send_sig_data: Header sent failure in DC-FIFO\n");
|
|
return;
|
|
}
|
|
|
|
//bytes_wrote += rtf_put(cx->sap[NAS_DC_INPUT_SAPI], skb->data, skb->len);
|
|
#ifdef PDCP_USE_NETLINK
|
|
memcpy(&(xbuffer[count]),(unsigned char *)skb->data, skb->len);
|
|
count += skb->len;
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], xbuffer, count);
|
|
#else
|
|
bytes_wrote += nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)skb->data, skb->len);
|
|
#endif
|
|
|
|
if (bytes_wrote!=p->length+skb->len) {
|
|
printk("nasrg_ASCTL_DC_send_sig_data: Data sent failure in DC-FIFO\n");
|
|
return;
|
|
}
|
|
|
|
gpriv->stats.tx_bytes += skb->len;
|
|
gpriv->stats.tx_packets ++;
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_sig_data - end \n");
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Confirm the establishment of a connection (DC channel)
|
|
int nasrg_ASCTL_DC_send_eNBmeasurement_req(struct cx_entity *cx)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nas_rg_dc_element *p;
|
|
int bytes_wrote = 0;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_eNBmeasurement_req - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_DC_send_eNBmeasurement_req - input parameter cx is NULL \n");
|
|
return NAS_ERROR_NOTCORRECTVALUE;
|
|
}
|
|
|
|
// End debug information
|
|
p= (struct nas_rg_dc_element *)(gpriv->xbuffer);
|
|
p->type = ENB_MEASUREMENT_REQ;
|
|
p->length = NAS_TL_SIZE + sizeof(struct NASENbMeasureReq);
|
|
p->nasRGDCPrimitive.eNBmeasurement_req.cell_id = cx->cellid;
|
|
//
|
|
//bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length);
|
|
bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length);
|
|
|
|
if (bytes_wrote==p->length) {
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_send_eNBmeasurement_req: ENB_MEASUREMENT_REQ primitive sent successfully in DC-FIFO\n");
|
|
printk(" cell_id %u\n",p->nasRGDCPrimitive.eNBmeasurement_req.cell_id);
|
|
#endif
|
|
} else
|
|
printk("nasrg_ASCTL_DC_send_eNBmeasurement_req: Message transmission failure to DC-FIFO\n");
|
|
|
|
return bytes_wrote;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Reception side
|
|
***************************************************************************/
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode CONN_ESTABLISH_IND message from RRC
|
|
void nasrg_ASCTL_DC_decode_cx_establish_ind(struct cx_entity *cx, struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int i;
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_establish - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_cx_establish - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
if (nasrg_ASCTL_DC_send_cx_establish_confirm(cx, ACCEPTED)>0) {
|
|
nasrg_TOOL_imei2iid(p->nasRGDCPrimitive.conn_establish_ind.InterfaceIMEI, (uint8_t *)cx->iid6);
|
|
cx->iid4=97; // A AUTOMATISER
|
|
cx->lcr = p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef;
|
|
cx->state=NAS_CX_DCH;
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_establish: CONN_ESTABLISH_IND reception\n");
|
|
printk(" primitive length %d\n",p->length);
|
|
printk(" Local Connection reference %d\n",p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef);
|
|
printk(" IMEI ");
|
|
|
|
for (i=0; i<14; ++i)
|
|
printk("%u",p->nasRGDCPrimitive.conn_establish_ind.InterfaceIMEI[i]);
|
|
|
|
printk(" state ");
|
|
nasrg_TOOL_print_state(cx->state);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode CONN_RELEASE_IND message from RRC
|
|
void nasrg_ASCTL_DC_decode_cx_release_ind(struct cx_entity *cx, struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_release - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_cx_release - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
cx->state=NAS_IDLE;
|
|
cx->iid4=0;
|
|
nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6);
|
|
nasrg_COMMON_flush_rb(cx);
|
|
nasrg_CLASS_flush_sclassifier(cx);
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_release: CONN_RELEASE_IND reception\n");
|
|
printk(" Primitive length %u\n",p->length);
|
|
printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.conn_release_ind.localConnectionRef);
|
|
printk(" Release cause %u\n",p->nasRGDCPrimitive.conn_release_ind.releaseCause);
|
|
nasrg_TOOL_print_state(cx->state);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode CONN_LOSS_IND message from RRC
|
|
void nasrg_ASCTL_DC_decode_cx_loss_ind(struct cx_entity *cx, struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_loss - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_cx_loss - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
cx->state = NAS_IDLE;
|
|
cx->iid4=0;
|
|
nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6);
|
|
nasrg_COMMON_flush_rb(cx);
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_cx_loss: CONN_LOSS_IND reception\n");
|
|
printk(" Primitive length %u\n",(int)(p->length));
|
|
printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef);
|
|
nasrg_TOOL_print_state(cx->state);
|
|
#endif
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
// Decode RB_ESTABLISH_CNF message from RRC
|
|
void nasrg_ASCTL_DC_decode_rb_establish_cnf(struct cx_entity *cx, struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct rb_entity *rb;
|
|
int rb_id;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
rb_id = p->nasRGDCPrimitive.rb_establish_conf.rbId;
|
|
rb=nasrg_COMMON_search_rb(cx, rb_id - (NAS_RB_MAX_NUM * cx->lcr));
|
|
|
|
//
|
|
if (rb!=NULL) {
|
|
if (rb->state==NAS_CX_CONNECTING) {
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF received\n");
|
|
printk(" Primitive length %u\n", p->length);
|
|
printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef);
|
|
printk(" RB Id %u\n",p->nasRGDCPrimitive.rb_establish_conf.rbId);
|
|
printk(" SAP Id %u\n",p->nasRGDCPrimitive.rb_establish_conf.sapId);
|
|
printk(" Status %u, Failure code %d, Cx state, RB state\n",p->nasRGDCPrimitive.rb_establish_conf.status, p->nasRGDCPrimitive.rb_establish_conf.fail_code);
|
|
nasrg_TOOL_print_state(cx->state);
|
|
nasrg_TOOL_print_state(rb->state);
|
|
#endif
|
|
|
|
switch (p->nasRGDCPrimitive.rb_establish_conf.status) {
|
|
case ACCEPTED:
|
|
rb->state = NAS_CX_DCH;
|
|
rb->countimer=1;
|
|
break;
|
|
|
|
case FAILURE:
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF rejected\n");
|
|
rb->state = NAS_CX_CONNECTING_FAILURE;
|
|
//delete rb
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF reception, invalid status\n");
|
|
}
|
|
} else
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish: invalid state %u\n", cx->state);
|
|
} else
|
|
printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF, No corresponding radio bearer\n");
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode DATA_TRANSFER_IND message from RRC
|
|
void nasrg_ASCTL_DC_decode_data_transfer_ind(struct cx_entity *cx, struct nas_rg_dc_element *p, char *buffer)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
uint8_t nasrg_data[10];
|
|
unsigned int nas_length;
|
|
char data_type;
|
|
int bytes_read=0;
|
|
unsigned int peer_command;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
|
|
bytes_read=p->length;
|
|
// Get first character
|
|
nas_length = (p->nasRGDCPrimitive.data_transfer_ind.nasDataLength) -1;
|
|
#ifndef PDCP_USE_NETLINK
|
|
bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], &data_type, 1);
|
|
#else
|
|
memcpy (&data_type, (char *)(&buffer[bytes_read]), 1);
|
|
bytes_read ++;
|
|
#endif
|
|
|
|
//check if peer message
|
|
if (data_type =='A') {
|
|
// receive in a skbuff
|
|
//nasrg_COMMON_receive((p->length) + 1, nas_length, cx->sap[NAS_DC_OUTPUT_SAPI]); // original
|
|
#ifndef PDCP_USE_NETLINK
|
|
//void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap);
|
|
// data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer)
|
|
nasrg_COMMON_receive((p->length) + 1, nas_length, NULL, 2, cx->sap[NAS_DC_OUTPUT_SAPI]);
|
|
#else
|
|
//nasrg_COMMON_receive((p->length) + 1, nas_length, (unsigned char *)p+p->length+1, 2, 0);
|
|
nasrg_COMMON_receive((p->length) + 1, nas_length, (unsigned char *)(&buffer[bytes_read]), 2, 0);
|
|
#endif
|
|
} else {
|
|
// if FIFO, empty remaining data
|
|
#ifndef PDCP_USE_NETLINK
|
|
bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], (gpriv->rbuffer)+ (p->length), nas_length);
|
|
#endif
|
|
|
|
if (data_type=='Z') {
|
|
#ifndef PDCP_USE_NETLINK
|
|
memcpy (&nasrg_data, (char *)(gpriv->rbuffer)+ (p->length), 10);
|
|
#else
|
|
memcpy (&nasrg_data, (char *)(&buffer[bytes_read]), 10);
|
|
#endif
|
|
peer_command = (int)nasrg_data[0];
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: Received peer message %d %d \n", nasrg_data[0], peer_command);
|
|
nasrg_TOOL_print_buffer(nasrg_data, 10);
|
|
|
|
if (nasrg_data[0]== NAS_CMD_OPEN_RB) {
|
|
// open radio bearer
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: Opening Default Radio Bearer\n");
|
|
nasrg_ASCTL_start_default_rb(cx);
|
|
} else if (nasrg_data[0]== NAS_CMD_ENTER_SLEEP) {
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: Entering Sleep Mode\n");
|
|
cx->state = NAS_CX_RELEASING;
|
|
} else if (nasrg_data[0]== NAS_CMD_LEAVE_SLEEP) {
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: Leaving Sleep Mode\n");
|
|
cx->state = NAS_CX_DCH;
|
|
} else {
|
|
printk("\n\nnasrg_ASCTL_DC_decode_data_transfer: Unknown peer command\n");
|
|
}
|
|
} else
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: Error during reception of the message - Dropped\n");
|
|
}
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_data_transfer: DATA_TRANSFER_IND reception\n");
|
|
printk(" Primitive length %u\n", p->length);
|
|
printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.data_transfer_ind.localConnectionRef);
|
|
printk(" Data Length %u\n", p->nasRGDCPrimitive.data_transfer_ind.nasDataLength);
|
|
nasrg_TOOL_print_state(cx->state);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode MBMS_BEARER_ESTABLISH_CNF message from RRC
|
|
void nasrg_ASCTL_DC_decode_mbms_bearer_establish_cnf(struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int mbms_ix;
|
|
int rb_id;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish - begin \n");
|
|
#endif
|
|
|
|
if (!p) {
|
|
printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
rb_id = p->nasRGDCPrimitive.mbms_establish_cnf.rbId;
|
|
mbms_ix = 0; // A revoir - find using cnxid...
|
|
|
|
if (rb_id == gpriv->mbms_rb[mbms_ix].mbms_rbId) {
|
|
switch (p->nasRGDCPrimitive.mbms_establish_cnf.status) {
|
|
case ACCEPTED:
|
|
gpriv->mbms_rb[mbms_ix].state = NAS_CX_DCH;
|
|
gpriv->mbms_rb[mbms_ix].rab_id = gpriv->mbms_rb[mbms_ix].mbms_rbId;
|
|
nasrg_ASCTL_start_mbmsclassifier(mbms_ix,&(gpriv->mbms_rb[mbms_ix]));
|
|
break;
|
|
|
|
case FAILURE:
|
|
printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF rejected\n");
|
|
gpriv->mbms_rb[mbms_ix].state = NAS_CX_CONNECTING_FAILURE; //supprimer l'entree
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF reception, invalid status\n");
|
|
}
|
|
} else
|
|
printk(" nasrg_ASCTL_DC_decode_mbms_bearer_establish: invalid RB_Id %d\n", rb_id);
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk(" nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF reception\n");
|
|
printk(" Primitive length %u\n",p->length);
|
|
printk(" rb_id %d, status %d\n",p->nasRGDCPrimitive.mbms_establish_cnf.rbId, p->nasRGDCPrimitive.mbms_establish_cnf.status);
|
|
nasrg_TOOL_print_state(gpriv->mbms_rb[mbms_ix].state);
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Decode MBMS_UE_NOTIFY_CNF message from RRC
|
|
void nasrg_ASCTL_DC_decode_mbms_ue_notify_cnf(struct cx_entity *cx, struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int i, j, k;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_mbms_ue_notify - begin \n");
|
|
#endif
|
|
|
|
if (!cx || !p) {
|
|
printk("nasrg_ASCTL_DC_decode_mbms_ue_notify - input parameter is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.mbmsStatus == ACCEPTED) {
|
|
for (i = 0; i<NASRG_MBMS_SVCES_MAX; i++) {
|
|
if (cx->requested_joined_services[i] >=0) {
|
|
for (j = 0; j<NASRG_MBMS_SVCES_MAX; j++) {
|
|
if (cx->joined_services[j] ==-1) {
|
|
cx->joined_services[j]= cx->requested_joined_services[i];
|
|
cx->requested_joined_services[i]=-1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cx->requested_left_services[i] >=0) {
|
|
for (k = 0; k<NASRG_MBMS_SVCES_MAX; k++) {
|
|
if (cx->joined_services[k] == cx->requested_left_services[i]) {
|
|
cx->joined_services[k]=-1;
|
|
cx->requested_left_services[i]=-1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef NAS_DEBUG_DC
|
|
printk(" nasrg_ASCTL_DC_decode_mbms_ue_notify: MBMS_UE_NOTIFY_CNF reception\n");
|
|
printk(" Primitive length %u\n",p->length);
|
|
printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef);
|
|
printk(" MBMS Status: %d\n", p->nasRGDCPrimitive.mbms_ue_notify_cnf.mbmsStatus);
|
|
printk(" UE services currently joined \n");
|
|
|
|
for (i = 0; i<NASRG_MBMS_SVCES_MAX; i++)
|
|
printk ("%d * ", cx->joined_services[i]);
|
|
|
|
nasrg_TOOL_print_state(cx->state);
|
|
#endif
|
|
}
|
|
/*
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.cell_id = protocol_bs->rrc.rg_cell_id;
|
|
// next values are temp hard coded, to be replaced by real values
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.num_UEs = num_connected_UEs;
|
|
for (ix=0; ix<ralpriv->num_connected_UEs; ix++){
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].rlcBufferOccupancy = 100 - (30*ix);
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].scheduledPRB = 500 - (200*ix);
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].totalDataVolume = 640000 + (160000*ix);
|
|
}
|
|
msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs = 1000;
|
|
|
|
*/
|
|
//---------------------------------------------------------------------------
|
|
// Decode ENB_MEASUREMENT_IND message from RRC
|
|
void nasrg_ASCTL_DC_decode_eNBmeasurement_ind(struct nas_rg_dc_element *p)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
uint8_t i;
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC
|
|
printk("nasrg_ASCTL_DC_decode_eNBmeasurement_ind - begin \n");
|
|
#endif
|
|
|
|
if (!p) {
|
|
printk("nasrg_ASCTL_DC_decode_eNBmeasurement_ind - input parameter p is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
#ifdef NAS_DEBUG_DC_DETAIL
|
|
printk(" nasrg_ASCTL_DC_decode_eNBmeasurement_ind : ENB_MEASUREMENT_IND reception\n");
|
|
printk(" Measured Cell: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.cell_id);
|
|
printk(" Number of Connected Mobiles: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.num_UEs);
|
|
|
|
for (i=0; i<p->nasRGDCPrimitive.eNBmeasurement_ind.num_UEs; ++i) {
|
|
printk(" UE[%u]: rlcBufferOccupancy %u, scheduledPRB: %u, totalDataVolume: %u\n", i,
|
|
p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].rlcBufferOccupancy,
|
|
p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].scheduledPRB,
|
|
p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].totalDataVolume);
|
|
}
|
|
|
|
printk(" Total number of PRBs: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs);
|
|
#endif
|
|
// store Measures
|
|
gpriv->measured_cell_id = p->nasRGDCPrimitive.eNBmeasurement_ind.cell_id;
|
|
gpriv->num_UEs = p->nasRGDCPrimitive.eNBmeasurement_ind.num_UEs;
|
|
|
|
for (i=0; i<gpriv-> num_UEs; ++i) {
|
|
gpriv->rlcBufferOccupancy[i] = p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].rlcBufferOccupancy;
|
|
gpriv->scheduledPRB[i] += p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].scheduledPRB;
|
|
gpriv->totalDataVolume[i] += p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].totalDataVolume;
|
|
}
|
|
|
|
gpriv->totalNumPRBs += p->nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Check if anything in DC FIFO and process it (RG Finite State Machine)
|
|
int nasrg_ASCTL_DC_receive(struct cx_entity *cx, char *buffer)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
int bytes_read=0;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_DC_DETAIL
|
|
printk("nasrg_ASCTL_DC_receive - begin \n");
|
|
#endif
|
|
|
|
if (!cx) {
|
|
printk("nasrg_ASCTL_DC_receive - input parameter cx is NULL \n");
|
|
return 0;
|
|
}
|
|
|
|
// End debug information
|
|
|
|
#ifndef PDCP_USE_NETLINK
|
|
bytes_read = rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI] , gpriv->rbuffer, NAS_TL_SIZE);
|
|
#else
|
|
bytes_read = NAS_TL_SIZE;
|
|
#endif
|
|
|
|
if (bytes_read>0) {
|
|
struct nas_rg_dc_element *p;
|
|
#ifndef PDCP_USE_NETLINK
|
|
p= (struct nas_rg_dc_element *)(gpriv->rbuffer);
|
|
//get the rest of the primitive
|
|
bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], (uint8_t *)p+NAS_TL_SIZE, p->length-NAS_TL_SIZE);
|
|
|
|
if (bytes_read!=p->length) {
|
|
printk("nasrg_ASCTL_DC_receive: Problem while reading primitive's header\n");
|
|
return bytes_read;
|
|
}
|
|
|
|
#else
|
|
p= (struct nas_rg_dc_element *)(buffer);
|
|
bytes_read=p->length;
|
|
#endif
|
|
|
|
switch (p->type) {
|
|
case CONN_ESTABLISH_IND :
|
|
if (p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: CONN_ESTABLISH_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_IDLE:
|
|
nasrg_ASCTL_DC_decode_cx_establish_ind(cx,p);
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: CONN_ESTABLISH_IND reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case CONN_RELEASE_IND :
|
|
if (p->nasRGDCPrimitive.conn_release_ind.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: CONN_RELEASE_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_release_ind.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_CX_DCH:
|
|
nasrg_ASCTL_DC_decode_cx_release_ind(cx,p);
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: CONN_RELEASE_IND reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case CONN_LOSS_IND:
|
|
if (p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: CONN_LOSS_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_CX_DCH:
|
|
nasrg_ASCTL_DC_decode_cx_loss_ind(cx,p);
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: CONN_LOSS_IND reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case RB_ESTABLISH_CNF:
|
|
if (p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: RB_ESTABLISH_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_CX_DCH:
|
|
nasrg_ASCTL_DC_decode_rb_establish_cnf(cx,p);
|
|
#ifdef NAS_AUTO_MBMS
|
|
nasrg_ASCTL_start_default_ue_notification(cx);
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: RB_ESTABLISH_CNF reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case DATA_TRANSFER_IND:
|
|
if (p->nasRGDCPrimitive.data_transfer_ind.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: DATA_TRANSFER_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_CX_DCH:
|
|
case NAS_CX_RELEASING:
|
|
nasrg_ASCTL_DC_decode_data_transfer_ind(cx,p,buffer);
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: DATA_TRANSFER_IND reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
// Temp - Should be in uplink GC-SAP
|
|
case MBMS_BEARER_ESTABLISH_CNF:
|
|
// if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef!=cx->lcr)
|
|
// printk("nasrg_ASCTL_DC_receive: MBMS_BEARER_ESTABLISH_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef);
|
|
// else
|
|
nasrg_ASCTL_DC_decode_mbms_bearer_establish_cnf(p);
|
|
break;
|
|
|
|
case MBMS_UE_NOTIFY_CNF:
|
|
if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef!=cx->lcr)
|
|
printk("nasrg_ASCTL_DC_receive: MBMS_UE_NOTIFY_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef);
|
|
else {
|
|
switch(cx->state) {
|
|
case NAS_CX_DCH:
|
|
nasrg_ASCTL_DC_decode_mbms_ue_notify_cnf(cx,p);
|
|
/* //Temp
|
|
nasrg_ASCTL_start_default_mbms_service();*/
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_ASCTL_DC_receive: MBMS_UE_NOTIFY_CNF reception, invalid state %u\n", cx->state);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
// Temp - Should be in uplink GC-SAP
|
|
case ENB_MEASUREMENT_IND :
|
|
// if (p->nasRGDCPrimitive.eNBmeasurement_ind.localConnectionRef!=cx->lcr)
|
|
// printk("nasrg_ASCTL_DC_receive: ENB_MEASUREMENT_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.localConnectionRef);
|
|
// else
|
|
nasrg_ASCTL_DC_decode_eNBmeasurement_ind(p);
|
|
break;
|
|
|
|
default :
|
|
printk("nasrg_ASCTL_DC_receive: Invalid message received\n");
|
|
}
|
|
}
|
|
|
|
return bytes_read;
|
|
}
|
|
|
|
#endif
|