Browse Source

Add configuration commands.

Add support for setting video input/output names, video output locking
and video output routing.
Georgi Chorbadzhiyski 9 years ago
parent
commit
20b533f5a8
7 changed files with 204 additions and 2 deletions
  1. 2
    0
      ChangeLog
  2. 11
    0
      README
  3. 0
    1
      TODO
  4. 99
    0
      cmd.c
  5. 13
    0
      cmd.h
  6. 2
    0
      data.h
  7. 77
    1
      videohubctrl.c

+ 2
- 0
ChangeLog View File

@@ -4,6 +4,8 @@ xxxx-xx-xx : Version next
4 4
  * Rename -h parameter (help) to -H.
5 5
  * Rename -s parameter (host) to -h.
6 6
  * Change output formatting to better show port locks and numbers.
7
+ * Add support for setting video input/output names, video output locking
8
+   and video output routing.
7 9
 
8 10
 2014-11-27 : Version 0.2
9 11
  * Fix port routing. Previously it was reversed and incorrect.

+ 11
- 0
README View File

@@ -90,6 +90,17 @@ Commands:
90 90
  -i --info                  | Show device info (default command).
91 91
  -m --monitor               | Show real time monitor for config changes.
92 92
 
93
+Configuration:
94
+ --vi-name <in_X> <name>    | Set input <name> to input port X.
95
+ --vo-name <out_X> <name>   | Set output <name> to output port X.
96
+
97
+ --vo-route <out_X> <in_Y>  | Connect output port X to input port Y.
98
+
99
+ --vo-lock <out_X>          | Lock output port X.
100
+ --vo-unlock <out_X>        | Unlock output port X.
101
+
102
+  NOTE: For <in_X/out_X/in_Y> you may use port number or port name.
103
+
93 104
 
94 105
 Example usage
95 106
 =============

+ 0
- 1
TODO View File

@@ -1,3 +1,2 @@
1
-- Add commands to set labels, routing and locking.
2 1
 - Create man page.
3 2
 - Add support for all Videohub commands described in the docs.

+ 99
- 0
cmd.c View File

@@ -302,3 +302,102 @@ int parse_text_buffer(struct videohub_data *data, char *cmd_buffer) {
302 302
 	free(bcopy);
303 303
 	return ok_commands;
304 304
 }
305
+
306
+// Try to find input/output with certain name, return 0 on not found, pos + 1 is found
307
+static int search_video_output_name(struct videohub_data *d, char *name) {
308
+	unsigned int i;
309
+	for(i = 0; i < MIN(d->device.num_video_outputs, ARRAY_SIZE(d->outputs)); i++) {
310
+		if (streq(name, d->outputs[i].name)) {
311
+			return i + 1;
312
+		}
313
+	}
314
+	return 0;
315
+}
316
+
317
+static int search_video_input_name(struct videohub_data *d, char *name) {
318
+	unsigned int i;
319
+	for(i = 0; i < MIN(d->device.num_video_inputs, ARRAY_SIZE(d->inputs)); i++) {
320
+		if (streq(name, d->inputs[i].name)) {
321
+			return i + 1;
322
+		}
323
+	}
324
+	return 0;
325
+}
326
+
327
+// Return 0 on error, number otherwise if it can parse the whole input
328
+static unsigned int my_atoi(char *txt) {
329
+	char *endptr = NULL;
330
+	if (!txt)
331
+		return 0;
332
+	unsigned int ret = strtoul(txt, &endptr, 10);
333
+	if (endptr == txt || *endptr)
334
+		return 0;
335
+	return ret;
336
+}
337
+
338
+void prepare_cmd_entry(struct videohub_data *d, struct vcmd_entry *e) {
339
+	e->port_no1 = my_atoi(e->param1);
340
+	e->port_no2 = my_atoi(e->param2);
341
+	switch (e->cmd) {
342
+	case CMD_INPUT_LABELS:
343
+		if (e->port_no1 == 0 || e->port_no1 > d->device.num_video_inputs) {
344
+			e->port_no1 = search_video_input_name(d, e->param1);
345
+			if (!e->port_no1)
346
+				die("Unknown input port number/name: %s", e->param1);
347
+		}
348
+		break;
349
+	case CMD_OUTPUT_LABELS:
350
+	case CMD_VIDEO_OUTPUT_LOCKS:
351
+		if (e->port_no1 == 0 || e->port_no1 > d->device.num_video_outputs) {
352
+			e->port_no1 = search_video_output_name(d, e->param1);
353
+			if (!e->port_no1)
354
+				die("Unknown output port number/name: %s", e->param1);
355
+			e->locked_other = d->outputs[e->port_no1 - 1].locked_other;
356
+		} else {
357
+			e->locked_other = d->outputs[e->port_no1 - 1].locked_other;
358
+		}
359
+		break;
360
+	case CMD_VIDEO_OUTPUT_ROUTING:
361
+		if (e->port_no1 == 0 || e->port_no1 > d->device.num_video_outputs) {
362
+			e->port_no1 = search_video_output_name(d, e->param1);
363
+			if (!e->port_no1)
364
+				die("Unknown output port number/name: %s", e->param1);
365
+		}
366
+		if (e->port_no2 == 0 || e->port_no2 > d->device.num_video_inputs) {
367
+			e->port_no2 = search_video_input_name(d, e->param2);
368
+			if (!e->port_no2)
369
+				die("Unknown input port number/name: %s", e->param2);
370
+		}
371
+		break;
372
+	case CMD_PROTOCOL_PREAMBLE:
373
+	case CMD_VIDEOHUB_DEVICE:
374
+	case CMD_PING:
375
+	case CMD_ACK:
376
+	case CMD_NAK:
377
+		break;
378
+	}
379
+}
380
+
381
+void format_cmd_text(struct vcmd_entry *e, char *buf, unsigned int bufsz) {
382
+	switch (e->cmd) {
383
+	case CMD_INPUT_LABELS:
384
+	case CMD_OUTPUT_LABELS:
385
+		snprintf(buf, bufsz, "%s:\n%u %s\n\n", get_cmd_text(e->cmd),
386
+			e->port_no1 - 1, e->param2);
387
+		break;
388
+	case CMD_VIDEO_OUTPUT_LOCKS:
389
+		snprintf(buf, bufsz, "%s:\n%u %s\n\n", get_cmd_text(e->cmd),
390
+			e->port_no1 - 1, e->do_lock ? "O" : (e->locked_other ? "F" : "U"));
391
+		break;
392
+	case CMD_VIDEO_OUTPUT_ROUTING:
393
+		snprintf(buf, bufsz, "%s:\n%u %u\n\n", get_cmd_text(e->cmd),
394
+			e->port_no1 - 1, e->port_no2 - 1);
395
+		break;
396
+	case CMD_PROTOCOL_PREAMBLE:
397
+	case CMD_VIDEOHUB_DEVICE:
398
+	case CMD_PING:
399
+	case CMD_ACK:
400
+	case CMD_NAK:
401
+		break;
402
+	}
403
+}

+ 13
- 0
cmd.h View File

@@ -30,4 +30,17 @@ enum vcmd {
30 30
 bool parse_command(struct videohub_data *d, char *cmd);
31 31
 int parse_text_buffer(struct videohub_data *data, char *cmd_buffer);
32 32
 
33
+struct vcmd_entry {
34
+	enum vcmd		cmd;
35
+	char			*param1;
36
+	char			*param2;
37
+	unsigned int	port_no1;
38
+	unsigned int	port_no2;
39
+	bool			do_lock;
40
+	bool			locked_other;
41
+};
42
+
43
+void prepare_cmd_entry(struct videohub_data *d, struct vcmd_entry *e);
44
+void format_cmd_text(struct vcmd_entry *e, char *buf, unsigned int bufsz);
45
+
33 46
 #endif

+ 2
- 0
data.h View File

@@ -19,6 +19,8 @@
19 19
 #define MAX_OUTPUTS 288
20 20
 #define MAX_NAME_LEN 64
21 21
 
22
+#define MAX_RUN_CMDS (MAX_INPUTS + (MAX_OUTPUTS * 2))
23
+
22 24
 struct device_desc {
23 25
 	bool			dev_present;
24 26
 	bool			needs_fw_update;

+ 77
- 1
videohubctrl.c View File

@@ -42,6 +42,11 @@ static const struct option long_options[] = {
42 42
 	{ "version",			no_argument,       NULL, 'V' },
43 43
 	{ "info",				no_argument,       NULL, 'i' },
44 44
 	{ "monitor",			no_argument,       NULL, 'm' },
45
+	{ "vi-name",			required_argument, NULL, 1001 },
46
+	{ "vo-name",			required_argument, NULL, 1002 },
47
+	{ "vo-route",			required_argument, NULL, 1011 },
48
+	{ "vo-lock",			required_argument, NULL, 1021 },
49
+	{ "vo-unlock",			required_argument, NULL, 1022 },
45 50
 	{ 0, 0, 0, 0 }
46 51
 };
47 52
 
@@ -63,10 +68,27 @@ static void show_help(struct videohub_data *data) {
63 68
 	printf(" -i --info                  | Show device info (default command).\n");
64 69
 	printf(" -m --monitor               | Show real time monitor for config changes.\n");
65 70
 	printf("\n");
71
+	printf("Configuration:\n");
72
+	printf(" --vi-name <in_X> <name>    | Set input <name> to input port X.\n");
73
+	printf(" --vo-name <out_X> <name>   | Set output <name> to output port X.\n");
74
+	printf("\n");
75
+	printf(" --vo-route <out_X> <in_Y>  | Connect output port X to input port Y.\n");
76
+	printf("\n");
77
+	printf(" --vo-lock <out_X>          | Lock output port X.\n");
78
+	printf(" --vo-unlock <out_X>        | Unlock output port X.\n");
79
+	printf("\n");
80
+	printf("  NOTE: For <in_X/out_X/in_Y> you may use port number or port name.\n");
81
+	printf("\n");
66 82
 }
67 83
 
84
+static int num_parsed_cmds = 0;
85
+static struct run_cmds {
86
+	struct vcmd_entry	entry[MAX_RUN_CMDS];
87
+} parsed_cmds;
88
+
68 89
 static void parse_options(struct videohub_data *data, int argc, char **argv) {
69 90
 	int j, err = 0;
91
+	struct vcmd_entry *c = &parsed_cmds.entry[0];
70 92
 	// Set defaults
71 93
 	data->dev_port = "9990";
72 94
 	while ((j = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
@@ -93,6 +115,36 @@ static void parse_options(struct videohub_data *data, int argc, char **argv) {
93 115
 			case 'm': // --monitor
94 116
 				show_monitor = 1;
95 117
 				break;
118
+			case 1001: // --vi-name
119
+			case 1002: // --vo-name
120
+			case 1011: // --vi-route
121
+			case 1012: // --vo-route
122
+				if (num_parsed_cmds == ARRAY_SIZE(parsed_cmds.entry))
123
+					die("No more than %u commands are supported.", num_parsed_cmds);
124
+				if (optind == argc || argv[optind - 1][0] == '-' || argv[optind][0] == '-') {
125
+					fprintf(stderr, "%s: option '%s' requires two arguments\n", argv[0], argv[optind - 2]);
126
+					exit(EXIT_FAILURE);
127
+				}
128
+				switch (j) {
129
+				case 1001: c->cmd = CMD_INPUT_LABELS; break; // --vi-name
130
+				case 1002: c->cmd = CMD_OUTPUT_LABELS; break; // --vo-name
131
+				case 1011: c->cmd = CMD_VIDEO_OUTPUT_ROUTING; break; // --vo-route
132
+				}
133
+				c->param1 = argv[optind - 1];
134
+				c->param2 = argv[optind];
135
+				c->param1 = argv[optind - 1];
136
+				c->param2 = argv[optind];
137
+				c = &parsed_cmds.entry[++num_parsed_cmds];
138
+				break;
139
+			case 1021: // --vo-lock
140
+			case 1022: // --vo-unlock
141
+				if (num_parsed_cmds == ARRAY_SIZE(parsed_cmds.entry))
142
+					die("No more than %u commands are supported.", num_parsed_cmds);
143
+				c->cmd = CMD_VIDEO_OUTPUT_LOCKS;
144
+				c->param1 = argv[optind - 1];
145
+				c->do_lock = (j == 1021);
146
+				c = &parsed_cmds.entry[++num_parsed_cmds];
147
+				break;
96 148
 			case 'H': // --help
97 149
 				show_help(data);
98 150
 				exit(EXIT_SUCCESS);
@@ -199,7 +251,31 @@ int main(int argc, char **argv) {
199 251
 		die("The device supports %d outputs. Recompile the program with more MAX_OUTPUTS (currently %d)\n",
200 252
 			data->device.num_video_outputs, MAX_OUTPUTS);
201 253
 
202
-	if (show_monitor) {
254
+	if (num_parsed_cmds) {
255
+		unsigned int i;
256
+		for (i = 0; i < ARRAY_SIZE(parsed_cmds.entry); i++) {
257
+			struct vcmd_entry *ve = &parsed_cmds.entry[i];
258
+			if (!ve->param1)
259
+				continue;
260
+			prepare_cmd_entry(data, &parsed_cmds.entry[i]);
261
+		}
262
+
263
+		//print_device_settings(data);
264
+		for (i = 0; i < ARRAY_SIZE(parsed_cmds.entry); i++) {
265
+			char cmd_buffer[1024];
266
+			struct vcmd_entry *ve = &parsed_cmds.entry[i];
267
+			if (!ve->param1)
268
+				continue;
269
+			format_cmd_text(ve, cmd_buffer, sizeof(cmd_buffer));
270
+			if (strlen(cmd_buffer)) {
271
+				printf("%s", cmd_buffer);
272
+				fdwrite(data->dev_fd, cmd_buffer, strlen(cmd_buffer));
273
+			}
274
+		}
275
+		//usleep(100000);
276
+		//read_device_command_stream(data);
277
+		//print_device_settings(data);
278
+	} else if (show_monitor) {
203 279
 		while (1) {
204 280
 			printf("\e[2J\e[H"); // Clear screen
205 281
 			printf("%s\n", program_id);

Loading…
Cancel
Save