|
|
@ -122,8 +122,8 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes);
|
|
|
|
gtpu_log->info_hex(pdu->msg, pdu->N_bytes, "TX PDU, RNTI: 0x%x, LCID: %d, n_bytes=%d", rnti, lcid, pdu->N_bytes);
|
|
|
|
gtpu_header_t header;
|
|
|
|
gtpu_header_t header;
|
|
|
|
header.flags = 0x30;
|
|
|
|
header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL;
|
|
|
|
header.message_type = 0xFF;
|
|
|
|
header.message_type = GTPU_MSG_DATA_PDU;
|
|
|
|
header.length = pdu->N_bytes;
|
|
|
|
header.length = pdu->N_bytes;
|
|
|
|
header.teid = rnti_bearers[rnti].teids_out[lcid];
|
|
|
|
header.teid = rnti_bearers[rnti].teids_out[lcid];
|
|
|
|
|
|
|
|
|
|
|
@ -132,7 +132,10 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t* pdu)
|
|
|
|
servaddr.sin_addr.s_addr = htonl(rnti_bearers[rnti].spgw_addrs[lcid]);
|
|
|
|
servaddr.sin_addr.s_addr = htonl(rnti_bearers[rnti].spgw_addrs[lcid]);
|
|
|
|
servaddr.sin_port = htons(GTPU_PORT);
|
|
|
|
servaddr.sin_port = htons(GTPU_PORT);
|
|
|
|
|
|
|
|
|
|
|
|
gtpu_write_header(&header, pdu, gtpu_log);
|
|
|
|
if(!gtpu_write_header(&header, pdu, gtpu_log)){
|
|
|
|
|
|
|
|
gtpu_log->error("Error writing GTP-U Header. Flags 0x%x, Message Type 0x%x\n", header.flags, header.message_type);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) {
|
|
|
|
if (sendto(fd, pdu->msg, pdu->N_bytes, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))<0) {
|
|
|
|
perror("sendto");
|
|
|
|
perror("sendto");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -224,18 +227,19 @@ void gtpu::run_thread()
|
|
|
|
|
|
|
|
|
|
|
|
pdu->N_bytes = (uint32_t) n;
|
|
|
|
pdu->N_bytes = (uint32_t) n;
|
|
|
|
|
|
|
|
|
|
|
|
if(pdu->msg[1] == 0x01) {
|
|
|
|
gtpu_header_t header;
|
|
|
|
if(n<10) {
|
|
|
|
if(!gtpu_read_header(pdu, &header,gtpu_log)){
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(header.message_type) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case GTPU_MSG_ECHO_REQUEST:
|
|
|
|
// Echo request - send response
|
|
|
|
// Echo request - send response
|
|
|
|
uint16_t seq = 0;
|
|
|
|
echo_response(client.sin_addr.s_addr, client.sin_port, header.seq_number);
|
|
|
|
uint8_to_uint16(&pdu->msg[8], &seq);
|
|
|
|
break;
|
|
|
|
echo_response(client.sin_addr.s_addr, client.sin_port, seq);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
case GTPU_MSG_DATA_PDU:
|
|
|
|
gtpu_header_t header;
|
|
|
|
|
|
|
|
gtpu_read_header(pdu, &header,gtpu_log);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t rnti = 0;
|
|
|
|
uint16_t rnti = 0;
|
|
|
|
uint16_t lcid = 0;
|
|
|
|
uint16_t lcid = 0;
|
|
|
@ -266,6 +270,7 @@ void gtpu::run_thread()
|
|
|
|
usleep(10000);
|
|
|
|
usleep(10000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while(!pdu);
|
|
|
|
} while(!pdu);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
running = false;
|
|
|
|
running = false;
|
|
|
@ -275,20 +280,27 @@ void gtpu::echo_response(in_addr_t addr, in_port_t port, uint16_t seq)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq);
|
|
|
|
gtpu_log->info("TX GTPU Echo Response, Seq: %d\n", seq);
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t resp[12];
|
|
|
|
gtpu_header_t header;
|
|
|
|
bzero(resp, 12);
|
|
|
|
srslte::byte_buffer_t *pdu = pool_allocate;
|
|
|
|
resp[0] = 0x32; //flags
|
|
|
|
|
|
|
|
resp[1] = 0x02; //type
|
|
|
|
//header
|
|
|
|
uint16_to_uint8(4, &resp[2]); //length
|
|
|
|
header.flags = GTPU_FLAGS_VERSION_V1 | GTPU_FLAGS_GTP_PROTOCOL | GTPU_FLAGS_SEQUENCE;
|
|
|
|
uint32_to_uint8(0, &resp[4]); //TEID
|
|
|
|
header.message_type = GTPU_MSG_ECHO_RESPONSE;
|
|
|
|
uint16_to_uint8(seq, &resp[8]); //seq
|
|
|
|
header.teid = 0;
|
|
|
|
|
|
|
|
header.length = 4;
|
|
|
|
|
|
|
|
header.seq_number = seq;
|
|
|
|
|
|
|
|
header.n_pdu = 0;
|
|
|
|
|
|
|
|
header.next_ext_hdr_type = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtpu_write_header(&header,pdu,gtpu_log);
|
|
|
|
|
|
|
|
|
|
|
|
struct sockaddr_in servaddr;
|
|
|
|
struct sockaddr_in servaddr;
|
|
|
|
servaddr.sin_family = AF_INET;
|
|
|
|
servaddr.sin_family = AF_INET;
|
|
|
|
servaddr.sin_addr.s_addr = addr;
|
|
|
|
servaddr.sin_addr.s_addr = addr;
|
|
|
|
servaddr.sin_port = port;
|
|
|
|
servaddr.sin_port = port;
|
|
|
|
|
|
|
|
|
|
|
|
sendto(fd, resp, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
|
|
|
|
sendto(fd, pdu->msg, 12, MSG_EOR, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
|
|
pool->deallocate(pdu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
/****************************************************************************
|
|
|
|