/* * Copyright 2020 sysmocom - s.f.m.c. GmbH * Author: Pau Espin Pedrol * * 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 #include #include #include #include /* 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));