aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/device/ipc/shm.h
blob: 0ad0fd978138a15aef725899a8b380b2a856c989 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
* Copyright 2020 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
*
* SPDX-License-Identifier: AGPL-3.0+
*
* This software is distributed under multiple licenses; see the COPYING file in
* the main directory for licensing information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

    This program 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.

*/

/*
https://www.softprayog.in/programming/interprocess-communication-using-posix-shared-memory-in-linux

man shm_open: link with -lrt
Link with -pthread.

#include <sys/mman.h>
#include <sys/stat.h>        // For mode constants
#include <fcntl.h>           // For O_* constants
#include <semaphore.h>

On start:
int fd = shm_open(const char *name, int oflag, mode_t mode);
* name must start with "/" and not contain more slashes.
* name must be a null-terminted string of up to NAME_MAX (255)
* oflag: O_CREAT|O_RDWR|O_EXCL
* mode: check man open

ftruncate(fd, len = sizeof(struct myshamemorystruct) to expand the memory region

shm = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

int sem_init(sem_t *&(shm->sem), 1, unsigned int value) == 0;

close(fd); // After a call to mmap(2) the file descriptor may be closed without affecting the memory mapping.


On exit:
int shm_unlink(const char *name);


sem_t *sem_open(const char *name, int oflag,
                       mode_t mode, unsigned int value);
*  by a name of the form /somename; that is, a null-terminated string of up to NAME_MAX-4 (i.e., 251) characters
              consisting of an initial slash, followed by one or more characters, none of which are slashes.


* unamed semaphore: sem_init + sem_destroy
* Programs using the POSIX semaphores API must be compiled with cc -pthread to link against the real-time library, librt
*/

#include <stdint.h>
#include <unistd.h>
#include <limits.h>

/* RAW structures */
struct ipc_shm_raw_smpl_buf {
        uint32_t timestamp;
        uint32_t data_len; /* In samples */
        uint16_t samples[0];
};

struct ipc_shm_raw_stream {
        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;
        struct ipc_shm_raw_stream *raw;
        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_PATH "/tmp/ipc_sock"
#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];
} __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          min_rx_gain;
        double          max_rx_gain;
        double          min_tx_gain;
        double          max_tx_gain;
        uint32_t        max_num_chans;
        char            dev_desc[200];
        struct ipc_sk_if_info_chan chan_info[0];
} __attribute__ ((packed));

struct ipc_sk_if_open_req {
        uint32_t        num_chans;
        uint32_t        clockref; /* One of FEATUER_MASK_CLOCKREF_* */
        uint32_t        rx_sps;
        uint32_t        tx_sps;
        uint32_t        bandwidth;
        struct ipc_sk_if_open_req_chan chan_info[0];
} __attribute__ ((packed));

struct ipc_sk_if_open_cnf {
        uint8_t return_code;
        char shm_name[SHM_NAME_MAX];
        struct ipc_sk_if_open_cnf_chan chan_info[0];
} __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_MSG_START_REQ	0x00
#define IPC_IF_MSG_START_CNF	0x01
#define IPC_IF_MSG_STOP_REQ	0x02
#define IPC_IF_MSG_STOP_CNF	0x03
#define IPC_IF_MSG_SETGAIN_REQ	0x04
#define IPC_IF_MSG_SETGAIN_CNF	0x05
#define IPC_IF_MSG_SETFREQ_REQ	0x04
#define IPC_IF_MSG_SETFREQ_CNF	0x05

struct ipc_sk_chan_if_op_void {
} __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 {
	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;
	} u;
} __attribute__ ((packed));