adding mbms-gw broadcast support, adding parameter for automatic mbms service start

master
yagoda 7 years ago
parent 13c62eb55e
commit fac8bb7b7a

@ -585,7 +585,7 @@ bool sch_subh::set_ta_cmd(uint8_t ta_cmd)
bool sch_subh::set_next_mch_sched_info(uint8_t lcid_, uint16_t mtch_stop) bool sch_subh::set_next_mch_sched_info(uint8_t lcid_, uint16_t mtch_stop)
{ {
if (((sch_pdu*)parent)->has_space_ce(2, true)) { if (((sch_pdu*)parent)->has_space_ce(2, true)) {
w_payload_ce[nof_mch_sched_ce*2] = (lcid_&0x1F) << 3 | (uint8_t) (mtch_stop&0x0700)>>8 ; w_payload_ce[nof_mch_sched_ce*2] = (lcid_&0x1F) << 3 | (uint8_t) ((mtch_stop&0x0700)>>8);
w_payload_ce[nof_mch_sched_ce*2+1] = (uint8_t) (mtch_stop&0xff); w_payload_ce[nof_mch_sched_ce*2+1] = (uint8_t) (mtch_stop&0xff);
nof_mch_sched_ce++; nof_mch_sched_ce++;
lcid = MCH_SCHED_INFO; lcid = MCH_SCHED_INFO;

@ -639,6 +639,7 @@ int mac::get_mch_sched(bool is_mcch, dl_sched_t *dl_sched_res)
mch.pdu[i].lcid = srslte::sch_subh::MCH_SCHED_INFO; mch.pdu[i].lcid = srslte::sch_subh::MCH_SCHED_INFO;
// mch.mtch_sched[i].lcid = 1+i; // mch.mtch_sched[i].lcid = 1+i;
} }
mch.pdu[mch.num_mtch_sched].lcid = 0; mch.pdu[mch.num_mtch_sched].lcid = 0;
mch.pdu[mch.num_mtch_sched].nbytes = current_mcch_length; mch.pdu[mch.num_mtch_sched].nbytes = current_mcch_length;
dl_sched_res->sched_grants[0].rnti = SRSLTE_MRNTI; dl_sched_res->sched_grants[0].rnti = SRSLTE_MRNTI;

@ -170,7 +170,6 @@ while(mch_run_enable) {
pdu->N_bytes = (uint32_t) n; pdu->N_bytes = (uint32_t) n;
printf("Bytes=%d\n",n);
gtpu_header_t header; gtpu_header_t header;
gtpu_read_header(pdu, &header); gtpu_read_header(pdu, &header);

@ -52,7 +52,14 @@ typedef struct {
std::string m1u_multi_addr; std::string m1u_multi_addr;
} mbms_gw_args_t; } mbms_gw_args_t;
struct pseudo_hdr
{
uint32_t src_addr;
uint32_t dst_addr;
uint8_t placeholder;
uint8_t protocol;
uint16_t udp_len;
};
class mbms_gw: class mbms_gw:
public thread public thread
@ -73,8 +80,9 @@ private:
srslte::error_t init_sgi_mb_if(mbms_gw_args_t *args); srslte::error_t init_sgi_mb_if(mbms_gw_args_t *args);
srslte::error_t init_m1_u(mbms_gw_args_t *args); srslte::error_t init_m1_u(mbms_gw_args_t *args);
void handle_sgi_md_pdu(srslte::byte_buffer_t *msg); void handle_sgi_md_pdu(srslte::byte_buffer_t *msg);
uint16_t in_cksum(uint16_t *iphdr, int count);
/* Members */ /* Members */
bool m_running; bool m_running;
srslte::byte_buffer_pool *m_pool; srslte::byte_buffer_pool *m_pool;

@ -12,7 +12,7 @@
##################################################################### #####################################################################
[mbms_gw] [mbms_gw]
name = srsmbmsgw01 name = srsmbmsgw01
sgi_mb_if_addr = 172.16.0.254 sgi_mb_if_addr = 172.16.1.1
m1u_multi_addr = 239.255.0.1 m1u_multi_addr = 239.255.0.1
#################################################################### ####################################################################

@ -32,6 +32,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <netinet/udp.h>
#include <linux/ip.h> #include <linux/ip.h>
#include "srsepc/hdr/mbms-gw/mbms-gw.h" #include "srsepc/hdr/mbms-gw/mbms-gw.h"
#include "srslte/upper/gtpu.h" #include "srslte/upper/gtpu.h"
@ -195,7 +196,7 @@ mbms_gw::init_sgi_mb_if(mbms_gw_args_t *args)
} }
ifr.ifr_netmask.sa_family = AF_INET; ifr.ifr_netmask.sa_family = AF_INET;
((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.255"); ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr = inet_addr("255.255.255.0");
if (ioctl(sgi_mb_sock, SIOCSIFNETMASK, &ifr) < 0) { if (ioctl(sgi_mb_sock, SIOCSIFNETMASK, &ifr) < 0) {
m_mbms_gw_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno)); m_mbms_gw_log->error("Failed to set TUN interface Netmask. Error: %s\n", strerror(errno));
close(m_sgi_mb_if); close(m_sgi_mb_if);
@ -285,6 +286,7 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg)
uint8_t version; uint8_t version;
srslte::gtpu_header_t header; srslte::gtpu_header_t header;
in_addr_t baddr = inet_addr("172.16.0.255"); in_addr_t baddr = inet_addr("172.16.0.255");
in_addr_t saddr = inet_addr("172.16.0.254");
//Setup GTP-U header //Setup GTP-U header
header.flags = 0x30; header.flags = 0x30;
@ -298,14 +300,45 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg)
m_mbms_gw_log->error("IPv4 min len: %d, drop msg len %d\n", 20, msg->N_bytes); m_mbms_gw_log->error("IPv4 min len: %d, drop msg len %d\n", 20, msg->N_bytes);
return; return;
} }
version = msg->msg[0]>>4;
if(version !=4) //IP+UDP Headers
struct iphdr *iph = (struct iphdr *) msg->msg;
struct udphdr *udph = (struct udphdr *) (msg->msg + iph->ihl*4);
if(iph->version != 4)
{ {
m_mbms_gw_log->warning("IPv6 not supported yet.\n"); m_mbms_gw_log->warning("IPv6 not supported yet.\n");
return; return;
} }
//Replace Destination IP with broadcast address //Replace Destination IP with broadcast address
memcpy(&msg->msg[16],&baddr,4); iph->daddr = baddr;
//Replace Source IP with address in same subnet
iph->saddr = saddr;
//Replace IP cheksum
iph->check = 0;
iph->check = in_cksum((uint16_t*)msg->msg,4*(msg->msg[0] & 0x0F));
//Set Pseudo Header
struct pseudo_hdr phdr;
phdr.src_addr = iph->saddr;
phdr.dst_addr = iph->daddr;
phdr.protocol = IPPROTO_UDP;
phdr.placeholder = 0;
phdr.udp_len = udph->len;
//Set Pseudo Datagram
udph->check = 0;
int psize = sizeof(struct pseudo_hdr) + ntohs(udph->len);
uint8_t * pseudo_dgram = (uint8_t*) malloc(psize);
memcpy(pseudo_dgram, &phdr,sizeof(struct pseudo_hdr));
memcpy(pseudo_dgram+sizeof(pseudo_hdr),udph,ntohs(udph->len));
//Recompute UDP checksum
udph->check = in_cksum((uint16_t*) pseudo_dgram, psize);
free(pseudo_dgram);
printf("UDP cksum %x",udph->check);
//Write GTP-U header into packet //Write GTP-U header into packet
if(!srslte::gtpu_write_header(&header, msg)) if(!srslte::gtpu_write_header(&header, msg))
@ -321,6 +354,33 @@ mbms_gw::handle_sgi_md_pdu(srslte::byte_buffer_t *msg)
else{ else{
m_mbms_gw_log->console("Sent %d Bytes\n", msg->N_bytes); m_mbms_gw_log->console("Sent %d Bytes\n", msg->N_bytes);
} }
}
uint16_t
mbms_gw::in_cksum(uint16_t *iphdr, int count)
{
//RFC 1071
uint32_t sum = 0;
uint16_t padd = 0;
uint16_t result;
while(count > 1)
{
sum+= *iphdr++;
count -= 2;
}
if( count > 0 )
{
padd = * (uint8_t *) iphdr;
sum += padd;
} }
/*Fold 32-bit sum to 16-bit*/
// while(sum>>16)
// sum = (sum & 0xffff) + (sum >> 16);
sum = (sum>>16)+(sum & 0xFFFF);
sum = sum + (sum >> 16);
result = (uint16_t) ~sum;
return result;
}
} //namespace srsepc } //namespace srsepc

@ -522,7 +522,9 @@ int main(int argc, char *argv[])
ue->start_plot(); ue->start_plot();
} }
if(args.expert.mbms_service > -1) { if(args.expert.mbms_service > -1) {
ue->mbms_service_start(args.expert.mbms_service, 4321); serv = args.expert.mbms_service;
port = 14321;
mbms_service_start = true;
} }
} }
int cnt=0; int cnt=0;

Loading…
Cancel
Save