rrc_rrm_interface.c 7.01 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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
 */

22 23 24
/*!
*******************************************************************************

25
\file     rrm_sock.c
26

27 28 29 30
\brief    RRM (Radio Ressource Manager ) Socket: communication withe other medium:
          - RRC ,
          - CMM ,
          - PUSU
31

32
\author   BURLOT Pascal
33

34
\date     10/07/08
35 36 37 38


\par     Historique:
        P.BURLOT 2009-01-20
39 40 41
            + send a message via fifo:
                - sending header
                - and data if any
42 43 44 45 46

*******************************************************************************
*/

#ifndef RRC_RRM_FIFOS_XFACE
47 48 49 50 51
  #include <stdio.h>
  #include <stdlib.h>
  #include <errno.h>
  #include <string.h>
  #include <unistd.h>
52

53 54
  #include <sys/socket.h>
  #include <sys/un.h>
55 56 57

#else

58
  #include<rtai_fifos.h>
59 60 61 62 63

#endif

#include "rrc_rrm_interface.h"
#include "defs.h"
64 65
//! \brief  Taille maximale de la charge utile
#define SIZE_MAX_PAYLOAD  2048
66
//! \brief PID de l'espace utilisateur (Netlink mode)
67
//#define PID_USERSPACE   0xAA
68 69 70 71 72 73 74 75 76 77 78 79 80





#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(
81
  sock_rrm_t *s,    ///< socket descriptor
82
  char *path_local,   ///< local socket path if unix socket
83
  char *path_dest,    ///< host  Socket path if unix socket
84
  int rrm_inst        ///< instance of the rrm entity
85
) {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  /* 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 ;
113 114 115 116 117 118 119
}
/*!
*******************************************************************************
\brief  This function closes a RRM socket
\return none
*/
void close_socket(
120
  sock_rrm_t *sock  ///< the socket handle
121
) {
122 123
  shutdown(sock->s, SHUT_RDWR);
  close(sock->s);
124 125 126 127 128 129 130 131 132
}

/*!
*******************************************************************************
\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(
133
  sock_rrm_t *s,   ///< socket descriptor
134
  msg_t *smsg       ///< the message to send
135
) {
136 137 138 139 140 141 142
  /* Unix socket */
  int         ret   = 0 ;
  //  char        *buf    = NULL;
  struct  msghdr    msghd ;
  struct  iovec     iov;
  int         taille  = sizeof(msg_head_t)  ;

143
  if ( smsg == NULL ) {
144
    return -1 ;
145
  }
146

147
  if ( smsg->data != NULL ) {
148
    taille += smsg->head.size ;
149
  }
150 151 152 153

  //buf = RRM_MALLOC(char, taille);
  //if (buf ==NULL)
  //return -1 ;
154
  memcpy( BUFF, &(smsg->head), sizeof(msg_head_t) ) ;
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  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 ;
175 176 177 178 179 180 181 182 183
}

/*!
*******************************************************************************
\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(
184
  sock_rrm_t *s   ///< socket descriptor
185
) {
186 187 188 189 190 191 192 193 194 195 196
  /* 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);

197
  if ( buf == NULL ) {
198
    return NULL ;
199
  }
200 201 202 203 204 205 206 207 208

  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 ;
209
  ret = recvmsg(s->s, &msghd, 0 ) ;
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

  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 ;
226
  smsg    = RRM_CALLOC(char, size_msg ) ;
227

228
  if ( smsg != NULL ) {
229
    memcpy( smsg, buf, size_msg ) ;
230
  }
231 232 233

  RRM_FREE( buf ) ;
  return smsg ;
234 235 236 237
}

#else  //XFACE

238
int send_msg_fifo(int *s, msg_t *fmsg) {
239
  int   ret   = 0, ret1;
240 241
  int  taille = sizeof(msg_head_t)  ;
  msg("write on fifos %d, msg %p\n",*s,fmsg);
242

243
  if ( fmsg == NULL ) {
244
    return -1 ;
245
  }
246

247
  // envoi le header
248
  ret1 = rtf_put (*s,(char *) &(fmsg->head), taille);
249 250

  if(ret1 <0) {
251 252 253 254
    msg("rtf_put H ERR %d\n",ret1);
    rtf_reset(*s);
    return ret1;
  }
255

256
  ret=ret1;
257

258
  // envoi les datas si elles sont definis
259
  if ( fmsg->data != NULL ) {
260
    ret1 += rtf_put (*s,(char *) fmsg->data, fmsg->head.size);
261 262

    if(ret1 <0) {
263 264 265 266 267
      msg("rtf_put D ERR %d\n",ret1);
      rtf_reset(*s);
      return ret1;
    }
  }
268

269 270 271 272 273 274
  ret+=ret1;
  return ret;
}

#endif //XFACE

275
int send_msg(void *s, msg_t *smsg) {
276 277
  send_msg_sock((sock_rrm_t *)s, smsg);
}