/*! ******************************************************************************* \file rrm_sock.c \brief RRM (Radio Ressource Manager ) Socket Ceux sont les fonctions relatives à la communication avec les autres entites: - RRC , - CMM , - PUSU \author BURLOT Pascal \date 10/07/08 \par Historique: P.BURLOT 2009-01-20 + l'envoi de message via la fifo: - envoi du header - puis des donnees s'il y en a ******************************************************************************* */ #ifndef RRC_RRM_FIFOS_XFACE #include #include #include #include #include #include #include #else #include #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 }