mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly
For automated changes based on OAI PL v1.1:
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml
The rest (cmake, files with missing license, cmake) manually.
502 lines
16 KiB
C
502 lines
16 KiB
C
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
/*!
|
|
* \brief API to stream I/Q samples over standard ethernet
|
|
*/
|
|
|
|
#include <arpa/inet.h>
|
|
#include <linux/if_packet.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
#include <net/if.h>
|
|
#include <netinet/ether.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include "common_lib.h"
|
|
#include "ethernet_lib.h"
|
|
|
|
//#define DEBUG 0
|
|
|
|
//struct sockaddr_ll dest_addr[MAX_INST];
|
|
//struct sockaddr_ll local_addr[MAX_INST];
|
|
//int addr_len[MAX_INST];
|
|
//struct ifreq if_index[MAX_INST];
|
|
|
|
int eth_socket_init_raw(openair0_device_t *device)
|
|
{
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
const char *local_mac, *remote_mac;
|
|
int sock_dom=0;
|
|
int sock_type=0;
|
|
int sock_proto=0;
|
|
|
|
if (device->host_type == RRU_HOST ) { /* RRU doesn't know remote MAC(will be retrieved from first packet send from RAU) and remote port(don't care) */
|
|
local_mac = device->eth_params->my_addr;
|
|
remote_mac = malloc(ETH_ALEN);
|
|
memset((void*)remote_mac,0,ETH_ALEN);
|
|
printf("[%s] local MAC addr (user) %s remote MAC addr (user) %s\n","RRU", local_mac,remote_mac);
|
|
} else {
|
|
local_mac = device->eth_params->my_addr;
|
|
remote_mac = device->eth_params->remote_addr;
|
|
printf("[%s] local MAC addr (user) %s remote MAC addr (user) %s\n","RAU", local_mac,remote_mac);
|
|
}
|
|
|
|
|
|
/* Open a RAW socket to send on */
|
|
sock_dom=AF_PACKET;
|
|
sock_type=SOCK_RAW;
|
|
sock_proto=IPPROTO_RAW;
|
|
if ((eth->sockfdc = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
|
perror("ETHERNET: Error opening RAW socket (control)");
|
|
exit(0);
|
|
}
|
|
for (int i=0;i<eth->num_fd;i++)
|
|
if ((eth->sockfdd[i] = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
|
perror("ETHERNET: Error opening RAW socket (user)");
|
|
exit(0);
|
|
}
|
|
|
|
/* initialize destination address */
|
|
bzero((void *)&(eth->local_addrd_ll), sizeof(struct sockaddr_ll));
|
|
bzero((void *)&(eth->if_index), sizeof(struct ifreq));
|
|
|
|
/* Get the index of the interface to send on */
|
|
strcpy(eth->if_index.ifr_name,eth->if_name);
|
|
if (ioctl(eth->sockfdc, SIOCGIFINDEX, &(eth->if_index)) < 0)
|
|
perror("SIOCGIFINDEX");
|
|
for (int i=0;i<eth->num_fd;i++)
|
|
if (ioctl(eth->sockfdd[i], SIOCGIFINDEX, &(eth->if_index)) < 0)
|
|
perror("SIOCGIFINDEX");
|
|
|
|
eth->local_addrd_ll.sll_family = AF_PACKET;
|
|
eth->local_addrd_ll.sll_ifindex = eth->if_index.ifr_ifindex;
|
|
/* hear traffic from specific protocol*/
|
|
eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
|
|
|
|
eth->local_addrd_ll.sll_halen = ETH_ALEN;
|
|
eth->local_addrd_ll.sll_pkttype = PACKET_OTHERHOST;
|
|
eth->addr_len = sizeof(struct sockaddr_ll);
|
|
|
|
for (int i=0;i<eth->num_fd;i++)
|
|
if (bind(eth->sockfdd[i],(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) {
|
|
perror("ETHERNET: Cannot bind to socket (user)");
|
|
exit(0);
|
|
}
|
|
|
|
/* Construct the Ethernet header */
|
|
ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost)));
|
|
ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->ehd.ether_dhost)));
|
|
eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
|
|
eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
|
|
|
|
printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* 09/03/2019: fix obvious inconsistencies, but this code hasn't be tested for sure */
|
|
int trx_eth_write_raw(openair0_device_t *device, openair0_timestamp_t timestamp, void **buff, int nsamps, int cc, int flags)
|
|
{
|
|
int bytes_sent=0;
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
int sendto_flag =0;
|
|
int i=0;
|
|
//sendto_flag|=flags;
|
|
|
|
eth->tx_nsamps=nsamps;
|
|
int pktsize;
|
|
if (eth->compression == ALAW_COMPRESS) {
|
|
pktsize = RAW_PACKET_SIZE_BYTES_ALAW(nsamps);
|
|
} else {
|
|
pktsize = RAW_PACKET_SIZE_BYTES(nsamps);
|
|
}
|
|
for (i=0;i<cc;i++) {
|
|
/* buff[i] points to the position in tx buffer where the payload to be sent is
|
|
buff2 points to the position in tx buffer where the packet header will be placed */
|
|
void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES);
|
|
|
|
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
|
|
struct ether_header temp = *(struct ether_header *)buff2;
|
|
int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
|
|
openair0_timestamp_t temp1 = *(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
|
|
|
|
bytes_sent = 0;
|
|
memcpy(buff2,(void*)ð->ehd,MAC_HEADER_SIZE_BYTES);
|
|
*(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1);
|
|
*(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
|
|
|
|
/*printf("[RRU]write mod_%d %d , len %d, buff %p \n",
|
|
Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/
|
|
|
|
while(bytes_sent < pktsize) {
|
|
|
|
/* Send packet */
|
|
|
|
bytes_sent += send(eth->sockfdd[cc % eth->num_fd],
|
|
buff2,
|
|
pktsize,
|
|
sendto_flag);
|
|
if ( bytes_sent == -1) {
|
|
eth->num_tx_errors++;
|
|
perror("ETHERNET WRITE: ");
|
|
exit(-1);
|
|
} else {
|
|
|
|
eth->tx_actual_nsamps=bytes_sent>>2;
|
|
eth->tx_count++;
|
|
}
|
|
}
|
|
|
|
/* tx buffer values restored */
|
|
*(struct ether_header *)buff2 = temp;
|
|
*(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
|
|
*(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
|
|
}
|
|
return (bytes_sent-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
|
|
}
|
|
|
|
int trx_eth_write_raw_IF4p5(openair0_device_t *device, openair0_timestamp_t timestamp, void **buff, int nsamps, int cc, int flags)
|
|
{
|
|
int nblocks = nsamps;
|
|
int bytes_sent = 0;
|
|
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
|
|
ssize_t packet_size;
|
|
|
|
if (flags == IF4p5_PDLFFT) {
|
|
packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks);
|
|
} else if (flags == IF4p5_PULFFT) {
|
|
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
|
|
} else if (flags == IF4p5_PULTICK) {
|
|
packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;
|
|
} else {
|
|
packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
|
|
}
|
|
|
|
eth->tx_nsamps = nblocks;
|
|
|
|
memcpy(buff[0], (void*)ð->ehd, MAC_HEADER_SIZE_BYTES);
|
|
|
|
|
|
bytes_sent = send(eth->sockfdd[cc % eth->num_fd],
|
|
buff[0],
|
|
packet_size,
|
|
0);
|
|
|
|
if (bytes_sent == -1) {
|
|
eth->num_tx_errors++;
|
|
perror("ETHERNET WRITE: ");
|
|
exit(-1);
|
|
} else {
|
|
eth->tx_actual_nsamps = bytes_sent>>1;
|
|
eth->tx_count++;
|
|
}
|
|
|
|
return (bytes_sent-MAC_HEADER_SIZE_BYTES);
|
|
}
|
|
|
|
int trx_eth_read_raw(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc)
|
|
{
|
|
int ret;
|
|
int bytes_received=0;
|
|
int i=0;
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
int rcvfrom_flag =0;
|
|
|
|
int block_cnt=0;
|
|
int again_cnt=0;
|
|
|
|
eth->rx_nsamps=nsamps;
|
|
|
|
for (i=0;i<cc;i++) {
|
|
/* buff[i] points to the position in rx buffer where the payload to be received will be placed
|
|
buff2 points to the position in rx buffer where the packet header will be placed */
|
|
void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES);
|
|
|
|
/* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
|
|
struct ether_header temp = *(struct ether_header *)buff2;
|
|
int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
|
|
openair0_timestamp_t temp1 = *(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
|
|
|
|
bytes_received=0;
|
|
int receive_bytes;
|
|
if (eth->compression == ALAW_COMPRESS) {
|
|
receive_bytes = RAW_PACKET_SIZE_BYTES_ALAW(nsamps);
|
|
} else {
|
|
receive_bytes = RAW_PACKET_SIZE_BYTES(nsamps);
|
|
}
|
|
|
|
while(bytes_received < receive_bytes) {
|
|
again:
|
|
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
|
buff2,
|
|
receive_bytes,
|
|
rcvfrom_flag);
|
|
|
|
if (ret ==-1) {
|
|
eth->num_rx_errors++;
|
|
if (errno == EAGAIN) {
|
|
again_cnt++;
|
|
usleep(10);
|
|
if (again_cnt == 1000) {
|
|
perror("ETHERNET IF5 READ (EAGAIN): ");
|
|
exit(-1);
|
|
} else {
|
|
printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
|
|
goto again;
|
|
}
|
|
} else if (errno == EWOULDBLOCK) {
|
|
block_cnt++;
|
|
usleep(10);
|
|
if (block_cnt == 1000) {
|
|
perror("ETHERNET IF5 READ (EWOULDBLOCK): ");
|
|
exit(-1);
|
|
} else {
|
|
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
|
|
goto again;
|
|
}
|
|
} else {
|
|
perror("ETHERNET IF5 READ");
|
|
printf("(%s):\n", strerror(errno));
|
|
exit(-1);
|
|
}
|
|
|
|
} else {
|
|
bytes_received+=ret;
|
|
/* store the timestamp value from packet's header */
|
|
*timestamp = *(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
|
|
eth->rx_actual_nsamps=bytes_received>>2;
|
|
eth->rx_count++;
|
|
}
|
|
}
|
|
|
|
#if DEBUG
|
|
printf("------- RX------: nu=%x an_id=%d ts%d bytes_recv=%d \n",
|
|
*(uint8_t *)(buff2 + ETH_ALEN),
|
|
*(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)),
|
|
*(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)),
|
|
bytes_received);
|
|
|
|
dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, RAW_PACKET_SIZE_BYTES(nsamps),RX_FLAG);
|
|
|
|
#endif
|
|
|
|
/* tx buffer values restored */
|
|
*(struct ether_header *)buff2 = temp;
|
|
*(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
|
|
*(openair0_timestamp_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
|
|
}
|
|
return (bytes_received-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
|
|
}
|
|
|
|
int trx_eth_read_raw_IF4p5(openair0_device_t *device, openair0_timestamp_t *timestamp, void **buff, int nsamps, int cc)
|
|
{
|
|
int ret;
|
|
// Read nblocks info from packet itself
|
|
int nblocks = nsamps;
|
|
int bytes_received=0;
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
|
|
ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t;
|
|
IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES);
|
|
|
|
int block_cnt=0;
|
|
int again_cnt=0;
|
|
|
|
while (bytes_received < packet_size) {
|
|
again:
|
|
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
|
buff[0],
|
|
packet_size,
|
|
MSG_PEEK);
|
|
if (ret ==-1) {
|
|
eth->num_rx_errors++;
|
|
if (errno == EAGAIN) {
|
|
again_cnt++;
|
|
usleep(10);
|
|
if (again_cnt == 1000) {
|
|
perror("ETHERNET IF4p5 READ (EAGAIN): ");
|
|
exit(-1);
|
|
} else {
|
|
printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
|
|
goto again;
|
|
}
|
|
} else if (errno == EWOULDBLOCK) {
|
|
block_cnt++;
|
|
usleep(10);
|
|
if (block_cnt == 1000) {
|
|
perror("ETHERNET IF4p5 READ (EWOULDBLOCK): ");
|
|
exit(-1);
|
|
} else {
|
|
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
|
|
goto again;
|
|
}
|
|
} else {
|
|
perror("ETHERNET IF4p5 READ");
|
|
printf("(%s):\n", strerror(errno));
|
|
exit(-1);
|
|
}
|
|
}
|
|
else bytes_received+=ret;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
for (int i=0;i<packet_size;i++)
|
|
printf("%2x.",((uint8_t*)buff[0])[i]);
|
|
printf("\n");
|
|
#endif
|
|
|
|
*timestamp = test_header->sub_type;
|
|
|
|
if (test_header->sub_type == IF4p5_PDLFFT) {
|
|
packet_size = RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks);
|
|
} else if (test_header->sub_type == IF4p5_PULFFT) {
|
|
packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);
|
|
} else {
|
|
packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
|
|
}
|
|
|
|
while(bytes_received < packet_size) {
|
|
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
|
buff[0],
|
|
packet_size,
|
|
0);
|
|
if (ret ==-1) {
|
|
eth->num_rx_errors++;
|
|
perror("ETHERNET IF4p5 READ (payload): ");
|
|
return(-1);
|
|
} else {
|
|
bytes_received+=ret;
|
|
eth->rx_actual_nsamps = bytes_received>>1;
|
|
eth->rx_count++;
|
|
}
|
|
}
|
|
|
|
eth->rx_nsamps = nsamps;
|
|
return(bytes_received);
|
|
}
|
|
|
|
int eth_set_dev_conf_raw(openair0_device_t *device)
|
|
{
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
void *msg;
|
|
ssize_t msg_len;
|
|
|
|
/* a RAU client sends to RRU a set of configuration parameters (openair0_config_t)
|
|
so that RF front end is configured appropriately and
|
|
frame/packet size etc. can be set */
|
|
|
|
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
|
|
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
|
|
|
|
|
|
memcpy(msg,(void*)ð->ehc,MAC_HEADER_SIZE_BYTES);
|
|
memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t));
|
|
|
|
if (send(eth->sockfdc,
|
|
msg,
|
|
msg_len,
|
|
0)==-1) {
|
|
perror("ETHERNET: ");
|
|
exit(0);
|
|
}
|
|
free(msg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int eth_set_dev_conf_raw_IF4p5(openair0_device_t *device)
|
|
{
|
|
// use for cc_id info
|
|
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
void *msg;
|
|
ssize_t msg_len;
|
|
|
|
/* a RAU client sends to RRU a set of configuration parameters (openair0_config_t)
|
|
so that RF front end is configured appropriately and
|
|
frame/packet size etc. can be set */
|
|
|
|
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
|
|
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
|
|
|
|
|
|
memcpy(msg,(void*)ð->ehc,MAC_HEADER_SIZE_BYTES);
|
|
memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t));
|
|
|
|
if (send(eth->sockfdc,
|
|
msg,
|
|
msg_len,
|
|
0)==-1) {
|
|
perror("ETHERNET: ");
|
|
exit(0);
|
|
}
|
|
|
|
free(msg);
|
|
return 0;
|
|
}
|
|
|
|
int eth_get_dev_conf_raw(openair0_device_t *device)
|
|
{
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
void *msg;
|
|
ssize_t msg_len;
|
|
|
|
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
|
|
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
|
|
|
|
/* RRU receives from RAU openair0_config_t */
|
|
if (recv(eth->sockfdc,
|
|
msg,
|
|
msg_len,
|
|
0)==-1) {
|
|
perror("ETHERNET: ");
|
|
exit(0);
|
|
}
|
|
|
|
/* RRU stores the remote MAC address */
|
|
memcpy(eth->ehd.ether_dhost,(msg+ETH_ALEN),ETH_ALEN);
|
|
//memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t));
|
|
device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES);
|
|
printf("[%s] binding mod to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5],eth->ehd.ether_dhost[0],eth->ehd.ether_dhost[1],eth->ehd.ether_dhost[2],eth->ehd.ether_dhost[3],eth->ehd.ether_dhost[4],eth->ehd.ether_dhost[5]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int eth_get_dev_conf_raw_IF4p5(openair0_device_t *device)
|
|
{
|
|
// use for cc_id info
|
|
|
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
|
void *msg;
|
|
ssize_t msg_len;
|
|
|
|
msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
|
|
msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
|
|
|
|
/* RRU receives from RAU openair0_config_t */
|
|
if (recv(eth->sockfdc,
|
|
msg,
|
|
msg_len,
|
|
0)==-1) {
|
|
perror("ETHERNET: ");
|
|
exit(0);
|
|
}
|
|
|
|
/* RRU stores the remote MAC address */
|
|
memcpy(eth->ehd.ether_dhost,(msg+ETH_ALEN),ETH_ALEN);
|
|
//memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t));
|
|
//device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES);
|
|
printf("[%s] binding mod to hardware address %x:%x:%x:%x:%x:%x hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5],eth->ehd.ether_dhost[0],eth->ehd.ether_dhost[1],eth->ehd.ether_dhost[2],eth->ehd.ether_dhost[3],eth->ehd.ether_dhost[4],eth->ehd.ether_dhost[5]);
|
|
|
|
free(msg);
|
|
return 0;
|
|
}
|