235 lines
6.6 KiB
C
235 lines
6.6 KiB
C
/*
|
|
* Copyright 2020 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
|
*
|
|
* SPDX-License-Identifier: 0BSD
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
* with or without fee is hereby granted.THE SOFTWARE IS PROVIDED "AS IS" AND THE
|
|
* AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
|
* USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
|
|
/* RAW structures */
|
|
struct ipc_shm_raw_smpl_buf {
|
|
uint64_t timestamp;
|
|
uint32_t data_len; /* In samples */
|
|
uint16_t samples[0];
|
|
};
|
|
|
|
struct ipc_shm_raw_stream {
|
|
pthread_mutex_t lock; /* protects this struct */
|
|
pthread_cond_t cf; /* signals fill to reader */
|
|
pthread_cond_t ce; /* signals empty nbuf to writer */
|
|
uint32_t num_buffers;
|
|
uint32_t buffer_size; /* In samples */
|
|
uint32_t read_next;
|
|
uint32_t write_next;
|
|
uint32_t buffer_offset[0];
|
|
//struct ipc_shm_smpl_buf buffers[0];
|
|
};
|
|
|
|
struct ipc_shm_raw_channel {
|
|
uint32_t dl_buf_offset;
|
|
uint32_t ul_buf_offset;
|
|
};
|
|
|
|
struct ipc_shm_raw_region {
|
|
uint32_t num_chans;
|
|
uint32_t chan_offset[0];
|
|
};
|
|
|
|
/* non-raw, Pointer converted structures */
|
|
struct ipc_shm_stream {
|
|
uint32_t num_buffers;
|
|
uint32_t buffer_size;
|
|
volatile struct ipc_shm_raw_stream *raw;
|
|
volatile struct ipc_shm_raw_smpl_buf *buffers[0];
|
|
};
|
|
|
|
struct ipc_shm_channel {
|
|
struct ipc_shm_stream *dl_stream;
|
|
struct ipc_shm_stream *ul_stream;
|
|
};
|
|
|
|
/* Pointer converted structures */
|
|
struct ipc_shm_region {
|
|
uint32_t num_chans;
|
|
struct ipc_shm_channel *channels[0];
|
|
};
|
|
|
|
unsigned int ipc_shm_encode_region(struct ipc_shm_raw_region *root_raw, uint32_t num_chans, uint32_t num_buffers,
|
|
uint32_t buffer_size);
|
|
struct ipc_shm_region *ipc_shm_decode_region(void *tall_ctx, struct ipc_shm_raw_region *root_raw);
|
|
/****************************************/
|
|
/* UNIX SOCKET API */
|
|
/****************************************/
|
|
|
|
//////////////////
|
|
// Master socket
|
|
//////////////////
|
|
#define IPC_SOCK_API_VERSION 1
|
|
|
|
/* msg_type */
|
|
#define IPC_IF_MSG_GREETING_REQ 0x00
|
|
#define IPC_IF_MSG_GREETING_CNF 0x01
|
|
#define IPC_IF_MSG_INFO_REQ 0x02
|
|
#define IPC_IF_MSG_INFO_CNF 0x03
|
|
#define IPC_IF_MSG_OPEN_REQ 0x04
|
|
#define IPC_IF_MSG_OPEN_CNF 0x05
|
|
|
|
#define MAX_NUM_CHANS 30
|
|
#define RF_PATH_NAME_SIZE 25
|
|
#define MAX_NUM_RF_PATHS 10
|
|
#define SHM_NAME_MAX NAME_MAX /* 255 */
|
|
|
|
#define FEATURE_MASK_CLOCKREF_INTERNAL (0x1 << 0)
|
|
#define FEATURE_MASK_CLOCKREF_EXTERNAL (0x1 << 1)
|
|
struct ipc_sk_if_info_chan {
|
|
char tx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
|
|
char rx_path[MAX_NUM_RF_PATHS][RF_PATH_NAME_SIZE];
|
|
double min_rx_gain;
|
|
double max_rx_gain;
|
|
double min_tx_gain;
|
|
double max_tx_gain;
|
|
double nominal_tx_power; /* dBm */
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_open_req_chan {
|
|
char tx_path[RF_PATH_NAME_SIZE];
|
|
char rx_path[RF_PATH_NAME_SIZE];
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_open_cnf_chan {
|
|
char chan_ipc_sk_path[108];
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_greeting {
|
|
uint8_t req_version;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_info_req {
|
|
uint8_t spare;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_info_cnf {
|
|
uint32_t feature_mask;
|
|
double iq_scaling_val_rx; /* for scaling, sample format is 16 bit, but adc/dac might be less */
|
|
double iq_scaling_val_tx;
|
|
uint32_t max_num_chans;
|
|
char dev_desc[200];
|
|
struct ipc_sk_if_info_chan chan_info[MAX_NUM_CHANS];
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_open_req {
|
|
uint32_t num_chans;
|
|
uint32_t clockref; /* One of FEATUER_MASK_CLOCKREF_* */
|
|
uint32_t rx_sample_freq_num;
|
|
uint32_t rx_sample_freq_den;
|
|
uint32_t tx_sample_freq_num;
|
|
uint32_t tx_sample_freq_den;
|
|
uint32_t bandwidth;
|
|
struct ipc_sk_if_open_req_chan chan_info[MAX_NUM_CHANS];
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if_open_cnf {
|
|
uint8_t return_code;
|
|
uint32_t path_delay;
|
|
char shm_name[SHM_NAME_MAX];
|
|
struct ipc_sk_if_open_cnf_chan chan_info[MAX_NUM_CHANS];
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_if {
|
|
uint8_t msg_type; /* message type */
|
|
uint8_t spare[2];
|
|
|
|
union {
|
|
struct ipc_sk_if_greeting greeting_req;
|
|
struct ipc_sk_if_greeting greeting_cnf;
|
|
struct ipc_sk_if_info_req info_req;
|
|
struct ipc_sk_if_info_cnf info_cnf;
|
|
struct ipc_sk_if_open_req open_req;
|
|
struct ipc_sk_if_open_cnf open_cnf;
|
|
} u;
|
|
} __attribute__((packed));
|
|
|
|
//////////////////
|
|
// Channel socket
|
|
//////////////////
|
|
#define IPC_IF_CHAN_MSG_OFFSET 50
|
|
#define IPC_IF_MSG_START_REQ IPC_IF_CHAN_MSG_OFFSET + 0
|
|
#define IPC_IF_MSG_START_CNF IPC_IF_CHAN_MSG_OFFSET + 1
|
|
#define IPC_IF_MSG_STOP_REQ IPC_IF_CHAN_MSG_OFFSET + 2
|
|
#define IPC_IF_MSG_STOP_CNF IPC_IF_CHAN_MSG_OFFSET + 3
|
|
#define IPC_IF_MSG_SETGAIN_REQ IPC_IF_CHAN_MSG_OFFSET + 4
|
|
#define IPC_IF_MSG_SETGAIN_CNF IPC_IF_CHAN_MSG_OFFSET + 5
|
|
#define IPC_IF_MSG_SETFREQ_REQ IPC_IF_CHAN_MSG_OFFSET + 6
|
|
#define IPC_IF_MSG_SETFREQ_CNF IPC_IF_CHAN_MSG_OFFSET + 7
|
|
|
|
#define IPC_IF_NOTIFY_UNDERFLOW IPC_IF_CHAN_MSG_OFFSET + 8
|
|
#define IPC_IF_NOTIFY_OVERFLOW IPC_IF_CHAN_MSG_OFFSET + 9
|
|
|
|
#define IPC_IF_MSG_SETTXATTN_REQ IPC_IF_CHAN_MSG_OFFSET + 10
|
|
#define IPC_IF_MSG_SETTXATTN_CNF IPC_IF_CHAN_MSG_OFFSET + 11
|
|
|
|
struct ipc_sk_chan_if_op_void {
|
|
// at least one dummy byte, to allow c/c++ compatibility
|
|
uint8_t dummy;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_op_rc {
|
|
uint8_t return_code;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_gain {
|
|
double gain;
|
|
uint8_t is_tx;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_freq_req {
|
|
double freq;
|
|
uint8_t is_tx;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_freq_cnf {
|
|
uint8_t return_code;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_notfiy {
|
|
uint8_t dummy;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if_tx_attenuation {
|
|
double attenuation;
|
|
} __attribute__((packed));
|
|
|
|
struct ipc_sk_chan_if {
|
|
uint8_t msg_type; /* message type */
|
|
uint8_t spare[2];
|
|
|
|
union {
|
|
struct ipc_sk_chan_if_op_void start_req;
|
|
struct ipc_sk_chan_if_op_rc start_cnf;
|
|
struct ipc_sk_chan_if_op_void stop_req;
|
|
struct ipc_sk_chan_if_op_rc stop_cnf;
|
|
struct ipc_sk_chan_if_gain set_gain_req;
|
|
struct ipc_sk_chan_if_gain set_gain_cnf;
|
|
struct ipc_sk_chan_if_freq_req set_freq_req;
|
|
struct ipc_sk_chan_if_freq_cnf set_freq_cnf;
|
|
struct ipc_sk_chan_if_notfiy notify;
|
|
struct ipc_sk_chan_if_tx_attenuation txatten_req;
|
|
struct ipc_sk_chan_if_tx_attenuation txatten_cnf;
|
|
} u;
|
|
} __attribute__((packed));
|