Browse Source

Parse commands based on their type.

This allows adding of new commands without any changes to command
parsing and generation code.
Georgi Chorbadzhiyski 9 years ago
parent
commit
40bb54c2a3
3 changed files with 171 additions and 194 deletions
  1. 143
    188
      cmd.c
  2. 24
    2
      cmd.h
  3. 4
    4
      videohubctrl.c

+ 143
- 188
cmd.c View File

12
 
12
 
13
 #include <stdio.h>
13
 #include <stdio.h>
14
 #include <stdlib.h>
14
 #include <stdlib.h>
15
+#include <stddef.h>
15
 #include <string.h>
16
 #include <string.h>
16
 
17
 
17
 #include "data.h"
18
 #include "data.h"
18
 #include "cmd.h"
19
 #include "cmd.h"
19
 #include "util.h"
20
 #include "util.h"
20
 
21
 
21
-enum cmd_flags {
22
-	PARSE_NONE      = (1 << 0), /* The result if this command needs no parsing */
23
-	PARSE_CUSTOM    = (1 << 1), /* Use custom parser for this command */
24
-	PARSE_SLOT_TXT  = (1 << 2), /* Parse [slot_num] [slot_text] */
25
-	PARSE_SLOT_DEST = (1 << 3), /* Parse [slot_num] [dest_slot] */
22
+const char *videohub_commands_text[NUM_COMMANDS] = {
23
+	[CMD_PROTOCOL_PREAMBLE]    = "PROTOCOL PREAMBLE",
24
+	[CMD_VIDEOHUB_DEVICE]      = "VIDEOHUB DEVICE",
25
+	[CMD_INPUT_LABELS]         = "INPUT LABELS",
26
+	[CMD_OUTPUT_LABELS]        = "OUTPUT LABELS",
27
+	[CMD_VIDEO_OUTPUT_LOCKS]   = "VIDEO OUTPUT LOCKS",
28
+	[CMD_VIDEO_OUTPUT_ROUTING] = "VIDEO OUTPUT ROUTING",
29
+	[CMD_VIDEO_INPUT_STATUS]   = "VIDEO INPUT STATUS",
30
+	[CMD_VIDEO_OUTPUT_STATUS]  = "VIDEO OUTPUT STATUS",
31
+	[CMD_PING]                 = "PING",
32
+	[CMD_ACK]                  = "ACK",
33
+	[CMD_NAK]                  = "NAK",
26
 };
34
 };
27
 
35
 
28
-static struct videohub_commands {
29
-	enum vcmd	cmd;
30
-	const char	*txt;
31
-	unsigned int	flags;
32
-} videohub_commands[] = {
33
-	{ CMD_PROTOCOL_PREAMBLE,    "PROTOCOL PREAMBLE",    PARSE_CUSTOM },
34
-	{ CMD_VIDEOHUB_DEVICE,      "VIDEOHUB DEVICE",      PARSE_CUSTOM },
35
-	{ CMD_INPUT_LABELS,         "INPUT LABELS",         PARSE_SLOT_TXT },
36
-	{ CMD_OUTPUT_LABELS,        "OUTPUT LABELS",        PARSE_SLOT_TXT },
37
-	{ CMD_VIDEO_OUTPUT_LOCKS,   "VIDEO OUTPUT LOCKS",   PARSE_SLOT_TXT },
38
-	{ CMD_VIDEO_OUTPUT_ROUTING, "VIDEO OUTPUT ROUTING", PARSE_SLOT_DEST },
39
-	{ CMD_VIDEO_INPUT_STATUS,   "VIDEO INPUT STATUS",   PARSE_SLOT_TXT },
40
-	{ CMD_VIDEO_OUTPUT_STATUS,  "VIDEO OUTPUT STATUS",  PARSE_SLOT_TXT },
41
-	{ CMD_PING,                 "PING",                 PARSE_NONE },
42
-	{ CMD_ACK,                  "ACK",                  PARSE_NONE },
43
-	{ CMD_NAK,                  "NAK",                  PARSE_NONE },
44
-};
36
+#define OFS(X) offsetof(struct videohub_data, X)
45
 
37
 
46
-static const char *get_cmd_text(enum vcmd cmd) {
47
-	unsigned int i;
48
-	for (i = 0; i < ARRAY_SIZE(videohub_commands); i++) {
49
-		if (videohub_commands[i].cmd == cmd)
50
-			return videohub_commands[i].txt;
51
-	}
52
-	return "";
53
-}
38
+struct videohub_commands videohub_commands[NUM_COMMANDS] = {
39
+	[CMD_PROTOCOL_PREAMBLE]    = { .cmd = CMD_PROTOCOL_PREAMBLE   , .type = PARSE_CUSTOM },
40
+	[CMD_VIDEOHUB_DEVICE]      = { .cmd = CMD_VIDEOHUB_DEVICE     , .type = PARSE_CUSTOM },
41
+	[CMD_INPUT_LABELS]         = { .cmd = CMD_INPUT_LABELS        , .type = PARSE_LABEL,
42
+		.ports1 = OFS(inputs),  .port_id1 = "video input",  },
43
+	[CMD_OUTPUT_LABELS]        = { .cmd = CMD_OUTPUT_LABELS       , .type = PARSE_LABEL,
44
+		.ports1 = OFS(outputs), .port_id1 = "video output", },
45
+	[CMD_VIDEO_OUTPUT_LOCKS]   = { .cmd = CMD_VIDEO_OUTPUT_LOCKS  , .type = PARSE_LOCK,
46
+		.ports1 = OFS(outputs), .port_id1 = "video output",  },
47
+	[CMD_VIDEO_OUTPUT_ROUTING] = { .cmd = CMD_VIDEO_OUTPUT_ROUTING, .type = PARSE_ROUTE,
48
+		.ports1   = OFS(outputs), .ports2 = OFS(inputs),
49
+		.port_id1 = "video output",     .port_id2 = "video input",
50
+	},
51
+	[CMD_VIDEO_INPUT_STATUS]   = { .cmd = CMD_VIDEO_INPUT_STATUS  , .type = PARSE_STATUS,
52
+		.ports1 = OFS(inputs),  .port_id1 = "video input",   },
53
+	[CMD_VIDEO_OUTPUT_STATUS]  = { .cmd = CMD_VIDEO_OUTPUT_STATUS , .type = PARSE_STATUS,
54
+		.ports1 = OFS(outputs), .port_id1 = "video output",  },
55
+	[CMD_PING]                 = { .cmd = CMD_PING                , .type = PARSE_NONE },
56
+	[CMD_ACK]                  = { .cmd = CMD_ACK                 , .type = PARSE_NONE },
57
+	[CMD_NAK]                  = { .cmd = CMD_NAK                 , .type = PARSE_NONE },
58
+};
54
 
59
 
55
 static char *parse_text(char *line, char *cmd) {
60
 static char *parse_text(char *line, char *cmd) {
56
 	char *parsed_text = strstr(line, cmd);
61
 	char *parsed_text = strstr(line, cmd);
60
 	return NULL;
65
 	return NULL;
61
 }
66
 }
62
 
67
 
63
-bool parse_command(struct videohub_data *data, char *cmd) {
68
+bool parse_command(struct videohub_data *d, char *cmd) {
64
 	unsigned int i;
69
 	unsigned int i;
65
 	bool ret = true;
70
 	bool ret = true;
66
 	if (!strlen(cmd))
71
 	if (!strlen(cmd))
67
 		return false;
72
 		return false;
68
 	struct videohub_commands *v = NULL;
73
 	struct videohub_commands *v = NULL;
69
-	for (i = 0; i < ARRAY_SIZE(videohub_commands); i++) {
70
-		if (!videohub_commands[i].txt)
71
-			continue;
72
-		if (strstr(cmd, videohub_commands[i].txt) == cmd) {
74
+	const char *cmd_txt = NULL;
75
+	for (i = 0; i < NUM_COMMANDS; i++) {
76
+		const char *cmd_text = videohub_commands_text[i];
77
+		if (strstr(cmd, cmd_text) == cmd) {
73
 			v = &videohub_commands[i];
78
 			v = &videohub_commands[i];
79
+			cmd_txt = videohub_commands_text[i];
74
 			break;
80
 			break;
75
 		}
81
 		}
76
 	}
82
 	}
85
 		return false;
91
 		return false;
86
 	}
92
 	}
87
 
93
 
88
-	d("debug: Got '%s' command.\n", v->txt);
94
+	d("debug: Got '%s' command.\n", cmd_txt);
89
 	if (debug > 1)
95
 	if (debug > 1)
90
 		d("----\n%s\n----\n", cmd);
96
 		d("----\n%s\n----\n", cmd);
91
 
97
 
92
-	char *p, *cmd_data = xstrdup( cmd + strlen(v->txt) + 2 ); // +2 to compensate for :\n at the end of the command
98
+	struct port_set *s_port = !v->ports1 ? NULL : (void *)d + v->ports1;
99
+	struct port_set *d_port = !v->ports2 ? NULL : (void *)d + v->ports2;
100
+
101
+	char *p, *cmd_data = xstrdup( cmd + strlen(cmd_txt) + 2 ); // +2 to compensate for :\n at the end of the command
93
 	// Split line by line
102
 	// Split line by line
94
 	char *line, *saveptr = NULL;
103
 	char *line, *saveptr = NULL;
95
 	for(i = 0, line = strtok_r(cmd_data, "\n", &saveptr); line; line = strtok_r(NULL, "\n", &saveptr), i++) {
104
 	for(i = 0, line = strtok_r(cmd_data, "\n", &saveptr); line; line = strtok_r(NULL, "\n", &saveptr), i++) {
96
 
105
 
97
-		// Parse command data response looking like that: "[slot_pos] [slot_data]"
98
-		char *slot_data = NULL;
99
-		unsigned int slot_pos = 0, dest_pos = 0;
106
+		// Parse command data response
107
+		unsigned int port_num = 0;
108
+		unsigned int dest_port_num = 0;
109
+		char *port_data = NULL;
100
 
110
 
101
-		if (v->flags & (PARSE_SLOT_TXT | PARSE_SLOT_DEST)) {
102
-			slot_data = strchr(line, ' ');
103
-			if (!slot_data)
111
+		if (v->type != PARSE_NONE && v->type != PARSE_CUSTOM) {
112
+			port_data = strchr(line, ' ');
113
+			if (!port_data)
104
 				continue;
114
 				continue;
105
-			slot_data[0] = '\0'; // Separate slot_pos from slot_data
106
-			slot_data++;
107
-			slot_pos = strtoul(line, NULL, 10);
108
-			if (slot_pos + 1 > data->outputs.num) {
109
-				q("WARNING: %s - invalid slot %u\n", v->txt, slot_pos);
115
+			port_data[0] = '\0'; // Separate port_num from port_data
116
+			port_data++;
117
+			port_num = strtoul(line, NULL, 10);
118
+			if (port_num + 1 > s_port->num) {
119
+				q("WARNING: %s: invalid %s port %u (valid 0..%u)\n", cmd_txt,
120
+				  v->port_id1, port_num, s_port->num - 1);
110
 				continue;
121
 				continue;
111
 			}
122
 			}
112
 		}
123
 		}
113
 
124
 
114
-		if (v->flags & PARSE_SLOT_DEST) {
115
-			dest_pos = strtoul(slot_data, NULL, 10);
116
-			if (dest_pos + 1 > data->inputs.num) {
117
-				q("WARNING: %s - invalid dest %u\n", v->txt, dest_pos);
125
+		switch (v->type) {
126
+		case PARSE_LABEL:
127
+			snprintf(s_port->port[port_num].name, sizeof(s_port->port[port_num].name), "%s", port_data);
128
+			break;
129
+		case PARSE_STATUS:
130
+			snprintf(s_port->port[port_num].status, sizeof(s_port->port[port_num].status), "%s", port_data);
131
+			break;
132
+		case PARSE_ROUTE:
133
+			dest_port_num = strtoul(port_data, NULL, 10);
134
+			if (dest_port_num + 1 > d_port->num) {
135
+				q("WARNING: %s: invalid %s port %u (valid 0..%u)\n", cmd_txt,
136
+				  v->port_id2, dest_port_num, d_port->num - 1);
118
 				continue;
137
 				continue;
119
 			}
138
 			}
139
+			s_port->port[port_num].routed_to = dest_port_num;
140
+			break;
141
+		case PARSE_LOCK:
142
+			switch (port_data[0]) {
143
+			case 'O': s_port->port[port_num].lock = PORT_LOCKED; break;
144
+			case 'L': s_port->port[port_num].lock = PORT_LOCKED_OTHER; break;
145
+			default : s_port->port[port_num].lock = PORT_UNLOCKED; break;
146
+			}
147
+			break;
148
+		default: break;
120
 		}
149
 		}
121
 
150
 
122
-		// Parse commands
151
+		// Parse custom commands
123
 		switch (v->cmd) {
152
 		switch (v->cmd) {
124
 		case CMD_PROTOCOL_PREAMBLE:
153
 		case CMD_PROTOCOL_PREAMBLE:
125
 			if ((p = parse_text(line, "Version: ")))
154
 			if ((p = parse_text(line, "Version: ")))
126
-				snprintf(data->device.protocol_ver, sizeof(data->device.protocol_ver), "%s", p);
155
+				snprintf(d->device.protocol_ver, sizeof(d->device.protocol_ver), "%s", p);
127
 			break;
156
 			break;
128
-
129
 		case CMD_VIDEOHUB_DEVICE:
157
 		case CMD_VIDEOHUB_DEVICE:
130
 			if ((p = parse_text(line, "Device present: "))) {
158
 			if ((p = parse_text(line, "Device present: "))) {
131
-				data->device.dev_present = streq(p, "true");
132
-				data->device.needs_fw_update = streq(p, "needs_update");
159
+				d->device.dev_present = streq(p, "true");
160
+				d->device.needs_fw_update = streq(p, "needs_update");
133
 			}
161
 			}
134
-
135
 			if ((p = parse_text(line, "Model name: ")))
162
 			if ((p = parse_text(line, "Model name: ")))
136
-				snprintf(data->device.model_name, sizeof(data->device.model_name), "%s", p);
137
-
163
+				snprintf(d->device.model_name, sizeof(d->device.model_name), "%s", p);
138
 			if ((p = parse_text(line, "Unique ID: ")))
164
 			if ((p = parse_text(line, "Unique ID: ")))
139
-				snprintf(data->device.unique_id, sizeof(data->device.unique_id) , "%s", p);
140
-
165
+				snprintf(d->device.unique_id, sizeof(d->device.unique_id) , "%s", p);
141
 			if ((p = parse_text(line, "Video inputs: ")))
166
 			if ((p = parse_text(line, "Video inputs: ")))
142
-				data->inputs.num = strtoul(p, NULL, 10);
143
-
167
+				d->inputs.num = strtoul(p, NULL, 10);
144
 			if ((p = parse_text(line, "Video processing units: ")))
168
 			if ((p = parse_text(line, "Video processing units: ")))
145
-				data->device.num_video_processing_units = strtoul(p, NULL, 10);
146
-
169
+				d->device.num_video_processing_units = strtoul(p, NULL, 10);
147
 			if ((p = parse_text(line, "Video outputs: ")))
170
 			if ((p = parse_text(line, "Video outputs: ")))
148
-				data->outputs.num = strtoul(p, NULL, 10);
149
-
171
+				d->outputs.num = strtoul(p, NULL, 10);
150
 			if ((p = parse_text(line, "Video monitoring output: ")))
172
 			if ((p = parse_text(line, "Video monitoring output: ")))
151
-				data->device.num_video_monitoring_outputs = strtoul(p, NULL, 10);
152
-
173
+				d->device.num_video_monitoring_outputs = strtoul(p, NULL, 10);
153
 			if ((p = parse_text(line, "Serial ports: ")))
174
 			if ((p = parse_text(line, "Serial ports: ")))
154
-				data->device.num_serial_ports = strtoul(p, NULL, 10);
155
-			break;
156
-
157
-		case CMD_INPUT_LABELS:
158
-			snprintf(data->inputs.port[slot_pos].name, sizeof(data->inputs.port[slot_pos].name), "%s", slot_data);
159
-			break;
160
-
161
-		case CMD_OUTPUT_LABELS:
162
-			snprintf(data->outputs.port[slot_pos].name, sizeof(data->outputs.port[slot_pos].name), "%s", slot_data);
163
-			break;
164
-
165
-		case CMD_VIDEO_INPUT_STATUS:
166
-			snprintf(data->inputs.port[slot_pos].status, sizeof(data->inputs.port[slot_pos].status), "%s", slot_data);
167
-			break;
168
-
169
-		case CMD_VIDEO_OUTPUT_STATUS:
170
-			snprintf(data->outputs.port[slot_pos].status, sizeof(data->outputs.port[slot_pos].status), "%s", slot_data);
171
-			break;
172
-
173
-		case CMD_VIDEO_OUTPUT_LOCKS:
174
-			switch (slot_data[0]) {
175
-			case 'O': data->outputs.port[slot_pos].lock = PORT_LOCKED; break;
176
-			case 'L': data->outputs.port[slot_pos].lock = PORT_LOCKED_OTHER; break;
177
-			default : data->outputs.port[slot_pos].lock = PORT_UNLOCKED; break;
178
-			}
179
-			break;
180
-
181
-		case CMD_VIDEO_OUTPUT_ROUTING:
182
-			data->outputs.port[slot_pos].routed_to = dest_pos;
183
-
184
-		case CMD_PING:
185
-		case CMD_ACK:
186
-			// Do nothing
175
+				d->device.num_serial_ports = strtoul(p, NULL, 10);
187
 			break;
176
 			break;
188
 		case CMD_NAK:
177
 		case CMD_NAK:
189
 			ret = false;
178
 			ret = false;
190
 			break;
179
 			break;
180
+		default: break;
191
 		}
181
 		}
192
 	}
182
 	}
193
 	free(cmd_data);
183
 	free(cmd_data);
194
 	return ret;
184
 	return ret;
195
 }
185
 }
196
 
186
 
197
-int parse_text_buffer(struct videohub_data *data, char *cmd_buffer) {
187
+int parse_text_buffer(struct videohub_data *d, char *cmd_buffer) {
198
 	// The buffer contains only one command, no splitting is needed
188
 	// The buffer contains only one command, no splitting is needed
199
 	if (!strstr(cmd_buffer, "\n\n"))
189
 	if (!strstr(cmd_buffer, "\n\n"))
200
-		return parse_command(data, cmd_buffer);
190
+		return parse_command(d, cmd_buffer);
201
 	// Split commands and parse them one by one
191
 	// Split commands and parse them one by one
202
 	int ok_commands = 0;
192
 	int ok_commands = 0;
203
 	char *buf_copy = xstrdup(cmd_buffer);
193
 	char *buf_copy = xstrdup(cmd_buffer);
205
 	while(1) {
195
 	while(1) {
206
 		newcmd = strstr(cmd, "\n\n"); // Find next command
196
 		newcmd = strstr(cmd, "\n\n"); // Find next command
207
 		if (!newcmd) {
197
 		if (!newcmd) {
208
-			if (parse_command(data, cmd)) // Parse current command
198
+			if (parse_command(d, cmd)) // Parse current command
209
 				ok_commands++;
199
 				ok_commands++;
210
 			break;
200
 			break;
211
 		}
201
 		}
212
 		newcmd[0] = '\0'; // Terminate previous command
202
 		newcmd[0] = '\0'; // Terminate previous command
213
-		if (parse_command(data, cmd)) // Parse previous command
203
+		if (parse_command(d, cmd)) // Parse previous command
214
 			ok_commands++;
204
 			ok_commands++;
215
 		cmd = newcmd + 2; // Advance cmd to the next command
205
 		cmd = newcmd + 2; // Advance cmd to the next command
216
 	}
206
 	}
241
 }
231
 }
242
 
232
 
243
 void prepare_cmd_entry(struct videohub_data *d, struct vcmd_entry *e) {
233
 void prepare_cmd_entry(struct videohub_data *d, struct vcmd_entry *e) {
234
+	struct port_set *s_port = !e->cmd->ports1 ? NULL : (void *)d + e->cmd->ports1;
235
+	struct port_set *d_port = !e->cmd->ports2 ? NULL : (void *)d + e->cmd->ports2;
236
+
237
+	// All command types needs parsing of the "source port"
244
 	e->port_no1 = my_atoi(e->param1);
238
 	e->port_no1 = my_atoi(e->param1);
245
-	e->port_no2 = my_atoi(e->param2);
246
-	switch (e->cmd) {
247
-	case CMD_INPUT_LABELS:
248
-		if (e->port_no1 == 0 || e->port_no1 > d->inputs.num) {
249
-			e->port_no1 = get_port_by_name(&d->inputs, e->param1);
250
-			if (!e->port_no1)
251
-				die("Unknown input port number/name: %s", e->param1);
252
-		}
253
-		break;
254
-	case CMD_OUTPUT_LABELS:
255
-	case CMD_VIDEO_OUTPUT_LOCKS:
256
-		if (e->port_no1 == 0 || e->port_no1 > d->outputs.num) {
257
-			e->port_no1 = get_port_by_name(&d->outputs, e->param1);
258
-			if (!e->port_no1)
259
-				die("Unknown output port number/name: %s", e->param1);
260
-		}
261
-		e->lock = d->outputs.port[e->port_no1 - 1].lock;
262
-		break;
263
-	case CMD_VIDEO_OUTPUT_ROUTING:
264
-		if (e->port_no1 == 0 || e->port_no1 > d->outputs.num) {
265
-			e->port_no1 = get_port_by_name(&d->outputs, e->param1);
266
-			if (!e->port_no1)
267
-				die("Unknown output port number/name: %s", e->param1);
268
-		}
269
-		if (e->port_no2 == 0 || e->port_no2 > d->inputs.num) {
270
-			e->port_no2 = get_port_by_name(&d->inputs, e->param2);
239
+	if (e->port_no1 == 0 || e->port_no1 > s_port->num) {
240
+		e->port_no1 = get_port_by_name(s_port, e->param1);
241
+		if (!e->port_no1)
242
+			die("Unknown %s port number/name: %s", e->cmd->port_id1, e->param1);
243
+	}
244
+
245
+	// ROUTE type needs parsing of the "destination port"
246
+	if (e->cmd->type == PARSE_ROUTE) {
247
+		e->port_no2 = my_atoi(e->param2);
248
+		if (e->port_no2 == 0 || e->port_no2 > d_port->num) {
249
+			e->port_no2 = get_port_by_name(d_port, e->param2);
271
 			if (!e->port_no2)
250
 			if (!e->port_no2)
272
-				die("Unknown input port number/name: %s", e->param2);
251
+				die("Unknown %s port number/name: %s", e->cmd->port_id2, e->param2);
273
 		}
252
 		}
274
-		break;
275
-	case CMD_VIDEO_INPUT_STATUS:
276
-	case CMD_VIDEO_OUTPUT_STATUS:
277
-	case CMD_PROTOCOL_PREAMBLE:
278
-	case CMD_VIDEOHUB_DEVICE:
279
-	case CMD_PING:
280
-	case CMD_ACK:
281
-	case CMD_NAK:
282
-		break;
253
+	}
254
+
255
+	if (e->cmd->type == PARSE_LOCK) {
256
+		e->lock = s_port->port[e->port_no1 - 1].lock;
283
 	}
257
 	}
284
 }
258
 }
285
 
259
 
286
 void format_cmd_text(struct vcmd_entry *e, char *buf, unsigned int bufsz) {
260
 void format_cmd_text(struct vcmd_entry *e, char *buf, unsigned int bufsz) {
287
-	switch (e->cmd) {
288
-	case CMD_INPUT_LABELS:
289
-		snprintf(buf, bufsz, "%s:\n%u %s\n\n", get_cmd_text(e->cmd),
261
+	switch (e->cmd->type) {
262
+	case PARSE_LABEL:
263
+		snprintf(buf, bufsz, "%s:\n%u %s\n\n", videohub_commands_text[e->cmd->cmd],
290
 			e->port_no1 - 1, e->param2);
264
 			e->port_no1 - 1, e->param2);
291
 		break;
265
 		break;
292
-	case CMD_OUTPUT_LABELS:
293
-		snprintf(buf, bufsz, "%s:\n%u %s\n\n", get_cmd_text(e->cmd),
294
-			e->port_no1 - 1, e->param2);
295
-		break;
296
-	case CMD_VIDEO_OUTPUT_LOCKS:
297
-		snprintf(buf, bufsz, "%s:\n%u %s\n\n", get_cmd_text(e->cmd),
266
+	case PARSE_LOCK:
267
+		snprintf(buf, bufsz, "%s:\n%u %s\n\n", videohub_commands_text[e->cmd->cmd],
298
 			e->port_no1 - 1, e->do_lock ? "O" : (e->lock == PORT_LOCKED_OTHER ? "F" : "U"));
268
 			e->port_no1 - 1, e->do_lock ? "O" : (e->lock == PORT_LOCKED_OTHER ? "F" : "U"));
299
 		break;
269
 		break;
300
-	case CMD_VIDEO_OUTPUT_ROUTING:
301
-		snprintf(buf, bufsz, "%s:\n%u %u\n\n", get_cmd_text(e->cmd),
270
+	case PARSE_ROUTE:
271
+		snprintf(buf, bufsz, "%s:\n%u %u\n\n", videohub_commands_text[e->cmd->cmd],
302
 			e->port_no1 - 1, e->port_no2 - 1);
272
 			e->port_no1 - 1, e->port_no2 - 1);
303
 		break;
273
 		break;
304
-	case CMD_VIDEO_INPUT_STATUS:
305
-	case CMD_VIDEO_OUTPUT_STATUS:
306
-	case CMD_PROTOCOL_PREAMBLE:
307
-	case CMD_VIDEOHUB_DEVICE:
308
-	case CMD_PING:
309
-	case CMD_ACK:
310
-	case CMD_NAK:
311
-		break;
274
+	default: break;
312
 	}
275
 	}
313
 }
276
 }
314
 
277
 
315
 void show_cmd(struct videohub_data *d, struct vcmd_entry *e) {
278
 void show_cmd(struct videohub_data *d, struct vcmd_entry *e) {
279
+	struct port_set *s_port = !e->cmd->ports1 ? NULL : (void *)d + e->cmd->ports1;
280
+	struct port_set *d_port = !e->cmd->ports2 ? NULL : (void *)d + e->cmd->ports2;
316
 	const char *prefix = "videohub: ";
281
 	const char *prefix = "videohub: ";
317
-	switch (e->cmd) {
318
-	case CMD_INPUT_LABELS:
319
-		printf("%srename video input %d - \"%s\" to \"%s\"\n",
282
+	switch (e->cmd->type) {
283
+	case PARSE_LABEL:
284
+		printf("%srename %s %d \"%s\" to \"%s\"\n",
320
 			prefix,
285
 			prefix,
321
-			e->port_no1, d->inputs.port[e->port_no1 - 1].name,
286
+			e->cmd->port_id1,
287
+			e->port_no1, s_port->port[e->port_no1 - 1].name,
322
 			e->param2
288
 			e->param2
323
 		);
289
 		);
324
 		break;
290
 		break;
325
-	case CMD_OUTPUT_LABELS:
326
-		printf("%srename video output %d - \"%s\" to \"%s\"\n",
327
-			prefix,
328
-			e->port_no1, d->outputs.port[e->port_no1 - 1].name,
329
-			e->param2
330
-		);
331
-		break;
332
-	case CMD_VIDEO_OUTPUT_LOCKS:
333
-		printf("%s%s video output %d - \"%s\"\n",
291
+	case PARSE_LOCK:
292
+		printf("%s%s %s %d \"%s\"\n",
334
 			prefix,
293
 			prefix,
335
 			e->do_lock ? "lock" : (e->lock == PORT_LOCKED_OTHER ? "force unlock" : "unlock"),
294
 			e->do_lock ? "lock" : (e->lock == PORT_LOCKED_OTHER ? "force unlock" : "unlock"),
336
-			e->port_no1, d->outputs.port[e->port_no1 - 1].name
295
+			e->cmd->port_id1,
296
+			e->port_no1, s_port->port[e->port_no1 - 1].name
337
 		);
297
 		);
338
 		break;
298
 		break;
339
-	case CMD_VIDEO_OUTPUT_ROUTING:
340
-		printf("%sset video output %d \"%s\" to read from input %d \"%s\"\n",
299
+	case PARSE_ROUTE:
300
+		printf("%sset %s %d \"%s\" to read from %s %d \"%s\"\n",
341
 			prefix,
301
 			prefix,
342
-			e->port_no1, d->outputs.port[e->port_no1 - 1].name,
343
-			e->port_no2, d->inputs.port [e->port_no2 - 1].name
302
+			e->cmd->port_id1,
303
+			e->port_no1, s_port->port[e->port_no1 - 1].name,
304
+			e->cmd->port_id2,
305
+			e->port_no2, d_port->port [e->port_no2 - 1].name
344
 		);
306
 		);
345
 		break;
307
 		break;
346
-	case CMD_VIDEO_INPUT_STATUS:
347
-	case CMD_VIDEO_OUTPUT_STATUS:
348
-	case CMD_PROTOCOL_PREAMBLE:
349
-	case CMD_VIDEOHUB_DEVICE:
350
-	case CMD_PING:
351
-	case CMD_ACK:
352
-	case CMD_NAK:
353
-		break;
308
+	default: break;
354
 	}
309
 	}
355
 }
310
 }

+ 24
- 2
cmd.h View File

15
 
15
 
16
 #include <stdbool.h>
16
 #include <stdbool.h>
17
 
17
 
18
+#define NUM_COMMANDS 11
19
+
18
 enum vcmd {
20
 enum vcmd {
19
 	CMD_PROTOCOL_PREAMBLE,
21
 	CMD_PROTOCOL_PREAMBLE,
20
 	CMD_VIDEOHUB_DEVICE,
22
 	CMD_VIDEOHUB_DEVICE,
26
 	CMD_VIDEO_OUTPUT_STATUS,
28
 	CMD_VIDEO_OUTPUT_STATUS,
27
 	CMD_PING,
29
 	CMD_PING,
28
 	CMD_ACK,
30
 	CMD_ACK,
29
-	CMD_NAK,
31
+	CMD_NAK = (NUM_COMMANDS - 1),
30
 };
32
 };
31
 
33
 
34
+enum cmd_flags {
35
+	PARSE_NONE,   /* The result if this command needs no parsing */
36
+	PARSE_CUSTOM, /* Use custom parser for this command */
37
+	PARSE_LABEL,  /* Parse [port_num] [port_text] */
38
+	PARSE_STATUS, /* Parse [port_num] [port_status] */
39
+	PARSE_ROUTE,  /* Parse [port_num] [dest_port] */
40
+	PARSE_LOCK,   /* Parse [port_num] [dest_slot] */
41
+};
42
+
43
+struct videohub_commands {
44
+	enum vcmd		cmd;
45
+	enum cmd_flags	type;
46
+	size_t			ports1;
47
+	size_t			ports2;
48
+	const char		*port_id1;
49
+	const char		*port_id2;
50
+};
51
+
52
+extern struct videohub_commands videohub_commands[NUM_COMMANDS];
53
+
32
 bool parse_command(struct videohub_data *d, char *cmd);
54
 bool parse_command(struct videohub_data *d, char *cmd);
33
 int parse_text_buffer(struct videohub_data *data, char *cmd_buffer);
55
 int parse_text_buffer(struct videohub_data *data, char *cmd_buffer);
34
 
56
 
35
 struct vcmd_entry {
57
 struct vcmd_entry {
36
-	enum vcmd		cmd;
58
+	struct videohub_commands *cmd;
37
 	char			*param1;
59
 	char			*param1;
38
 	char			*param2;
60
 	char			*param2;
39
 	unsigned int	port_no1;
61
 	unsigned int	port_no1;

+ 4
- 4
videohubctrl.c View File

180
 					exit(EXIT_FAILURE);
180
 					exit(EXIT_FAILURE);
181
 				}
181
 				}
182
 				switch (j) {
182
 				switch (j) {
183
-				case 1001: c->cmd = CMD_INPUT_LABELS; break; // --vi-name
184
-				case 1002: c->cmd = CMD_OUTPUT_LABELS; break; // --vo-name
185
-				case 1011: c->cmd = CMD_VIDEO_OUTPUT_ROUTING; break; // --vo-route
183
+				case 1001: c->cmd = &videohub_commands[CMD_INPUT_LABELS]; break; // --vi-name
184
+				case 1002: c->cmd = &videohub_commands[CMD_OUTPUT_LABELS]; break; // --vo-name
185
+				case 1011: c->cmd = &videohub_commands[CMD_VIDEO_OUTPUT_ROUTING]; break; // --vo-route
186
 				}
186
 				}
187
 				c->param1 = argv[optind - 1];
187
 				c->param1 = argv[optind - 1];
188
 				c->param2 = argv[optind];
188
 				c->param2 = argv[optind];
194
 			case 1022: // --vo-unlock
194
 			case 1022: // --vo-unlock
195
 				if (num_parsed_cmds == ARRAY_SIZE(parsed_cmds.entry))
195
 				if (num_parsed_cmds == ARRAY_SIZE(parsed_cmds.entry))
196
 					die("No more than %u commands are supported.", num_parsed_cmds);
196
 					die("No more than %u commands are supported.", num_parsed_cmds);
197
-				c->cmd = CMD_VIDEO_OUTPUT_LOCKS;
197
+				c->cmd = &videohub_commands[CMD_VIDEO_OUTPUT_LOCKS];
198
 				c->param1 = argv[optind - 1];
198
 				c->param1 = argv[optind - 1];
199
 				c->do_lock = (j == 1021);
199
 				c->do_lock = (j == 1021);
200
 				c = &parsed_cmds.entry[++num_parsed_cmds];
200
 				c = &parsed_cmds.entry[++num_parsed_cmds];

Loading…
Cancel
Save