/* * 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 * the OAI Public License, Version 1.0 (the "License"); you may not use this file * 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 */ #include "local.h" #include "ioctl.h" #include "proto_extern.h" //#include <linux/in.h> #include <asm/uaccess.h> #include <asm/checksum.h> #include <asm/uaccess.h> // Statistic //--------------------------------------------------------------------------- void nas_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep, struct nas_priv *priv) { //--------------------------------------------------------------------------- msgrep->rx_packets=priv->stats.rx_packets; msgrep->tx_packets=priv->stats.tx_packets; msgrep->rx_bytes=priv->stats.rx_bytes; msgrep->tx_bytes=priv->stats.tx_bytes; msgrep->rx_errors=priv->stats.rx_errors; msgrep->tx_errors=priv->stats.tx_errors; msgrep->rx_dropped=priv->stats.rx_dropped; msgrep->tx_dropped=priv->stats.tx_dropped; } //--------------------------------------------------------------------------- int nas_ioCTL_statistic_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_statistic_reply msgrep; printk("NAS_IOCTL_STATISTIC: stat requested\n"); nas_set_msg_statistic_reply(&msgrep,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_STATISTIC: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Connections List //--------------------------------------------------------------------------- void nas_set_msg_cx_list_reply(uint8_t *msgrep, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; nasLocalConnectionRef_t lcr; struct nas_msg_cx_list_reply *list; msgrep[0]=NAS_CX_MAX; list=(struct nas_msg_cx_list_reply *)(msgrep+1); for(lcr=0; lcr<NAS_CX_MAX; ++lcr) { cx=nas_COMMON_search_cx(lcr,priv); list[lcr].lcr=lcr; list[lcr].state=cx->state; list[lcr].cellid=cx->cellid; list[lcr].iid4=cx->iid4; list[lcr].iid6[0]=cx->iid6[0]; list[lcr].iid6[1]=cx->iid6[1]; list[lcr].num_rb=cx->num_rb; list[lcr].nsclassifier=cx->nsclassifier; printk("NAS_SET_MSG_CX_LIST_REPLY: nsc=%u\n",cx->nsclassifier); } } //--------------------------------------------------------------------------- int nas_ioCTL_cx_list_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1]; printk("NAS_IOCTL_CX_LIST: connection list requested\n"); nas_set_msg_cx_list_reply(msgrep,priv); if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) { printk("NAS_IOCTL_CX_LIST: copy_to_user failure\n"); return -EFAULT; } printk("NAS_IOCTL_CX_LIST: end\n"); return 0; } /////////////////////////////////////////////////////////////////////////////// // Connection Establishment //--------------------------------------------------------------------------- void nas_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep, struct nas_msg_cx_establishment_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx!=NULL) { cx->cellid=msgreq->cellid; msgrep->status=nas_mesh_DC_send_cx_establish_request(cx,priv); } else msgrep->status=-NAS_ERROR_NOTCORRECTLCR; } //--------------------------------------------------------------------------- int nas_ioCTL_cx_establishment_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_cx_establishment_request msgreq; struct nas_msg_cx_establishment_reply msgrep; printk("NAS_IOCTL_ESTABLISHMENT: connection establishment requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_cx_establishment_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Connection Release //--------------------------------------------------------------------------- void nas_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep, struct nas_msg_cx_release_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx!=NULL) msgrep->status=nas_mesh_DC_send_cx_release_request(cx,priv); else msgrep->status=-NAS_ERROR_NOTCORRECTLCR; } //--------------------------------------------------------------------------- // Request the release of a connection int nas_ioCTL_cx_release_request(struct nas_ioctl *gifr,struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_cx_release_request msgreq; struct nas_msg_cx_release_reply msgrep; printk("NAS_IOCTL_CX_RELEASE: connection release requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_CX_RELEASE: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_cx_release_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_CX_RELEASE: copy_to_user failure\n"); return -EFAULT; } printk("NAS_IOCTL_CX_RELEASE: end\n"); return 0; } /////////////////////////////////////////////////////////////////////////////// // Radio Bearer List //--------------------------------------------------------------------------- void nas_set_msg_rb_list_reply(uint8_t *msgrep, struct nas_msg_rb_list_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx!=NULL) { uint8_t rbi; struct rb_entity *rb; struct nas_msg_rb_list_reply *list; if (cx->num_rb > NAS_LIST_RB_MAX) msgrep[0] = NAS_LIST_RB_MAX; else msgrep[0] = cx->num_rb; list=(struct nas_msg_rb_list_reply *)(msgrep+1); for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbi<msgrep[0]); rb=rb->next, ++rbi) { list[rbi].state=rb->state; list[rbi].rab_id=rb->rab_id; list[rbi].sapi=rb->sapi; list[rbi].qos=rb->qos; } } else msgrep[0]=0; } //--------------------------------------------------------------------------- int nas_ioCTL_rb_list_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1]; struct nas_msg_rb_list_request msgreq; printk("NAS_IOCTL_RB_LIST: Radio Bearer list requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_RB_LIST: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_rb_list_reply(msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) { printk("NAS_IOCTL_RB_LIST: copy_to_user failure\n"); return -EFAULT; } printk("NAS_IOCTL_CX_LIST: end\n"); return 0; } /////////////////////////////////////////////////////////////////////////////// // Radio Bearer Establishment //--------------------------------------------------------------------------- void nas_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep, struct nas_msg_rb_establishment_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- // if ((msgreq->rab_id<3)||(msgreq->rab_id>127)) if ((msgreq->rab_id<1)||(msgreq->rab_id>MAX_RABS)) // navid : increase the number msgrep->status=-NAS_ERROR_NOTCORRECTRABI; else { struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx==NULL) msgrep->status=-NAS_ERROR_NOTCORRECTLCR; else { struct rb_entity *rb; rb=nas_COMMON_add_rb(cx, msgreq->rab_id, msgreq->qos); if (rb!=NULL) { // rb->cnxid = msgreq->cnxid; // msgrep->status=nas_rg_DC_send_rb_establish_request(cx, rb); } else msgrep->status=-NAS_ERROR_NOMEMORY; // msgrep->cnxid = msgreq->cnxid; } } } //--------------------------------------------------------------------------- int nas_ioCTL_rb_establishment_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_rb_establishment_request msgreq; struct nas_msg_rb_establishment_reply msgrep; printk("NAS_IOCTL_RB_ESTABLISHMENT: Radio bearer establishment requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_rb_establishment_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Radio Bearer Release //--------------------------------------------------------------------------- void nas_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep, struct nas_msg_rb_release_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- if (msgreq->lcr<NAS_CX_MAX) { struct rb_entity *rb; struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); rb=nas_COMMON_search_rb(cx, msgreq->rab_id); if (rb!=NULL) { //msgrep->status=nas_rg_DC_send_rb_release_request(cx, rb); } else msgrep->status=-NAS_ERROR_NOTCONNECTED; // msgrep->cnxid = msgreq->cnxid; } else msgrep->status=-NAS_ERROR_NOTCORRECTLCR; } //--------------------------------------------------------------------------- int nas_ioCTL_rb_release_request( struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_rb_release_request msgreq; struct nas_msg_rb_release_reply msgrep; printk("NAS_IOCTL_RB_RELEASE: Radio bearer release requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_RB_RELEASE: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_rb_release_reply(&msgrep, &msgreq, priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_RB_RELEASE: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Classifier List //--------------------------------------------------------------------------- void nas_set_msg_class_list_reply( uint8_t *msgrep, struct nas_msg_class_list_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; struct classifier_entity *gc; struct nas_msg_class_list_reply *list; uint8_t cli; list=(struct nas_msg_class_list_reply *)(msgrep+1); switch(msgreq->dir) { case NAS_DIRECTION_SEND: cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx==NULL) { msgrep[0]=0; return; } gc=cx->sclassifier[msgreq->dscp]; break; case NAS_DIRECTION_RECEIVE: cx=NULL; gc=priv->rclassifier[msgreq->dscp]; break; default: cx=NULL; msgrep[0]=0; return; } for (cli=0; (gc!=NULL)&&(cli<NAS_LIST_CLASS_MAX); gc=gc->next, ++cli) { list[cli].classref=gc->classref; list[cli].lcr=msgreq->lcr; list[cli].dir=msgreq->dir; list[cli].dscp=msgreq->dscp; list[cli].rab_id=gc->rab_id; list[cli].version=gc->version; switch(gc->version) { case 4: list[cli].saddr.ipv4 = gc->saddr.ipv4; list[cli].daddr.ipv4 = gc->daddr.ipv4; break; case 6: list[cli].saddr.ipv6 = gc->saddr.ipv6; list[cli].daddr.ipv6 = gc->daddr.ipv6; break; } list[cli].protocol=gc->protocol; list[cli].sport=ntohs(gc->sport); list[cli].dport=ntohs(gc->dport); list[cli].splen=gc->splen; list[cli].dplen=gc->dplen; list[cli].fct=nas_TOOL_invfct(gc); } msgrep[0]=cli; } //--------------------------------------------------------------------------- int nas_ioCTL_class_list_request( struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1]; struct nas_msg_class_list_request msgreq; printk("NAS_IOCTL_CLASS_LIST: classifier list requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_CLASS_LIST: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_class_list_reply(msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) { printk("NAS_IOCTL_CLASS_LIST: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Request the addition of a classifier rule //--------------------------------------------------------------------------- void nas_set_msg_class_add_reply( struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct classifier_entity *gc,*gc2; unsigned char *saddr,*daddr; unsigned int *saddr32,*daddr32; printk("[NAS][CLASS] nas_set_msg_class_add_reply\n"); if (msgreq->dscp>NAS_DSCP_MAX) { printk("NAS_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=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx!=NULL) { printk("NAS_SET_MSG_CLASS_ADD_REPLY: DSCP/EXP %d, Classref %d, RB %u\n", msgreq->dscp, msgreq->classref,msgreq->rab_id ); gc=nas_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref); printk("NAS_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=nas_COMMON_search_rb(cx, gc->rab_id); printk("NAS_SET_MSG_CLASS_ADD_REPLY: gc_rb %p %u \n", gc->rb, gc->rab_id); } else { if (msgreq->dir==NAS_DIRECTION_RECEIVE) { gc=nas_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref, priv); if (gc==NULL) { msgrep->status=-NAS_ERROR_NOMEMORY; return; } gc->rab_id=msgreq->rab_id; } else { msgrep->status=-NAS_ERROR_NOTCORRECTDIR; return; } for (gc2 = priv->rclassifier[msgreq->dscp]; gc2!=NULL ; gc2 = gc2->next) printk("[NAS][CLASS] Add Receive Classifier dscp %d: rab_id %d (%p,next %p)\n",msgreq->dscp,gc2->rab_id,gc2,gc2->next); } printk("[NAS][CLASS] Getting addresses ...\n"); nas_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; // #ifdef NAS_CLASS_DEBUG saddr = (unsigned char *)&gc->saddr.ipv4; daddr = (unsigned char *)&gc->daddr.ipv4; printk("[NAS][CLASS] Adding IPv4 %d.%d.%d.%d -> %d.%d.%d.%d\n", saddr[0],saddr[1],saddr[2],saddr[3], daddr[0],daddr[1],daddr[2],daddr[3]); //#endif gc->splen=msgreq->splen; gc->dplen=msgreq->dplen; break; case 6: memcpy(&gc->saddr.ipv6,&msgreq->saddr.ipv6,16); memcpy(&gc->daddr.ipv6,&msgreq->daddr.ipv6,16); saddr32 = (unsigned int *)&gc->saddr.ipv6; daddr32 = (unsigned int *)&gc->daddr.ipv6; printk("[NAS][CLASS] Adding IPv6 %X:%X:%X:%X -> %X.%X.%X.%X\n", saddr32[0],saddr32[1],saddr32[2],saddr32[3], daddr32[0],daddr32[1],daddr32[2],daddr32[3]); gc->splen=msgreq->splen; gc->dplen=msgreq->dplen; break; case NAS_MPLS_VERSION_CODE: printk("[NAS][CLASS] Adding MPLS label %d with exp %d\n", msgreq->daddr.mpls_label,msgreq->dscp); gc->daddr.mpls_label = msgreq->daddr.mpls_label; 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->protocol_message_type=msgreq->protocol_message_type; gc->sport=htons(msgreq->sport); gc->dport=htons(msgreq->dport); msgrep->status=0; } //--------------------------------------------------------------------------- int nas_ioCTL_class_add_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_class_add_request msgreq; struct nas_msg_class_add_reply msgrep; printk("NAS_IOCTL_CLASS_ADD: Add classifier components requested\n"); printk("NAS_IOCTL_CLASS_ADD: size of gifr msg %zd\n", sizeof(gifr->msg)); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_CLASS_ADD: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_class_add_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_CLASS_ADD: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Request the deletion of a classifier rule //--------------------------------------------------------------------------- void nas_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep, struct nas_msg_class_del_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- if (msgreq->dscp>NAS_DSCP_DEFAULT) { printk("NAS_SET_MSG_CLASS_DEL_REPLY: Incoherent parameter value\n"); msgrep->status=-NAS_ERROR_NOTCORRECTDSCP; return; } if (msgreq->dir==NAS_DIRECTION_SEND) { struct cx_entity *cx; cx=nas_COMMON_search_cx(msgreq->lcr,priv); if (cx!=NULL) nas_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref); else { msgrep->status=-NAS_ERROR_NOTCORRECTLCR; return; } } else { if (msgreq->dir==NAS_DIRECTION_RECEIVE) nas_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref,priv); else { msgrep->status=-NAS_ERROR_NOTCORRECTDIR; return; } } msgrep->status=0; } //--------------------------------------------------------------------------- int nas_ioCTL_class_del_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_class_del_request msgreq; struct nas_msg_class_del_reply msgrep; printk("NAS_IOCTL_CLASS_DEL: Del classifier components requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_CLASS_DEL: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_class_del_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_CLASS_DEL: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // Measurement // Messages for Measurement transfer //--------------------------------------------------------------------------- void nas_set_msg_measure_reply(struct nas_msg_measure_reply *msgrep, struct nas_msg_measure_request *msgreq, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; int lcr=0; // Temp lcr->mt =0 int i; cx=nas_COMMON_search_cx(lcr,priv); if (cx!=NULL) { msgrep->num_cells = cx->num_measures; for (i=0; i<cx->num_measures; i++) { msgrep-> measures[i].cell_id = cx->meas_cell_id[i]; msgrep-> measures[i].level = cx->meas_level[i]; msgrep-> measures[i].provider_id = cx->provider_id[i]; } msgrep->signal_lost_flag = 0; } } //--------------------------------------------------------------------------- int nas_ioCTL_measure_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_measure_request msgreq; struct nas_msg_measure_reply msgrep; printk("NAS_IOCTL_MEASURE: Measurement requested\n"); if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { printk("NAS_IOCTL_MEASURE: copy_from_user failure\n"); return -EFAULT; } nas_set_msg_measure_reply(&msgrep, &msgreq,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_MEASURE: copy_to_user failure\n"); return -EFAULT; } return 0; } /////////////////////////////////////////////////////////////////////////////// // IMEI // Messages for IMEI transfer //--------------------------------------------------------------------------- void nas_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct cx_entity *cx; int lcr=0; // Temp lcr->mt =0 cx=nas_COMMON_search_cx(lcr,priv); if (cx!=NULL) { msgrep->l2id[0] = cx->iid6[0]; msgrep->l2id[1] = cx->iid6[1]; } } //--------------------------------------------------------------------------- int nas_ioCTL_imei_request(struct nas_ioctl *gifr, struct nas_priv *priv) { //--------------------------------------------------------------------------- struct nas_msg_l2id_reply msgrep; printk("NAS_IOCTL_IMEI: IMEI requested\n"); nas_set_msg_imei_reply(&msgrep,priv); if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { printk("NAS_IOCTL_IMEI: copy_to_user failure\n"); return -EFAULT; } return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IOCTL command //--------------------------------------------------------------------------- int nas_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { //--------------------------------------------------------------------------- struct nas_ioctl *gifr; struct nas_priv *priv=netdev_priv(dev); int r; // printk("NAS_CTL_IOCTL: begin ioctl for instance %d\n",find_inst(dev)); switch(cmd) { case NAS_IOCTL_RRM: gifr=(struct nas_ioctl *)ifr; switch(gifr->type) { case NAS_MSG_STATISTIC_REQUEST: r=nas_ioCTL_statistic_request(gifr,priv); break; case NAS_MSG_CX_ESTABLISHMENT_REQUEST: r=nas_ioCTL_cx_establishment_request(gifr,priv); break; case NAS_MSG_CX_RELEASE_REQUEST: r=nas_ioCTL_cx_release_request(gifr,priv); break; case NAS_MSG_CX_LIST_REQUEST: r=nas_ioCTL_cx_list_request(gifr,priv); break; case NAS_MSG_RB_ESTABLISHMENT_REQUEST: r=nas_ioCTL_rb_establishment_request(gifr,priv); break; case NAS_MSG_RB_RELEASE_REQUEST: r= nas_ioCTL_rb_release_request(gifr,priv); break; case NAS_MSG_RB_LIST_REQUEST: r=nas_ioCTL_rb_list_request(gifr,priv); break; case NAS_MSG_CLASS_ADD_REQUEST: r=nas_ioCTL_class_add_request(gifr,priv); break; case NAS_MSG_CLASS_LIST_REQUEST: r=nas_ioCTL_class_list_request(gifr,priv); break; case NAS_MSG_CLASS_DEL_REQUEST: r=nas_ioCTL_class_del_request(gifr,priv); break; case NAS_MSG_MEAS_REQUEST: r=nas_ioCTL_measure_request(gifr,priv); break; case NAS_MSG_IMEI_REQUEST: r=nas_ioCTL_imei_request(gifr,priv); break; default: // printk("NAS_IOCTL_RRM: unkwon request type, type=%x\n", gifr->type); r=-EFAULT; } break; default: // printk("NAS_CTL_IOCTL: Unknown ioctl command, cmd=%x\n", cmd); r=-EFAULT; } // printk("NAS_CTL_IOCTL: end\n"); return r; } //--------------------------------------------------------------------------- void nas_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc, int inst, struct nas_priv *gpriv) { //--------------------------------------------------------------------------- printk("NAS_CTL_SEND - void \n"); }