libosmoctrl  0.11.0.54.60f31
Osmocom CTRL library
control_cmd.h
Go to the documentation of this file.
1 
3 #pragma once
4 
5 #include <osmocom/core/msgb.h>
6 #include <osmocom/core/talloc.h>
8 #include <osmocom/core/logging.h>
9 #include <osmocom/core/utils.h>
10 #include <osmocom/vty/vector.h>
11 
12 #define CTRL_CMD_ERROR -1
13 #define CTRL_CMD_HANDLED 0
14 #define CTRL_CMD_REPLY 1
15 
16 struct ctrl_handle;
17 
20  CTRL_NODE_ROOT, /* Root elements */
21  CTRL_NODE_BTS, /* BTS specific (net.btsN.) */
22  CTRL_NODE_TRX, /* TRX specific (net.btsN.trxM.) */
23  CTRL_NODE_TS, /* TS specific (net.btsN.trxM.tsI.) */
24  CTRL_NODE_FSM, /* Finite State Machine (description) */
25  CTRL_NODE_FSM_INST, /* Finite State Machine (instance) */
27 };
28 
30 enum ctrl_type {
38 };
39 
41 extern const struct value_string ctrl_type_vals[];
42 
46 
49 
51  struct msgb *pending_msg;
52 
54  void (*closed_cb)(struct ctrl_connection *conn);
55 
57  struct llist_head cmds;
58 
61 };
62 
63 struct ctrl_cmd_def;
64 
66 struct ctrl_cmd {
71  char *id;
73  void *node;
75  char *variable;
77  char *value;
79  char *reply;
82 };
83 
84 #define ctrl_cmd_reply_printf(cmd, fmt, args ...) \
85  osmo_talloc_asprintf(cmd, cmd->reply, fmt, ## args)
86 
89  char **command;
90 };
91 
96  const char *name;
97  struct ctrl_cmd_struct strcmd;
99  int (*set)(struct ctrl_cmd *cmd, void *data);
101  int (*get)(struct ctrl_cmd *cmd, void *data);
103  int (*verify)(struct ctrl_cmd *cmd, const char *value, void *data);
104 };
105 
106 struct ctrl_cmd_map {
107  char *cmd;
109 };
110 
111 /* deferred control command, i.e. responded asynchronously */
112 struct ctrl_cmd_def {
113  struct llist_head list; /* ctrl_connection.def_cmds */
114  struct ctrl_cmd *cmd;
115  void *data; /* opaque user data */
116 };
117 
118 struct ctrl_cmd_def *
119 ctrl_cmd_def_make(const void *ctx, struct ctrl_cmd *cmd, void *data, unsigned int secs);
120 int ctrl_cmd_def_is_zombie(struct ctrl_cmd_def *cd);
121 int ctrl_cmd_def_send(struct ctrl_cmd_def *cd);
122 
123 int ctrl_cmd_exec(vector vline, struct ctrl_cmd *command, vector node, void *data);
124 int ctrl_cmd_install(enum ctrl_node_type node, struct ctrl_cmd_element *cmd);
125 int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd);
126 int ctrl_cmd_send_to_all(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd);
127 struct ctrl_cmd *ctrl_cmd_parse2(void *ctx, struct msgb *msg);
128 struct ctrl_cmd *ctrl_cmd_parse(void *ctx, struct msgb *msg);
129 struct msgb *ctrl_cmd_make(struct ctrl_cmd *cmd);
130 struct ctrl_cmd *ctrl_cmd_cpy(void *ctx, struct ctrl_cmd *cmd);
131 struct ctrl_cmd *ctrl_cmd_create(void *ctx, enum ctrl_type);
132 struct ctrl_cmd *ctrl_cmd_trap(struct ctrl_cmd *cmd);
133 
138 #define CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_name) \
139 static struct ctrl_cmd_element cmd_##cmdname = { \
140  .name = cmdstr, \
141  .get = &get_##cmdname, \
142  .set = &set_##cmdname, \
143  .verify = verify_name, \
144 }
145 
150 #define CTRL_HELPER_GET_INT(cmdname, dtype, element) \
151 static int get_##cmdname(struct ctrl_cmd *cmd, void *_data) \
152 { \
153  dtype *node = cmd->node; \
154  cmd->reply = talloc_asprintf(cmd, "%i", node->element); \
155  if (!cmd->reply) { \
156  cmd->reply = "OOM"; \
157  return CTRL_CMD_ERROR; \
158  } \
159  return CTRL_CMD_REPLY; \
160 }
161 
166 #define CTRL_HELPER_SET_INT(cmdname, dtype, element) \
167 static int set_##cmdname(struct ctrl_cmd *cmd, void *_data) \
168 { \
169  dtype *node = cmd->node; \
170  int tmp = atoi(cmd->value); \
171  node->element = tmp; \
172  return get_##cmdname(cmd, _data); \
173 }
174 
179 #define CTRL_HELPER_VERIFY_RANGE(cmdname, min, max) \
180 static int verify_##cmdname(struct ctrl_cmd *cmd, const char *value, void *_data) \
181 { \
182  int tmp = atoi(value); \
183  if ((tmp >= min)&&(tmp <= max)) { \
184  return 0; \
185  } \
186  cmd->reply = "Input not within the range"; \
187  return -1; \
188 }
189 
197 #define CTRL_CMD_DEFINE_RANGE(cmdname, cmdstr, dtype, element, min, max) \
198  CTRL_HELPER_GET_INT(cmdname, dtype, element) \
199  CTRL_HELPER_SET_INT(cmdname, dtype, element) \
200  CTRL_HELPER_VERIFY_RANGE(cmdname, min, max) \
201 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_##cmdname)
202 
207 #define CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
208 static int get_##cmdname(struct ctrl_cmd *cmd, void *_data) \
209 { \
210  dtype *data = cmd->node; \
211  cmd->reply = talloc_asprintf(cmd, "%s", data->element); \
212  if (!cmd->reply) { \
213  cmd->reply = "OOM"; \
214  return CTRL_CMD_ERROR; \
215  } \
216  return CTRL_CMD_REPLY; \
217 }
218 
223 #define CTRL_HELPER_SET_STRING(cmdname, dtype, element) \
224 static int set_##cmdname(struct ctrl_cmd *cmd, void *_data) \
225 { \
226  dtype *data = cmd->node; \
227  osmo_talloc_replace_string(cmd->node, &data->element, cmd->value); \
228  return get_##cmdname(cmd, _data); \
229 }
230 
238 #define CTRL_CMD_DEFINE_STRING(cmdname, cmdstr, dtype, element) \
239  CTRL_HELPER_GET_STRING(cmdname, dtype, element) \
240  CTRL_HELPER_SET_STRING(cmdname, dtype, element) \
241 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, NULL)
242 
246 #define CTRL_CMD_DEFINE(cmdname, cmdstr) \
247 static int get_##cmdname(struct ctrl_cmd *cmd, void *data); \
248 static int set_##cmdname(struct ctrl_cmd *cmd, void *data); \
249 static int verify_##cmdname(struct ctrl_cmd *cmd, const char *value, void *data); \
250 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_##cmdname)
251 
255 #define CTRL_CMD_DEFINE_RO(cmdname, cmdstr) \
256 static int get_##cmdname(struct ctrl_cmd *cmd, void *data); \
257 static int set_##cmdname(struct ctrl_cmd *cmd, void *data) \
258 { \
259  cmd->reply = "Read Only attribute"; \
260  return CTRL_CMD_ERROR; \
261 } \
262 static int verify_##cmdname(struct ctrl_cmd *cmd, const char *value, void *data) \
263 { \
264  cmd->reply = "Read Only attribute"; \
265  return 1; \
266 } \
267 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_##cmdname)
268 
272 #define CTRL_CMD_DEFINE_WO(cmdname, cmdstr) \
273 static int set_##cmdname(struct ctrl_cmd *cmd, void *data); \
274 static int get_##cmdname(struct ctrl_cmd *cmd, void *data) \
275 { \
276  cmd->reply = "Write Only attribute"; \
277  return CTRL_CMD_ERROR; \
278 } \
279 static int verify_##cmdname(struct ctrl_cmd *cmd, const char *val, void *data); \
280 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_##cmdname)
281 
285 #define CTRL_CMD_DEFINE_WO_NOVRF(cmdname, cmdstr) \
286 static int set_##cmdname(struct ctrl_cmd *cmd, void *data); \
287 static int get_##cmdname(struct ctrl_cmd *cmd, void *data) \
288 { \
289  cmd->reply = "Write Only attribute"; \
290  return CTRL_CMD_ERROR; \
291 } \
292 static int verify_##cmdname(struct ctrl_cmd *cmd, const char *val, void *data) \
293 { \
294  return 0; \
295 } \
296 CTRL_CMD_DEFINE_STRUCT(cmdname, cmdstr, verify_##cmdname)
297 
298 struct gsm_network;
Represents a single ctrl connection.
Definition: control_cmd.h:44
Definition: control_cmd.h:26
Definition: control_cmd.h:34
ctrl_node_type
The class of node at which a ctrl command is registered to.
Definition: control_cmd.h:19
Definition: control_cmd.h:22
char * variable
name of the variable
Definition: control_cmd.h:75
Definition: control_cmd.h:24
void(* closed_cb)(struct ctrl_connection *conn)
Callback if the connection was closed.
Definition: control_cmd.h:54
struct llist_head list_entry
Definition: control_cmd.h:45
ctrl_type
Ctrl command types (GET, SET, ...)
Definition: control_cmd.h:30
struct ctrl_connection * ccon
connection through which the command was received
Definition: control_cmd.h:68
Definition: control_cmd.h:20
Definition: control_cmd.h:112
Definition: control_cmd.h:31
struct ctrl_cmd * ctrl_cmd_create(void *ctx, enum ctrl_type)
Allocate a control command of given type.
Definition: control_cmd.c:238
Definition: control_cmd.h:106
struct ctrl_cmd * ctrl_cmd_cpy(void *ctx, struct ctrl_cmd *cmd)
Perform a deepl copy of the given cmd, allocating memory from ctx.
Definition: control_cmd.c:254
struct ctrl_cmd_def * ctrl_cmd_def_make(const void *ctx, struct ctrl_cmd *cmd, void *data, unsigned int secs)
Build a deferred control command state and keep it the per-connection list of deferred commands...
Definition: control_cmd.c:596
void * data
Definition: control_cmd.h:115
char * value
value of the specified CTRL variable
Definition: control_cmd.h:77
struct msgb * ctrl_cmd_make(struct ctrl_cmd *cmd)
Encode a given CTRL command from its parsed form into a message buffer.
Definition: control_cmd.c:496
int ctrl_cmd_install(enum ctrl_node_type node, struct ctrl_cmd_element *cmd)
Install a given command definition at a given CTRL node.
Definition: control_cmd.c:213
void * node
node of the specified variable
Definition: control_cmd.h:73
struct ctrl_cmd * ctrl_cmd_parse2(void *ctx, struct msgb *msg)
Parse/Decode CTRL from Message buffers into command struct.
Definition: control_cmd.c:320
char * reply
respnse message string
Definition: control_cmd.h:79
struct msgb * pending_msg
Buffer for partial input data.
Definition: control_cmd.h:51
int ctrl_cmd_send_to_all(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd)
Send a CTRL command to all connections.
Definition: control_if.c:106
Definition: control_cmd.h:33
char * cmd
Definition: control_cmd.h:107
struct ctrl_cmd * ctrl_cmd_parse(void *ctx, struct msgb *msg)
Parse/Decode CTRL from Message buffers into command struct.
Definition: control_cmd.c:295
char * id
Definition: control_cmd.h:71
int ctrl_cmd_def_send(struct ctrl_cmd_def *cd)
Send the response to a deferred ctrl command.
Definition: control_cmd.c:635
Definition: control_cmd.h:37
int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd)
Encode a CTRL command and append it to the given write queue.
Definition: control_if.c:124
int nr_commands
Definition: control_cmd.h:88
Definition: control_cmd.h:21
Definition: control_cmd.h:32
int ctrl_cmd_def_is_zombie(struct ctrl_cmd_def *cd)
Determine if the given deferred control command is still alive or a zombie.
Definition: control_cmd.c:618
const char * name
textual name/id of the CTRL command
Definition: control_cmd.h:96
char ** command
Definition: control_cmd.h:89
Definition: control_cmd.h:23
Definition: control_if.h:13
struct llist_head def_cmds
Pending deferred command responses for this connection.
Definition: control_cmd.h:60
int ctrl_cmd_exec(vector vline, struct ctrl_cmd *command, vector node, void *data)
Execute a given received command.
Definition: control_cmd.c:98
Definition: control_cmd.h:25
struct llist_head cmds
Pending commands for this connection.
Definition: control_cmd.h:57
uint8_t type
Represents a single ctrl command after parsing.
Definition: control_cmd.h:66
const struct value_string ctrl_type_vals[]
human-readable string names for ctrl_type
Definition: control_cmd.c:47
Definition: control_cmd.h:35
Definition: control_cmd.h:87
struct ctrl_cmd * cmd
Definition: control_cmd.h:114
struct ctrl_cmd * ctrl_cmd_trap(struct ctrl_cmd *cmd)
Copy given cmd and convert copy to CTRL_TYPE_TRAP.
Definition: control_if.c:170
struct ctrl_cmd_def * defer
state representing deferred (async) response, if any
Definition: control_cmd.h:81
Definition: control_cmd.h:36
struct osmo_wqueue write_queue
The queue for sending data back.
Definition: control_cmd.h:48
Implementation of a given CTRL command.
Definition: control_cmd.h:94