git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5714 818b1a75-f10b-46b9-bf7c-635c3b92a50f
293 lines
7.1 KiB
C
293 lines
7.1 KiB
C
/*******************************************************************************
|
|
OpenAirInterface
|
|
Copyright(c) 1999 - 2014 Eurecom
|
|
|
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
|
|
OpenAirInterface is distributed in the hope that 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 OpenAirInterface.The full GNU General Public License is
|
|
included in this distribution in the file called "COPYING". If not,
|
|
see <http://www.gnu.org/licenses/>.
|
|
|
|
Contact Information
|
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
|
|
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
|
|
|
*******************************************************************************/
|
|
/*!
|
|
*******************************************************************************
|
|
|
|
\file rrm_sock.c
|
|
|
|
\brief RRM (Radio Ressource Manager ) Socket: communication withe other medium:
|
|
- RRC ,
|
|
- CMM ,
|
|
- PUSU
|
|
|
|
\author BURLOT Pascal
|
|
|
|
\date 10/07/08
|
|
|
|
|
|
\par Historique:
|
|
P.BURLOT 2009-01-20
|
|
+ send a message via fifo:
|
|
- sending header
|
|
- and data if any
|
|
|
|
*******************************************************************************
|
|
*/
|
|
|
|
#ifndef RRC_RRM_FIFOS_XFACE
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
|
|
#else
|
|
|
|
#include<rtai_fifos.h>
|
|
|
|
#endif
|
|
|
|
#include "rrc_rrm_interface.h"
|
|
#include "defs.h"
|
|
//! \brief Taille maximale de la charge utile
|
|
#define SIZE_MAX_PAYLOAD 2048
|
|
//! \brief PID de l'espace utilisateur (Netlink mode)
|
|
//#define PID_USERSPACE 0xAA
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef RRC_RRM_FIFOS_XFACE
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief This function opens a unix socket for the rrm communication
|
|
\return The return value is a socket handle
|
|
*/
|
|
int open_socket(
|
|
sock_rrm_t *s , ///< socket descriptor
|
|
char *path_local, ///< local socket path if unix socket
|
|
char *path_dest , ///< host Socket path if unix socket
|
|
int rrm_inst ///< instance of the rrm entity
|
|
)
|
|
{ /* Unix socket */
|
|
int socket_fd ;
|
|
int len ;
|
|
|
|
if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
|
|
{
|
|
perror("unix socket");
|
|
return -1 ;
|
|
}
|
|
|
|
memset(&(s->un_local_addr), 0, sizeof(struct sockaddr_un));
|
|
s->un_local_addr.sun_family = AF_UNIX;
|
|
sprintf(s->un_local_addr.sun_path,"%s%d", path_local, rrm_inst );
|
|
unlink(s->un_local_addr.sun_path);
|
|
msg("local %s\n",s->un_local_addr.sun_path);
|
|
len = strlen((s->un_local_addr).sun_path) + sizeof((s->un_local_addr).sun_family);
|
|
|
|
if (bind(socket_fd, (struct sockaddr *)&(s->un_local_addr), len) == -1)
|
|
{
|
|
perror("bind");
|
|
return -1 ;
|
|
}
|
|
|
|
memset(&(s->un_dest_addr), 0, sizeof(struct sockaddr_un));
|
|
s->un_dest_addr.sun_family = AF_UNIX;
|
|
sprintf(s->un_dest_addr.sun_path,"%s%d", path_dest, rrm_inst );
|
|
msg("Dest %s\n",s->un_dest_addr.sun_path);
|
|
|
|
|
|
s->s = socket_fd ;
|
|
return socket_fd ;
|
|
}
|
|
/*!
|
|
*******************************************************************************
|
|
\brief This function closes a RRM socket
|
|
\return none
|
|
*/
|
|
void close_socket(
|
|
sock_rrm_t *sock ///< the socket handle
|
|
)
|
|
{
|
|
shutdown(sock->s, SHUT_RDWR);
|
|
close(sock->s);
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief This function send a buffer message to the unix socket
|
|
\return if OK then "0" is returned else "-1"
|
|
*/
|
|
char BUFF[2048];
|
|
int send_msg_sock(
|
|
sock_rrm_t *s ,///< socket descriptor
|
|
msg_t *smsg ///< the message to send
|
|
)
|
|
{ /* Unix socket */
|
|
int ret = 0 ;
|
|
// char *buf = NULL;
|
|
struct msghdr msghd ;
|
|
struct iovec iov;
|
|
int taille = sizeof(msg_head_t) ;
|
|
|
|
if ( smsg == NULL )
|
|
return -1 ;
|
|
|
|
if ( smsg->data != NULL )
|
|
taille += smsg->head.size ;
|
|
|
|
//buf = RRM_MALLOC(char, taille);
|
|
//if (buf ==NULL)
|
|
//return -1 ;
|
|
|
|
memcpy( BUFF , &(smsg->head) , sizeof(msg_head_t) ) ;
|
|
memcpy( BUFF+sizeof(msg_head_t), smsg->data, smsg->head.size ) ;
|
|
|
|
iov.iov_base = (void *)BUFF;
|
|
iov.iov_len = taille ;
|
|
|
|
msghd.msg_name = (void *)&(s->un_dest_addr);
|
|
msghd.msg_namelen = sizeof(s->un_dest_addr);
|
|
msghd.msg_iov = &iov;
|
|
msghd.msg_iovlen = 1;
|
|
msghd.msg_control = NULL ;
|
|
msghd.msg_controllen = 0 ;
|
|
if ( sendmsg(s->s, &msghd, 0) < 0 )
|
|
{
|
|
ret = -1;
|
|
msg("socket %d, dest %s\n",s->s,s->un_dest_addr.sun_path);
|
|
perror("sendmsg:unix socket");
|
|
}
|
|
|
|
//RRM_FREE(buf) ;
|
|
//RRM_FREE(msg->data) ;
|
|
//RRM_FREE(msg) ;
|
|
|
|
return ret ;
|
|
}
|
|
|
|
/*!
|
|
*******************************************************************************
|
|
\brief This function read a buffer from a unix socket
|
|
\return the function returns a message pointer. If the pointeur is NULL, a error
|
|
is happened.
|
|
*/
|
|
char *recv_msg(
|
|
sock_rrm_t *s ///< socket descriptor
|
|
)
|
|
{ /* Unix socket */
|
|
char *buf = NULL;
|
|
char *smsg = NULL;
|
|
struct msghdr msghd ;
|
|
struct iovec iov;
|
|
int size_msg ;
|
|
msg_head_t *head ;
|
|
int ret ;
|
|
|
|
int taille = SIZE_MAX_PAYLOAD ;
|
|
|
|
buf = RRM_CALLOC( char,taille);
|
|
if ( buf == NULL )
|
|
return NULL ;
|
|
|
|
iov.iov_base = (void *)buf;
|
|
iov.iov_len = taille ;
|
|
msghd.msg_name = (void *)&(s->un_dest_addr);
|
|
msghd.msg_namelen = sizeof(s->un_dest_addr);
|
|
msghd.msg_iov = &iov;
|
|
msghd.msg_iovlen = 1;
|
|
msghd.msg_control = NULL ;
|
|
msghd.msg_controllen= 0 ;
|
|
|
|
ret = recvmsg(s->s, &msghd , 0 ) ;
|
|
if ( ret <= 0 )
|
|
{
|
|
// non-blocking socket
|
|
// perror("PB recvmsg_un");
|
|
RRM_FREE(buf);
|
|
return NULL ;
|
|
}
|
|
|
|
if (msghd.msg_flags != 0 )
|
|
{
|
|
fprintf(stderr,"error recvmsg_un: 0x%02x\n", msghd.msg_flags) ;
|
|
RRM_FREE(buf);
|
|
return NULL ;
|
|
}
|
|
|
|
head = (msg_head_t *) buf ;
|
|
size_msg = sizeof(msg_head_t) + head->size ;
|
|
|
|
smsg = RRM_CALLOC(char , size_msg ) ;
|
|
if ( smsg != NULL )
|
|
memcpy( smsg , buf , size_msg ) ;
|
|
|
|
RRM_FREE( buf ) ;
|
|
|
|
return smsg ;
|
|
}
|
|
|
|
#else //XFACE
|
|
|
|
int send_msg_fifo(int *s, msg_t *fmsg){
|
|
int ret = 0, ret1;
|
|
int taille = sizeof(msg_head_t) ;
|
|
msg("write on fifos %d, msg %p\n",*s,fmsg);
|
|
if ( fmsg == NULL )
|
|
return -1 ;
|
|
// envoi le header
|
|
|
|
|
|
ret1 = rtf_put (*s,(char*) &(fmsg->head) , taille);
|
|
if(ret1 <0){
|
|
msg("rtf_put H ERR %d\n",ret1);
|
|
rtf_reset(*s);
|
|
return ret1;
|
|
}
|
|
ret=ret1;
|
|
// envoi les datas si elles sont definis
|
|
if ( fmsg->data != NULL ){
|
|
ret1 += rtf_put (*s,(char*) fmsg->data, fmsg->head.size);
|
|
if(ret1 <0){
|
|
msg("rtf_put D ERR %d\n",ret1);
|
|
rtf_reset(*s);
|
|
return ret1;
|
|
}
|
|
}
|
|
ret+=ret1;
|
|
return ret;
|
|
}
|
|
|
|
#endif //XFACE
|
|
|
|
int send_msg(void *s, msg_t *smsg){
|
|
#ifdef USER_MODE
|
|
send_msg_sock((sock_rrm_t *)s, smsg);
|
|
#else
|
|
send_msg_fifo((int *)s,smsg);
|
|
#endif
|
|
|
|
}
|