git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7117 818b1a75-f10b-46b9-bf7c-635c3b92a50f
255 lines
8.2 KiB
C
Executable File
255 lines
8.2 KiB
C
Executable File
/***************************************************************************
|
|
nasrg_netlink.c - description
|
|
-------------------
|
|
***************************************************************************
|
|
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_netlink.c
|
|
* \brief Netlink socket functions for OpenAirInterface CELLULAR version - MT
|
|
* \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
|
|
*/
|
|
/*******************************************************************************/
|
|
//#include <linux/config.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/netlink.h>
|
|
#include <net/sock.h>
|
|
#include <linux/kthread.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include "nasrg_variables.h"
|
|
#include "nasrg_proto.h"
|
|
|
|
static struct sock *nas_nl_sk = NULL;
|
|
static struct sock *nas_rrcnl_sk = NULL;
|
|
|
|
//static int exit_netlink_thread=0;
|
|
static DEFINE_MUTEX(nasrg_mutex);
|
|
|
|
// This can also be implemented using thread to get the data from PDCP without blocking.
|
|
//---------------------------------------------------------------------------
|
|
// Function for transfer with PDCP (from NASLITE)
|
|
static void nasrg_nl_data_ready (struct sk_buff *skb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nlmsghdr *nlh = NULL;
|
|
|
|
// Start debug information
|
|
#ifdef NETLINK_DEBUG
|
|
printk("nasrg_nl_data_ready - begin \n");
|
|
#endif
|
|
|
|
if (!skb) {
|
|
printk("nasrg_nl_data_ready - input parameter skb is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
|
|
#ifdef NETLINK_DEBUG
|
|
printk("nasrg_nl_data_ready - Received socket from PDCP\n");
|
|
#endif //NETLINK_DEBUG
|
|
nlh = (struct nlmsghdr *)skb->data;
|
|
nasrg_COMMON_QOS_receive(nlh);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Function for transfer with RRC
|
|
static void nasrg_rrcnl_data_ready (struct sk_buff *skb)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct nlmsghdr *nlh = NULL;
|
|
char target_sap;
|
|
uint8_t cxi;
|
|
|
|
// Start debug information
|
|
#ifdef NAS_DEBUG_RRCNL
|
|
printk("nasrg_rrcnl_data_ready - begin \n");
|
|
#endif
|
|
|
|
if (!skb) {
|
|
printk("nasrg_rrcnl_data_ready - input parameter skb is NULL \n");
|
|
return;
|
|
}
|
|
|
|
// End debug information
|
|
|
|
nlh = (struct nlmsghdr *)skb->data;
|
|
//pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh);
|
|
//nasrg_TOOL_print_buffer((char *)NLMSG_DATA(nlh), 48);
|
|
|
|
target_sap = ((char*)NLMSG_DATA(nlh))[0];
|
|
#ifdef NAS_DEBUG_RRCNL
|
|
printk("nasrg_rrcnl_data_ready - Received on socket from RRC, SAP %d\n", target_sap);
|
|
#endif //NAS_DEBUG_RRCNL
|
|
|
|
switch (target_sap) {
|
|
case RRC_NAS_DC0_OUT:
|
|
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
|
|
cxi = 0;
|
|
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
|
|
break;
|
|
|
|
case RRC_NAS_DC1_OUT:
|
|
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
|
|
cxi = 1;
|
|
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
|
|
break;
|
|
|
|
case RRC_NAS_DC2_OUT:
|
|
//printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n");
|
|
cxi = 2;
|
|
nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]);
|
|
break;
|
|
|
|
default:
|
|
printk("nasrg_rrcnl_data_ready - Invalid SAP value received\n");
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nasrg_netlink_init(void)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
printk("nasrg_netlink_init - begin \n");
|
|
|
|
nas_nl_sk = netlink_kernel_create(&init_net,OAI_IP_DRIVER_NETLINK_ID, 0, nasrg_nl_data_ready,
|
|
&nasrg_mutex, // NULL
|
|
THIS_MODULE);
|
|
|
|
if (!nas_nl_sk) {
|
|
printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket\n");
|
|
// TEMP printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket %d\n", errno);
|
|
return(-1);
|
|
}
|
|
|
|
nas_rrcnl_sk = netlink_kernel_create(&init_net,NAS_RRCNL_ID, 0, nasrg_rrcnl_data_ready,
|
|
&nasrg_mutex, // NULL
|
|
THIS_MODULE);
|
|
|
|
if (!nas_rrcnl_sk) {
|
|
printk("nasrg_rrcnl_init - netlink_kernel_create failed for RRC socket\n");
|
|
return(-1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void nasrg_netlink_release(void)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
printk("nasrg_netlink_release - begin \n");
|
|
|
|
//exit_netlink_thread=1;
|
|
printk("nasrg_netlink_release - Releasing netlink sockets\n");
|
|
|
|
if(nas_nl_sk) {
|
|
netlink_kernel_release(nas_nl_sk);
|
|
}
|
|
|
|
if(nas_rrcnl_sk) {
|
|
netlink_kernel_release(nas_rrcnl_sk);
|
|
}
|
|
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nasrg_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
struct sk_buff *nl_skb;
|
|
struct nlmsghdr *nlh;
|
|
int status;
|
|
// Start debug information
|
|
#ifdef NETLINK_DEBUG
|
|
printk("nasrg_netlink_send - begin \n");
|
|
#endif
|
|
|
|
if (!data_buffer) {
|
|
printk("nasrg_netlink_send - ERROR - input parameter data is NULL \n");
|
|
return(0);
|
|
}
|
|
|
|
if (!nas_nl_sk || !nas_rrcnl_sk) {
|
|
printk("nasrg_netlink_send - ERROR - socket is NULL\n");
|
|
return(0);
|
|
}
|
|
|
|
// End debug information
|
|
|
|
nl_skb = alloc_skb(NLMSG_SPACE(data_length),GFP_ATOMIC);
|
|
|
|
if (!nl_skb) {
|
|
printk("nasrg_netlink_send - ERROR - could not allocate skbuffer\n");
|
|
return(0);
|
|
}
|
|
|
|
nlh = (struct nlmsghdr *)nl_skb->data;
|
|
|
|
// printk("nasrg_netlink_send Sending %d bytes (%d)\n",data_length,NLMSG_SPACE(data_length));
|
|
skb_put(nl_skb, NLMSG_SPACE(data_length));
|
|
memcpy(NLMSG_DATA(nlh), data_buffer, data_length);
|
|
nlh->nlmsg_len = NLMSG_SPACE(data_length);
|
|
|
|
nlh->nlmsg_pid = 0; /* from kernel */
|
|
NETLINK_CB(nl_skb).pid = 0;
|
|
|
|
// destination 0 = PDCP, 1 = RRC
|
|
if (destination== NASNL_DEST_PDCP) {
|
|
#ifdef NETLINK_DEBUG
|
|
printk("nasrg_netlink_send - Sending to PDCP - nl_skb %p, nl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_nl_sk, nlh, nlh->nlmsg_len);
|
|
#ifdef NAS_DEBUG_SEND_DETAIL
|
|
nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),48);
|
|
#endif
|
|
#endif //DEBUG_NETLINK
|
|
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
|
|
} else {
|
|
#ifdef NAS_DEBUG_RRCNL
|
|
printk("nasrg_netlink_send - Sending to RRC - nl_skb %p, nas_rrcnl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_rrcnl_sk, nlh, nlh->nlmsg_len);
|
|
nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),data_length);
|
|
#endif //NAS_DEBUG_RRCNL
|
|
status = netlink_unicast(nas_rrcnl_sk, nl_skb, NL_DEST_RRC_PID, MSG_DONTWAIT);
|
|
}
|
|
|
|
if (status < 0) {
|
|
printk("nasrg_netlink_send - SEND status is %d\n",status);
|
|
return(0);
|
|
} else {
|
|
#ifdef NETLINK_DEBUG
|
|
printk("nasrg_netlink_send - SEND status is %d, data_length %d\n",status, data_length);
|
|
#endif
|
|
return data_length;
|
|
}
|
|
}
|
|
|
|
|