1 /*
2  *    webu_text.c
3  *
4  *    Create the text(programatic) interface Motion
5  *
6  *    This software is distributed under the GNU Public License Version 2
7  *    See also the file 'COPYING'.
8  *
9  *    This module processes the requests associated with the text inferface
10  *    of the webcontrol.  This interface is intended to be used by programs
11  *    and does not have any user interface to navigate.  The same actions
12  *    are available as the HTML as well as a few more.
13  *      Additional functions not directly available via HTML
14  *          get:    Returns the value of a parameter.
15  *          quit:   Terminates motion
16  *          list:   Lists all the configuration parameters and values
17  *          status  Whether the camera is in pause mode.
18  *          connection  Whether the camera connection is working
19  *
20  */
21 
22 #include "motion.h"
23 #include "webu.h"
24 #include "webu_text.h"
25 #include "translate.h"
26 
webu_text_seteol(struct webui_ctx * webui)27 static void webu_text_seteol(struct webui_ctx *webui) {
28     /* Set the end of line character for text interface */
29     if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
30         snprintf(webui->text_eol, WEBUI_LEN_PARM,"%s","<br>");
31     } else {
32         snprintf(webui->text_eol, WEBUI_LEN_PARM,"%s","");
33     }
34 
35 }
36 
webu_text_camera_name(struct webui_ctx * webui)37 static void webu_text_camera_name(struct webui_ctx *webui) {
38     char response[WEBUI_LEN_RESP];
39 
40     if (webui->cntlst[webui->thread_nbr]->conf.camera_name == NULL){
41         snprintf(response,sizeof(response),
42             "Camera %s %s\n"
43             ,webui->uri_camid,webui->text_eol
44         );
45     } else {
46         snprintf(response,sizeof(response),
47             "Camera %s %s\n"
48             ,webui->cntlst[webui->thread_nbr]->conf.camera_name
49             ,webui->text_eol
50         );
51     }
52     webu_write(webui, response);
53 
54 }
55 
webu_text_back(struct webui_ctx * webui,const char * prevuri)56 static void webu_text_back(struct webui_ctx *webui, const char *prevuri) {
57     char response[WEBUI_LEN_RESP];
58 
59     if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
60         snprintf(response,sizeof(response),
61             "<a href=/%s%s><- back</a><br><br>\n"
62             ,webui->uri_camid, prevuri
63         );
64         webu_write(webui, response);
65     }
66 
67 }
68 
webu_text_header(struct webui_ctx * webui)69 static void webu_text_header(struct webui_ctx *webui) {
70     char response[WEBUI_LEN_RESP];
71 
72     if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
73         snprintf(response, sizeof (response),"%s",
74             "<!DOCTYPE html>\n"
75             "<html>\n"
76             "<head><title>Motion "VERSION" </title></head>\n"
77             "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\n"
78             "<body>\n");
79         webu_write(webui, response);
80     }
81 }
82 
webu_text_trailer(struct webui_ctx * webui)83 static void webu_text_trailer(struct webui_ctx *webui) {
84     char response[WEBUI_LEN_RESP];
85 
86     if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
87         snprintf(response, sizeof (response),"%s",
88             "</body>\n"
89             "</html>\n");
90         webu_write(webui, response);
91     }
92 
93 }
94 
webu_text_badreq(struct webui_ctx * webui)95 void webu_text_badreq(struct webui_ctx *webui) {
96     char response[WEBUI_LEN_RESP];
97 
98     webu_text_header(webui);
99     snprintf(response, sizeof (response),
100         "Bad Request %s\n"
101         "The server did not understand your request. %s\n"
102         ,webui->text_eol, webui->text_eol
103     );
104     webu_write(webui, response);
105     webu_text_trailer(webui);
106 
107     return;
108 }
109 
webu_text_page_raw(struct webui_ctx * webui)110 static void webu_text_page_raw(struct webui_ctx *webui) {
111     /* Write the main page text */
112     char response[WEBUI_LEN_RESP];
113     int indx;
114 
115     snprintf(response, sizeof (response),
116         "Motion "VERSION" Running [%d] Camera%s \n"
117         ,webui->cam_count
118         ,(webui->cam_count > 1 ? "s" : "")
119     );
120     webu_write(webui, response);
121 
122     if (webui->cam_threads > 1){
123         for (indx = 1; indx < webui->cam_threads; indx++) {
124             snprintf(response, sizeof (response),
125                 "%d \n"
126                 ,webui->cntlst[indx]->camera_id
127             );
128             webu_write(webui, response);
129         }
130     }
131 
132 }
133 
webu_text_page_basic(struct webui_ctx * webui)134 static void webu_text_page_basic(struct webui_ctx *webui) {
135     /* Write the main page text */
136     char response[WEBUI_LEN_RESP];
137     int indx;
138 
139     webu_text_header(webui);
140     snprintf(response, sizeof (response),
141         "Motion "VERSION" Running [%d] Camera%s<br>\n"
142         "<a href='/%d/'>All</a><br>\n"
143         ,webui->cam_count, (webui->cam_count > 1 ? "s" : "")
144         ,webui->cntlst[0]->camera_id);
145     webu_write(webui, response);
146 
147     if (webui->cam_threads > 1){
148         for (indx = 1; indx < webui->cam_threads; indx++) {
149             if (webui->cntlst[indx]->conf.camera_name == NULL){
150                 snprintf(response, sizeof (response),
151                     "<a href='/%d/'>Camera %d</a><br>\n"
152                     , webui->cntlst[indx]->camera_id
153                     , indx);
154                 webu_write(webui, response);
155             } else {
156                 snprintf(response, sizeof (response),
157                     "<a href='/%d/'>Camera %s</a><br>\n"
158                     , webui->cntlst[indx]->camera_id
159                     ,webui->cntlst[indx]->conf.camera_name);
160                 webu_write(webui, response);
161             }
162         }
163     }
164     webu_text_trailer(webui);
165 
166 }
167 
webu_text_list_raw(struct webui_ctx * webui)168 static void webu_text_list_raw(struct webui_ctx *webui) {
169     /* Write out the options and values */
170     char response[WEBUI_LEN_RESP];
171     int indx_parm;
172     const char *val_parm;
173 
174     indx_parm = 0;
175     while (config_params[indx_parm].param_name != NULL){
176 
177         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
178             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
179             ((webui->thread_nbr != 0) && (config_params[indx_parm].main_thread != 0))){
180             indx_parm++;
181             continue;
182         }
183 
184         val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, webui->thread_nbr);
185         if (val_parm == NULL){
186             val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, 0);
187         }
188         snprintf(response, sizeof (response),
189             "  %s = %s \n"
190             ,config_params[indx_parm].param_name
191             ,val_parm
192         );
193         webu_write(webui, response);
194 
195         indx_parm++;
196     }
197 
198 }
199 
webu_text_list_basic(struct webui_ctx * webui)200 static void webu_text_list_basic(struct webui_ctx *webui) {
201     /* Write out the options and values */
202     char response[WEBUI_LEN_RESP];
203     int indx_parm;
204     const char *val_parm;
205 
206     webu_text_header(webui);
207 
208     snprintf(response,sizeof(response),
209         "<a href=/%s/config><- back</a><br><br>"
210         ,webui->uri_camid
211     );
212     webu_write(webui, response);
213 
214     webu_text_camera_name(webui);
215 
216     snprintf(response,sizeof(response),"%s","<ul>\n");
217     webu_write(webui, response);
218 
219     indx_parm = 0;
220     while (config_params[indx_parm].param_name != NULL){
221 
222         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
223             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
224             ((webui->thread_nbr != 0) && (config_params[indx_parm].main_thread != 0))){
225             indx_parm++;
226             continue;
227         }
228 
229         val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, webui->thread_nbr);
230         if (val_parm == NULL){
231             val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, 0);
232         }
233         snprintf(response, sizeof (response),
234             "  <li><a href=/%s/config/set?%s>%s</a> = %s</li>\n"
235             ,webui->uri_camid
236             ,config_params[indx_parm].param_name
237             ,config_params[indx_parm].param_name
238             ,val_parm);
239         webu_write(webui, response);
240 
241         indx_parm++;
242     }
243 
244     snprintf(response,sizeof(response),"%s","</ul>\n");
245     webu_write(webui, response);
246 
247     webu_text_trailer(webui);
248 
249 }
250 
webu_text_set_menu(struct webui_ctx * webui)251 static void webu_text_set_menu(struct webui_ctx *webui) {
252 
253     /* Write out the options and values to allow user to set them*/
254     char response[WEBUI_LEN_RESP];
255     int indx_parm;
256     const char *val_parm;
257 
258     webu_text_header(webui);
259 
260     webu_text_back(webui,"/config");
261 
262     webu_text_camera_name(webui);
263 
264     snprintf(response, sizeof (response),"%s",
265         "<script language='javascript'>function show() {\n"
266         " top.location.href='set?'\n"
267         " +document.n.onames.options[document.n.onames.selectedIndex].value\n"
268         " +'='+document.s.valor.value;}\n"
269         " </script>\n"
270         "<form name='n'> \n"
271         "<select name='onames'>\n"
272     );
273     webu_write(webui, response);
274 
275     indx_parm = 0;
276     while (config_params[indx_parm].param_name != NULL){
277 
278         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
279             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
280             ((webui->thread_nbr != 0) && (config_params[indx_parm].main_thread != 0))){
281             indx_parm++;
282             continue;
283         }
284 
285         val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, webui->thread_nbr);
286         if (val_parm == NULL){
287             val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, 0);
288         }
289         snprintf(response, sizeof(response),
290             "<option value='%s'>%s</option>\n"
291             ,config_params[indx_parm].param_name
292             ,config_params[indx_parm].param_name
293         );
294         webu_write(webui, response);
295 
296         indx_parm++;
297     }
298 
299     snprintf(response, sizeof (response),"%s",
300         "</select>\n"
301         "</form>\n"
302         "<form action=set name='s'ONSUBMIT='if (!this.submitted) return false; else return true;'>\n"
303         "<input type=text name='valor' value=''>\n"
304         "<input type='button' value='set' onclick='javascript:show()'>\n"
305         "</form>\n"
306     );
307     webu_write(webui, response);
308 
309     webu_text_trailer(webui);
310 
311 
312 }
313 
webu_text_set_query(struct webui_ctx * webui)314 static void webu_text_set_query(struct webui_ctx *webui) {
315 
316     /* Write out the options and values to allow user to set them*/
317     char response[WEBUI_LEN_RESP];
318     int indx_parm;
319     const char *val_parm;
320 
321     webu_text_header(webui);
322 
323     webu_text_back(webui,"/config/list");
324 
325     webu_text_camera_name(webui);
326 
327     indx_parm = 0;
328     while (config_params[indx_parm].param_name != NULL){
329 
330         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
331             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
332             ((webui->thread_nbr != 0) && (config_params[indx_parm].main_thread != 0)) ||
333             (strcmp(webui->uri_parm1, config_params[indx_parm].param_name))) {
334             indx_parm++;
335             continue;
336         }
337 
338         val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, webui->thread_nbr);
339         if (val_parm == NULL){
340             val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, 0);
341         }
342 
343         snprintf(response, sizeof (response),
344             "<form action=set?>\n"
345             "%s <input type=text name='%s' value='%s' size=60>\n"
346             "<input type='submit' value='set'>\n"
347             ,config_params[indx_parm].param_name
348             ,config_params[indx_parm].param_name
349             ,val_parm
350         );
351         webu_write(webui, response);
352 
353         break;
354 
355         indx_parm++;
356     }
357 
358     webu_text_trailer(webui);
359 
360 }
361 
webu_text_set_assign(struct webui_ctx * webui)362 static void webu_text_set_assign(struct webui_ctx *webui) {
363     /* Set a particular configuration parameter to desired value */
364 
365     char response[WEBUI_LEN_RESP];
366     int retcd;
367 
368     retcd = webu_process_config(webui);
369 
370     if (retcd == 0){
371         webu_text_header(webui);
372 
373         webu_text_back(webui,"/config");
374 
375         snprintf(response,sizeof(response),
376             "%s = %s %s\n"
377             "Done %s\n"
378             ,webui->uri_parm1
379             ,webui->uri_value1
380             ,webui->text_eol, webui->text_eol
381         );
382         webu_write(webui, response);
383 
384         webu_text_trailer(webui);
385     } else {
386         webu_text_badreq(webui);
387     }
388 
389 }
390 
webu_text_get_menu(struct webui_ctx * webui)391 static void webu_text_get_menu(struct webui_ctx *webui) {
392     char response[WEBUI_LEN_RESP];
393     int indx_parm;
394 
395     webu_text_header(webui);
396 
397     webu_text_back(webui,"/config");
398 
399     webu_text_camera_name(webui);
400 
401     snprintf(response, sizeof (response),"%s",
402         "<form action=get>\n"
403         "<select name='query'>\n"
404     );
405     webu_write(webui, response);
406 
407     indx_parm = 0;
408     while (config_params[indx_parm].param_name != NULL){
409 
410         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
411             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
412             ((webui->thread_nbr != 0) && (config_params[indx_parm].main_thread != 0))){
413             indx_parm++;
414             continue;
415         }
416 
417         snprintf(response, sizeof(response),
418             "<option value='%s'>%s</option>\n"
419             ,config_params[indx_parm].param_name
420             ,config_params[indx_parm].param_name
421         );
422         webu_write(webui, response);
423 
424         indx_parm++;
425     }
426 
427     snprintf(response, sizeof (response),"%s",
428         "</select>\n"
429         "<input type='submit' value='get'>\n"
430         "</form>\n"
431     );
432     webu_write(webui, response);
433 
434     webu_text_trailer(webui);
435 
436 }
437 
webu_text_action_quit(struct webui_ctx * webui)438 static void webu_text_action_quit(struct webui_ctx *webui) {
439     /* Shut down motion or the associated thread */
440     char response[WEBUI_LEN_RESP];
441 
442     webu_process_action(webui);
443 
444     webu_text_back(webui,"/action");
445 
446     webu_text_header(webui);
447     snprintf(response,sizeof(response),
448         "quit in progress ... bye %s\nDone %s\n"
449         ,webui->text_eol, webui->text_eol
450     );
451     webu_write(webui, response);
452     webu_text_trailer(webui);
453 
454 }
455 
webu_text_action_makemovie(struct webui_ctx * webui)456 static void webu_text_action_makemovie(struct webui_ctx *webui) {
457     /* end the event.  Legacy api name*/
458 
459     char response[WEBUI_LEN_RESP];
460 
461     webu_process_action(webui);
462 
463     webu_text_back(webui,"/action");
464 
465     webu_text_header(webui);
466 
467     snprintf(response,sizeof(response)
468         ,"makemovie for camera %d %s\nDone%s\n"
469         ,webui->cnt->camera_id
470         ,webui->text_eol,webui->text_eol
471     );
472     webu_write(webui, response);
473 
474     webu_text_trailer(webui);
475 
476 }
477 
webu_text_action_eventstart(struct webui_ctx * webui)478 static void webu_text_action_eventstart(struct webui_ctx *webui) {
479     /* Start the event*/
480 
481     char response[WEBUI_LEN_RESP];
482 
483     webu_process_action(webui);
484 
485     webu_text_header(webui);
486 
487     webu_text_back(webui,"/action");
488 
489     snprintf(response,sizeof(response)
490         ,"Start event for camera %d %s\nDone%s\n"
491         ,webui->cnt->camera_id
492         ,webui->text_eol,webui->text_eol
493     );
494     webu_write(webui, response);
495 
496     webu_text_trailer(webui);
497 
498 }
499 
webu_text_action_eventend(struct webui_ctx * webui)500 static void webu_text_action_eventend(struct webui_ctx *webui) {
501     /* End any active event*/
502 
503     char response[WEBUI_LEN_RESP];
504 
505     webu_process_action(webui);
506 
507     webu_text_header(webui);
508 
509     webu_text_back(webui,"/action");
510 
511     snprintf(response,sizeof(response)
512         ,"End event for camera %d %s\nDone %s\n"
513         ,webui->cnt->camera_id
514         ,webui->text_eol,webui->text_eol
515     );
516     webu_write(webui, response);
517 
518     webu_text_trailer(webui);
519 
520 }
521 
webu_text_action_snapshot(struct webui_ctx * webui)522 static void webu_text_action_snapshot(struct webui_ctx *webui) {
523     /* trigger a snapshot*/
524 
525     char response[WEBUI_LEN_RESP];
526 
527     webu_process_action(webui);
528 
529     webu_text_header(webui);
530 
531     webu_text_back(webui,"/action");
532 
533     snprintf(response,sizeof(response)
534         ,"Snapshot for camera %d %s\nDone%s\n"
535         ,webui->cnt->camera_id
536         ,webui->text_eol,webui->text_eol
537     );
538     webu_write(webui, response);
539 
540     webu_text_trailer(webui);
541 
542 }
543 
webu_text_action_restart(struct webui_ctx * webui)544 static void webu_text_action_restart(struct webui_ctx *webui) {
545     /* Restart*/
546 
547     char response[WEBUI_LEN_RESP];
548 
549     webu_process_action(webui);
550 
551     webu_text_header(webui);
552 
553     webu_text_back(webui,"/action");
554 
555     snprintf(response,sizeof(response)
556         ,"Restart in progress ...%s\nDone %s\n"
557         ,webui->text_eol,webui->text_eol
558     );
559     webu_write(webui, response);
560 
561     webu_text_trailer(webui);
562 
563 }
564 
webu_text_action_start(struct webui_ctx * webui)565 static void webu_text_action_start(struct webui_ctx *webui) {
566     /* un-pause the camera*/
567 
568     char response[WEBUI_LEN_RESP];
569 
570     webu_process_action(webui);
571 
572     webu_text_header(webui);
573 
574     webu_text_back(webui,"/detection");
575 
576     snprintf(response,sizeof(response)
577         ,"Camera %d Detection resumed%s\nDone %s\n"
578         ,webui->cnt->camera_id
579         ,webui->text_eol,webui->text_eol
580     );
581     webu_write(webui, response);
582 
583     webu_text_trailer(webui);
584 
585 }
586 
webu_text_action_pause(struct webui_ctx * webui)587 static void webu_text_action_pause(struct webui_ctx *webui) {
588     /* pause the camera*/
589 
590     char response[WEBUI_LEN_RESP];
591 
592     webu_process_action(webui);
593 
594     webu_text_header(webui);
595 
596     webu_text_back(webui,"/detection");
597 
598     snprintf(response,sizeof(response)
599         ,"Camera %d Detection paused%s\nDone %s\n"
600         ,webui->cnt->camera_id
601         ,webui->text_eol,webui->text_eol
602     );
603     webu_write(webui, response);
604 
605     webu_text_trailer(webui);
606 
607 }
608 
webu_text_action_write(struct webui_ctx * webui)609 static void webu_text_action_write(struct webui_ctx *webui) {
610     /* write the parms to file*/
611 
612     char response[WEBUI_LEN_RESP];
613 
614     webu_process_action(webui);
615 
616     webu_text_header(webui);
617 
618     webu_text_back(webui,"/config");
619 
620     snprintf(response,sizeof(response)
621         ,"Camera %d write %s\nDone %s\n"
622         ,webui->cnt->camera_id
623         ,webui->text_eol,webui->text_eol
624     );
625     webu_write(webui, response);
626 
627     webu_text_trailer(webui);
628 
629 }
630 
webu_text_action(struct webui_ctx * webui)631 static void webu_text_action(struct webui_ctx *webui) {
632     /* Call the action functions */
633 
634     if (!strcmp(webui->uri_cmd2,"makemovie")){
635         webu_text_action_makemovie(webui);
636 
637     } else if (strcmp(webui->uri_cmd2,"eventstart") == 0){
638         webu_text_action_eventstart(webui);
639 
640     } else if (!strcmp(webui->uri_cmd2,"eventend")){
641         webu_text_action_eventend(webui);
642 
643     } else if (!strcmp(webui->uri_cmd2,"snapshot")){
644         webu_text_action_snapshot(webui);
645 
646     } else if (!strcmp(webui->uri_cmd2,"restart")){
647         webu_text_action_restart(webui);
648 
649     } else if (!strcmp(webui->uri_cmd2,"start")){
650         webu_text_action_start(webui);
651 
652     } else if (!strcmp(webui->uri_cmd2,"pause")){
653         webu_text_action_pause(webui);
654 
655     } else if ((!strcmp(webui->uri_cmd2,"quit")) ||
656                (!strcmp(webui->uri_cmd2,"end"))){
657         webu_text_action_quit(webui);
658 
659     } else if ((!strcmp(webui->uri_cmd2,"write")) ||
660                (!strcmp(webui->uri_cmd2,"writeyes"))){
661         webu_text_action_write(webui);
662 
663     } else {
664         webu_text_badreq(webui);
665         MOTION_LOG(INF, TYPE_STREAM, NO_ERRNO,
666             _("Invalid action requested: >%s< >%s< >%s<")
667             ,webui->uri_camid, webui->uri_cmd1, webui->uri_cmd2);
668         return;
669     }
670 
671 }
672 
webu_text_track_pantilt(struct webui_ctx * webui)673 static void webu_text_track_pantilt(struct webui_ctx *webui) {
674     /* Call the track function */
675     char response[WEBUI_LEN_RESP];
676 
677     webu_text_header(webui);
678 
679     webu_text_back(webui,"/track");
680 
681     webu_text_camera_name(webui);
682 
683     snprintf(response,sizeof(response),"%s",
684         "<form action='set'>\n"
685         "Pan<input type=text name='pan' value=''>\n"
686         "Tilt<input type=text name='tilt' value=''>\n"
687         "<input type=submit value='set relative'>\n"
688         "</form>\n"
689         "<form action='set'>\n"
690         "X<input type=text name='x' value=''>\n"
691         "Y<input type=text name='y' value=''>\n"
692         "<input type=submit value='set absolute'>\n"
693         "</form>\n"
694     );
695     webu_write(webui, response);
696     webu_text_trailer(webui);
697 
698 }
699 
webu_text_track(struct webui_ctx * webui)700 static void webu_text_track(struct webui_ctx *webui) {
701     /* Call the track function */
702     char response[WEBUI_LEN_RESP];
703     int retcd;
704 
705     retcd = webu_process_track(webui);
706     if (retcd == 0){
707         webu_text_header(webui);
708 
709         webu_text_back(webui,"/track");
710 
711         webu_text_camera_name(webui);
712 
713         snprintf(response,sizeof(response)
714             ,"Track %s %s\n"
715             "Done %s\n"
716             ,webui->uri_cmd2,webui->text_eol
717             ,webui->text_eol
718         );
719         webu_write(webui, response);
720 
721         webu_text_trailer(webui);
722     } else {
723         webu_text_badreq(webui);
724     }
725 
726 }
727 
webu_text_menu(struct webui_ctx * webui)728 static void webu_text_menu(struct webui_ctx *webui) {
729     char response[WEBUI_LEN_RESP];
730 
731     webu_text_header(webui);
732 
733     snprintf(response,sizeof(response),
734         "<a href=/><- back</a><br><br>"
735     );
736     webu_write(webui, response);
737 
738     webu_text_camera_name(webui);
739     snprintf(response,sizeof(response),
740             "<a href='/%s/config'>config</a><br>\n"
741             "<a href='/%s/action'>action</a><br>\n"
742             "<a href='/%s/detection'>detection</a><br>\n"
743             "<a href='/%s/track'>track</a><br>\n"
744         ,webui->uri_camid, webui->uri_camid
745         ,webui->uri_camid, webui->uri_camid
746     );
747     webu_write(webui, response);
748     webu_text_trailer(webui);
749 
750 }
751 
webu_text_menu_config(struct webui_ctx * webui)752 static void webu_text_menu_config(struct webui_ctx *webui) {
753     char response[WEBUI_LEN_RESP];
754 
755     webu_text_header(webui);
756 
757     webu_text_back(webui,"/");
758 
759     webu_text_camera_name(webui);
760     snprintf(response,sizeof(response),
761         "<a href=/%s/config/list>list</a><br>"
762         "<a href=/%s/config/write>write</a><br>"
763         "<a href=/%s/config/set>set</a><br>"
764         "<a href=/%s/config/get>get</a><br>"
765         ,webui->uri_camid, webui->uri_camid
766         ,webui->uri_camid, webui->uri_camid
767     );
768     webu_write(webui, response);
769     webu_text_trailer(webui);
770 
771 }
772 
webu_text_menu_action(struct webui_ctx * webui)773 static void webu_text_menu_action(struct webui_ctx *webui) {
774     char response[WEBUI_LEN_RESP];
775 
776     webu_text_header(webui);
777 
778     webu_text_back(webui,"/");
779 
780     webu_text_camera_name(webui);
781     snprintf(response,sizeof(response),
782         "<a href=/%s/action/eventstart>eventstart</a><br>"
783         "<a href=/%s/action/eventend>eventend</a><br>"
784         "<a href=/%s/action/snapshot>snapshot</a><br>"
785         "<a href=/%s/action/restart>restart</a><br>"
786         "<a href=/%s/action/quit>quit</a><br>"
787         "<a href=/%s/action/end>end</a><br>"
788         ,webui->uri_camid, webui->uri_camid, webui->uri_camid
789         ,webui->uri_camid, webui->uri_camid, webui->uri_camid
790     );
791     webu_write(webui, response);
792     webu_text_trailer(webui);
793 
794 }
795 
webu_text_menu_detection(struct webui_ctx * webui)796 static void webu_text_menu_detection(struct webui_ctx *webui) {
797     char response[WEBUI_LEN_RESP];
798 
799     webu_text_header(webui);
800 
801     webu_text_back(webui,"/");
802 
803     webu_text_camera_name(webui);
804 
805     snprintf(response,sizeof(response),
806         "<a href=/%s/detection/status>status</a><br>"
807         "<a href=/%s/detection/start>start</a><br>"
808         "<a href=/%s/detection/pause>pause</a><br>"
809         "<a href=/%s/detection/connection>connection</a><br>"
810         ,webui->uri_camid, webui->uri_camid
811         ,webui->uri_camid, webui->uri_camid
812     );
813     webu_write(webui, response);
814     webu_text_trailer(webui);
815 
816 }
817 
webu_text_menu_track(struct webui_ctx * webui)818 static void webu_text_menu_track(struct webui_ctx *webui) {
819     char response[WEBUI_LEN_RESP];
820 
821     webu_text_header(webui);
822 
823     webu_text_back(webui,"/");
824 
825     webu_text_camera_name(webui);
826 
827     snprintf(response,sizeof(response),
828         "<a href=/%s/track/set>track set pan/tilt</a><br>"
829         "<a href=/%s/track/center>track center</a><br>"
830         ,webui->uri_camid, webui->uri_camid
831     );
832     webu_write(webui, response);
833 
834     webu_text_trailer(webui);
835 
836 }
837 
webu_text_submenu(struct webui_ctx * webui)838 static void webu_text_submenu(struct webui_ctx *webui) {
839 
840     if ((!strcmp(webui->uri_cmd1,"config")) &&
841         (strlen(webui->uri_cmd2) == 0)) {
842         webu_text_menu_config(webui);
843 
844     } else if ((!strcmp(webui->uri_cmd1,"action")) &&
845                 (strlen(webui->uri_cmd2) == 0)) {
846         webu_text_menu_action(webui);
847 
848     } else if ((!strcmp(webui->uri_cmd1,"detection")) &&
849                 (strlen(webui->uri_cmd2) == 0)) {
850         webu_text_menu_detection(webui);
851 
852     } else if ((!strcmp(webui->uri_cmd1,"track")) &&
853                 (strlen(webui->uri_cmd2) == 0)) {
854         webu_text_menu_track(webui);
855 
856     } else {
857         MOTION_LOG(INF, TYPE_STREAM, NO_ERRNO,
858             _("Invalid action requested: >%s< >%s< >%s<")
859             ,webui->uri_camid, webui->uri_cmd1, webui->uri_cmd2);
860         webu_text_badreq(webui);
861     }
862 
863 }
864 
webu_text_get_query(struct webui_ctx * webui)865 void webu_text_get_query(struct webui_ctx *webui) {
866     /* Write out the option value for one parm */
867     char response[WEBUI_LEN_RESP];
868     int indx_parm;
869     const char *val_parm;
870     char temp_name[WEBUI_LEN_PARM];
871 
872 
873     /* Search through the depreciated parms and if applicable,
874      * get the new parameter name so we can check its webcontrol_parms level
875      */
876     snprintf(temp_name, WEBUI_LEN_PARM, "%s", webui->uri_value1);
877     indx_parm=0;
878     while (dep_config_params[indx_parm].name != NULL) {
879         if (strcmp(dep_config_params[indx_parm].name, webui->uri_value1) == 0){
880             snprintf(temp_name, WEBUI_LEN_PARM, "%s", dep_config_params[indx_parm].newname);
881             break;
882         }
883         indx_parm++;
884     }
885 
886     indx_parm = 0;
887     while (config_params[indx_parm].param_name != NULL){
888 
889         if ((config_params[indx_parm].webui_level > webui->cntlst[0]->conf.webcontrol_parms) ||
890             (config_params[indx_parm].webui_level == WEBUI_LEVEL_NEVER) ||
891             strcmp(webui->uri_parm1,"query") ||
892             strcmp(temp_name, config_params[indx_parm].param_name)){
893             indx_parm++;
894             continue;
895         }
896 
897         val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, webui->thread_nbr);
898         if (val_parm == NULL){
899             val_parm = config_params[indx_parm].print(webui->cntlst, NULL, indx_parm, 0);
900         }
901 
902         if (strcmp(webui->uri_value1, config_params[indx_parm].param_name) != 0){
903             MOTION_LOG(NTC, TYPE_STREAM, NO_ERRNO
904             , _("'%s' option is depreciated.  New option name is '%s'")
905             ,webui->uri_value1, config_params[indx_parm].param_name);
906         }
907 
908         webu_text_header(webui);
909 
910         webu_text_back(webui,"/config");
911 
912         webu_text_camera_name(webui);
913 
914         if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
915             snprintf(response, sizeof (response),
916                 "<ul>\n"
917                 "  <li>%s = %s </li>\n"
918                 "</ul>\n"
919                 ,config_params[indx_parm].param_name
920                 ,val_parm
921             );
922         } else {
923             snprintf(response, sizeof (response),
924                 "%s = %s %s\n"
925                 "Done %s\n"
926                 ,config_params[indx_parm].param_name
927                 ,val_parm
928                 ,webui->text_eol, webui->text_eol
929             );
930         }
931         webu_write(webui, response);
932         webu_text_trailer(webui);
933 
934         break;
935     }
936 
937     if (config_params[indx_parm].param_name == NULL){
938         webu_text_badreq(webui);
939     }
940 
941 }
942 
webu_text_status(struct webui_ctx * webui)943 void webu_text_status(struct webui_ctx *webui) {
944     /* Write out the pause/active status */
945 
946     char response[WEBUI_LEN_RESP];
947     int indx, indx_st;
948 
949     webu_text_header(webui);
950 
951     webu_text_back(webui,"/detection");
952 
953     if (webui->thread_nbr == 0){
954         indx_st = 1;
955         if (webui->cam_threads == 1) indx_st = 0;
956 
957         for (indx = indx_st; indx < webui->cam_threads; indx++) {
958             snprintf(response, sizeof(response),
959                 "Camera %d Detection status %s %s\n"
960                 ,webui->cntlst[indx]->camera_id
961                 ,(!webui->cntlst[indx]->running)? "NOT RUNNING":
962                 (webui->cntlst[indx]->pause)? "PAUSE":"ACTIVE"
963                 ,webui->text_eol
964             );
965             webu_write(webui, response);
966         }
967     } else {
968         snprintf(response, sizeof(response),
969             "Camera %d Detection status %s %s\n"
970             ,webui->cnt->camera_id
971             ,(!webui->cnt->running)? "NOT RUNNING":
972             (webui->cnt->pause)? "PAUSE":"ACTIVE"
973             ,webui->text_eol
974         );
975         webu_write(webui, response);
976     }
977     webu_text_trailer(webui);
978 }
979 
webu_text_connection(struct webui_ctx * webui)980 void webu_text_connection(struct webui_ctx *webui) {
981     /* Write out the connection status */
982     char response[WEBUI_LEN_RESP];
983     int indx, indx_st;
984 
985     webu_text_header(webui);
986 
987     webu_text_back(webui,"/detection");
988 
989     webu_text_camera_name(webui);
990 
991     if (webui->thread_nbr == 0){
992         indx_st = 1;
993         if (webui->cam_threads == 1) indx_st = 0;
994 
995         for (indx = indx_st; indx < webui->cam_threads; indx++) {
996             snprintf(response,sizeof(response)
997                 , "Camera %d%s%s %s %s\n"
998                 ,webui->cntlst[indx]->camera_id
999                 ,webui->cntlst[indx]->conf.camera_name ? " -- " : ""
1000                 ,webui->cntlst[indx]->conf.camera_name ? webui->cntlst[indx]->conf.camera_name : ""
1001                 ,(!webui->cntlst[indx]->running)? "NOT RUNNING" :
1002                 (webui->cntlst[indx]->lost_connection)? "Lost connection": "Connection OK"
1003                 ,webui->text_eol
1004             );
1005             webu_write(webui, response);
1006         }
1007     } else {
1008         snprintf(response,sizeof(response)
1009             , "Camera %d%s%s %s %s\n"
1010             ,webui->cnt->camera_id
1011             ,webui->cnt->conf.camera_name ? " -- " : ""
1012             ,webui->cnt->conf.camera_name ? webui->cnt->conf.camera_name : ""
1013             ,(!webui->cnt->running)? "NOT RUNNING" :
1014              (webui->cnt->lost_connection)? "Lost connection": "Connection OK"
1015             ,webui->text_eol
1016         );
1017         webu_write(webui, response);
1018     }
1019     webu_text_trailer(webui);
1020 }
1021 
webu_text_list(struct webui_ctx * webui)1022 void webu_text_list(struct webui_ctx *webui) {
1023 
1024     if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
1025         webu_text_list_basic(webui);
1026     } else {
1027         webu_text_list_raw(webui);
1028     }
1029 
1030 }
1031 
webu_text_main(struct webui_ctx * webui)1032 void webu_text_main(struct webui_ctx *webui) {
1033 
1034     /* Main entry point for processing requests for the text interface */
1035 
1036     webu_text_seteol(webui);
1037 
1038     if (strlen(webui->uri_camid) == 0){
1039         if (webui->cntlst[0]->conf.webcontrol_interface == 2) {
1040             webu_text_page_basic(webui);
1041         } else {
1042             webu_text_page_raw(webui);
1043         }
1044 
1045     } else if (strlen(webui->uri_cmd1) == 0) {
1046         webu_text_menu(webui);
1047 
1048     } else if (strlen(webui->uri_cmd2) == 0) {
1049         webu_text_submenu(webui);
1050 
1051     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1052                (!strcmp(webui->uri_cmd2,"set")) &&
1053                (strlen(webui->uri_parm1) == 0)) {
1054         webu_text_set_menu(webui);
1055 
1056     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1057                (!strcmp(webui->uri_cmd2,"set")) &&
1058                (strlen(webui->uri_parm1) > 0) &&
1059                (strlen(webui->uri_value1) == 0) ) {
1060         webu_text_set_query(webui);
1061 
1062     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1063                (!strcmp(webui->uri_cmd2,"set"))) {
1064         webu_text_set_assign(webui);
1065 
1066     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1067                (!strcmp(webui->uri_cmd2,"write"))) {
1068         webu_text_action(webui);
1069 
1070     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1071                (!strcmp(webui->uri_cmd2,"list"))) {
1072         webu_text_list(webui);
1073 
1074     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1075                (!strcmp(webui->uri_cmd2,"get")) &&
1076                (strlen(webui->uri_parm1) == 0)) {
1077         webu_text_get_menu(webui);
1078 
1079     } else if ((!strcmp(webui->uri_cmd1,"config")) &&
1080                (!strcmp(webui->uri_cmd2,"get"))) {
1081         webu_text_get_query(webui);
1082 
1083     } else if ((!strcmp(webui->uri_cmd1,"detection")) &&
1084                (!strcmp(webui->uri_cmd2,"status"))) {
1085         webu_text_status(webui);
1086 
1087     } else if ((!strcmp(webui->uri_cmd1,"detection")) &&
1088                (!strcmp(webui->uri_cmd2,"connection"))) {
1089         webu_text_connection(webui);
1090 
1091     } else if ((!strcmp(webui->uri_cmd1,"detection")) &&
1092                (!strcmp(webui->uri_cmd2,"start"))) {
1093         webu_text_action(webui);
1094 
1095     } else if ((!strcmp(webui->uri_cmd1,"detection")) &&
1096                (!strcmp(webui->uri_cmd2,"pause"))) {
1097         webu_text_action(webui);
1098 
1099     } else if ((strcmp(webui->uri_cmd1,"action") == 0) &&
1100                (strcmp(webui->uri_cmd2,"quit") == 0)){
1101         webu_text_action(webui);
1102 
1103     } else if ((strcmp(webui->uri_cmd1,"action") == 0) &&
1104                (strcmp(webui->uri_cmd2,"end") == 0)){
1105         webu_text_action(webui);
1106 
1107     } else if (!strcmp(webui->uri_cmd1,"action")) {
1108         webu_text_action(webui);
1109 
1110     } else if ((strcmp(webui->uri_cmd1,"track") == 0) &&
1111                (strcmp(webui->uri_cmd2,"set") == 0) &&
1112                (strlen(webui->uri_parm1) == 0)) {
1113         webu_text_track_pantilt(webui);
1114 
1115     } else if ((strcmp(webui->uri_cmd1,"track") == 0)){
1116         webu_text_track(webui);
1117 
1118     } else{
1119         MOTION_LOG(INF, TYPE_STREAM, NO_ERRNO,
1120             _("Invalid action requested: >%s< >%s< >%s<")
1121             ,webui->uri_camid, webui->uri_cmd1, webui->uri_cmd2);
1122         webu_text_badreq(webui);
1123     }
1124 
1125     return;
1126 }
1127