mirror of https://github.com/pvnis/srsRAN_4G.git
adding common code including headers and tests
parent
eb0e104bb2
commit
ae186d8195
@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BCD_HELPERS
|
||||||
|
#define BCD_HELPERS
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Convert between string and BCD-coded MCC.
|
||||||
|
* Digits are represented by 4-bit nibbles. Unused nibbles are filled with 0xF.
|
||||||
|
* MCC 001 results in 0xF001
|
||||||
|
*****************************************************************************/
|
||||||
|
inline bool string_to_mcc(std::string str, uint16_t *mcc)
|
||||||
|
{
|
||||||
|
uint32_t len = str.size();
|
||||||
|
if(len != 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!isdigit(str[0]) || !isdigit(str[1]) || !isdigit(str[2])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*mcc = 0xF000;
|
||||||
|
*mcc |= ((uint8_t)(str[0]-'0') << 8);
|
||||||
|
*mcc |= ((uint8_t)(str[1]-'0') << 4);
|
||||||
|
*mcc |= ((uint8_t)(str[2]-'0'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool mcc_to_string(uint16_t mcc, std::string *str)
|
||||||
|
{
|
||||||
|
if((mcc & 0xF000) != 0xF000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*str = "";
|
||||||
|
*str += ((mcc & 0x0F00) >> 8) + '0';
|
||||||
|
*str += ((mcc & 0x00F0) >> 4) + '0';
|
||||||
|
*str += (mcc & 0x000F) + '0';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Convert between string and BCD-coded MNC.
|
||||||
|
* Digits are represented by 4-bit nibbles. Unused nibbles are filled with 0xF.
|
||||||
|
* MNC 001 results in 0xF001
|
||||||
|
* MNC 01 results in 0xFF01
|
||||||
|
*****************************************************************************/
|
||||||
|
inline bool string_to_mnc(std::string str, uint16_t *mnc)
|
||||||
|
{
|
||||||
|
uint32_t len = str.size();
|
||||||
|
if(len != 3 && len != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(len == 3) {
|
||||||
|
if(!isdigit(str[0]) || !isdigit(str[1]) || !isdigit(str[2])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*mnc = 0xF000;
|
||||||
|
*mnc |= ((uint8_t)(str[0]-'0') << 8);
|
||||||
|
*mnc |= ((uint8_t)(str[1]-'0') << 4);
|
||||||
|
*mnc |= ((uint8_t)(str[2]-'0'));
|
||||||
|
}
|
||||||
|
if(len == 2) {
|
||||||
|
if(!isdigit(str[0]) || !isdigit(str[1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*mnc = 0xFF00;
|
||||||
|
*mnc |= ((uint8_t)(str[0]-'0') << 4);
|
||||||
|
*mnc |= ((uint8_t)(str[1]-'0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool mnc_to_string(uint16_t mnc, std::string *str)
|
||||||
|
{
|
||||||
|
if((mnc & 0xF000) != 0xF000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*str = "";
|
||||||
|
if((mnc & 0xFF00) != 0xFF00) {
|
||||||
|
*str += ((mnc & 0x0F00) >> 8) + '0';
|
||||||
|
}
|
||||||
|
*str += ((mnc & 0x00F0) >> 4) + '0';
|
||||||
|
*str += (mnc & 0x000F) + '0';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // BCD_HELPERS
|
@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLOCK_QUEUE
|
||||||
|
#define BLOCK_QUEUE
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
template<typename myobj>
|
||||||
|
class block_queue {
|
||||||
|
|
||||||
|
public:
|
||||||
|
block_queue<myobj>() {
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
pthread_cond_init(&cvar, NULL);
|
||||||
|
}
|
||||||
|
void push(const myobj& value) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
q.push(value);
|
||||||
|
pthread_cond_signal(&cvar);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_pop(myobj *value) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if (q.empty()) {
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
*value = q.front();
|
||||||
|
q.pop();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
myobj wait_pop() { // blocking pop
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(q.empty()) {
|
||||||
|
pthread_cond_wait(&cvar, &mutex);
|
||||||
|
}
|
||||||
|
myobj value = q.front();
|
||||||
|
q.pop();
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const { // queue is empty?
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
bool ret = q.empty();
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() { // remove all items
|
||||||
|
myobj item;
|
||||||
|
while (try_pop(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::queue<myobj> q;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t cvar;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUFFER_POOL_H
|
||||||
|
#define BUFFER_POOL_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <stack>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
INCLUDES
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Buffer pool
|
||||||
|
*
|
||||||
|
* Preallocates a large number of buffer_t and provides allocate and
|
||||||
|
* deallocate functions. Provides quick object creation and deletion as well
|
||||||
|
* as object reuse.
|
||||||
|
* Singleton class of byte_buffer_t (but other pools of different type can be created)
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template <class buffer_t>
|
||||||
|
class buffer_pool{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// non-static methods
|
||||||
|
buffer_pool(uint32_t nof_buffers = POOL_SIZE)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
for(int i=0;i<nof_buffers;i++) {
|
||||||
|
buffer_t *b = new buffer_t;
|
||||||
|
available.push(b);
|
||||||
|
}
|
||||||
|
capacity = nof_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
~buffer_pool() {
|
||||||
|
// this destructor assumes all buffers have been properly deallocated
|
||||||
|
while(available.size()) {
|
||||||
|
delete available.top();
|
||||||
|
available.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
buffer_t* allocate()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
buffer_t* b = NULL;
|
||||||
|
|
||||||
|
if(available.size() > 0)
|
||||||
|
{
|
||||||
|
b = available.top();
|
||||||
|
used.push_back(b);
|
||||||
|
available.pop();
|
||||||
|
|
||||||
|
if (available.size() < capacity/20) {
|
||||||
|
printf("Warning buffer pool capacity is %f %%\n", (float) available.size()/capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Error - buffer pool is empty\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deallocate(buffer_t *b)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
typename std::vector<buffer_t*>::iterator elem = std::find(used.begin(), used.end(), b);
|
||||||
|
if (elem != used.end()) {
|
||||||
|
used.erase(elem);
|
||||||
|
available.push(b);
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
printf("Error deallocating from buffer pool: buffer not created in this pool.\n");
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int POOL_SIZE = 2048;
|
||||||
|
std::stack<buffer_t*> available;
|
||||||
|
std::vector<buffer_t*> used;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
uint32_t capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class byte_buffer_pool {
|
||||||
|
public:
|
||||||
|
// Singleton static methods
|
||||||
|
static byte_buffer_pool *instance;
|
||||||
|
static byte_buffer_pool* get_instance(void);
|
||||||
|
static void cleanup(void);
|
||||||
|
byte_buffer_pool() {
|
||||||
|
pool = new buffer_pool<byte_buffer_t>;
|
||||||
|
}
|
||||||
|
~byte_buffer_pool() {
|
||||||
|
delete pool;
|
||||||
|
}
|
||||||
|
byte_buffer_t* allocate() {
|
||||||
|
return pool->allocate();
|
||||||
|
}
|
||||||
|
void deallocate(byte_buffer_t *b) {
|
||||||
|
b->reset();
|
||||||
|
pool->deallocate(b);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
buffer_pool<byte_buffer_t> *pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // BUFFER_POOL_H
|
@ -0,0 +1,224 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
INCLUDES
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
DEFINES
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#define SRSUE_UE_CATEGORY 4
|
||||||
|
|
||||||
|
#define SRSUE_N_SRB 3
|
||||||
|
#define SRSUE_N_DRB 8
|
||||||
|
#define SRSUE_N_RADIO_BEARERS 11
|
||||||
|
|
||||||
|
// Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI
|
||||||
|
// 3GPP 36.306 Table 4.1.1
|
||||||
|
#define SRSUE_MAX_BUFFER_SIZE_BITS 102048
|
||||||
|
#define SRSUE_MAX_BUFFER_SIZE_BYTES 12756
|
||||||
|
#define SRSUE_BUFFER_HEADER_OFFSET 1024
|
||||||
|
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
TYPEDEFS
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
ERROR_NONE = 0,
|
||||||
|
ERROR_INVALID_PARAMS,
|
||||||
|
ERROR_INVALID_COMMAND,
|
||||||
|
ERROR_OUT_OF_BOUNDS,
|
||||||
|
ERROR_CANT_START,
|
||||||
|
ERROR_ALREADY_STARTED,
|
||||||
|
ERROR_N_ITEMS,
|
||||||
|
}error_t;
|
||||||
|
static const char error_text[ERROR_N_ITEMS][20] = { "None",
|
||||||
|
"Invalid parameters",
|
||||||
|
"Invalid command",
|
||||||
|
"Out of bounds",
|
||||||
|
"Can't start",
|
||||||
|
"Already started"};
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
RB_ID_SRB0 = 0,
|
||||||
|
RB_ID_SRB1,
|
||||||
|
RB_ID_SRB2,
|
||||||
|
RB_ID_DRB1,
|
||||||
|
RB_ID_DRB2,
|
||||||
|
RB_ID_DRB3,
|
||||||
|
RB_ID_DRB4,
|
||||||
|
RB_ID_DRB5,
|
||||||
|
RB_ID_DRB6,
|
||||||
|
RB_ID_DRB7,
|
||||||
|
RB_ID_DRB8,
|
||||||
|
RB_ID_N_ITEMS,
|
||||||
|
}rb_id_t;
|
||||||
|
static const char rb_id_text[RB_ID_N_ITEMS][20] = { "SRB0",
|
||||||
|
"SRB1",
|
||||||
|
"SRB2",
|
||||||
|
"DRB1",
|
||||||
|
"DRB2",
|
||||||
|
"DRB3",
|
||||||
|
"DRB4",
|
||||||
|
"DRB5",
|
||||||
|
"DRB6",
|
||||||
|
"DRB7",
|
||||||
|
"DRB8"};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Byte and Bit buffers
|
||||||
|
*
|
||||||
|
* Generic buffers with headroom to accommodate packet headers and custom
|
||||||
|
* copy constructors & assignment operators for quick copying. Byte buffer
|
||||||
|
* holds a next pointer to support linked lists.
|
||||||
|
*****************************************************************************/
|
||||||
|
class byte_buffer_t{
|
||||||
|
public:
|
||||||
|
uint32_t N_bytes;
|
||||||
|
uint8_t buffer[SRSUE_MAX_BUFFER_SIZE_BYTES];
|
||||||
|
uint8_t *msg;
|
||||||
|
|
||||||
|
byte_buffer_t():N_bytes(0)
|
||||||
|
{
|
||||||
|
timestamp_is_set = false;
|
||||||
|
msg = &buffer[SRSUE_BUFFER_HEADER_OFFSET];
|
||||||
|
next = NULL;
|
||||||
|
}
|
||||||
|
byte_buffer_t(const byte_buffer_t& buf)
|
||||||
|
{
|
||||||
|
N_bytes = buf.N_bytes;
|
||||||
|
memcpy(msg, buf.msg, N_bytes);
|
||||||
|
}
|
||||||
|
byte_buffer_t & operator= (const byte_buffer_t & buf)
|
||||||
|
{
|
||||||
|
N_bytes = buf.N_bytes;
|
||||||
|
memcpy(msg, buf.msg, N_bytes);
|
||||||
|
}
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
msg = &buffer[SRSUE_BUFFER_HEADER_OFFSET];
|
||||||
|
N_bytes = 0;
|
||||||
|
timestamp_is_set = false;
|
||||||
|
}
|
||||||
|
uint32_t get_headroom()
|
||||||
|
{
|
||||||
|
return msg-buffer;
|
||||||
|
}
|
||||||
|
long get_latency_us()
|
||||||
|
{
|
||||||
|
if(!timestamp_is_set)
|
||||||
|
return 0;
|
||||||
|
gettimeofday(×tamp[2], NULL);
|
||||||
|
get_time_interval(timestamp);
|
||||||
|
return timestamp[0].tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_timestamp()
|
||||||
|
{
|
||||||
|
gettimeofday(×tamp[1], NULL);
|
||||||
|
timestamp_is_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
void get_time_interval(struct timeval * tdata) {
|
||||||
|
|
||||||
|
tdata[0].tv_sec = tdata[2].tv_sec - tdata[1].tv_sec;
|
||||||
|
tdata[0].tv_usec = tdata[2].tv_usec - tdata[1].tv_usec;
|
||||||
|
if (tdata[0].tv_usec < 0) {
|
||||||
|
tdata[0].tv_sec--;
|
||||||
|
tdata[0].tv_usec += 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct timeval timestamp[3];
|
||||||
|
bool timestamp_is_set;
|
||||||
|
byte_buffer_t *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bit_buffer_t{
|
||||||
|
uint32_t N_bits;
|
||||||
|
uint8_t buffer[SRSUE_MAX_BUFFER_SIZE_BITS];
|
||||||
|
uint8_t *msg;
|
||||||
|
|
||||||
|
bit_buffer_t():N_bits(0)
|
||||||
|
{
|
||||||
|
msg = &buffer[SRSUE_BUFFER_HEADER_OFFSET];
|
||||||
|
}
|
||||||
|
bit_buffer_t(const bit_buffer_t& buf){
|
||||||
|
N_bits = buf.N_bits;
|
||||||
|
memcpy(msg, buf.msg, N_bits);
|
||||||
|
}
|
||||||
|
bit_buffer_t & operator= (const bit_buffer_t & buf){
|
||||||
|
N_bits = buf.N_bits;
|
||||||
|
memcpy(msg, buf.msg, N_bits);
|
||||||
|
}
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
msg = &buffer[SRSUE_BUFFER_HEADER_OFFSET];
|
||||||
|
N_bits = 0;
|
||||||
|
timestamp_is_set = false;
|
||||||
|
}
|
||||||
|
uint32_t get_headroom()
|
||||||
|
{
|
||||||
|
return msg-buffer;
|
||||||
|
}
|
||||||
|
long get_latency_us()
|
||||||
|
{
|
||||||
|
if(!timestamp_is_set)
|
||||||
|
return 0;
|
||||||
|
gettimeofday(×tamp[2], NULL);
|
||||||
|
return timestamp[0].tv_usec;
|
||||||
|
}
|
||||||
|
void set_timestamp()
|
||||||
|
{
|
||||||
|
gettimeofday(×tamp[1], NULL);
|
||||||
|
timestamp_is_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct timeval timestamp[3];
|
||||||
|
bool timestamp_is_set;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // COMMON_H
|
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
// Generic helper definitions for shared library support
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#define SRSAPPS_IMPORT __declspec(dllimport)
|
||||||
|
#define SRSAPPS_EXPORT __declspec(dllexport)
|
||||||
|
#define SRSAPPS_LOCAL
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define SRSAPPS_IMPORT __attribute__ ((visibility ("default")))
|
||||||
|
#define SRSAPPS_EXPORT __attribute__ ((visibility ("default")))
|
||||||
|
#else
|
||||||
|
#define SRSAPPS_IMPORT
|
||||||
|
#define SRSAPPS_EXPORT
|
||||||
|
#define SRSAPPS_LOCAL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Define SRSAPPS_API
|
||||||
|
// is used for the public API symbols.
|
||||||
|
#ifdef SRSAPPS_DLL_EXPORTS // defined if we are building the SRSAPPS DLL (instead of using it)
|
||||||
|
#define SRSAPPS_EXPORT
|
||||||
|
#else
|
||||||
|
#define SRSAPPS_IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// cf_t definition
|
||||||
|
typedef _Complex float cf_t;
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
@ -0,0 +1,234 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: interfaces.h
|
||||||
|
* Description: Abstract base class interfaces provided by layers
|
||||||
|
* to other layers.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INTERFACES_H
|
||||||
|
#define INTERFACES_H
|
||||||
|
|
||||||
|
#include "liblte_rrc.h"
|
||||||
|
#include "common/interfaces_common.h"
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "common/security.h"
|
||||||
|
#include "mac_interface.h"
|
||||||
|
#include "phy_interface.h"
|
||||||
|
|
||||||
|
namespace srsue {
|
||||||
|
|
||||||
|
// UE interface
|
||||||
|
class ue_interface
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// USIM interface for NAS
|
||||||
|
class usim_interface_nas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0;
|
||||||
|
virtual void get_imei_vec(uint8_t* imei_, uint32_t n) = 0;
|
||||||
|
virtual void generate_authentication_response(uint8_t *rand,
|
||||||
|
uint8_t *autn_enb,
|
||||||
|
uint16_t mcc,
|
||||||
|
uint16_t mnc,
|
||||||
|
bool *net_valid,
|
||||||
|
uint8_t *res) = 0;
|
||||||
|
virtual void generate_nas_keys(uint8_t *k_nas_enc,
|
||||||
|
uint8_t *k_nas_int,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// USIM interface for RRC
|
||||||
|
class usim_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void generate_as_keys(uint32_t count_ul,
|
||||||
|
uint8_t *k_rrc_enc,
|
||||||
|
uint8_t *k_rrc_int,
|
||||||
|
uint8_t *k_up_enc,
|
||||||
|
uint8_t *k_up_int,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// GW interface for NAS
|
||||||
|
class gw_interface_nas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// GW interface for PDCP
|
||||||
|
class gw_interface_pdcp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// NAS interface for RRC
|
||||||
|
class nas_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool is_attached() = 0;
|
||||||
|
virtual void notify_connection_setup() = 0;
|
||||||
|
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
virtual uint32_t get_ul_count() = 0;
|
||||||
|
virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for MAC
|
||||||
|
class rrc_interface_mac
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void release_pucch_srs() = 0;
|
||||||
|
virtual void ra_problem() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for PHY
|
||||||
|
class rrc_interface_phy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void in_sync() = 0;
|
||||||
|
virtual void out_of_sync() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for NAS
|
||||||
|
class rrc_interface_nas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
virtual uint16_t get_mcc() = 0;
|
||||||
|
virtual uint16_t get_mnc() = 0;
|
||||||
|
virtual void enable_capabilities() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for GW
|
||||||
|
class rrc_interface_gw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool rrc_connected() = 0;
|
||||||
|
virtual void rrc_connect() = 0;
|
||||||
|
virtual bool have_drb() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for PDCP
|
||||||
|
class rrc_interface_pdcp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RRC interface for RLC
|
||||||
|
class rrc_interface_rlc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void max_retx_attempted() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// PDCP interface for GW
|
||||||
|
class pdcp_interface_gw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// PDCP interface for RRC
|
||||||
|
class pdcp_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void reset() = 0;
|
||||||
|
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0;
|
||||||
|
virtual void config_security(uint32_t lcid,
|
||||||
|
uint8_t *k_rrc_enc_,
|
||||||
|
uint8_t *k_rrc_int_,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// PDCP interface for RLC
|
||||||
|
class pdcp_interface_rlc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* RLC calls PDCP to push a PDCP PDU. */
|
||||||
|
virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
virtual void write_pdu_pcch(srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RLC interface for RRC
|
||||||
|
class rlc_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void reset() = 0;
|
||||||
|
virtual void add_bearer(uint32_t lcid) = 0;
|
||||||
|
virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// RLC interface for PDCP
|
||||||
|
class rlc_interface_pdcp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls
|
||||||
|
* RLC PDUs according to TB size. */
|
||||||
|
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//RLC interface for MAC
|
||||||
|
class rlc_interface_mac : public srslte::read_pdu_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* MAC calls RLC to get buffer state for a logical channel.
|
||||||
|
* This function should return quickly. */
|
||||||
|
virtual uint32_t get_buffer_state(uint32_t lcid) = 0;
|
||||||
|
virtual uint32_t get_total_buffer_state(uint32_t lcid) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
const static int MAX_PDU_SEGMENTS = 20;
|
||||||
|
|
||||||
|
/* MAC calls RLC to get RLC segment of nof_bytes length.
|
||||||
|
* Segmentation happens in this function. RLC PDU is stored in payload. */
|
||||||
|
virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||||
|
|
||||||
|
/* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread.
|
||||||
|
* PDU gets placed into the buffer and higher layer thread gets notified. */
|
||||||
|
virtual void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||||
|
virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||||
|
virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||||
|
virtual void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // INTERFACES_H
|
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#include "common/timers.h"
|
||||||
|
|
||||||
|
#ifndef INTERFACE_COMMON_H
|
||||||
|
#define INTERFACE_COMMON_H
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class mac_interface_timers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Timer services with ms resolution.
|
||||||
|
* timer_id must be lower than MAC_NOF_UPPER_TIMERS
|
||||||
|
*/
|
||||||
|
virtual timers::timer* get(uint32_t timer_id) = 0;
|
||||||
|
virtual uint32_t get_unique_id() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class read_pdu_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t requested_bytes) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: log.h
|
||||||
|
*
|
||||||
|
* Description: Abstract logging service
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LOG_H
|
||||||
|
#define LOG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOG_LEVEL_NONE = 0,
|
||||||
|
LOG_LEVEL_ERROR,
|
||||||
|
LOG_LEVEL_WARNING,
|
||||||
|
LOG_LEVEL_INFO,
|
||||||
|
LOG_LEVEL_DEBUG,
|
||||||
|
LOG_LEVEL_N_ITEMS
|
||||||
|
} LOG_LEVEL_ENUM;
|
||||||
|
static const char log_level_text[LOG_LEVEL_N_ITEMS][16] = {"None ",
|
||||||
|
"Error ",
|
||||||
|
"Warning",
|
||||||
|
"Info ",
|
||||||
|
"Debug "};
|
||||||
|
|
||||||
|
class log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
log() {
|
||||||
|
service_name = "";
|
||||||
|
tti = 0;
|
||||||
|
level = LOG_LEVEL_NONE;
|
||||||
|
hex_limit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(std::string service_name_) {
|
||||||
|
service_name = service_name_;
|
||||||
|
tti = 0;
|
||||||
|
level = LOG_LEVEL_NONE;
|
||||||
|
hex_limit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function shall be called at the start of every tti for printing tti
|
||||||
|
void step(uint32_t tti_) {
|
||||||
|
tti = tti_;
|
||||||
|
}
|
||||||
|
uint32_t get_tti() {
|
||||||
|
return tti;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_level(LOG_LEVEL_ENUM l) {
|
||||||
|
level = l;
|
||||||
|
}
|
||||||
|
LOG_LEVEL_ENUM get_level() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_hex_limit(int limit) {
|
||||||
|
hex_limit = limit;
|
||||||
|
}
|
||||||
|
int get_hex_limit() {
|
||||||
|
return hex_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pure virtual methods for logging
|
||||||
|
virtual void console(std::string message, ...) = 0;
|
||||||
|
virtual void error(std::string message, ...) = 0;
|
||||||
|
virtual void warning(std::string message, ...) = 0;
|
||||||
|
virtual void info(std::string message, ...) = 0;
|
||||||
|
virtual void debug(std::string message, ...) = 0;
|
||||||
|
|
||||||
|
// Same with hex dump
|
||||||
|
virtual void error_hex(uint8_t *hex, int size, std::string message, ...){error("error_hex not implemented.\n");}
|
||||||
|
virtual void warning_hex(uint8_t *hex, int size, std::string message, ...){error("warning_hex not implemented.\n");}
|
||||||
|
virtual void info_hex(uint8_t *hex, int size, std::string message, ...){error("info_hex not implemented.\n");}
|
||||||
|
virtual void debug_hex(uint8_t *hex, int size, std::string message, ...){error("debug_hex not implemented.\n");}
|
||||||
|
|
||||||
|
// Same with line and file info
|
||||||
|
virtual void error_line(std::string file, int line, std::string message, ...){error("error_line not implemented.\n");}
|
||||||
|
virtual void warning_line(std::string file, int line, std::string message, ...){error("warning_line not implemented.\n");}
|
||||||
|
virtual void info_line(std::string file, int line, std::string message, ...){error("info_line not implemented.\n");}
|
||||||
|
virtual void debug_line(std::string file, int line, std::string message, ...){error("debug_line not implemented.\n");}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string get_service_name() { return service_name; }
|
||||||
|
uint32_t tti;
|
||||||
|
LOG_LEVEL_ENUM level;
|
||||||
|
int hex_limit;
|
||||||
|
std::string service_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // LOG_H
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: log_filter.h
|
||||||
|
* Description: Log filter for a specific layer or element.
|
||||||
|
* Performs filtering based on log level, generates
|
||||||
|
* timestamped log strings and passes them to the
|
||||||
|
* common logger object.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LOG_FILTER_H
|
||||||
|
#define LOG_FILTER_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
#include <common/log.h>
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class log_filter : public srslte::log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
log_filter();
|
||||||
|
log_filter(std::string layer, logger *logger_, bool tti=false);
|
||||||
|
|
||||||
|
void init(std::string layer, logger *logger_, bool tti=false);
|
||||||
|
|
||||||
|
void console(std::string message, ...);
|
||||||
|
void error(std::string message, ...);
|
||||||
|
void warning(std::string message, ...);
|
||||||
|
void info(std::string message, ...);
|
||||||
|
void debug(std::string message, ...);
|
||||||
|
|
||||||
|
void error_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void warning_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void info_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void debug_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
|
||||||
|
void error_line(std::string file, int line, std::string message, ...);
|
||||||
|
void warning_line(std::string file, int line, std::string message, ...);
|
||||||
|
void info_line(std::string file, int line, std::string message, ...);
|
||||||
|
void debug_line(std::string file, int line, std::string message, ...);
|
||||||
|
|
||||||
|
private:
|
||||||
|
logger *logger_h;
|
||||||
|
bool do_tti;
|
||||||
|
|
||||||
|
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg);
|
||||||
|
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg, uint8_t *hex, int size);
|
||||||
|
void all_log_line(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, char *msg);
|
||||||
|
std::string now_time();
|
||||||
|
std::string hex_string(uint8_t *hex, int size);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // LOG_FILTER_H
|
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: log_stout.h
|
||||||
|
*
|
||||||
|
* Description: Logging service through standard output. Inherits log interface
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LOGSTDOUT_H
|
||||||
|
#define LOGSTDOUT_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
#include <common/log.h>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class log_stdout : public log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
log_stdout(std::string service_name_) : log(service_name_) { }
|
||||||
|
|
||||||
|
void console(std::string message, ...);
|
||||||
|
void error(std::string message, ...);
|
||||||
|
void warning(std::string message, ...);
|
||||||
|
void info(std::string message, ...);
|
||||||
|
void debug(std::string message, ...);
|
||||||
|
|
||||||
|
// Same with hex dump
|
||||||
|
void error_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void warning_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void info_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
void debug_hex(uint8_t *hex, int size, std::string message, ...);
|
||||||
|
|
||||||
|
// Same with line and file info
|
||||||
|
void error_line(std::string file, int line, std::string message, ...);
|
||||||
|
void warning_line(std::string file, int line, std::string message, ...);
|
||||||
|
void info_line(std::string file, int line, std::string message, ...);
|
||||||
|
void debug_line(std::string file, int line, std::string message, ...);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void printlog(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, std::string message, va_list args);
|
||||||
|
void printlog(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string message, va_list args);
|
||||||
|
|
||||||
|
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg);
|
||||||
|
void all_log(srslte::LOG_LEVEL_ENUM level, uint32_t tti, char *msg, uint8_t *hex, int size);
|
||||||
|
void all_log_line(srslte::LOG_LEVEL_ENUM level, uint32_t tti, std::string file, int line, char *msg);
|
||||||
|
std::string now_time();
|
||||||
|
std::string hex_string(uint8_t *hex, int size);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: logger.h
|
||||||
|
* Description: Common log object. Maintains a queue of log messages
|
||||||
|
* and runs a thread to read messages and write to file.
|
||||||
|
* Multiple producers, single consumer. If full, producers
|
||||||
|
* increase queue size. If empty, consumer blocks.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
#include "common/threads.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
typedef std::string* str_ptr;
|
||||||
|
|
||||||
|
class logger : public thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
logger();
|
||||||
|
logger(std::string file);
|
||||||
|
~logger();
|
||||||
|
void init(std::string file);
|
||||||
|
void log(const char *msg);
|
||||||
|
void log(str_ptr msg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void run_thread();
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
FILE* logfile;
|
||||||
|
bool inited;
|
||||||
|
bool not_done;
|
||||||
|
std::string filename;
|
||||||
|
pthread_cond_t not_empty;
|
||||||
|
pthread_cond_t not_full;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_t thread;
|
||||||
|
std::deque<str_ptr> buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // LOGGER_H
|
@ -0,0 +1,177 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: mac_interface.h
|
||||||
|
* Description: LTE MAC layer interface
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAC_INTERFACE_H
|
||||||
|
#define MAC_INTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
#include "common/interfaces_common.h"
|
||||||
|
#include "common/timers.h"
|
||||||
|
|
||||||
|
#include "liblte_rrc.h"
|
||||||
|
|
||||||
|
namespace srsue {
|
||||||
|
|
||||||
|
/* Interface PHY -> MAC */
|
||||||
|
class mac_interface_phy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t pid;
|
||||||
|
uint32_t tti;
|
||||||
|
uint32_t last_tti;
|
||||||
|
bool ndi;
|
||||||
|
bool last_ndi;
|
||||||
|
uint32_t n_bytes;
|
||||||
|
int rv;
|
||||||
|
uint16_t rnti;
|
||||||
|
bool is_from_rar;
|
||||||
|
bool is_sps_release;
|
||||||
|
bool has_cqi_request;
|
||||||
|
srslte_rnti_type_t rnti_type;
|
||||||
|
srslte_phy_grant_t phy_grant;
|
||||||
|
} mac_grant_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool decode_enabled;
|
||||||
|
int rv;
|
||||||
|
uint16_t rnti;
|
||||||
|
bool generate_ack;
|
||||||
|
bool default_ack;
|
||||||
|
// If non-null, called after tb_decoded_ok to determine if ack needs to be sent
|
||||||
|
bool (*generate_ack_callback)(void*);
|
||||||
|
void *generate_ack_callback_arg;
|
||||||
|
uint8_t *payload_ptr;
|
||||||
|
srslte_softbuffer_rx_t *softbuffer;
|
||||||
|
srslte_phy_grant_t phy_grant;
|
||||||
|
} tb_action_dl_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool tx_enabled;
|
||||||
|
bool expect_ack;
|
||||||
|
uint32_t rv;
|
||||||
|
uint16_t rnti;
|
||||||
|
uint32_t current_tx_nb;
|
||||||
|
srslte_softbuffer_tx_t *softbuffer;
|
||||||
|
srslte_phy_grant_t phy_grant;
|
||||||
|
uint8_t *payload_ptr;
|
||||||
|
} tb_action_ul_t;
|
||||||
|
|
||||||
|
/* Indicate reception of UL grant.
|
||||||
|
* payload_ptr points to memory where MAC PDU must be written by MAC layer */
|
||||||
|
virtual void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) = 0;
|
||||||
|
|
||||||
|
/* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */
|
||||||
|
virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0;
|
||||||
|
|
||||||
|
/* Indicate reception of HARQ information only through PHICH. */
|
||||||
|
virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0;
|
||||||
|
|
||||||
|
/* Indicate reception of DL grant. */
|
||||||
|
virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0;
|
||||||
|
|
||||||
|
/* Indicate successfull decoding of PDSCH TB. */
|
||||||
|
virtual void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0;
|
||||||
|
|
||||||
|
/* Indicate successfull decoding of BCH TB through PBCH */
|
||||||
|
virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0;
|
||||||
|
|
||||||
|
/* Indicate successfull decoding of PCH TB through PDSCH */
|
||||||
|
virtual void pch_decoded_ok(uint32_t len) = 0;
|
||||||
|
|
||||||
|
/* Function called every start of a subframe (TTI). Warning, this function is called
|
||||||
|
* from a high priority thread and should terminate asap
|
||||||
|
*/
|
||||||
|
virtual void tti_clock(uint32_t tti) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Interface RRC -> MAC */
|
||||||
|
class mac_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main;
|
||||||
|
LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach;
|
||||||
|
LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr;
|
||||||
|
uint32_t prach_config_index;
|
||||||
|
} mac_cfg_t;
|
||||||
|
|
||||||
|
|
||||||
|
// Class to handle UE specific RNTIs between RRC and MAC
|
||||||
|
typedef struct {
|
||||||
|
uint16_t crnti;
|
||||||
|
uint16_t temp_rnti;
|
||||||
|
uint16_t tpc_rnti;
|
||||||
|
uint16_t sps_rnti;
|
||||||
|
uint64_t contention_id;
|
||||||
|
} ue_rnti_t;
|
||||||
|
|
||||||
|
/* Instructs the MAC to start receiving BCCH */
|
||||||
|
virtual void bcch_start_rx() = 0;
|
||||||
|
virtual void bcch_stop_rx() = 0;
|
||||||
|
virtual void bcch_start_rx(int si_window_start, int si_window_length) = 0;
|
||||||
|
|
||||||
|
/* Instructs the MAC to start receiving PCCH */
|
||||||
|
virtual void pcch_start_rx() = 0;
|
||||||
|
virtual void pcch_stop_rx() = 0;
|
||||||
|
|
||||||
|
/* RRC configures a logical channel */
|
||||||
|
virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t get_current_tti() = 0;
|
||||||
|
|
||||||
|
virtual void set_config(mac_cfg_t *mac_cfg) = 0;
|
||||||
|
virtual void set_config_main(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *main_cfg) = 0;
|
||||||
|
virtual void set_config_rach(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT *rach_cfg, uint32_t prach_config_index) = 0;
|
||||||
|
virtual void set_config_sr(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT *sr_cfg) = 0;
|
||||||
|
virtual void get_config(mac_cfg_t *mac_cfg) = 0;
|
||||||
|
|
||||||
|
virtual void get_rntis(ue_rnti_t *rntis) = 0;
|
||||||
|
virtual void set_contention_id(uint64_t uecri) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
virtual void reconfiguration() = 0;
|
||||||
|
virtual void reset() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MACPCAP_H
|
||||||
|
#define MACPCAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "common/pcap.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class mac_pcap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mac_pcap() {enable_write=false; ue_id=0; pcap_file = NULL; };
|
||||||
|
void enable(bool en);
|
||||||
|
void open(const char *filename, uint32_t ue_id = 0);
|
||||||
|
void close();
|
||||||
|
void write_ul_crnti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t crnti, uint32_t reTX, uint32_t tti);
|
||||||
|
void write_dl_crnti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t crnti, bool crc_ok, uint32_t tti);
|
||||||
|
void write_dl_ranti(uint8_t *pdu, uint32_t pdu_len_bytes, uint16_t ranti, bool crc_ok, uint32_t tti);
|
||||||
|
|
||||||
|
// SI and BCH only for DL
|
||||||
|
void write_dl_sirnti(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||||
|
void write_dl_bch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||||
|
void write_dl_pch(uint8_t *pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool enable_write;
|
||||||
|
FILE *pcap_file;
|
||||||
|
uint32_t ue_id;
|
||||||
|
void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reTX, bool crc_ok, uint32_t tti,
|
||||||
|
uint16_t crnti_, uint8_t direction, uint8_t rnti_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // MACPCAP_H
|
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: metrics_hub.h
|
||||||
|
* Description: Centralizes metrics interfaces to allow different metrics clients
|
||||||
|
* to get metrics
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef METRICS_HUB_H
|
||||||
|
#define METRICS_HUB_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "common/threads.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
template<typename metrics_t>
|
||||||
|
class metrics_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool get_metrics(metrics_t &m) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename metrics_t>
|
||||||
|
class metrics_listener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void set_metrics(metrics_t &m) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename metrics_t>
|
||||||
|
class metrics_hub : public periodic_thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool init(metrics_interface<metrics_t> *m_, float report_period_secs=1.0) {
|
||||||
|
m = m_;
|
||||||
|
start_periodic(report_period_secs*1e6);
|
||||||
|
}
|
||||||
|
void stop() {
|
||||||
|
thread_cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_listener(metrics_listener<metrics_t> *listener) {
|
||||||
|
listeners.push_back(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void run_period() {
|
||||||
|
metrics_t metric;
|
||||||
|
m->get_metrics(metric);
|
||||||
|
for (int i=0;i<listeners.size();i++) {
|
||||||
|
listeners[i]->set_metrics(metric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metrics_interface<metrics_t> *m;
|
||||||
|
std::vector<metrics_listener<metrics_t>*> listeners;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // METRICS_HUB_H
|
@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: msg_queue.h
|
||||||
|
* Description: Thread-safe bounded circular buffer of srsue_byte_buffer pointers.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MSG_QUEUE_H
|
||||||
|
#define MSG_QUEUE_H
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class msg_queue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
msg_queue(uint32_t capacity_ = 128)
|
||||||
|
:head(0)
|
||||||
|
,tail(0)
|
||||||
|
,unread(0)
|
||||||
|
,unread_bytes(0)
|
||||||
|
,capacity(capacity_)
|
||||||
|
{
|
||||||
|
buf = new byte_buffer_t*[capacity];
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
pthread_cond_init(¬_empty, NULL);
|
||||||
|
pthread_cond_init(¬_full, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
~msg_queue()
|
||||||
|
{
|
||||||
|
delete [] buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(byte_buffer_t *msg)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(is_full()) {
|
||||||
|
pthread_cond_wait(¬_full, &mutex);
|
||||||
|
}
|
||||||
|
buf[head] = msg;
|
||||||
|
head = (head+1)%capacity;
|
||||||
|
unread++;
|
||||||
|
unread_bytes += msg->N_bytes;
|
||||||
|
|
||||||
|
pthread_cond_signal(¬_empty);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read(byte_buffer_t **msg)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(is_empty()) {
|
||||||
|
pthread_cond_wait(¬_empty, &mutex);
|
||||||
|
}
|
||||||
|
*msg = buf[tail];
|
||||||
|
tail = (tail+1)%capacity;
|
||||||
|
unread--;
|
||||||
|
unread_bytes -= (*msg)->N_bytes;
|
||||||
|
|
||||||
|
pthread_cond_signal(¬_full);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_read(byte_buffer_t **msg)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if(is_empty())
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
*msg = buf[tail];
|
||||||
|
tail = (tail+1)%capacity;
|
||||||
|
unread--;
|
||||||
|
unread_bytes -= (*msg)->N_bytes;
|
||||||
|
pthread_cond_signal(¬_full);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
uint32_t r = unread;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size_bytes()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
uint32_t r = unread_bytes;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size_tail_bytes()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
uint32_t r = buf[tail]->N_bytes;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_empty() const { return unread == 0; }
|
||||||
|
bool is_full() const { return unread == capacity; }
|
||||||
|
|
||||||
|
pthread_cond_t not_empty;
|
||||||
|
pthread_cond_t not_full;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
byte_buffer_t **buf;
|
||||||
|
uint32_t capacity;
|
||||||
|
uint32_t unread;
|
||||||
|
uint32_t unread_bytes;
|
||||||
|
uint32_t head;
|
||||||
|
uint32_t tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MSG_QUEUE_H
|
@ -0,0 +1,218 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UEPCAP_H
|
||||||
|
#define UEPCAP_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define MAC_LTE_DLT 147
|
||||||
|
|
||||||
|
|
||||||
|
/* This structure gets written to the start of the file */
|
||||||
|
typedef struct pcap_hdr_s {
|
||||||
|
unsigned int magic_number; /* magic number */
|
||||||
|
unsigned short version_major; /* major version number */
|
||||||
|
unsigned short version_minor; /* minor version number */
|
||||||
|
unsigned int thiszone; /* GMT to local correction */
|
||||||
|
unsigned int sigfigs; /* accuracy of timestamps */
|
||||||
|
unsigned int snaplen; /* max length of captured packets, in octets */
|
||||||
|
unsigned int network; /* data link type */
|
||||||
|
} pcap_hdr_t;
|
||||||
|
|
||||||
|
/* This structure precedes each packet */
|
||||||
|
typedef struct pcaprec_hdr_s {
|
||||||
|
unsigned int ts_sec; /* timestamp seconds */
|
||||||
|
unsigned int ts_usec; /* timestamp microseconds */
|
||||||
|
unsigned int incl_len; /* number of octets of packet saved in file */
|
||||||
|
unsigned int orig_len; /* actual length of packet */
|
||||||
|
} pcaprec_hdr_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* radioType */
|
||||||
|
#define FDD_RADIO 1
|
||||||
|
#define TDD_RADIO 2
|
||||||
|
|
||||||
|
/* Direction */
|
||||||
|
#define DIRECTION_UPLINK 0
|
||||||
|
#define DIRECTION_DOWNLINK 1
|
||||||
|
|
||||||
|
/* rntiType */
|
||||||
|
#define NO_RNTI 0 /* Used for BCH-BCH */
|
||||||
|
#define P_RNTI 1
|
||||||
|
#define RA_RNTI 2
|
||||||
|
#define C_RNTI 3
|
||||||
|
#define SI_RNTI 4
|
||||||
|
#define SPS_RNTI 5
|
||||||
|
#define M_RNTI 6
|
||||||
|
|
||||||
|
#define MAC_LTE_START_STRING "mac-lte"
|
||||||
|
|
||||||
|
#define MAC_LTE_RNTI_TAG 0x02
|
||||||
|
/* 2 bytes, network order */
|
||||||
|
|
||||||
|
#define MAC_LTE_UEID_TAG 0x03
|
||||||
|
/* 2 bytes, network order */
|
||||||
|
|
||||||
|
#define MAC_LTE_SUBFRAME_TAG 0x04
|
||||||
|
/* 2 bytes, network order */
|
||||||
|
|
||||||
|
#define MAC_LTE_PREDFINED_DATA_TAG 0x05
|
||||||
|
/* 1 byte */
|
||||||
|
|
||||||
|
#define MAC_LTE_RETX_TAG 0x06
|
||||||
|
/* 1 byte */
|
||||||
|
|
||||||
|
#define MAC_LTE_CRC_STATUS_TAG 0x07
|
||||||
|
/* 1 byte */
|
||||||
|
|
||||||
|
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
|
||||||
|
continues until the end of the frame) */
|
||||||
|
#define MAC_LTE_PAYLOAD_TAG 0x01
|
||||||
|
|
||||||
|
|
||||||
|
/* Context information for every MAC PDU that will be logged */
|
||||||
|
typedef struct MAC_Context_Info_t {
|
||||||
|
unsigned short radioType;
|
||||||
|
unsigned char direction;
|
||||||
|
unsigned char rntiType;
|
||||||
|
unsigned short rnti;
|
||||||
|
unsigned short ueid;
|
||||||
|
unsigned char isRetx;
|
||||||
|
unsigned char crcStatusOK;
|
||||||
|
|
||||||
|
unsigned short sysFrameNumber;
|
||||||
|
unsigned short subFrameNumber;
|
||||||
|
|
||||||
|
} MAC_Context_Info_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* API functions for opening/writing/closing MAC-LTE PCAP files */
|
||||||
|
|
||||||
|
/* Open the file and write file header */
|
||||||
|
inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
|
||||||
|
{
|
||||||
|
pcap_hdr_t file_header =
|
||||||
|
{
|
||||||
|
0xa1b2c3d4, /* magic number */
|
||||||
|
2, 4, /* version number is 2.4 */
|
||||||
|
0, /* timezone */
|
||||||
|
0, /* sigfigs - apparently all tools do this */
|
||||||
|
65535, /* snaplen - this should be long enough */
|
||||||
|
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE *fd = fopen(fileName, "w");
|
||||||
|
if (fd == NULL) {
|
||||||
|
printf("Failed to open file \"%s\" for writing\n", fileName);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the file header */
|
||||||
|
fwrite(&file_header, sizeof(pcap_hdr_t), 1, fd);
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||||
|
inline int MAC_LTE_PCAP_WritePDU(FILE *fd, MAC_Context_Info_t *context,
|
||||||
|
const unsigned char *PDU, unsigned int length)
|
||||||
|
{
|
||||||
|
pcaprec_hdr_t packet_header;
|
||||||
|
char context_header[256];
|
||||||
|
int offset = 0;
|
||||||
|
unsigned short tmp16;
|
||||||
|
|
||||||
|
/* Can't write if file wasn't successfully opened */
|
||||||
|
if (fd == NULL) {
|
||||||
|
printf("Error: Can't write to empty file handle\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
/* Context information (same as written by UDP heuristic clients */
|
||||||
|
context_header[offset++] = context->radioType;
|
||||||
|
context_header[offset++] = context->direction;
|
||||||
|
context_header[offset++] = context->rntiType;
|
||||||
|
|
||||||
|
/* RNTI */
|
||||||
|
context_header[offset++] = MAC_LTE_RNTI_TAG;
|
||||||
|
tmp16 = htons(context->rnti);
|
||||||
|
memcpy(context_header+offset, &tmp16, 2);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
/* UEId */
|
||||||
|
context_header[offset++] = MAC_LTE_UEID_TAG;
|
||||||
|
tmp16 = htons(context->ueid);
|
||||||
|
memcpy(context_header+offset, &tmp16, 2);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
/* Subframe number */
|
||||||
|
context_header[offset++] = MAC_LTE_SUBFRAME_TAG;
|
||||||
|
tmp16 = htons(context->subFrameNumber);
|
||||||
|
memcpy(context_header+offset, &tmp16, 2);
|
||||||
|
offset += 2;
|
||||||
|
|
||||||
|
/* CRC Status */
|
||||||
|
context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
|
||||||
|
context_header[offset++] = context->crcStatusOK;
|
||||||
|
|
||||||
|
/* Data tag immediately preceding PDU */
|
||||||
|
context_header[offset++] = MAC_LTE_PAYLOAD_TAG;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************/
|
||||||
|
/* PCAP Header */
|
||||||
|
struct timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
packet_header.ts_sec = t.tv_sec;
|
||||||
|
packet_header.ts_usec = t.tv_usec;
|
||||||
|
packet_header.incl_len = offset + length;
|
||||||
|
packet_header.orig_len = offset + length;
|
||||||
|
|
||||||
|
/***************************************************************/
|
||||||
|
/* Now write everything to the file */
|
||||||
|
fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, fd);
|
||||||
|
fwrite(context_header, 1, offset, fd);
|
||||||
|
fwrite(PDU, 1, length, fd);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the PCAP file */
|
||||||
|
inline void MAC_LTE_PCAP_Close(FILE *fd)
|
||||||
|
{
|
||||||
|
if(fd)
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UEPCAP_H */
|
@ -0,0 +1,339 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MACPDU_H
|
||||||
|
#define MACPDU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/interfaces_common.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* MAC PDU Packing/Unpacking functions. Section 6 of 36.321 */
|
||||||
|
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
template<class SubH>
|
||||||
|
class pdu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
pdu(uint32_t max_subheaders_) : subheaders(max_subheaders_) {
|
||||||
|
max_subheaders = max_subheaders_;
|
||||||
|
nof_subheaders = 0;
|
||||||
|
cur_idx = -1;
|
||||||
|
pdu_len = 0;
|
||||||
|
rem_len = 0;
|
||||||
|
last_sdu_idx = -1;
|
||||||
|
pdu_is_ul = false;
|
||||||
|
buffer_tx = NULL;
|
||||||
|
total_sdu_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fprint(FILE *stream) {
|
||||||
|
fprintf(stream, "Number of Subheaders: %d\n", nof_subheaders);
|
||||||
|
for (int i=0;i<nof_subheaders;i++) {
|
||||||
|
fprintf(stream, " -- Subheader %d: ", i);
|
||||||
|
subheaders[i].fprint(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resets the Read/Write position and remaining PDU length */
|
||||||
|
void reset() {
|
||||||
|
cur_idx = -1;
|
||||||
|
last_sdu_idx = -1;
|
||||||
|
rem_len = pdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_rx(uint32_t pdu_len_bytes, bool is_ulsch = false) {
|
||||||
|
init_(NULL, pdu_len_bytes, is_ulsch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_tx(uint8_t *payload, uint32_t pdu_len_bytes, bool is_ulsch = false) {
|
||||||
|
init_(payload, pdu_len_bytes, is_ulsch);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nof_subh() {
|
||||||
|
return nof_subheaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool new_subh() {
|
||||||
|
if (nof_subheaders < max_subheaders - 1 && rem_len > 0) {
|
||||||
|
nof_subheaders++;
|
||||||
|
next();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool next() {
|
||||||
|
if (cur_idx < nof_subheaders - 1) {
|
||||||
|
cur_idx++;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void del_subh() {
|
||||||
|
if (nof_subheaders > 0) {
|
||||||
|
nof_subheaders--;
|
||||||
|
}
|
||||||
|
if (cur_idx > 0) {
|
||||||
|
cur_idx--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SubH* get() {
|
||||||
|
if (cur_idx >= 0) {
|
||||||
|
return &subheaders[cur_idx];
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_ul() {
|
||||||
|
return pdu_is_ul;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* get_current_sdu_ptr() {
|
||||||
|
return &buffer_tx[total_sdu_len+sdu_offset_start];
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_sdu(uint32_t sdu_sz) {
|
||||||
|
total_sdu_len += sdu_sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section 6.1.2
|
||||||
|
void parse_packet(uint8_t *ptr) {
|
||||||
|
uint8_t *init_ptr = ptr;
|
||||||
|
nof_subheaders = 0;
|
||||||
|
while(subheaders[nof_subheaders].read_subheader(&ptr)) {
|
||||||
|
nof_subheaders++;
|
||||||
|
}
|
||||||
|
nof_subheaders++;
|
||||||
|
for (int i=0;i<nof_subheaders;i++) {
|
||||||
|
subheaders[i].read_payload(&ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<SubH> subheaders;
|
||||||
|
uint32_t pdu_len;
|
||||||
|
uint32_t rem_len;
|
||||||
|
int cur_idx;
|
||||||
|
int nof_subheaders;
|
||||||
|
uint32_t max_subheaders;
|
||||||
|
bool pdu_is_ul;
|
||||||
|
uint8_t* buffer_tx;
|
||||||
|
uint32_t total_sdu_len;
|
||||||
|
uint32_t sdu_offset_start;
|
||||||
|
int last_sdu_idx;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* Prepares the PDU for parsing or writing by setting the number of subheaders to 0 and the pdu length */
|
||||||
|
void init_(uint8_t *buffer_tx_ptr, uint32_t pdu_len_bytes, bool is_ulsch) {
|
||||||
|
nof_subheaders = 0;
|
||||||
|
pdu_len = pdu_len_bytes;
|
||||||
|
rem_len = pdu_len;
|
||||||
|
pdu_is_ul = is_ulsch;
|
||||||
|
buffer_tx = buffer_tx_ptr;
|
||||||
|
sdu_offset_start = max_subheaders*2 + 13; // Assuming worst-case 2 bytes per sdu subheader + all possible CE
|
||||||
|
total_sdu_len = 0;
|
||||||
|
last_sdu_idx = -1;
|
||||||
|
reset();
|
||||||
|
for (int i=0;i<max_subheaders;i++) {
|
||||||
|
subheaders[i].parent = this;
|
||||||
|
subheaders[i].init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class SubH>
|
||||||
|
class subh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual bool read_subheader(uint8_t** ptr) = 0;
|
||||||
|
virtual void read_payload(uint8_t **ptr) = 0;
|
||||||
|
virtual void write_subheader(uint8_t** ptr, bool is_last) = 0;
|
||||||
|
virtual void write_payload(uint8_t **ptr) = 0;
|
||||||
|
virtual void fprint(FILE *stream) = 0;
|
||||||
|
|
||||||
|
pdu<SubH>* parent;
|
||||||
|
private:
|
||||||
|
virtual void init() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class sch_subh : public subh<sch_subh>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PHR_REPORT = 26,
|
||||||
|
CRNTI = 27,
|
||||||
|
CON_RES_ID = 28,
|
||||||
|
TRUNC_BSR = 28,
|
||||||
|
TA_CMD = 29,
|
||||||
|
SHORT_BSR = 29,
|
||||||
|
DRX_CMD = 30,
|
||||||
|
LONG_BSR = 30,
|
||||||
|
PADDING = 31,
|
||||||
|
SDU = 0
|
||||||
|
} cetype;
|
||||||
|
|
||||||
|
// Size of MAC CEs
|
||||||
|
const static int MAC_CE_CONTRES_LEN = 6;
|
||||||
|
|
||||||
|
// Reading functions
|
||||||
|
bool is_sdu();
|
||||||
|
cetype ce_type();
|
||||||
|
uint32_t size_plus_header();
|
||||||
|
void set_payload_size(uint32_t size);
|
||||||
|
|
||||||
|
bool read_subheader(uint8_t** ptr);
|
||||||
|
void read_payload(uint8_t **ptr);
|
||||||
|
uint32_t get_sdu_lcid();
|
||||||
|
uint32_t get_payload_size();
|
||||||
|
uint32_t get_header_size(bool is_last);
|
||||||
|
uint8_t* get_sdu_ptr();
|
||||||
|
|
||||||
|
uint16_t get_c_rnti();
|
||||||
|
uint64_t get_con_res_id();
|
||||||
|
uint8_t get_ta_cmd();
|
||||||
|
float get_phr();
|
||||||
|
int get_bsr(uint32_t buff_size[4]);
|
||||||
|
|
||||||
|
// Writing functions
|
||||||
|
void write_subheader(uint8_t** ptr, bool is_last);
|
||||||
|
void write_payload(uint8_t **ptr);
|
||||||
|
int set_sdu(uint32_t lcid, uint32_t nof_bytes, uint8_t *payload);
|
||||||
|
int set_sdu(uint32_t lcid, uint32_t requested_bytes, read_pdu_interface *sdu_itf);
|
||||||
|
bool set_c_rnti(uint16_t crnti);
|
||||||
|
bool set_bsr(uint32_t buff_size[4], sch_subh::cetype format);
|
||||||
|
bool set_con_res_id(uint64_t con_res_id);
|
||||||
|
bool set_ta_cmd(uint8_t ta_cmd);
|
||||||
|
bool set_phr(float phr);
|
||||||
|
void set_padding();
|
||||||
|
void set_padding(uint32_t padding_len);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void fprint(FILE *stream);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int MAX_CE_PAYLOAD_LEN = 8;
|
||||||
|
uint32_t lcid;
|
||||||
|
int nof_bytes;
|
||||||
|
uint8_t* payload;
|
||||||
|
uint8_t w_payload_ce[8];
|
||||||
|
bool F_bit;
|
||||||
|
uint32_t sizeof_ce(uint32_t lcid, bool is_ul);
|
||||||
|
static uint8_t buff_size_table(uint32_t buffer_size);
|
||||||
|
static uint8_t phr_report_table(float phr_value);
|
||||||
|
};
|
||||||
|
|
||||||
|
class sch_pdu : public pdu<sch_subh>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
sch_pdu(uint32_t max_subh) : pdu(max_subh) {}
|
||||||
|
|
||||||
|
void parse_packet(uint8_t *ptr);
|
||||||
|
uint8_t* write_packet();
|
||||||
|
uint8_t* write_packet(srslte::log *log_h);
|
||||||
|
bool has_space_ce(uint32_t nbytes);
|
||||||
|
bool has_space_sdu(uint32_t nbytes);
|
||||||
|
int get_pdu_len();
|
||||||
|
int rem_size();
|
||||||
|
int get_sdu_space();
|
||||||
|
|
||||||
|
static uint32_t size_header_sdu(uint32_t nbytes);
|
||||||
|
bool update_space_ce(uint32_t nbytes);
|
||||||
|
bool update_space_sdu(uint32_t nbytes);
|
||||||
|
void fprint(FILE *stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
class rar_subh : public subh<rar_subh>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const uint32_t RAR_GRANT_LEN = 20;
|
||||||
|
|
||||||
|
// Reading functions
|
||||||
|
bool read_subheader(uint8_t** ptr);
|
||||||
|
void read_payload(uint8_t** ptr);
|
||||||
|
uint32_t get_rapid();
|
||||||
|
uint32_t get_ta_cmd();
|
||||||
|
uint16_t get_temp_crnti();
|
||||||
|
void get_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
|
||||||
|
|
||||||
|
// Writing functoins
|
||||||
|
void write_subheader(uint8_t** ptr, bool is_last);
|
||||||
|
void write_payload(uint8_t** ptr);
|
||||||
|
void set_rapid(uint32_t rapid);
|
||||||
|
void set_ta_cmd(uint32_t ta);
|
||||||
|
void set_temp_crnti(uint16_t temp_rnti);
|
||||||
|
void set_sched_grant(uint8_t grant[RAR_GRANT_LEN]);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void fprint(FILE *stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t grant[RAR_GRANT_LEN];
|
||||||
|
uint32_t ta;
|
||||||
|
uint16_t temp_rnti;
|
||||||
|
uint32_t preamble;
|
||||||
|
};
|
||||||
|
|
||||||
|
class rar_pdu : public pdu<rar_subh>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
rar_pdu(uint32_t max_rars = 16);
|
||||||
|
|
||||||
|
void set_backoff(uint8_t bi);
|
||||||
|
bool has_backoff();
|
||||||
|
uint8_t get_backoff();
|
||||||
|
|
||||||
|
bool write_packet(uint8_t* ptr);
|
||||||
|
void fprint(FILE *stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool has_backoff_indicator;
|
||||||
|
uint8_t backoff_indicator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // MACPDU_H
|
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PDUPROC_H
|
||||||
|
#define PDUPROC_H
|
||||||
|
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/block_queue.h"
|
||||||
|
#include "common/buffer_pool.h"
|
||||||
|
#include "common/timers.h"
|
||||||
|
#include "common/pdu.h"
|
||||||
|
|
||||||
|
/* Logical Channel Demultiplexing and MAC CE dissassemble */
|
||||||
|
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class pdu_queue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class process_callback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void process_pdu(uint8_t *buff, uint32_t len) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL), log_h(NULL) {}
|
||||||
|
void init(process_callback *callback, log* log_h_);
|
||||||
|
|
||||||
|
uint8_t* request(uint32_t len);
|
||||||
|
void deallocate(uint8_t* pdu);
|
||||||
|
void push(uint8_t *ptr, uint32_t len);
|
||||||
|
|
||||||
|
bool process_pdus();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total
|
||||||
|
const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ptr[MAX_PDU_LEN];
|
||||||
|
uint32_t len;
|
||||||
|
} pdu_t;
|
||||||
|
|
||||||
|
block_queue<pdu_t*> pdu_q;
|
||||||
|
buffer_pool<pdu_t> pool;
|
||||||
|
|
||||||
|
process_callback *callback;
|
||||||
|
log *log_h;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // PDUPROC_H
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: phy_interface.h
|
||||||
|
* Description: PHY layer interfaces provided to other layers
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PHY_INTERFACE_H
|
||||||
|
#define PHY_INTERFACE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
#include "liblte_rrc.h"
|
||||||
|
|
||||||
|
namespace srsue {
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool ul_pwr_ctrl_en;
|
||||||
|
float prach_gain;
|
||||||
|
int pdsch_max_its;
|
||||||
|
bool attach_enable_64qam;
|
||||||
|
int nof_phy_threads;
|
||||||
|
|
||||||
|
int worker_cpu_mask;
|
||||||
|
int sync_cpu_affinity;
|
||||||
|
|
||||||
|
uint32_t nof_rx_ant;
|
||||||
|
std::string equalizer_mode;
|
||||||
|
int cqi_max;
|
||||||
|
int cqi_fixed;
|
||||||
|
float snr_ema_coeff;
|
||||||
|
std::string snr_estim_alg;
|
||||||
|
bool cfo_integer_enabled;
|
||||||
|
float cfo_correct_tol_hz;
|
||||||
|
int time_correct_period;
|
||||||
|
bool sfo_correct_disable;
|
||||||
|
std::string sss_algorithm;
|
||||||
|
float estimator_fil_w;
|
||||||
|
bool rssi_sensor_enabled;
|
||||||
|
} phy_args_t;
|
||||||
|
|
||||||
|
/* Interface MAC -> PHY */
|
||||||
|
class phy_interface_mac
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Configure PRACH using parameters written by RRC */
|
||||||
|
virtual void configure_prach_params() = 0;
|
||||||
|
|
||||||
|
/* Start synchronization with strongest cell in the current carrier frequency */
|
||||||
|
virtual void sync_start() = 0;
|
||||||
|
virtual void sync_stop() = 0;
|
||||||
|
|
||||||
|
/* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */
|
||||||
|
virtual void set_crnti(uint16_t rnti) = 0;
|
||||||
|
|
||||||
|
virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0;
|
||||||
|
virtual int prach_tx_tti() = 0;
|
||||||
|
|
||||||
|
/* Indicates the transmission of a SR signal in the next opportunity */
|
||||||
|
virtual void sr_send() = 0;
|
||||||
|
virtual int sr_last_tx_tti() = 0;
|
||||||
|
|
||||||
|
/* Time advance commands */
|
||||||
|
virtual void set_timeadv_rar(uint32_t ta_cmd) = 0;
|
||||||
|
virtual void set_timeadv(uint32_t ta_cmd) = 0;
|
||||||
|
|
||||||
|
/* Sets RAR grant payload */
|
||||||
|
virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0;
|
||||||
|
|
||||||
|
/* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */
|
||||||
|
virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
|
||||||
|
virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0;
|
||||||
|
virtual void pdcch_ul_search_reset() = 0;
|
||||||
|
virtual void pdcch_dl_search_reset() = 0;
|
||||||
|
|
||||||
|
virtual uint32_t get_current_tti() = 0;
|
||||||
|
|
||||||
|
virtual float get_phr() = 0;
|
||||||
|
virtual float get_pathloss_db() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class phy_interface_rrc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT prach_cnfg;
|
||||||
|
LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT pdsch_cnfg;
|
||||||
|
LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT pusch_cnfg;
|
||||||
|
LIBLTE_RRC_PHICH_CONFIG_STRUCT phich_cnfg;
|
||||||
|
LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT pucch_cnfg;
|
||||||
|
LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT srs_ul_cnfg;
|
||||||
|
LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT ul_pwr_ctrl;
|
||||||
|
LIBLTE_RRC_TDD_CONFIG_STRUCT tdd_cnfg;
|
||||||
|
LIBLTE_RRC_ANTENNA_PORTS_COUNT_ENUM ant_info;
|
||||||
|
} phy_cfg_common_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT dedicated;
|
||||||
|
phy_cfg_common_t common;
|
||||||
|
bool enable_64qam;
|
||||||
|
} phy_cfg_t;
|
||||||
|
|
||||||
|
virtual void get_current_cell(srslte_cell_t *cell) = 0;
|
||||||
|
virtual void get_config(phy_cfg_t *phy_cfg) = 0;
|
||||||
|
virtual void set_config(phy_cfg_t *phy_cfg) = 0;
|
||||||
|
virtual void set_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated) = 0;
|
||||||
|
virtual void set_config_common(phy_cfg_common_t *common) = 0;
|
||||||
|
virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0;
|
||||||
|
virtual void set_config_64qam_en(bool enable) = 0;
|
||||||
|
|
||||||
|
/* Is the PHY downlink synchronized? */
|
||||||
|
virtual bool status_is_sync() = 0;
|
||||||
|
|
||||||
|
/* Configure UL using parameters written with set_param() */
|
||||||
|
virtual void configure_ul_params(bool pregen_disabled = false) = 0;
|
||||||
|
|
||||||
|
virtual void reset() = 0;
|
||||||
|
|
||||||
|
virtual void resync_sfn() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SECURITY_H
|
||||||
|
#define SECURITY_H
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Common security header - wraps ciphering/integrity check algorithms.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SECURITY_DIRECTION_UPLINK 0
|
||||||
|
#define SECURITY_DIRECTION_DOWNLINK 1
|
||||||
|
|
||||||
|
namespace srsue{
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
CIPHERING_ALGORITHM_ID_EEA0 = 0,
|
||||||
|
CIPHERING_ALGORITHM_ID_128_EEA1,
|
||||||
|
CIPHERING_ALGORITHM_ID_128_EEA2,
|
||||||
|
CIPHERING_ALGORITHM_ID_N_ITEMS,
|
||||||
|
}CIPHERING_ALGORITHM_ID_ENUM;
|
||||||
|
static const char ciphering_algorithm_id_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"EEA0",
|
||||||
|
"128-EEA1",
|
||||||
|
"128-EEA2"};
|
||||||
|
typedef enum{
|
||||||
|
INTEGRITY_ALGORITHM_ID_EIA0 = 0,
|
||||||
|
INTEGRITY_ALGORITHM_ID_128_EIA1,
|
||||||
|
INTEGRITY_ALGORITHM_ID_128_EIA2,
|
||||||
|
INTEGRITY_ALGORITHM_ID_N_ITEMS,
|
||||||
|
}INTEGRITY_ALGORITHM_ID_ENUM;
|
||||||
|
static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"EIA0",
|
||||||
|
"128-EIA1",
|
||||||
|
"128-EIA2"};
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Key Generation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_generate_k_asme( uint8_t *ck,
|
||||||
|
uint8_t *ik,
|
||||||
|
uint8_t *ak,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint16_t mcc,
|
||||||
|
uint16_t mnc,
|
||||||
|
uint8_t *k_asme);
|
||||||
|
|
||||||
|
uint8_t security_generate_k_enb( uint8_t *k_asme,
|
||||||
|
uint32_t nas_count,
|
||||||
|
uint8_t *k_enb);
|
||||||
|
|
||||||
|
uint8_t security_generate_k_nas( uint8_t *k_asme,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_nas_enc,
|
||||||
|
uint8_t *k_nas_int);
|
||||||
|
|
||||||
|
uint8_t security_generate_k_rrc( uint8_t *k_enb,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_rrc_enc,
|
||||||
|
uint8_t *k_rrc_int);
|
||||||
|
|
||||||
|
uint8_t security_generate_k_up( uint8_t *k_enb,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_up_enc,
|
||||||
|
uint8_t *k_up_int);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Integrity Protection
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_128_eia1( uint8_t *key,
|
||||||
|
uint32_t count,
|
||||||
|
uint8_t bearer,
|
||||||
|
uint8_t direction,
|
||||||
|
uint8_t *msg,
|
||||||
|
uint32_t msg_len,
|
||||||
|
uint8_t *mac);
|
||||||
|
|
||||||
|
uint8_t security_128_eia2( uint8_t *key,
|
||||||
|
uint32_t count,
|
||||||
|
uint8_t bearer,
|
||||||
|
uint8_t direction,
|
||||||
|
uint8_t *msg,
|
||||||
|
uint32_t msg_len,
|
||||||
|
uint8_t *mac);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Authentication
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_milenage_f1( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint8_t *amf,
|
||||||
|
uint8_t *mac_a);
|
||||||
|
|
||||||
|
uint8_t security_milenage_f1_star( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint8_t *amf,
|
||||||
|
uint8_t *mac_s);
|
||||||
|
|
||||||
|
uint8_t security_milenage_f2345( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *res,
|
||||||
|
uint8_t *ck,
|
||||||
|
uint8_t *ik,
|
||||||
|
uint8_t *ak);
|
||||||
|
|
||||||
|
uint8_t security_milenage_f5_star( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *ak);
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // SECURITY_H
|
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------
|
||||||
|
* snow_3g.h
|
||||||
|
*
|
||||||
|
* Adapted from ETSI/SAGE specifications:
|
||||||
|
* "Specification of the 3GPP Confidentiality and
|
||||||
|
* Integrity Algorithms UEA2 & UIA2.
|
||||||
|
* Document 1: UEA2 and UIA2 Specification"
|
||||||
|
* "Specification of the 3GPP Confidentiality
|
||||||
|
* and Integrity Algorithms UEA2 & UIA2.
|
||||||
|
* Document 2: SNOW 3G Specification"
|
||||||
|
*---------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
|
/* Initialization.
|
||||||
|
* Input k[4]: Four 32-bit words making up 128-bit key.
|
||||||
|
* Input IV[4]: Four 32-bit words making 128-bit initialization variable.
|
||||||
|
* Output: All the LFSRs and FSM are initialized for key generation.
|
||||||
|
* See Section 4.1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_initialize(u32 k[4], u32 IV[4]);
|
||||||
|
|
||||||
|
/* Generation of Keystream.
|
||||||
|
* input n: number of 32-bit words of keystream.
|
||||||
|
* input z: space for the generated keystream, assumes
|
||||||
|
* memory is allocated already.
|
||||||
|
* output: generated keystream which is filled in z
|
||||||
|
* See section 4.2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_generate_keystream(u32 n, u32 *z);
|
||||||
|
|
||||||
|
/* f8.
|
||||||
|
* Input key: 128 bit Confidentiality Key.
|
||||||
|
* Input count:32-bit Count, Frame dependent input.
|
||||||
|
* Input bearer: 5-bit Bearer identity (in the LSB side).
|
||||||
|
* Input dir:1 bit, direction of transmission.
|
||||||
|
* Input data: length number of bits, input bit stream.
|
||||||
|
* Input length: 32 bit Length, i.e., the number of bits to be encrypted or
|
||||||
|
* decrypted.
|
||||||
|
* Output data: Output bit stream. Assumes data is suitably memory
|
||||||
|
* allocated.
|
||||||
|
* Encrypts/decrypts blocks of data between 1 and 2^32 bits in length as
|
||||||
|
* defined in Section 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_f8( u8 *key, u32 count, u32 bearer, u32 dir, \
|
||||||
|
u8 *data, u32 length );
|
||||||
|
|
||||||
|
/* f9.
|
||||||
|
* Input key: 128 bit Integrity Key.
|
||||||
|
* Input count:32-bit Count, Frame dependent input.
|
||||||
|
* Input fresh: 32-bit Random number.
|
||||||
|
* Input dir:1 bit, direction of transmission (in the LSB).
|
||||||
|
* Input data: length number of bits, input bit stream.
|
||||||
|
* Input length: 64 bit Length, i.e., the number of bits to be MAC'd.
|
||||||
|
* Output : 32 bit block used as MAC
|
||||||
|
* Generates 32-bit MAC using UIA2 algorithm as defined in Section 4.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u8* snow3g_f9( u8* key, u32 count, u32 fresh, u32 dir, \
|
||||||
|
u8 *data, u64 length);
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: task_dispatcher.h
|
||||||
|
* Description:
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TASK_DISPATCHER_H
|
||||||
|
#define TASK_DISPATCHER_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <queue>
|
||||||
|
#include "common/threads.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class task_dispatcher : public thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
task_dispatcher(uint32_t max_pending_tasks);
|
||||||
|
~task_dispatcher();
|
||||||
|
void push_task(uint32_t task_code);
|
||||||
|
virtual void run_task(uint32_t task_code) = 0;
|
||||||
|
private:
|
||||||
|
std::queue<uint32_t> pending_tasks;
|
||||||
|
void run_thread();
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t cvar;
|
||||||
|
bool running;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // TASK_DISPATCHER_H
|
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: thread_pool.h
|
||||||
|
* Description: Implements a pool of threads. Pending tasks to execute are
|
||||||
|
* identified by a pointer.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef THREAD_POOL_H
|
||||||
|
#define THREAD_POOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include "common/threads.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class thread_pool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
class worker : public thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setup(uint32_t id, thread_pool *parent, uint32_t prio=0, uint32_t mask = 255);
|
||||||
|
void stop();
|
||||||
|
uint32_t get_id();
|
||||||
|
void release();
|
||||||
|
protected:
|
||||||
|
virtual void work_imp() = 0;
|
||||||
|
private:
|
||||||
|
uint32_t my_id;
|
||||||
|
thread_pool *my_parent;
|
||||||
|
bool running;
|
||||||
|
void run_thread();
|
||||||
|
void wait_to_start();
|
||||||
|
void finished();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
thread_pool(uint32_t nof_workers);
|
||||||
|
void init_worker(uint32_t id, worker*, uint32_t prio = 0, uint32_t mask = 255);
|
||||||
|
void stop();
|
||||||
|
worker* wait_worker();
|
||||||
|
worker* wait_worker(uint32_t tti);
|
||||||
|
worker* wait_worker_nb(uint32_t tti);
|
||||||
|
void start_worker(worker*);
|
||||||
|
void start_worker(uint32_t id);
|
||||||
|
worker* get_worker(uint32_t id);
|
||||||
|
uint32_t get_nof_workers();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool find_finished_worker(uint32_t tti, uint32_t *id);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
IDLE,
|
||||||
|
START_WORK,
|
||||||
|
WORKER_READY,
|
||||||
|
WORKING
|
||||||
|
}worker_status;
|
||||||
|
|
||||||
|
std::vector<worker*> workers;
|
||||||
|
uint32_t nof_workers;
|
||||||
|
uint32_t max_workers;
|
||||||
|
bool running;
|
||||||
|
pthread_cond_t cvar_queue;
|
||||||
|
pthread_mutex_t mutex_queue;
|
||||||
|
std::vector<worker_status> status;
|
||||||
|
std::vector<pthread_cond_t> cvar;
|
||||||
|
std::vector<pthread_mutex_t> mutex;
|
||||||
|
std::stack<worker*> available_workers;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg);
|
||||||
|
bool threads_new_rt_prio(pthread_t *thread, void *(*start_routine) (void*), void *arg, int prio_offset);
|
||||||
|
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu, int prio_offset);
|
||||||
|
bool threads_new_rt_mask(pthread_t *thread, void *(*start_routine) (void*), void *arg, int mask, int prio_offset);
|
||||||
|
void threads_print_self();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef THREADS_
|
||||||
|
#define THREADS_
|
||||||
|
|
||||||
|
class thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool start(int prio = -1) {
|
||||||
|
return threads_new_rt_prio(&_thread, thread_function_entry, this, prio);
|
||||||
|
}
|
||||||
|
bool start_cpu(int prio, int cpu) {
|
||||||
|
return threads_new_rt_cpu(&_thread, thread_function_entry, this, cpu, prio);
|
||||||
|
}
|
||||||
|
bool start_cpu_mask(int prio, int mask){
|
||||||
|
return threads_new_rt_mask(&_thread, thread_function_entry, this, mask, prio);
|
||||||
|
}
|
||||||
|
void print_priority() {
|
||||||
|
threads_print_self();
|
||||||
|
}
|
||||||
|
void wait_thread_finish() {
|
||||||
|
pthread_join(_thread, NULL);
|
||||||
|
}
|
||||||
|
void thread_cancel() {
|
||||||
|
pthread_cancel(_thread);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual void run_thread() = 0;
|
||||||
|
private:
|
||||||
|
static void *thread_function_entry(void *_this) { ((thread*) _this)->run_thread(); return NULL; }
|
||||||
|
pthread_t _thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
class periodic_thread : public thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void start_periodic(int period_us_, int priority = -1) {
|
||||||
|
period_us = period_us_;
|
||||||
|
start(priority);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
virtual void run_period() = 0;
|
||||||
|
private:
|
||||||
|
int wakeups_missed;
|
||||||
|
int timer_fd;
|
||||||
|
int period_us;
|
||||||
|
void run_thread() {
|
||||||
|
if (make_periodic()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(1) {
|
||||||
|
run_period();
|
||||||
|
wait_period();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int make_periodic() {
|
||||||
|
int ret = -1;
|
||||||
|
unsigned int ns;
|
||||||
|
unsigned int sec;
|
||||||
|
struct itimerspec itval;
|
||||||
|
|
||||||
|
/* Create the timer */
|
||||||
|
ret = timerfd_create (CLOCK_MONOTONIC, 0);
|
||||||
|
wakeups_missed = 0;
|
||||||
|
timer_fd = ret;
|
||||||
|
if (ret > 0) {
|
||||||
|
/* Make the timer periodic */
|
||||||
|
sec = period_us/1e6;
|
||||||
|
ns = (period_us - (sec * 1000000)) * 1000;
|
||||||
|
itval.it_interval.tv_sec = sec;
|
||||||
|
itval.it_interval.tv_nsec = ns;
|
||||||
|
itval.it_value.tv_sec = sec;
|
||||||
|
itval.it_value.tv_nsec = ns;
|
||||||
|
ret = timerfd_settime (timer_fd, 0, &itval, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("timerfd_settime");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
perror("timerfd_create");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void wait_period() {
|
||||||
|
unsigned long long missed;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Wait for the next timer event. If we have missed any the
|
||||||
|
number is written to "missed" */
|
||||||
|
ret = read (timer_fd, &missed, sizeof (missed));
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
perror ("read timer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "missed" should always be >= 1, but just to be sure, check it is not 0 anyway */
|
||||||
|
if (missed > 0) {
|
||||||
|
wakeups_missed += (missed - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // THREADS_
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: timeout.h
|
||||||
|
* Description: Millisecond resolution timeouts. Uses a dedicated thread to
|
||||||
|
* call an optional callback function upon timeout expiry.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TIMEOUT_H
|
||||||
|
#define TIMEOUT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class timeout_callback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void timeout_expired(uint32_t timeout_id) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class timeout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
timeout():running(false),callback(NULL), thread(0), timeout_id(0) {}
|
||||||
|
~timeout()
|
||||||
|
{
|
||||||
|
if(running && callback)
|
||||||
|
pthread_join(thread, NULL);
|
||||||
|
}
|
||||||
|
void start(int duration_msec_, uint32_t timeout_id_=0,timeout_callback *callback_=NULL)
|
||||||
|
{
|
||||||
|
if(duration_msec_ < 0)
|
||||||
|
return;
|
||||||
|
reset();
|
||||||
|
gettimeofday(&start_time[1], NULL);
|
||||||
|
duration_msec = duration_msec_;
|
||||||
|
running = true;
|
||||||
|
timeout_id = timeout_id_;
|
||||||
|
callback = callback_;
|
||||||
|
if(callback)
|
||||||
|
pthread_create(&thread, NULL, &thread_start, this);
|
||||||
|
}
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
if(callback)
|
||||||
|
pthread_cancel(thread);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
static void* thread_start(void *t_)
|
||||||
|
{
|
||||||
|
timeout *t = (timeout*)t_;
|
||||||
|
t->thread_func();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void thread_func()
|
||||||
|
{
|
||||||
|
|
||||||
|
// substract time elapsed until now from timer duration
|
||||||
|
gettimeofday(&start_time[2], NULL);
|
||||||
|
get_time_interval(start_time);
|
||||||
|
|
||||||
|
int32_t usec = duration_msec*1000-start_time[0].tv_usec;
|
||||||
|
if(usec > 0)
|
||||||
|
usleep(usec);
|
||||||
|
if(callback && running)
|
||||||
|
callback->timeout_expired(timeout_id);
|
||||||
|
}
|
||||||
|
bool expired()
|
||||||
|
{
|
||||||
|
if(running) {
|
||||||
|
gettimeofday(&start_time[2], NULL);
|
||||||
|
get_time_interval(start_time);
|
||||||
|
return start_time[0].tv_usec > duration_msec*1000;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool is_running()
|
||||||
|
{
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct timeval start_time[3];
|
||||||
|
pthread_t thread;
|
||||||
|
uint32_t timeout_id;
|
||||||
|
timeout_callback *callback;
|
||||||
|
bool running;
|
||||||
|
int duration_msec;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // TIMEOUT_H
|
@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: timers.h
|
||||||
|
* Description: Manually incremented timers. Call a callback function upon
|
||||||
|
* expiry.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TIMERS_H
|
||||||
|
#define TIMERS_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class timer_callback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void timer_expired(uint32_t timer_id) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class timers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
timer(uint32_t id_=0) {id = id_; counter = 0; timeout = 0; running = false; callback = NULL; }
|
||||||
|
void set(timer_callback *callback_, uint32_t timeout_) {
|
||||||
|
callback = callback_;
|
||||||
|
timeout = timeout_;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
bool is_running() {
|
||||||
|
return (counter < timeout) && running;
|
||||||
|
}
|
||||||
|
bool is_expired() {
|
||||||
|
return callback && (counter >= timeout || !running);
|
||||||
|
}
|
||||||
|
uint32_t get_timeout() {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
void reset() {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
void step() {
|
||||||
|
if (running) {
|
||||||
|
counter++;
|
||||||
|
if (is_expired()) {
|
||||||
|
running = false;
|
||||||
|
if (callback) {
|
||||||
|
callback->timer_expired(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void stop() {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
void run() {
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
uint32_t id;
|
||||||
|
private:
|
||||||
|
timer_callback *callback;
|
||||||
|
uint32_t timeout;
|
||||||
|
uint32_t counter;
|
||||||
|
bool running;
|
||||||
|
};
|
||||||
|
|
||||||
|
timers(uint32_t nof_timers_) : timer_list(nof_timers_) {
|
||||||
|
nof_timers = nof_timers_;
|
||||||
|
next_timer = 0;
|
||||||
|
for (uint32_t i=0;i<nof_timers;i++) {
|
||||||
|
timer_list[i].id = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void step_all() {
|
||||||
|
for (int i=0;i<nof_timers;i++) {
|
||||||
|
get(i)->step();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void stop_all() {
|
||||||
|
for (int i=0;i<nof_timers;i++) {
|
||||||
|
get(i)->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void run_all() {
|
||||||
|
for (int i=0;i<nof_timers;i++) {
|
||||||
|
get(i)->run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reset_all() {
|
||||||
|
for (int i=0;i<nof_timers;i++) {
|
||||||
|
get(i)->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timer *get(uint32_t i) {
|
||||||
|
if (i < nof_timers) {
|
||||||
|
return &timer_list[i];
|
||||||
|
} else {
|
||||||
|
printf("Error accessing invalid timer %d (Only %d timers available)\n", i, nof_timers);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t get_unique_id() {
|
||||||
|
if (next_timer == nof_timers){
|
||||||
|
printf("No more unique timer ids (Only %d timers available)\n", nof_timers);
|
||||||
|
next_timer = 0;
|
||||||
|
}
|
||||||
|
return next_timer++;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint32_t nof_timers;
|
||||||
|
uint32_t next_timer;
|
||||||
|
std::vector<timer> timer_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // TIMERS_H
|
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: trace.h
|
||||||
|
* Description:
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TRACE_H
|
||||||
|
#define TRACE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
template<class elemType>
|
||||||
|
class trace
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
trace(uint32_t nof_elems_) : tti(nof_elems_), data(nof_elems_) {
|
||||||
|
rpm=0;
|
||||||
|
nof_elems=nof_elems_;
|
||||||
|
wrapped = false;
|
||||||
|
};
|
||||||
|
void push_cur_time_us(uint32_t cur_tti) {
|
||||||
|
struct timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
elemType us = t.tv_sec*1e6+t.tv_usec;
|
||||||
|
push(cur_tti, us);
|
||||||
|
}
|
||||||
|
void push(uint32_t value_tti, elemType value) {
|
||||||
|
tti[rpm] = value_tti;
|
||||||
|
data[rpm] = value;
|
||||||
|
rpm++;
|
||||||
|
if (rpm >= nof_elems) {
|
||||||
|
rpm = 0;
|
||||||
|
wrapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool writeToBinary(std::string filename) {
|
||||||
|
FILE *f = fopen(filename.c_str(), "w");
|
||||||
|
if (f != NULL) {
|
||||||
|
uint32_t st=wrapped?(rpm+1):0;
|
||||||
|
do {
|
||||||
|
writeToBinaryValue(f, st++);
|
||||||
|
if (st >= nof_elems) {
|
||||||
|
st=0;
|
||||||
|
}
|
||||||
|
} while(st!=rpm);
|
||||||
|
fclose(f);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
perror("fopen");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint32_t> tti;
|
||||||
|
std::vector<elemType> data;
|
||||||
|
uint32_t rpm;
|
||||||
|
uint32_t nof_elems;
|
||||||
|
bool wrapped;
|
||||||
|
|
||||||
|
void writeToBinaryValue(FILE *f, uint32_t idx) {
|
||||||
|
fwrite(&tti[idx], 1, sizeof(uint32_t), f);
|
||||||
|
fwrite(&data[idx], 1, sizeof(elemType), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srslte
|
||||||
|
|
||||||
|
#endif // TRACE_H
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: tti_synch.h
|
||||||
|
* Description: Interface used for PHY-MAC synchronization
|
||||||
|
* (producer-consumer model). The consumer waits while its
|
||||||
|
* counter is lower than the producer counter.
|
||||||
|
* The PHY is the consumer. The MAC is the producer.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TTISYNC_H
|
||||||
|
#define TTISYNC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class tti_sync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tti_sync(uint32_t modulus_)
|
||||||
|
{
|
||||||
|
modulus = modulus_;
|
||||||
|
increment = 1;
|
||||||
|
init_counters(0);
|
||||||
|
}
|
||||||
|
virtual void increase() = 0;
|
||||||
|
virtual void resync() = 0;
|
||||||
|
virtual uint32_t wait() = 0;
|
||||||
|
virtual void set_producer_cntr(uint32_t) = 0;
|
||||||
|
uint32_t get_producer_cntr() { return producer_cntr; }
|
||||||
|
uint32_t get_consumer_cntr() { return consumer_cntr; }
|
||||||
|
void set_increment(uint32_t increment_) {
|
||||||
|
increment = increment_;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void increase_producer() { producer_cntr = (producer_cntr + increment)%modulus; }
|
||||||
|
void increase_consumer() { consumer_cntr = (consumer_cntr + increment)%modulus; }
|
||||||
|
bool wait_condition() { return producer_cntr == consumer_cntr; }
|
||||||
|
void init_counters(uint32_t val)
|
||||||
|
{
|
||||||
|
consumer_cntr = val;
|
||||||
|
producer_cntr = val;
|
||||||
|
}
|
||||||
|
uint32_t increment;
|
||||||
|
uint32_t modulus;
|
||||||
|
uint32_t producer_cntr;
|
||||||
|
uint32_t consumer_cntr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // TTISYNC_H
|
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* File: tti_synch_cv.h
|
||||||
|
* Description: Implements tti_sync interface with condition variables.
|
||||||
|
* Reference:
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TTISYNC_CV_H
|
||||||
|
#define TTISYNC_CV_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "common/tti_sync.h"
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
class tti_sync_cv : public tti_sync
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tti_sync_cv(uint32_t modulus = 10240);
|
||||||
|
~tti_sync_cv();
|
||||||
|
void increase();
|
||||||
|
uint32_t wait();
|
||||||
|
void resync();
|
||||||
|
void set_producer_cntr(uint32_t producer_cntr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_cond_t cond;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsue
|
||||||
|
|
||||||
|
#endif // TTISYNC_CV_H
|
@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
#
|
||||||
|
# This file is part of the srsLTE library.
|
||||||
|
#
|
||||||
|
# srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# srsLTE is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# A copy of the GNU Affero General Public License can be found in
|
||||||
|
# the LICENSE file in the top-level directory of this distribution
|
||||||
|
# and at http://www.gnu.org/licenses/.
|
||||||
|
#
|
||||||
|
|
||||||
|
file(GLOB CXX_SOURCES "*.cc")
|
||||||
|
file(GLOB C_SOURCES "*.c")
|
||||||
|
add_library(srslte_common SHARED ${C_SOURCES} ${CXX_SOURCES})
|
||||||
|
INSTALL(TARGETS srslte_common DESTINATION ${LIBRARY_DIR})
|
||||||
|
SRSLTE_SET_PIC(srslte_common)
|
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "common/buffer_pool.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace srslte{
|
||||||
|
|
||||||
|
byte_buffer_pool *byte_buffer_pool::instance = NULL;
|
||||||
|
pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
byte_buffer_pool* byte_buffer_pool::get_instance(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&instance_mutex);
|
||||||
|
if(NULL == instance)
|
||||||
|
instance = new byte_buffer_pool();
|
||||||
|
pthread_mutex_unlock(&instance_mutex);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_buffer_pool::cleanup(void)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&instance_mutex);
|
||||||
|
if(NULL != instance)
|
||||||
|
{
|
||||||
|
delete instance;
|
||||||
|
instance = NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&instance_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace srsue
|
@ -0,0 +1,316 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "common/log_filter.h"
|
||||||
|
|
||||||
|
namespace srslte{
|
||||||
|
|
||||||
|
log_filter::log_filter()
|
||||||
|
{
|
||||||
|
do_tti = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_filter::log_filter(std::string layer, logger *logger_, bool tti)
|
||||||
|
{
|
||||||
|
init(layer, logger_, tti);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::init(std::string layer, logger *logger_, bool tti)
|
||||||
|
{
|
||||||
|
service_name = layer;
|
||||||
|
logger_h = logger_;
|
||||||
|
do_tti = tti;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
if(logger_h) {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
if(do_tti)
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
ss << msg;
|
||||||
|
|
||||||
|
str_ptr s_ptr(new std::string(ss.str()));
|
||||||
|
logger_h->log(s_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
char *msg,
|
||||||
|
uint8_t *hex,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
if(logger_h) {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
if(do_tti)
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
|
||||||
|
ss << msg;
|
||||||
|
|
||||||
|
if (msg[strlen(msg)-1] != '\n') {
|
||||||
|
ss << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hex_limit > 0) {
|
||||||
|
ss << hex_string(hex, size);
|
||||||
|
}
|
||||||
|
str_ptr s_ptr(new std::string(ss.str()));
|
||||||
|
logger_h->log(s_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::all_log_line(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
std::string file,
|
||||||
|
int line,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
if(logger_h) {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
if(do_tti)
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
ss << msg;
|
||||||
|
|
||||||
|
str_ptr s_ptr(new std::string(ss.str()));
|
||||||
|
logger_h->log(s_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::console(std::string message, ...) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
printf("%s",args_msg); // Print directly to stdout
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::error(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_ERROR, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::warning(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_WARNING, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::info(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_INFO, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::debug(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_DEBUG, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::error_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_ERROR, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::warning_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_WARNING, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::info_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_INFO, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_filter::debug_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log(LOG_LEVEL_DEBUG, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::error_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log_line(LOG_LEVEL_ERROR, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::warning_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log_line(LOG_LEVEL_WARNING, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::info_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log_line(LOG_LEVEL_INFO, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_filter::debug_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0)
|
||||||
|
all_log_line(LOG_LEVEL_DEBUG, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string log_filter::now_time()
|
||||||
|
{
|
||||||
|
struct timeval rawtime;
|
||||||
|
struct tm * timeinfo;
|
||||||
|
char buffer[64];
|
||||||
|
char us[16];
|
||||||
|
|
||||||
|
gettimeofday(&rawtime, NULL);
|
||||||
|
timeinfo = localtime(&rawtime.tv_sec);
|
||||||
|
|
||||||
|
strftime(buffer,64,"%H:%M:%S",timeinfo);
|
||||||
|
strcat(buffer,".");
|
||||||
|
snprintf(us,16,"%06ld",rawtime.tv_usec);
|
||||||
|
strcat(buffer,us);
|
||||||
|
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string log_filter::hex_string(uint8_t *hex, int size)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
ss << std::hex << std::setfill('0');
|
||||||
|
if(hex_limit >= 0) {
|
||||||
|
size = (size > hex_limit) ? hex_limit : size;
|
||||||
|
}
|
||||||
|
while(c < size) {
|
||||||
|
ss << " " << std::setw(4) << static_cast<unsigned>(c) << ": ";
|
||||||
|
int tmp = (size-c < 16) ? size-c : 16;
|
||||||
|
for(int i=0;i<tmp;i++) {
|
||||||
|
ss << std::setw(2) << static_cast<unsigned>(hex[c++]) << " ";
|
||||||
|
}
|
||||||
|
ss << "\n";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsue
|
@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "common/log_stdout.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
void log_stdout::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
ss << msg;
|
||||||
|
|
||||||
|
cout << ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::all_log(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
char *msg,
|
||||||
|
uint8_t *hex,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
ss << msg << std::endl;
|
||||||
|
ss << hex_string(hex, size);
|
||||||
|
|
||||||
|
cout << ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::all_log_line(srslte::LOG_LEVEL_ENUM level,
|
||||||
|
uint32_t tti,
|
||||||
|
std::string file,
|
||||||
|
int line,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << now_time() << " ";
|
||||||
|
ss << "[" <<get_service_name() << "] ";
|
||||||
|
ss << log_level_text[level] << " ";
|
||||||
|
ss << "[" << std::setfill('0') << std::setw(5) << tti << "] ";
|
||||||
|
ss << msg;
|
||||||
|
|
||||||
|
cout << ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::console(std::string message, ...) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
printf("%s",args_msg); // Print directly to stdout
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::error(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_ERROR, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::warning(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_WARNING, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::info(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_INFO, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::debug(std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_DEBUG, tti, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::error_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_ERROR, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::warning_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_WARNING, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::info_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_INFO, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void log_stdout::debug_hex(uint8_t *hex, int size, std::string message, ...) {
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log(LOG_LEVEL_DEBUG, tti, args_msg, hex, size);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::error_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_ERROR) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log_line(LOG_LEVEL_ERROR, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::warning_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_WARNING) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log_line(LOG_LEVEL_WARNING, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::info_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_INFO) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log_line(LOG_LEVEL_INFO, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_stdout::debug_line(std::string file, int line, std::string message, ...)
|
||||||
|
{
|
||||||
|
if (level >= LOG_LEVEL_DEBUG) {
|
||||||
|
char *args_msg;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, message);
|
||||||
|
if(vasprintf(&args_msg, message.c_str(), args) > 0);
|
||||||
|
all_log_line(LOG_LEVEL_DEBUG, tti, file, line, args_msg);
|
||||||
|
va_end(args);
|
||||||
|
free(args_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string log_stdout::now_time()
|
||||||
|
{
|
||||||
|
struct timeval rawtime;
|
||||||
|
struct tm * timeinfo;
|
||||||
|
char buffer[64];
|
||||||
|
char us[16];
|
||||||
|
|
||||||
|
gettimeofday(&rawtime, NULL);
|
||||||
|
timeinfo = localtime(&rawtime.tv_sec);
|
||||||
|
|
||||||
|
strftime(buffer,64,"%H:%M:%S",timeinfo);
|
||||||
|
strcat(buffer,".");
|
||||||
|
snprintf(us,16,"%ld",rawtime.tv_usec);
|
||||||
|
strcat(buffer,us);
|
||||||
|
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string log_stdout::hex_string(uint8_t *hex, int size)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
ss << std::hex << std::setfill('0');
|
||||||
|
if(hex_limit >= 0) {
|
||||||
|
size = (size > hex_limit) ? hex_limit : size;
|
||||||
|
}
|
||||||
|
while(c < size) {
|
||||||
|
ss << " " << std::setw(4) << static_cast<unsigned>(c) << ": ";
|
||||||
|
int tmp = (size-c < 16) ? size-c : 16;
|
||||||
|
for(int i=0;i<tmp;i++) {
|
||||||
|
ss << std::setw(2) << static_cast<unsigned>(hex[c++]) << " ";
|
||||||
|
}
|
||||||
|
ss << "\n";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG_BUFFER_SIZE 1024*32
|
||||||
|
|
||||||
|
#include "common/logger.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace srslte{
|
||||||
|
|
||||||
|
logger::logger()
|
||||||
|
:inited(false)
|
||||||
|
,not_done(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
logger::~logger() {
|
||||||
|
not_done = false;
|
||||||
|
log("Closing log");
|
||||||
|
if(inited) {
|
||||||
|
wait_thread_finish();
|
||||||
|
flush();
|
||||||
|
fclose(logfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void logger::init(std::string file) {
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
pthread_cond_init(¬_empty, NULL);
|
||||||
|
pthread_cond_init(¬_full, NULL);
|
||||||
|
filename = file;
|
||||||
|
logfile = fopen(filename.c_str(), "w");
|
||||||
|
if(logfile==NULL) {
|
||||||
|
printf("Error: could not create log file, no messages will be logged");
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void logger::log(const char *msg) {
|
||||||
|
str_ptr s_ptr(new std::string(msg));
|
||||||
|
log(s_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logger::log(str_ptr msg) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
buffer.push_back(msg);
|
||||||
|
pthread_cond_signal(¬_empty);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logger::run_thread() {
|
||||||
|
while(not_done) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(buffer.empty()) {
|
||||||
|
pthread_cond_wait(¬_empty, &mutex);
|
||||||
|
}
|
||||||
|
str_ptr s = buffer.front();
|
||||||
|
pthread_cond_signal(¬_full);
|
||||||
|
if(logfile)
|
||||||
|
fprintf(logfile, "%s", s->c_str());
|
||||||
|
delete s;
|
||||||
|
buffer.pop_front();
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void logger::flush() {
|
||||||
|
std::deque<str_ptr>::iterator it;
|
||||||
|
for(it=buffer.begin();it!=buffer.end();it++)
|
||||||
|
{
|
||||||
|
str_ptr s = *it;
|
||||||
|
if(logfile)
|
||||||
|
fprintf(logfile, "%s", s->c_str());
|
||||||
|
delete s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsue
|
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
#include "common/pcap.h"
|
||||||
|
#include "common/mac_pcap.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
void mac_pcap::enable(bool en)
|
||||||
|
{
|
||||||
|
enable_write = true;
|
||||||
|
}
|
||||||
|
void mac_pcap::open(const char* filename, uint32_t ue_id)
|
||||||
|
{
|
||||||
|
pcap_file = MAC_LTE_PCAP_Open(filename);
|
||||||
|
ue_id = ue_id;
|
||||||
|
enable_write = true;
|
||||||
|
}
|
||||||
|
void mac_pcap::close()
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Saving PCAP file\n");
|
||||||
|
MAC_LTE_PCAP_Close(pcap_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_pcap::pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reTX, bool crc_ok, uint32_t tti,
|
||||||
|
uint16_t crnti, uint8_t direction, uint8_t rnti_type)
|
||||||
|
{
|
||||||
|
if (enable_write) {
|
||||||
|
MAC_Context_Info_t context =
|
||||||
|
{
|
||||||
|
FDD_RADIO, direction, rnti_type,
|
||||||
|
crnti, /* RNTI */
|
||||||
|
ue_id, /* UEId */
|
||||||
|
reTX, /* Retx */
|
||||||
|
crc_ok, /* CRC Stsatus (i.e. OK) */
|
||||||
|
tti/10, /* Sysframe number */
|
||||||
|
tti%10 /* Subframe number */
|
||||||
|
};
|
||||||
|
if (pdu) {
|
||||||
|
MAC_LTE_PCAP_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mac_pcap::write_dl_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, bool crc_ok, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, rnti, DIRECTION_DOWNLINK, C_RNTI);
|
||||||
|
}
|
||||||
|
void mac_pcap::write_dl_ranti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, bool crc_ok, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, rnti, DIRECTION_DOWNLINK, RA_RNTI);
|
||||||
|
}
|
||||||
|
void mac_pcap::write_ul_crnti(uint8_t* pdu, uint32_t pdu_len_bytes, uint16_t rnti, uint32_t reTX, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, reTX, true, tti, rnti, DIRECTION_UPLINK, C_RNTI);
|
||||||
|
}
|
||||||
|
void mac_pcap::write_dl_bch(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, 0, DIRECTION_DOWNLINK, NO_RNTI);
|
||||||
|
}
|
||||||
|
void mac_pcap::write_dl_pch(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, SRSLTE_PRNTI, DIRECTION_DOWNLINK, P_RNTI);
|
||||||
|
}
|
||||||
|
void mac_pcap::write_dl_sirnti(uint8_t* pdu, uint32_t pdu_len_bytes, bool crc_ok, uint32_t tti)
|
||||||
|
{
|
||||||
|
pack_and_write(pdu, pdu_len_bytes, 0, crc_ok, tti, SRSLTE_SIRNTI, DIRECTION_DOWNLINK, SI_RNTI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define Error(fmt, ...) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
#define Warning(fmt, ...) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
#define Info(fmt, ...) log_h->info_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
#define Debug(fmt, ...) log_h->debug_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#include "common/pdu_queue.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
|
||||||
|
void pdu_queue::init(process_callback *callback_, log* log_h_)
|
||||||
|
{
|
||||||
|
callback = callback_;
|
||||||
|
log_h = log_h_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* pdu_queue::request(uint32_t len)
|
||||||
|
{
|
||||||
|
if (len > MAX_PDU_LEN) {
|
||||||
|
fprintf(stderr, "Error request buffer of invalid size %d. Max bytes %d\n", len, MAX_PDU_LEN);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pdu_t *pdu = pool.allocate();
|
||||||
|
if (!pdu) {
|
||||||
|
if (log_h) {
|
||||||
|
log_h->error("Not enough buffers for MAC PDU\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Not enough buffers for MAC PDU\n");
|
||||||
|
}
|
||||||
|
if ((void*) pdu->ptr != (void*) pdu) {
|
||||||
|
fprintf(stderr, "Fatal error in memory alignment in struct pdu_queue::pdu_t\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdu->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pdu_queue::deallocate(uint8_t* pdu)
|
||||||
|
{
|
||||||
|
if (!pool.deallocate((pdu_t*) pdu)) {
|
||||||
|
log_h->warning("Error deallocating from buffer pool: buffer not created in this pool.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Demultiplexing of logical channels and dissassemble of MAC CE
|
||||||
|
* This function enqueues the packet and returns quicly because ACK
|
||||||
|
* deadline is important here.
|
||||||
|
*/
|
||||||
|
void pdu_queue::push(uint8_t *ptr, uint32_t len)
|
||||||
|
{
|
||||||
|
pdu_t *pdu = (pdu_t*) ptr;
|
||||||
|
pdu->len = len;
|
||||||
|
pdu_q.push(pdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pdu_queue::process_pdus()
|
||||||
|
{
|
||||||
|
bool have_data = false;
|
||||||
|
uint32_t cnt = 0;
|
||||||
|
pdu_t *pdu;
|
||||||
|
while(pdu_q.try_pop(&pdu)) {
|
||||||
|
if (callback) {
|
||||||
|
callback->process_pdu(pdu->ptr, pdu->len);
|
||||||
|
}
|
||||||
|
if (!pool.deallocate(pdu)) {
|
||||||
|
log_h->warning("Error deallocating from buffer pool: buffer not created in this pool.\n");
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
have_data = true;
|
||||||
|
}
|
||||||
|
if (cnt > 20) {
|
||||||
|
if (log_h) {
|
||||||
|
log_h->warning("PDU queue dispatched %d packets\n", cnt);
|
||||||
|
}
|
||||||
|
printf("Warning PDU queue dispatched %d packets\n", cnt);
|
||||||
|
}
|
||||||
|
return have_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common/security.h"
|
||||||
|
#include "liblte_security.h"
|
||||||
|
#include "common/snow_3g.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
namespace srsue{
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Key Generation
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_generate_k_asme( uint8_t *ck,
|
||||||
|
uint8_t *ik,
|
||||||
|
uint8_t *ak,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint16_t mcc,
|
||||||
|
uint16_t mnc,
|
||||||
|
uint8_t *k_asme)
|
||||||
|
{
|
||||||
|
return liblte_security_generate_k_asme(ck,
|
||||||
|
ik,
|
||||||
|
ak,
|
||||||
|
sqn,
|
||||||
|
mcc,
|
||||||
|
mnc,
|
||||||
|
k_asme);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_generate_k_enb( uint8_t *k_asme,
|
||||||
|
uint32_t nas_count,
|
||||||
|
uint8_t *k_enb)
|
||||||
|
{
|
||||||
|
return liblte_security_generate_k_enb(k_asme,
|
||||||
|
nas_count,
|
||||||
|
k_enb);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_generate_k_nas( uint8_t *k_asme,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_nas_enc,
|
||||||
|
uint8_t *k_nas_int)
|
||||||
|
{
|
||||||
|
return liblte_security_generate_k_nas( k_asme,
|
||||||
|
(LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM)enc_alg_id,
|
||||||
|
(LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM)int_alg_id,
|
||||||
|
k_nas_enc,
|
||||||
|
k_nas_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_generate_k_rrc( uint8_t *k_enb,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_rrc_enc,
|
||||||
|
uint8_t *k_rrc_int)
|
||||||
|
{
|
||||||
|
return liblte_security_generate_k_rrc(k_enb,
|
||||||
|
(LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM)enc_alg_id,
|
||||||
|
(LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM)int_alg_id,
|
||||||
|
k_rrc_enc,
|
||||||
|
k_rrc_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_generate_k_up( uint8_t *k_enb,
|
||||||
|
CIPHERING_ALGORITHM_ID_ENUM enc_alg_id,
|
||||||
|
INTEGRITY_ALGORITHM_ID_ENUM int_alg_id,
|
||||||
|
uint8_t *k_up_enc,
|
||||||
|
uint8_t *k_up_int)
|
||||||
|
{
|
||||||
|
return liblte_security_generate_k_up(k_enb,
|
||||||
|
(LIBLTE_SECURITY_CIPHERING_ALGORITHM_ID_ENUM)enc_alg_id,
|
||||||
|
(LIBLTE_SECURITY_INTEGRITY_ALGORITHM_ID_ENUM)int_alg_id,
|
||||||
|
k_up_enc,
|
||||||
|
k_up_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Integrity Protection
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_128_eia1( uint8_t *key,
|
||||||
|
uint32_t count,
|
||||||
|
uint8_t bearer,
|
||||||
|
uint8_t direction,
|
||||||
|
uint8_t *msg,
|
||||||
|
uint32_t msg_len,
|
||||||
|
uint8_t *mac)
|
||||||
|
{
|
||||||
|
uint32_t msg_len_bits;
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *m_ptr;
|
||||||
|
|
||||||
|
msg_len_bits = msg_len*8;
|
||||||
|
m_ptr = snow3g_f9(key,
|
||||||
|
count,
|
||||||
|
bearer,
|
||||||
|
direction,
|
||||||
|
msg,
|
||||||
|
msg_len_bits);
|
||||||
|
for(i=0; i<4; i++) {
|
||||||
|
mac[i] = m_ptr[i];
|
||||||
|
}
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_128_eia2( uint8_t *key,
|
||||||
|
uint32_t count,
|
||||||
|
uint8_t bearer,
|
||||||
|
uint8_t direction,
|
||||||
|
uint8_t *msg,
|
||||||
|
uint32_t msg_len,
|
||||||
|
uint8_t *mac)
|
||||||
|
{
|
||||||
|
return liblte_security_128_eia2(key,
|
||||||
|
count,
|
||||||
|
bearer,
|
||||||
|
direction,
|
||||||
|
msg,
|
||||||
|
msg_len,
|
||||||
|
mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Authentication
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t security_milenage_f1( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint8_t *amf,
|
||||||
|
uint8_t *mac_a)
|
||||||
|
{
|
||||||
|
return liblte_security_milenage_f1(k,
|
||||||
|
op,
|
||||||
|
rand,
|
||||||
|
sqn,
|
||||||
|
amf,
|
||||||
|
mac_a);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_milenage_f1_star( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *sqn,
|
||||||
|
uint8_t *amf,
|
||||||
|
uint8_t *mac_s)
|
||||||
|
{
|
||||||
|
return liblte_security_milenage_f1_star(k,
|
||||||
|
op,
|
||||||
|
rand,
|
||||||
|
sqn,
|
||||||
|
amf,
|
||||||
|
mac_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_milenage_f2345( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *res,
|
||||||
|
uint8_t *ck,
|
||||||
|
uint8_t *ik,
|
||||||
|
uint8_t *ak)
|
||||||
|
{
|
||||||
|
return liblte_security_milenage_f2345(k,
|
||||||
|
op,
|
||||||
|
rand,
|
||||||
|
res,
|
||||||
|
ck,
|
||||||
|
ik,
|
||||||
|
ak);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t security_milenage_f5_star( uint8_t *k,
|
||||||
|
uint8_t *op,
|
||||||
|
uint8_t *rand,
|
||||||
|
uint8_t *ak)
|
||||||
|
{
|
||||||
|
return liblte_security_milenage_f5_star(k,
|
||||||
|
op,
|
||||||
|
rand,
|
||||||
|
ak);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace srsue
|
@ -0,0 +1,577 @@
|
|||||||
|
/*------------------------------------------------------------------------
|
||||||
|
* snow_3g.c
|
||||||
|
*
|
||||||
|
* Adapted from ETSI/SAGE specifications:
|
||||||
|
* "Specification of the 3GPP Confidentiality and
|
||||||
|
* Integrity Algorithms UEA2 & UIA2.
|
||||||
|
* Document 1: UEA2 and UIA2 Specification"
|
||||||
|
* "Specification of the 3GPP Confidentiality
|
||||||
|
* and Integrity Algorithms UEA2 & UIA2.
|
||||||
|
* Document 2: SNOW 3G Specification"
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "common/snow_3g.h"
|
||||||
|
|
||||||
|
/* LFSR */
|
||||||
|
|
||||||
|
u32 LFSR_S0 = 0x00;
|
||||||
|
u32 LFSR_S1 = 0x00;
|
||||||
|
u32 LFSR_S2 = 0x00;
|
||||||
|
u32 LFSR_S3 = 0x00;
|
||||||
|
u32 LFSR_S4 = 0x00;
|
||||||
|
u32 LFSR_S5 = 0x00;
|
||||||
|
u32 LFSR_S6 = 0x00;
|
||||||
|
u32 LFSR_S7 = 0x00;
|
||||||
|
u32 LFSR_S8 = 0x00;
|
||||||
|
u32 LFSR_S9 = 0x00;
|
||||||
|
u32 LFSR_S10 = 0x00;
|
||||||
|
u32 LFSR_S11 = 0x00;
|
||||||
|
u32 LFSR_S12 = 0x00;
|
||||||
|
u32 LFSR_S13 = 0x00;
|
||||||
|
u32 LFSR_S14 = 0x00;
|
||||||
|
u32 LFSR_S15 = 0x00;
|
||||||
|
|
||||||
|
/* FSM */
|
||||||
|
|
||||||
|
u32 FSM_R1 = 0x00;
|
||||||
|
u32 FSM_R2 = 0x00;
|
||||||
|
u32 FSM_R3 = 0x00;
|
||||||
|
|
||||||
|
/* Rijndael S-box SR */
|
||||||
|
|
||||||
|
u8 SR[256] = {
|
||||||
|
0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
|
||||||
|
0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
|
||||||
|
0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
|
||||||
|
0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
|
||||||
|
0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
|
||||||
|
0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
|
||||||
|
0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
|
||||||
|
0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
|
||||||
|
0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
|
||||||
|
0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
|
||||||
|
0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
|
||||||
|
0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
|
||||||
|
0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
|
||||||
|
0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
|
||||||
|
0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
|
||||||
|
0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16
|
||||||
|
};
|
||||||
|
|
||||||
|
/* S-box SQ */
|
||||||
|
|
||||||
|
u8 SQ[256] = {
|
||||||
|
0x25,0x24,0x73,0x67,0xD7,0xAE,0x5C,0x30,0xA4,0xEE,0x6E,0xCB,0x7D,0xB5,0x82,0xDB,
|
||||||
|
0xE4,0x8E,0x48,0x49,0x4F,0x5D,0x6A,0x78,0x70,0x88,0xE8,0x5F,0x5E,0x84,0x65,0xE2,
|
||||||
|
0xD8,0xE9,0xCC,0xED,0x40,0x2F,0x11,0x28,0x57,0xD2,0xAC,0xE3,0x4A,0x15,0x1B,0xB9,
|
||||||
|
0xB2,0x80,0x85,0xA6,0x2E,0x02,0x47,0x29,0x07,0x4B,0x0E,0xC1,0x51,0xAA,0x89,0xD4,
|
||||||
|
0xCA,0x01,0x46,0xB3,0xEF,0xDD,0x44,0x7B,0xC2,0x7F,0xBE,0xC3,0x9F,0x20,0x4C,0x64,
|
||||||
|
0x83,0xA2,0x68,0x42,0x13,0xB4,0x41,0xCD,0xBA,0xC6,0xBB,0x6D,0x4D,0x71,0x21,0xF4,
|
||||||
|
0x8D,0xB0,0xE5,0x93,0xFE,0x8F,0xE6,0xCF,0x43,0x45,0x31,0x22,0x37,0x36,0x96,0xFA,
|
||||||
|
0xBC,0x0F,0x08,0x52,0x1D,0x55,0x1A,0xC5,0x4E,0x23,0x69,0x7A,0x92,0xFF,0x5B,0x5A,
|
||||||
|
0xEB,0x9A,0x1C,0xA9,0xD1,0x7E,0x0D,0xFC,0x50,0x8A,0xB6,0x62,0xF5,0x0A,0xF8,0xDC,
|
||||||
|
0x03,0x3C,0x0C,0x39,0xF1,0xB8,0xF3,0x3D,0xF2,0xD5,0x97,0x66,0x81,0x32,0xA0,0x00,
|
||||||
|
0x06,0xCE,0xF6,0xEA,0xB7,0x17,0xF7,0x8C,0x79,0xD6,0xA7,0xBF,0x8B,0x3F,0x1F,0x53,
|
||||||
|
0x63,0x75,0x35,0x2C,0x60,0xFD,0x27,0xD3,0x94,0xA5,0x7C,0xA1,0x05,0x58,0x2D,0xBD,
|
||||||
|
0xD9,0xC7,0xAF,0x6B,0x54,0x0B,0xE0,0x38,0x04,0xC8,0x9D,0xE7,0x14,0xB1,0x87,0x9C,
|
||||||
|
0xDF,0x6F,0xF9,0xDA,0x2A,0xC4,0x59,0x16,0x74,0x91,0xAB,0x26,0x61,0x76,0x34,0x2B,
|
||||||
|
0xAD,0x99,0xFB,0x72,0xEC,0x33,0x12,0xDE,0x98,0x3B,0xC0,0x9B,0x3E,0x18,0x10,0x3A,
|
||||||
|
0x56,0xE1,0x77,0xC9,0x1E,0x9E,0x95,0xA3,0x90,0x19,0xA8,0x6C,0x09,0xD0,0xF0,0x86
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MULx.
|
||||||
|
* Input V: an 8-bit input.
|
||||||
|
* Input c: an 8-bit input.
|
||||||
|
* Output : an 8-bit output.
|
||||||
|
* See section 3.1.1 for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u8 MULx(u8 V, u8 c)
|
||||||
|
{
|
||||||
|
if ( V & 0x80 )
|
||||||
|
return ( (V << 1) ^ c);
|
||||||
|
else
|
||||||
|
return ( V << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MULxPOW.
|
||||||
|
* Input V: an 8-bit input.
|
||||||
|
* Input i: a positive integer.
|
||||||
|
* Input c: an 8-bit input.
|
||||||
|
* Output : an 8-bit output.
|
||||||
|
* See section 3.1.2 for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u8 MULxPOW(u8 V, u8 i, u8 c)
|
||||||
|
{
|
||||||
|
if ( i == 0)
|
||||||
|
return V;
|
||||||
|
else
|
||||||
|
return MULx( MULxPOW( V, i-1, c ), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function MUL alpha.
|
||||||
|
* Input c: 8-bit input.
|
||||||
|
* Output : 32-bit output.
|
||||||
|
* See section 3.4.2 for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 MULalpha(u8 c)
|
||||||
|
{
|
||||||
|
return ( ( ((u32)MULxPOW(c, 23, 0xa9)) << 24 ) |
|
||||||
|
( ((u32)MULxPOW(c, 245, 0xa9)) << 16 ) |
|
||||||
|
( ((u32)MULxPOW(c, 48, 0xa9)) << 8 ) |
|
||||||
|
( ((u32)MULxPOW(c, 239, 0xa9)) ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function DIV alpha.
|
||||||
|
* Input c: 8-bit input.
|
||||||
|
* Output : 32-bit output.
|
||||||
|
* See section 3.4.3 for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 DIValpha(u8 c)
|
||||||
|
{
|
||||||
|
return ( ( ((u32)MULxPOW(c, 16, 0xa9)) << 24 ) |
|
||||||
|
( ((u32)MULxPOW(c, 39, 0xa9)) << 16 ) |
|
||||||
|
( ((u32)MULxPOW(c, 6, 0xa9)) << 8 ) |
|
||||||
|
( ((u32)MULxPOW(c, 64, 0xa9)) ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The 32x32-bit S-Box S1
|
||||||
|
* Input: a 32-bit input.
|
||||||
|
* Output: a 32-bit output of S1 box.
|
||||||
|
* See section 3.3.1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 S1(u32 w)
|
||||||
|
{
|
||||||
|
u8 r0=0, r1=0, r2=0, r3=0;
|
||||||
|
u8 srw0 = SR[ (u8)((w >> 24) & 0xff) ];
|
||||||
|
u8 srw1 = SR[ (u8)((w >> 16) & 0xff) ];
|
||||||
|
u8 srw2 = SR[ (u8)((w >> 8) & 0xff) ];
|
||||||
|
u8 srw3 = SR[ (u8)((w) & 0xff) ];
|
||||||
|
r0 = ( ( MULx( srw0 , 0x1b) ) ^
|
||||||
|
( srw1 ) ^
|
||||||
|
( srw2 ) ^
|
||||||
|
( (MULx( srw3, 0x1b)) ^ srw3 )
|
||||||
|
);
|
||||||
|
r1 = ( ( ( MULx( srw0 , 0x1b) ) ^ srw0 ) ^
|
||||||
|
( MULx(srw1, 0x1b) ) ^
|
||||||
|
( srw2 ) ^
|
||||||
|
( srw3 )
|
||||||
|
);
|
||||||
|
r2 = ( ( srw0 ) ^
|
||||||
|
( ( MULx( srw1 , 0x1b) ) ^ srw1 ) ^
|
||||||
|
( MULx(srw2, 0x1b) ) ^
|
||||||
|
( srw3 )
|
||||||
|
);
|
||||||
|
r3 = ( ( srw0 ) ^
|
||||||
|
( srw1 ) ^
|
||||||
|
( ( MULx( srw2 , 0x1b) ) ^ srw2 ) ^
|
||||||
|
( MULx( srw3, 0x1b) )
|
||||||
|
);
|
||||||
|
|
||||||
|
return ( ( ((u32)r0) << 24 ) | ( ((u32)r1) << 16 ) | ( ((u32)r2) << 8 ) |
|
||||||
|
( ((u32)r3) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The 32x32-bit S-Box S2
|
||||||
|
* Input: a 32-bit input.
|
||||||
|
* Output: a 32-bit output of S2 box.
|
||||||
|
* See section 3.3.2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 S2(u32 w)
|
||||||
|
{
|
||||||
|
u8 r0=0, r1=0, r2=0, r3=0;
|
||||||
|
u8 sqw0 = SQ[ (u8)((w >> 24) & 0xff) ];
|
||||||
|
u8 sqw1 = SQ[ (u8)((w >> 16) & 0xff) ];
|
||||||
|
u8 sqw2 = SQ[ (u8)((w >> 8) & 0xff) ];
|
||||||
|
u8 sqw3 = SQ[ (u8)((w) & 0xff) ];
|
||||||
|
r0 = ( ( MULx( sqw0 , 0x69) ) ^
|
||||||
|
( sqw1 ) ^
|
||||||
|
( sqw2 ) ^
|
||||||
|
( (MULx( sqw3, 0x69)) ^ sqw3 )
|
||||||
|
);
|
||||||
|
r1 = ( ( ( MULx( sqw0 , 0x69) ) ^ sqw0 ) ^
|
||||||
|
( MULx(sqw1, 0x69) ) ^
|
||||||
|
( sqw2 ) ^
|
||||||
|
( sqw3 )
|
||||||
|
);
|
||||||
|
r2 = ( ( sqw0 ) ^
|
||||||
|
( ( MULx( sqw1 , 0x69) ) ^ sqw1 ) ^
|
||||||
|
( MULx(sqw2, 0x69) ) ^
|
||||||
|
( sqw3 )
|
||||||
|
);
|
||||||
|
r3 = ( ( sqw0 ) ^
|
||||||
|
( sqw1 ) ^
|
||||||
|
( ( MULx( sqw2 , 0x69) ) ^ sqw2 ) ^
|
||||||
|
( MULx( sqw3, 0x69) )
|
||||||
|
);
|
||||||
|
return ( ( ((u32)r0) << 24 ) | ( ((u32)r1) << 16 ) | ( ((u32)r2) << 8 ) |
|
||||||
|
( ((u32)r3) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clocking LFSR in initialization mode.
|
||||||
|
* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock.
|
||||||
|
* Input F: a 32-bit word comes from output of FSM.
|
||||||
|
* See section 3.4.4.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ClockLFSRInitializationMode(u32 F)
|
||||||
|
{
|
||||||
|
u32 v = ( ( (LFSR_S0 << 8) & 0xffffff00 ) ^
|
||||||
|
( MULalpha( (u8)((LFSR_S0>>24) & 0xff) ) ) ^
|
||||||
|
( LFSR_S2 ) ^
|
||||||
|
( (LFSR_S11 >> 8) & 0x00ffffff ) ^
|
||||||
|
( DIValpha( (u8)( ( LFSR_S11) & 0xff ) ) ) ^
|
||||||
|
( F )
|
||||||
|
);
|
||||||
|
LFSR_S0 = LFSR_S1;
|
||||||
|
LFSR_S1 = LFSR_S2;
|
||||||
|
LFSR_S2 = LFSR_S3;
|
||||||
|
LFSR_S3 = LFSR_S4;
|
||||||
|
LFSR_S4 = LFSR_S5;
|
||||||
|
LFSR_S5 = LFSR_S6;
|
||||||
|
LFSR_S6 = LFSR_S7;
|
||||||
|
LFSR_S7 = LFSR_S8;
|
||||||
|
LFSR_S8 = LFSR_S9;
|
||||||
|
LFSR_S9 = LFSR_S10;
|
||||||
|
LFSR_S10 = LFSR_S11;
|
||||||
|
LFSR_S11 = LFSR_S12;
|
||||||
|
LFSR_S12 = LFSR_S13;
|
||||||
|
LFSR_S13 = LFSR_S14;
|
||||||
|
LFSR_S14 = LFSR_S15;
|
||||||
|
LFSR_S15 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clocking LFSR in keystream mode.
|
||||||
|
* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock.
|
||||||
|
* See section 3.4.5.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ClockLFSRKeyStreamMode()
|
||||||
|
{
|
||||||
|
u32 v = ( ( (LFSR_S0 << 8) & 0xffffff00 ) ^
|
||||||
|
( MULalpha( (u8)((LFSR_S0>>24) & 0xff) ) ) ^
|
||||||
|
( LFSR_S2 ) ^
|
||||||
|
( (LFSR_S11 >> 8) & 0x00ffffff ) ^
|
||||||
|
( DIValpha( (u8)( ( LFSR_S11) & 0xff ) ) )
|
||||||
|
);
|
||||||
|
LFSR_S0 = LFSR_S1;
|
||||||
|
LFSR_S1 = LFSR_S2;
|
||||||
|
LFSR_S2 = LFSR_S3;
|
||||||
|
LFSR_S3 = LFSR_S4;
|
||||||
|
LFSR_S4 = LFSR_S5;
|
||||||
|
LFSR_S5 = LFSR_S6;
|
||||||
|
LFSR_S6 = LFSR_S7;
|
||||||
|
LFSR_S7 = LFSR_S8;
|
||||||
|
LFSR_S8 = LFSR_S9;
|
||||||
|
LFSR_S9 = LFSR_S10;
|
||||||
|
LFSR_S10 = LFSR_S11;
|
||||||
|
LFSR_S11 = LFSR_S12;
|
||||||
|
LFSR_S12 = LFSR_S13;
|
||||||
|
LFSR_S13 = LFSR_S14;
|
||||||
|
LFSR_S14 = LFSR_S15;
|
||||||
|
LFSR_S15 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clocking FSM.
|
||||||
|
* Produces a 32-bit word F.
|
||||||
|
* Updates FSM registers R1, R2, R3.
|
||||||
|
* See Section 3.4.6.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 ClockFSM()
|
||||||
|
{
|
||||||
|
u32 F = ( ( LFSR_S15 + FSM_R1 ) & 0xffffffff ) ^ FSM_R2 ;
|
||||||
|
u32 r = ( FSM_R2 + ( FSM_R3 ^ LFSR_S5 ) ) & 0xffffffff ;
|
||||||
|
FSM_R3 = S2(FSM_R2);
|
||||||
|
FSM_R2 = S1(FSM_R1);
|
||||||
|
FSM_R1 = r;
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialization.
|
||||||
|
* Input k[4]: Four 32-bit words making up 128-bit key.
|
||||||
|
* Input IV[4]: Four 32-bit words making 128-bit initialization variable.
|
||||||
|
* Output: All the LFSRs and FSM are initialized for key generation.
|
||||||
|
* See Section 4.1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_initialize(u32 k[4], u32 IV[4])
|
||||||
|
{
|
||||||
|
u8 i=0;
|
||||||
|
u32 F = 0x0;
|
||||||
|
LFSR_S15 = k[3] ^ IV[0];
|
||||||
|
LFSR_S14 = k[2];
|
||||||
|
LFSR_S13 = k[1];
|
||||||
|
LFSR_S12 = k[0] ^ IV[1];
|
||||||
|
LFSR_S11 = k[3] ^ 0xffffffff;
|
||||||
|
LFSR_S10 = k[2] ^ 0xffffffff ^ IV[2];
|
||||||
|
LFSR_S9 = k[1] ^ 0xffffffff ^ IV[3];
|
||||||
|
LFSR_S8 = k[0] ^ 0xffffffff;
|
||||||
|
LFSR_S7 = k[3];
|
||||||
|
LFSR_S6 = k[2];
|
||||||
|
LFSR_S5 = k[1];
|
||||||
|
LFSR_S4 = k[0];
|
||||||
|
LFSR_S3 = k[3] ^ 0xffffffff;
|
||||||
|
LFSR_S2 = k[2] ^ 0xffffffff;
|
||||||
|
LFSR_S1 = k[1] ^ 0xffffffff;
|
||||||
|
LFSR_S0 = k[0] ^ 0xffffffff;
|
||||||
|
FSM_R1 = 0x0;
|
||||||
|
FSM_R2 = 0x0;
|
||||||
|
FSM_R3 = 0x0;
|
||||||
|
for(i=0;i<32;i++)
|
||||||
|
{
|
||||||
|
F = ClockFSM();
|
||||||
|
ClockLFSRInitializationMode(F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generation of Keystream.
|
||||||
|
* input n: number of 32-bit words of keystream.
|
||||||
|
* input z: space for the generated keystream, assumes
|
||||||
|
* memory is allocated already.
|
||||||
|
* output: generated keystream which is filled in z
|
||||||
|
* See section 4.2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_generate_keystream(u32 n, u32 *ks)
|
||||||
|
{
|
||||||
|
u32 t = 0;
|
||||||
|
u32 F = 0x0;
|
||||||
|
ClockFSM(); /* Clock FSM once. Discard the output. */
|
||||||
|
ClockLFSRKeyStreamMode(); /* Clock LFSR in keystream mode once. */
|
||||||
|
for ( t=0; t<n; t++)
|
||||||
|
{
|
||||||
|
F = ClockFSM(); /* STEP 1 */
|
||||||
|
ks[t] = F ^ LFSR_S0; /* STEP 2 */
|
||||||
|
/* Note that ks[t] corresponds to z_{t+1} in section 4.2
|
||||||
|
*/
|
||||||
|
ClockLFSRKeyStreamMode(); /* STEP 3 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* f8.
|
||||||
|
* Input key: 128 bit Confidentiality Key.
|
||||||
|
* Input count:32-bit Count, Frame dependent input.
|
||||||
|
* Input bearer: 5-bit Bearer identity (in the LSB side).
|
||||||
|
* Input dir:1 bit, direction of transmission.
|
||||||
|
* Input data: length number of bits, input bit stream.
|
||||||
|
* Input length: 32 bit Length, i.e., the number of bits to be encrypted or
|
||||||
|
* decrypted.
|
||||||
|
* Output data: Output bit stream. Assumes data is suitably memory
|
||||||
|
* allocated.
|
||||||
|
* Encrypts/decrypts blocks of data between 1 and 2^32 bits in length as
|
||||||
|
* defined in Section 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void snow3g_f8(u8 *key, u32 count, u32 bearer, u32 dir, u8 *data, u32 length)
|
||||||
|
{
|
||||||
|
u32 K[4],IV[4];
|
||||||
|
int n = ( length + 31 ) / 32;
|
||||||
|
int i=0;
|
||||||
|
int lastbits = (8-(length%8)) % 8;
|
||||||
|
u32 *KS;
|
||||||
|
|
||||||
|
/*Initialisation*/
|
||||||
|
/* Load the confidentiality key for SNOW 3G initialization as in section
|
||||||
|
3.4. */
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
K[3-i] = (key[4*i] << 24) ^ (key[4*i+1] << 16)
|
||||||
|
^ (key[4*i+2] << 8) ^ (key[4*i+3]);
|
||||||
|
|
||||||
|
/* Prepare the initialization vector (IV) for SNOW 3G initialization as in
|
||||||
|
section 3.4. */
|
||||||
|
IV[3] = count;
|
||||||
|
IV[2] = (bearer << 27) | ((dir & 0x1) << 26);
|
||||||
|
IV[1] = IV[3];
|
||||||
|
IV[0] = IV[2];
|
||||||
|
|
||||||
|
/* Run SNOW 3G algorithm to generate sequence of key stream bits KS*/
|
||||||
|
snow3g_initialize(K,IV);
|
||||||
|
KS = (u32 *)malloc(4*n);
|
||||||
|
snow3g_generate_keystream(n,(u32*)KS);
|
||||||
|
|
||||||
|
/* Exclusive-OR the input data with keystream to generate the output bit
|
||||||
|
stream */
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
{
|
||||||
|
data[4*i+0] ^= (u8) (KS[i] >> 24) & 0xff;
|
||||||
|
data[4*i+1] ^= (u8) (KS[i] >> 16) & 0xff;
|
||||||
|
data[4*i+2] ^= (u8) (KS[i] >> 8) & 0xff;
|
||||||
|
data[4*i+3] ^= (u8) (KS[i] ) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(KS);
|
||||||
|
|
||||||
|
/* zero last bits of data in case its length is not byte-aligned
|
||||||
|
this is an addition to the C reference code, which did not handle it */
|
||||||
|
if (lastbits)
|
||||||
|
data[length/8] &= 256 - (1<<lastbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MUL64x.
|
||||||
|
* Input V: a 64-bit input.
|
||||||
|
* Input c: a 64-bit input.
|
||||||
|
* Output : a 64-bit output.
|
||||||
|
* A 64-bit memory is allocated which is to be freed by the calling
|
||||||
|
* function.
|
||||||
|
* See section 4.3.2 for details.
|
||||||
|
*/
|
||||||
|
u64 MUL64x(u64 V, u64 c)
|
||||||
|
{
|
||||||
|
if ( V & 0x8000000000000000 )
|
||||||
|
return (V << 1) ^ c;
|
||||||
|
else
|
||||||
|
return V << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MUL64xPOW.
|
||||||
|
* Input V: a 64-bit input.
|
||||||
|
* Input i: a positive integer.
|
||||||
|
* Input c: a 64-bit input.
|
||||||
|
* Output : a 64-bit output.
|
||||||
|
* A 64-bit memory is allocated which is to be freed by the calling function.
|
||||||
|
* See section 4.3.3 for details.
|
||||||
|
*/
|
||||||
|
u64 MUL64xPOW(u64 V, u8 i, u64 c)
|
||||||
|
{
|
||||||
|
if ( i == 0)
|
||||||
|
return V;
|
||||||
|
else
|
||||||
|
return MUL64x( MUL64xPOW(V,i-1,c) , c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MUL64.
|
||||||
|
* Input V: a 64-bit input.
|
||||||
|
* Input P: a 64-bit input.
|
||||||
|
* Input c: a 64-bit input.
|
||||||
|
* Output : a 64-bit output.
|
||||||
|
* A 64-bit memory is allocated which is to be freed by the calling
|
||||||
|
* function.
|
||||||
|
* See section 4.3.4 for details.
|
||||||
|
*/
|
||||||
|
u64 MUL64(u64 V, u64 P, u64 c)
|
||||||
|
{
|
||||||
|
u64 result = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for ( i=0; i<64; i++)
|
||||||
|
{
|
||||||
|
if( ( P>>i ) & 0x1 )
|
||||||
|
result ^= MUL64xPOW(V,i,c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mask8bit.
|
||||||
|
* Input n: an integer in 1-7.
|
||||||
|
* Output : an 8 bit mask.
|
||||||
|
* Prepares an 8 bit mask with required number of 1 bits on the MSB side.
|
||||||
|
*/
|
||||||
|
u8 mask8bit(int n)
|
||||||
|
{
|
||||||
|
return 0xFF ^ ((1<<(8-n)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* f9.
|
||||||
|
* Input key: 128 bit Integrity Key.
|
||||||
|
* Input count:32-bit Count, Frame dependent input.
|
||||||
|
* Input fresh: 32-bit Random number.
|
||||||
|
* Input dir:1 bit, direction of transmission (in the LSB).
|
||||||
|
* Input data: length number of bits, input bit stream.
|
||||||
|
* Input length: 64 bit Length, i.e., the number of bits to be MAC'd.
|
||||||
|
* Output : 32 bit block used as MAC
|
||||||
|
* Generates 32-bit MAC using UIA2 algorithm as defined in Section 4.
|
||||||
|
*/
|
||||||
|
u8* snow3g_f9( u8* key, u32 count, u32 fresh, u32 dir, u8 *data, u64 length)
|
||||||
|
{
|
||||||
|
u32 K[4],IV[4], z[5];
|
||||||
|
u32 i=0, D;
|
||||||
|
static u8 MAC_I[4] = {0,0,0,0}; /* static memory for the result */
|
||||||
|
u64 EVAL;
|
||||||
|
u64 V;
|
||||||
|
u64 P;
|
||||||
|
u64 Q;
|
||||||
|
u64 c;
|
||||||
|
|
||||||
|
u64 M_D_2;
|
||||||
|
int rem_bits = 0;
|
||||||
|
|
||||||
|
/* Load the Integrity Key for SNOW3G initialization as in section 4.4. */
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
K[3-i] = (key[4*i] << 24) ^ (key[4*i+1] << 16) ^
|
||||||
|
(key[4*i+2] << 8) ^ (key[4*i+3]);
|
||||||
|
|
||||||
|
/* Prepare the Initialization Vector (IV) for SNOW3G initialization as
|
||||||
|
in section 4.4. */
|
||||||
|
IV[3] = count;
|
||||||
|
IV[2] = fresh;
|
||||||
|
IV[1] = count ^ ( dir << 31 ) ;
|
||||||
|
IV[0] = fresh ^ (dir << 15);
|
||||||
|
|
||||||
|
z[0] = z[1] = z[2] = z[3] = z[4] = 0;
|
||||||
|
|
||||||
|
/* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */
|
||||||
|
snow3g_initialize(K, IV);
|
||||||
|
snow3g_generate_keystream(5, z);
|
||||||
|
|
||||||
|
P = (u64)z[0] << 32 | (u64)z[1];
|
||||||
|
Q = (u64)z[2] << 32 | (u64)z[3];
|
||||||
|
|
||||||
|
/* Calculation */
|
||||||
|
if ((length % 64) == 0)
|
||||||
|
D = (length>>6) + 1;
|
||||||
|
else
|
||||||
|
D = (length>>6) + 2;
|
||||||
|
EVAL = 0;
|
||||||
|
c = 0x1b;
|
||||||
|
|
||||||
|
/* for 0 <= i <= D-3 */
|
||||||
|
for (i=0; i<D-2; i++)
|
||||||
|
{
|
||||||
|
V = EVAL ^ ( (u64)data[8*i ]<<56 | (u64)data[8*i+1]<<48 |
|
||||||
|
(u64)data[8*i+2]<<40 | (u64)data[8*i+3]<<32 |
|
||||||
|
(u64)data[8*i+4]<<24 | (u64)data[8*i+5]<<16 |
|
||||||
|
(u64)data[8*i+6]<< 8 | (u64)data[8*i+7] ) ;
|
||||||
|
EVAL = MUL64(V,P,c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for D-2 */
|
||||||
|
rem_bits = length % 64;
|
||||||
|
if (rem_bits == 0)
|
||||||
|
rem_bits = 64;
|
||||||
|
|
||||||
|
M_D_2 = 0;
|
||||||
|
i = 0;
|
||||||
|
while (rem_bits > 7)
|
||||||
|
{
|
||||||
|
M_D_2 |= (u64)data[8*(D-2)+i] << (8*(7-i));
|
||||||
|
rem_bits -= 8;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (rem_bits > 0)
|
||||||
|
M_D_2 |= (u64)(data[8*(D-2)+i] & mask8bit(rem_bits)) << (8*(7-i));
|
||||||
|
|
||||||
|
V = EVAL ^ M_D_2;
|
||||||
|
EVAL = MUL64(V,P,c);
|
||||||
|
|
||||||
|
/* for D-1 */
|
||||||
|
EVAL ^= length;
|
||||||
|
|
||||||
|
/* Multiply by Q */
|
||||||
|
EVAL = MUL64(EVAL,Q,c);
|
||||||
|
|
||||||
|
/* XOR with z_5: this is a modification to the reference C code,
|
||||||
|
which forgot to XOR z[5] */
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
/*
|
||||||
|
MAC_I[i] = (mac32 >> (8*(3-i))) & 0xff;
|
||||||
|
*/
|
||||||
|
MAC_I[i] = ((EVAL >> (56-(i*8))) ^ (z[4] >> (24-(i*8)))) & 0xff;
|
||||||
|
|
||||||
|
return MAC_I;
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "common/task_dispatcher.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
task_dispatcher::task_dispatcher(uint32_t max_pending_tasks)
|
||||||
|
{
|
||||||
|
pthread_cond_init(&cvar, NULL);
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
task_dispatcher::~task_dispatcher()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
pthread_cond_signal(&cvar);
|
||||||
|
wait_thread_finish();
|
||||||
|
pthread_cond_destroy(&cvar);
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void task_dispatcher::push_task(uint32_t task_code)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
pending_tasks.push(task_code);
|
||||||
|
pthread_cond_signal(&cvar);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void task_dispatcher::run_thread()
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
while(running) {
|
||||||
|
uint32_t task = 0;
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(pending_tasks.empty()) {
|
||||||
|
pthread_cond_wait(&cvar, &mutex);
|
||||||
|
}
|
||||||
|
task = (uint32_t) pending_tasks.front();
|
||||||
|
pending_tasks.pop();
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
if (running) {
|
||||||
|
run_task(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,289 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/thread_pool.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#define debug_thread(fmt, ...) do { if(DEBUG) printf(fmt, __VA_ARGS__); } while(0)
|
||||||
|
|
||||||
|
#define USE_QUEUE
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
|
||||||
|
void thread_pool::worker::setup(uint32_t id, thread_pool *parent, uint32_t prio, uint32_t mask)
|
||||||
|
{
|
||||||
|
my_id = id;
|
||||||
|
my_parent = parent;
|
||||||
|
if(mask == 255)
|
||||||
|
{
|
||||||
|
start(prio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_cpu_mask(prio,mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::worker::run_thread()
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
while(running) {
|
||||||
|
wait_to_start();
|
||||||
|
if (running) {
|
||||||
|
work_imp();
|
||||||
|
finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t thread_pool::worker::get_id()
|
||||||
|
{
|
||||||
|
return my_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::worker::stop()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
pthread_cond_signal(&my_parent->cvar[my_id]);
|
||||||
|
wait_thread_finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_pool::thread_pool(uint32_t max_workers_) :
|
||||||
|
workers(max_workers_),
|
||||||
|
status(max_workers_),
|
||||||
|
cvar(max_workers_),
|
||||||
|
mutex(max_workers_)
|
||||||
|
|
||||||
|
{
|
||||||
|
max_workers = max_workers_;
|
||||||
|
for (int i=0;i<max_workers;i++) {
|
||||||
|
workers[i] = NULL;
|
||||||
|
status[i] = IDLE;
|
||||||
|
pthread_mutex_init(&mutex[i], NULL);
|
||||||
|
pthread_cond_init(&cvar[i], NULL);
|
||||||
|
}
|
||||||
|
pthread_mutex_init(&mutex_queue, NULL);
|
||||||
|
pthread_cond_init(&cvar_queue, NULL);
|
||||||
|
running = true;
|
||||||
|
nof_workers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::init_worker(uint32_t id, worker *obj, uint32_t prio, uint32_t mask)
|
||||||
|
{
|
||||||
|
if (id < max_workers) {
|
||||||
|
if (id >= nof_workers) {
|
||||||
|
nof_workers = id+1;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&mutex_queue);
|
||||||
|
workers[id] = obj;
|
||||||
|
available_workers.push(obj);
|
||||||
|
obj->setup(id, this, prio, mask);
|
||||||
|
pthread_cond_signal(&cvar_queue);
|
||||||
|
pthread_mutex_unlock(&mutex_queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::stop()
|
||||||
|
{
|
||||||
|
/* Stop any thread waiting for available worker */
|
||||||
|
running = false;
|
||||||
|
|
||||||
|
/* Now stop all workers */
|
||||||
|
for (uint32_t i=0;i<nof_workers;i++) {
|
||||||
|
if (workers[i]) {
|
||||||
|
workers[i]->stop();
|
||||||
|
// Need to call start to wake it up
|
||||||
|
start_worker(i);
|
||||||
|
workers[i]->wait_thread_finish();
|
||||||
|
}
|
||||||
|
pthread_cond_destroy(&cvar[i]);
|
||||||
|
pthread_mutex_destroy(&mutex[i]);
|
||||||
|
}
|
||||||
|
pthread_cond_destroy(&cvar_queue);
|
||||||
|
pthread_mutex_destroy(&mutex_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void thread_pool::worker::release()
|
||||||
|
{
|
||||||
|
finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::worker::wait_to_start()
|
||||||
|
{
|
||||||
|
|
||||||
|
debug_thread("wait_to_start() id=%d, status=%d, enter\n", my_id, my_parent->status[my_id]);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&my_parent->mutex[my_id]);
|
||||||
|
while(my_parent->status[my_id] != START_WORK && running) {
|
||||||
|
pthread_cond_wait(&my_parent->cvar[my_id], &my_parent->mutex[my_id]);
|
||||||
|
}
|
||||||
|
my_parent->status[my_id] = WORKING;
|
||||||
|
pthread_mutex_unlock(&my_parent->mutex[my_id]);
|
||||||
|
|
||||||
|
debug_thread("wait_to_start() id=%d, status=%d, exit\n", my_id, my_parent->status[my_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_pool::worker::finished()
|
||||||
|
{
|
||||||
|
#ifdef USE_QUEUE
|
||||||
|
pthread_mutex_lock(&my_parent->mutex[my_id]);
|
||||||
|
my_parent->status[my_id] = IDLE;
|
||||||
|
pthread_mutex_unlock(&my_parent->mutex[my_id]);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&my_parent->mutex_queue);
|
||||||
|
pthread_cond_signal(&my_parent->cvar_queue);
|
||||||
|
pthread_mutex_unlock(&my_parent->mutex_queue);
|
||||||
|
#else
|
||||||
|
pthread_mutex_lock(&my_parent->mutex[my_id]);
|
||||||
|
my_parent->status[my_id] = IDLE;
|
||||||
|
pthread_cond_signal(&my_parent->cvar[my_id]);
|
||||||
|
pthread_mutex_unlock(&my_parent->mutex[my_id]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
thread_pool::worker* thread_pool::wait_worker()
|
||||||
|
{
|
||||||
|
return wait_worker(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thread_pool::find_finished_worker(uint32_t tti, uint32_t *id) {
|
||||||
|
for(int i=0;i<nof_workers;i++) {
|
||||||
|
if (status[i] == IDLE) {
|
||||||
|
*id = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_pool::worker* thread_pool::wait_worker(uint32_t tti)
|
||||||
|
{
|
||||||
|
thread_pool::worker *x;
|
||||||
|
|
||||||
|
#ifdef USE_QUEUE
|
||||||
|
debug_thread("wait_worker() - enter - tti=%d, state0=%d, state1=%d\n", tti, status[0], status[1]);
|
||||||
|
pthread_mutex_lock(&mutex_queue);
|
||||||
|
uint32_t id = 0;
|
||||||
|
while(!find_finished_worker(tti, &id) && running) {
|
||||||
|
pthread_cond_wait(&cvar_queue, &mutex_queue);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex_queue);
|
||||||
|
if (running) {
|
||||||
|
x = workers[id];
|
||||||
|
pthread_mutex_lock(&mutex[id]);
|
||||||
|
status[id] = WORKER_READY;
|
||||||
|
pthread_mutex_unlock(&mutex[id]);
|
||||||
|
} else {
|
||||||
|
x = NULL;
|
||||||
|
}
|
||||||
|
debug_thread("wait_worker() - exit - id=%d\n", id);
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint32_t id = tti%nof_workers;
|
||||||
|
pthread_mutex_lock(&mutex[id]);
|
||||||
|
while(status[id] != IDLE && running) {
|
||||||
|
pthread_cond_wait(&cvar[id], &mutex[id]);
|
||||||
|
}
|
||||||
|
if (running) {
|
||||||
|
x = (worker*) workers[id];
|
||||||
|
status[id] = WORKER_READY;
|
||||||
|
} else {
|
||||||
|
x = NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex[id]);
|
||||||
|
#endif
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_pool::worker* thread_pool::wait_worker_nb(uint32_t tti)
|
||||||
|
{
|
||||||
|
thread_pool::worker *x;
|
||||||
|
|
||||||
|
debug_thread("wait_worker() - enter - tti=%d, state0=%d, state1=%d\n", tti, status[0], status[1]);
|
||||||
|
pthread_mutex_lock(&mutex_queue);
|
||||||
|
uint32_t id = 0;
|
||||||
|
if (find_finished_worker(tti, &id)) {
|
||||||
|
x = workers[id];
|
||||||
|
} else {
|
||||||
|
x = NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex_queue);
|
||||||
|
if (running && x) {
|
||||||
|
pthread_mutex_lock(&mutex[id]);
|
||||||
|
status[id] = WORKER_READY;
|
||||||
|
pthread_mutex_unlock(&mutex[id]);
|
||||||
|
} else {
|
||||||
|
x = NULL;
|
||||||
|
}
|
||||||
|
debug_thread("wait_worker() - exit - id=%d\n", id);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void thread_pool::start_worker(uint32_t id) {
|
||||||
|
if (id < nof_workers) {
|
||||||
|
pthread_mutex_lock(&mutex[id]);
|
||||||
|
status[id] = START_WORK;
|
||||||
|
pthread_cond_signal(&cvar[id]);
|
||||||
|
pthread_mutex_unlock(&mutex[id]);
|
||||||
|
debug_thread("start_worker() id=%d, status=%d\n", id, status[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void thread_pool::start_worker(worker* x)
|
||||||
|
{
|
||||||
|
for (uint32_t i=0;i<nof_workers;i++) {
|
||||||
|
if (x == workers[i]) {
|
||||||
|
start_worker(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_pool::worker* thread_pool::get_worker(uint32_t id)
|
||||||
|
{
|
||||||
|
if (id < nof_workers) {
|
||||||
|
return workers[id];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t thread_pool::get_nof_workers()
|
||||||
|
{
|
||||||
|
return nof_workers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,153 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "common/threads.h"
|
||||||
|
|
||||||
|
bool threads_new_rt(pthread_t *thread, void *(*start_routine) (void*), void *arg) {
|
||||||
|
return threads_new_rt_prio(thread, start_routine, arg, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads_new_rt_prio(pthread_t *thread, void *(*start_routine) (void*), void *arg, int prio_offset) {
|
||||||
|
return threads_new_rt_cpu(thread, start_routine, arg, -1, prio_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads_new_rt_mask(pthread_t *thread, void *(*start_routine) (void*), void *arg,int mask, int prio_offset){
|
||||||
|
return threads_new_rt_cpu(thread, start_routine, arg, mask*100, prio_offset);// we multiply mask by 100 to distinguish it from a single cpu core id
|
||||||
|
}
|
||||||
|
|
||||||
|
bool threads_new_rt_cpu(pthread_t *thread, void *(*start_routine) (void*), void *arg, int cpu, int prio_offset) {
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
pthread_attr_t attr;
|
||||||
|
struct sched_param param;
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
if (prio_offset >= 0) {
|
||||||
|
param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
|
||||||
|
perror("pthread_attr_setinheritsched");
|
||||||
|
}
|
||||||
|
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
|
||||||
|
perror("pthread_attr_setschedpolicy");
|
||||||
|
}
|
||||||
|
if (pthread_attr_setschedparam(&attr, ¶m)) {
|
||||||
|
perror("pthread_attr_setschedparam");
|
||||||
|
fprintf(stderr, "Error not enough privileges to set Scheduling priority\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cpu != -1) {
|
||||||
|
if(cpu > 50) {
|
||||||
|
int mask;
|
||||||
|
mask = cpu/100;
|
||||||
|
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
for(int i = 0; i < 8;i++){
|
||||||
|
if(((mask >> i) & 0x01) == 1){
|
||||||
|
printf("Setting this worker with affinity to core %d\n", i);
|
||||||
|
CPU_SET((size_t) i , &cpuset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
CPU_SET((size_t) cpu, &cpuset);
|
||||||
|
printf("Setting CPU affinity to cpu_id=%d\n", cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset)) {
|
||||||
|
perror("pthread_attr_setaffinity_np");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = pthread_create(thread, prio_offset >= 0 ? &attr : NULL, start_routine, arg);
|
||||||
|
if (err) {
|
||||||
|
if (EPERM == err) {
|
||||||
|
perror("Warning: Failed to create thread with real-time priority. Creating it with normal priority");
|
||||||
|
err = pthread_create(thread, NULL, start_routine, arg);
|
||||||
|
if (err) {
|
||||||
|
perror("pthread_create");
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
perror("pthread_create");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
if (prio_offset >= 0) {
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void threads_print_self() {
|
||||||
|
pthread_t thread;
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
struct sched_param param;
|
||||||
|
int policy;
|
||||||
|
const char *p;
|
||||||
|
int s,j;
|
||||||
|
|
||||||
|
thread = pthread_self();
|
||||||
|
|
||||||
|
s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
|
||||||
|
if (s != 0) {
|
||||||
|
printf("error pthread_getaffinity_np: %s\n",strerror(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Set returned by pthread_getaffinity_np() contained:\n");
|
||||||
|
for (j = 0; j < CPU_SETSIZE; j++) {
|
||||||
|
if (CPU_ISSET(j, &cpuset)) {
|
||||||
|
printf(" CPU %d\n", j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = pthread_getschedparam(thread, &policy, ¶m);
|
||||||
|
if (s != 0) {
|
||||||
|
printf("error pthread_getaffinity_np: %s\n", strerror(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(policy) {
|
||||||
|
case SCHED_FIFO:
|
||||||
|
p = "SCHED_FIFO";
|
||||||
|
break;
|
||||||
|
case SCHED_RR:
|
||||||
|
p = "SCHED_RR";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
p = "Other";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Sched policy is %s. Priority is %d\n",p,param.sched_priority);
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "common/tti_sync_cv.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace srslte {
|
||||||
|
|
||||||
|
tti_sync_cv::tti_sync_cv(uint32_t modulus): tti_sync(modulus)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
pthread_cond_init(&cond, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
tti_sync_cv::~tti_sync_cv()
|
||||||
|
{
|
||||||
|
pthread_cond_destroy(&cond);
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tti_sync_cv::wait()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(wait_condition()) {
|
||||||
|
pthread_cond_wait(&cond, &mutex);
|
||||||
|
}
|
||||||
|
uint32_t x = consumer_cntr;
|
||||||
|
increase_consumer();
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tti_sync_cv::resync()
|
||||||
|
{
|
||||||
|
consumer_cntr = producer_cntr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tti_sync_cv::set_producer_cntr(uint32_t producer_cntr)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
init_counters(producer_cntr);
|
||||||
|
pthread_cond_signal(&cond);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tti_sync_cv::increase()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
increase_producer();
|
||||||
|
pthread_cond_signal(&cond);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
# Copyright 2015 Software Radio Systems Limited
|
||||||
|
#
|
||||||
|
# This file is part of srsUE
|
||||||
|
#
|
||||||
|
# srsUE is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# srsUE is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# A copy of the GNU Affero General Public License can be found in
|
||||||
|
# the LICENSE file in the top-level directory of this distribution
|
||||||
|
# and at http://www.gnu.org/licenses/.
|
||||||
|
#
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
# LOGGER TEST
|
||||||
|
#######################################################################
|
||||||
|
add_executable(logger_test logger_test.cc)
|
||||||
|
target_link_libraries(logger_test srslte_phy srslte_common srslte_phy lte ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||||
|
add_test(logger_test logger_test)
|
||||||
|
|
||||||
|
add_executable(msg_queue_test msg_queue_test.cc)
|
||||||
|
target_link_libraries(msg_queue_test srslte_phy srslte_common ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||||
|
add_test(msg_queue_test msg_queue_test)
|
||||||
|
|
||||||
|
add_executable(log_filter_test log_filter_test.cc)
|
||||||
|
target_link_libraries(log_filter_test srslte_phy srslte_common srslte_phy lte ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
add_executable(timeout_test timeout_test.cc)
|
||||||
|
target_link_libraries(timeout_test srslte_phy ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
|
add_executable(bcd_helpers_test bcd_helpers_test.cc)
|
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include "common/bcd_helpers.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
std::string mcc_str = "001";
|
||||||
|
std::string mnc_str = "001";
|
||||||
|
uint16_t mcc;
|
||||||
|
uint16_t mnc;
|
||||||
|
|
||||||
|
// String to code
|
||||||
|
|
||||||
|
assert(string_to_mcc(mcc_str, &mcc));
|
||||||
|
assert(mcc == 0xF001);
|
||||||
|
|
||||||
|
assert(string_to_mnc(mnc_str, &mnc));
|
||||||
|
assert(mnc == 0xF001);
|
||||||
|
|
||||||
|
mnc_str = "01";
|
||||||
|
assert(string_to_mnc(mnc_str, &mnc));
|
||||||
|
assert(mnc == 0xFF01);
|
||||||
|
|
||||||
|
// Code to string
|
||||||
|
|
||||||
|
mcc_str = "";
|
||||||
|
mnc_str = "";
|
||||||
|
mcc = 0xF001;
|
||||||
|
mnc = 0xF001;
|
||||||
|
|
||||||
|
assert(mcc_to_string(mcc, &mcc_str));
|
||||||
|
assert(mcc_str.compare("001") == 0);
|
||||||
|
|
||||||
|
assert(mnc_to_string(mnc, &mnc_str));
|
||||||
|
assert(mnc_str.compare("001") == 0);
|
||||||
|
|
||||||
|
mnc = 0xFF01;
|
||||||
|
assert(mnc_to_string(mnc, &mnc_str));
|
||||||
|
assert(mnc_str.compare("01") == 0);
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NTHREADS 100
|
||||||
|
#define NMSGS 100
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/log_filter.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
logger *l;
|
||||||
|
int thread_id;
|
||||||
|
}args_t;
|
||||||
|
|
||||||
|
void* thread_loop(void *a) {
|
||||||
|
args_t *args = (args_t*)a;
|
||||||
|
char buf[100];
|
||||||
|
|
||||||
|
sprintf(buf, "LAYER%d", args->thread_id);
|
||||||
|
log_filter filter(buf, args->l);
|
||||||
|
filter.set_level(LOG_LEVEL_INFO);
|
||||||
|
|
||||||
|
for(int i=0;i<NMSGS;i++)
|
||||||
|
{
|
||||||
|
filter.error("Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.warning("Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.info("Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.debug("Thread %d: %d", args->thread_id, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* thread_loop_hex(void *a) {
|
||||||
|
args_t *args = (args_t*)a;
|
||||||
|
char buf[100];
|
||||||
|
uint8_t hex[100];
|
||||||
|
|
||||||
|
for(int i=0;i<100;i++)
|
||||||
|
hex[i] = i & 0xFF;
|
||||||
|
sprintf(buf, "LAYER%d", args->thread_id);
|
||||||
|
log_filter filter(buf, args->l);
|
||||||
|
filter.set_level(LOG_LEVEL_DEBUG);
|
||||||
|
filter.set_hex_limit(32);
|
||||||
|
|
||||||
|
for(int i=0;i<NMSGS;i++)
|
||||||
|
{
|
||||||
|
filter.error_hex(hex, 100, "Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.warning_hex(hex, 100, "Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.info_hex(hex, 100, "Thread %d: %d", args->thread_id, i);
|
||||||
|
filter.debug_hex(hex, 100, "Thread %d: %d", args->thread_id, i);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(std::string filename) {
|
||||||
|
logger l;
|
||||||
|
l.init(filename);
|
||||||
|
pthread_t threads[NTHREADS];
|
||||||
|
args_t args[NTHREADS];
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
args[i].l = &l;
|
||||||
|
args[i].thread_id = i;
|
||||||
|
pthread_create(&threads[i], NULL, &thread_loop_hex, &args[i]);
|
||||||
|
}
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
pthread_join(threads[i], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read(std::string filename) {
|
||||||
|
bool pass = true;
|
||||||
|
bool written[NTHREADS][NMSGS];
|
||||||
|
int thread, msg;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
for(int j=0;j<NMSGS;j++) {
|
||||||
|
written[i][j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE *f = fopen(filename.c_str(), "r");
|
||||||
|
if(f!=NULL) {
|
||||||
|
while(fscanf(f, "Thread %d: %d\n", &thread, &msg)) {
|
||||||
|
written[thread][msg] = true;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
for(int j=0;j<NMSGS;j++) {
|
||||||
|
if(!written[i][j]) pass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bool result;
|
||||||
|
std::string f("log.txt");
|
||||||
|
write(f);
|
||||||
|
// result = read(f);
|
||||||
|
// remove(f.c_str());
|
||||||
|
// if(result) {
|
||||||
|
// printf("Passed\n");
|
||||||
|
// exit(0);
|
||||||
|
// }else{
|
||||||
|
// printf("Failed\n;");
|
||||||
|
// exit(1);
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NTHREADS 100
|
||||||
|
#define NMSGS 100
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/logger.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
logger *l;
|
||||||
|
int thread_id;
|
||||||
|
}args_t;
|
||||||
|
|
||||||
|
void* thread_loop(void *a) {
|
||||||
|
args_t *args = (args_t*)a;
|
||||||
|
char buf[100];
|
||||||
|
for(int i=0;i<NMSGS;i++)
|
||||||
|
{
|
||||||
|
sprintf(buf, "Thread %d: %d", args->thread_id, i);
|
||||||
|
args->l->log(buf);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(std::string filename) {
|
||||||
|
logger l;
|
||||||
|
l.init(filename);
|
||||||
|
pthread_t threads[NTHREADS];
|
||||||
|
args_t args[NTHREADS];
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
args[i].l = &l;
|
||||||
|
args[i].thread_id = i;
|
||||||
|
pthread_create(&threads[i], NULL, &thread_loop, &args[i]);
|
||||||
|
}
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
pthread_join(threads[i], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read(std::string filename) {
|
||||||
|
bool pass = true;
|
||||||
|
bool written[NTHREADS][NMSGS];
|
||||||
|
int thread, msg;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
for(int j=0;j<NMSGS;j++) {
|
||||||
|
written[i][j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FILE *f = fopen(filename.c_str(), "r");
|
||||||
|
if(f!=NULL) {
|
||||||
|
while(fscanf(f, "Thread %d: %d\n", &thread, &msg)) {
|
||||||
|
written[thread][msg] = true;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
for(int i=0;i<NTHREADS;i++) {
|
||||||
|
for(int j=0;j<NMSGS;j++) {
|
||||||
|
if(!written[i][j]) pass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bool result;
|
||||||
|
std::string f("log.txt");
|
||||||
|
write(f);
|
||||||
|
result = read(f);
|
||||||
|
remove(f.c_str());
|
||||||
|
if(result) {
|
||||||
|
printf("Passed\n");
|
||||||
|
exit(0);
|
||||||
|
}else{
|
||||||
|
printf("Failed\n;");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NMSGS 1000000
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/msg_queue.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
msg_queue *q;
|
||||||
|
}args_t;
|
||||||
|
|
||||||
|
void* write_thread(void *a) {
|
||||||
|
args_t *args = (args_t*)a;
|
||||||
|
for(uint32_t i=0;i<NMSGS;i++)
|
||||||
|
{
|
||||||
|
byte_buffer_t *b = new byte_buffer_t;
|
||||||
|
memcpy(b->msg, &i, 4);
|
||||||
|
b->N_bytes = 4;
|
||||||
|
args->q->write(b);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bool result;
|
||||||
|
msg_queue q;
|
||||||
|
byte_buffer_t *b;
|
||||||
|
pthread_t thread;
|
||||||
|
args_t args;
|
||||||
|
u_int32_t r;
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
args.q = &q;
|
||||||
|
|
||||||
|
pthread_create(&thread, NULL, &write_thread, &args);
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<NMSGS;i++)
|
||||||
|
{
|
||||||
|
q.read(&b);
|
||||||
|
memcpy(&r, b->msg, 4);
|
||||||
|
delete b;
|
||||||
|
if(r != i)
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_join(thread, NULL);
|
||||||
|
|
||||||
|
if(result) {
|
||||||
|
printf("Passed\n");
|
||||||
|
exit(0);
|
||||||
|
}else{
|
||||||
|
printf("Failed\n;");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2015 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* \section LICENSE
|
||||||
|
*
|
||||||
|
* This file is part of the srsUE library.
|
||||||
|
*
|
||||||
|
* srsUE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsUE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/timeout.h"
|
||||||
|
|
||||||
|
using namespace srslte;
|
||||||
|
|
||||||
|
class callback
|
||||||
|
: public timeout_callback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
callback() {
|
||||||
|
finished = false;
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
pthread_cond_init(&cvar, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeout_expired(uint32_t timeout_id)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
finished = true;
|
||||||
|
pthread_cond_signal(&cvar);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
void wait()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while(!finished) {
|
||||||
|
pthread_cond_wait(&cvar, &mutex);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
struct timeval start_time[3];
|
||||||
|
private:
|
||||||
|
bool finished;
|
||||||
|
pthread_cond_t cvar;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bool result;
|
||||||
|
uint32_t id = 0;
|
||||||
|
uint32_t duration_msec = 5;
|
||||||
|
|
||||||
|
callback c;
|
||||||
|
timeout t;
|
||||||
|
|
||||||
|
gettimeofday(&c.start_time[1], NULL);
|
||||||
|
t.start(duration_msec, 0, &c);
|
||||||
|
c.wait();
|
||||||
|
gettimeofday(&c.start_time[2], NULL);
|
||||||
|
get_time_interval(c.start_time);
|
||||||
|
uint32_t diff_ms = c.start_time[0].tv_usec*1e-3;
|
||||||
|
printf("Target duration: %dms, started: %ld:%ld, ended: %ld:%ld, actual duration %dms\n",
|
||||||
|
duration_msec, c.start_time[1].tv_sec, c.start_time[1].tv_usec, c.start_time[2].tv_sec, c.start_time[2].tv_usec, diff_ms);
|
||||||
|
|
||||||
|
result = (diff_ms == duration_msec);
|
||||||
|
|
||||||
|
if(result) {
|
||||||
|
printf("Passed\n");
|
||||||
|
exit(0);
|
||||||
|
}else{
|
||||||
|
printf("Failed\n;");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue