1 /** **************************************************************
2 \page run_scripts Executing Script Parsing Class
3
4 \par run_script.cxx (FLAMP)
5
6 \par Author(s):
7 Robert Stiles, KK5VD, Copyright © 2014
8 <br>
9 <br>
10 This is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version. This software is distributed in
14 the hope that it will be useful, but WITHOUT ANY WARRANTY; without
15 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 PURPOSE. See the GNU General Public License for more details. You
17 should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 <br>
20 <br>
21 \par USE:
22 This code is the interface between the parsing engine and the
23 GUI code. The processing of the GUI is performed via 'C' style
24 callback fuctions.
25 <br>
26 \par NOTE:
27 Do not call process_xxx() functions directly. Must be called from the
28 ScriptParsing Class.
29 *******************************************************************/
30
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <iostream>
34 #include <fstream>
35 #include <sstream>
36 #include <cstring>
37 #include <ctime>
38 #include <vector>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <stdio.h>
42 #include <errno.h>
43 #include <time.h>
44 #include <pthread.h>
45 #include <libgen.h>
46 #include <ctype.h>
47 #include <sys/time.h>
48
49 #include <FL/Fl.H>
50 #include <FL/Enumerations.H>
51 #include <FL/Fl_Window.H>
52 #include <FL/Fl_Button.H>
53 #include <FL/Fl_Group.H>
54 #include <FL/Fl_Sys_Menu_Bar.H>
55 #include <FL/x.H>
56 #include <FL/Fl_Help_Dialog.H>
57 #include <FL/Fl_Menu_Item.H>
58 #include <FL/Fl_File_Icon.H>
59 //#include <FL/Fl_Native_File_Chooser.H>
60 #include <FL/Fl_File_Chooser.H>
61
62 #include "flamp.h"
63 #include "amp.h"
64 #include "flamp_dialog.h"
65
66 #include "debug.h"
67 #include "util.h"
68 #include "gettext.h"
69 #include "flinput2.h"
70 #include "date.h"
71 #include "calendar.h"
72 #include "icons.h"
73 #include "fileselect.h"
74 #include "file_io.h"
75 #include "status.h"
76 #include "pixmaps.h"
77 #include "threads.h"
78 #include "xml_io.h"
79 #include "tagSearch.h"
80 #include "time_table.h"
81 #include "ztimer.h"
82 #include "script_parsing.h"
83 #include "fileselect.h"
84
85 #ifdef WIN32
86 # include "flamprc.h"
87 # include "compat.h"
88 #endif
89
90 #include <FL/filename.H>
91
92 #include <FL/x.H>
93 #include <FL/Fl_Pixmap.H>
94 #include <FL/Fl_Image.H>
95
96 #ifdef __WIN32__
97 #define PATH_SEPERATOR "\\"
98 #define PATH_CHAR_SEPERATOR '\\'
99 #else
100 #define PATH_SEPERATOR "/"
101 #define PATH_CHAR_SEPERATOR '/'
102 #endif
103
104 pthread_mutex_t mutex_script_io = PTHREAD_MUTEX_INITIALIZER;
105
106 extern const char *s_basic_modes[];
107 extern const char *event_types[];
108
109 extern std::string flamp_script_dir;
110 extern std::string flamp_script_default_dir;
111
112 extern void addfile(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
113 extern void auto_load_tx_queue_from_tx_directory(void);
114
115 static int process_auto_load_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
116 static int process_base(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
117 static int process_blocks(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
118 static int process_callfrom(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
119 static int process_clear_missing(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
120 static int process_clear_rx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
121 static int process_clear_tx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
122 static int process_compression(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
123 static int process_event_forever(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
124 static int process_event_timed(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
125 static int process_event_times(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
126 static int process_event_type(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
127 static int process_event(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
128 static int process_file(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
129 static int process_hamcast_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
130 static int process_hamcast(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
131 static int process_header_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
132 static int process_header_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
133 static int process_info(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
134 static int process_inhibit_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
135 static int process_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
136 static int process_load_txdir(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
137 static int process_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
138 static int process_queue_filepath(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
139 static int process_reset(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
140 static int process_rx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
141 static int process_sync_with(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
142 static int process_tx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
143 static int process_tx_report(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
144 static int process_unproto_markers(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
145 static int process_warn_user(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
146 static int process_xmit_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
147
148 #if 0 // Unsued fuctions
149 static int process_callto(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
150 static int process_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
151 static int process_path(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
152 static int process_proto(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
153 #endif
154
155 typedef struct _call_script {
156 char filename[FL_PATH_MAX];
157 bool queueflag;
158 } CALL_SCRIPT;
159
160 CALL_SCRIPT call_script;
161
162 void script_execute(void *);
163 void script_execute(const char *filename, bool queue_flag);
164
165 //! @struct command_funcs
166 //! An array of script commands to their respect call functions. Used
167 //! to assign the call back routine.
168
169 typedef struct command_funcs {
170 char * command;
171 int (*func)(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
172 } COMMAND_FUNCS;
173
174 //! @typedef COMMAND_FUNCS
175 //! @see struct command_funcs
176 //! Storage for the command to function call backs.
177
178 static COMMAND_FUNCS callback_functions[] = {
179 { (char *) CMD_AUTO_LOAD_QUEUE, process_auto_load_queue },
180 { (char *) CMD_BASE, process_base },
181 { (char *) CMD_BLOCKS, process_blocks },
182 { (char *) CMD_CALLFROM, process_callfrom },
183 { (char *) CMD_CLEAR_MISSING, process_clear_missing },
184 { (char *) CMD_CLEAR_RXQ, process_clear_rx_queue },
185 { (char *) CMD_CLEAR_TXQ, process_clear_tx_queue },
186 { (char *) CMD_COMP, process_compression },
187 { (char *) CMD_EVENT_FOREVER, process_event_forever },
188 { (char *) CMD_EVENT_TIMED, process_event_timed },
189 { (char *) CMD_EVENT_TIMES, process_event_times },
190 { (char *) CMD_EVENT_TYPE, process_event_type },
191 { (char *) CMD_EVENT, process_event },
192 { (char *) CMD_FILE, process_file },
193 { (char *) CMD_HAMCAST_MODEM, process_hamcast_modem },
194 { (char *) CMD_HAMCAST, process_hamcast },
195 { (char *) CMD_HDR_REPEAT, process_header_repeat },
196 { (char *) CMD_HEADER_MODEM, process_header_modem },
197 { (char *) CMD_INFO, process_info },
198 { (char *) CMD_INHIBIT_HEADER, process_inhibit_header},
199 { (char *) CMD_INTERVAL, process_interval },
200 { (char *) CMD_LOAD_TXDIR, process_load_txdir},
201 { (char *) CMD_MODEM, process_modem },
202 { (char *) CMD_QUEUE_FILEPATH, process_queue_filepath },
203 { (char *) CMD_RESET, process_reset },
204 { (char *) CMD_RX_INTERVAL, process_rx_interval },
205 { (char *) CMD_SYNC_WITH, process_sync_with },
206 { (char *) CMD_TX_INTERVAL, process_tx_interval },
207 { (char *) CMD_TX_REPORT, process_tx_report },
208 { (char *) CMD_UNPROTO_MARKERS, process_unproto_markers },
209 { (char *) CMD_WARN_USER, process_warn_user },
210 { (char *) CMD_XMIT_REPEAT, process_xmit_repeat },
211 #if 0 // Currently not used at this level
212 { (char *) CMD_CALLTO, process_callto }, // Handled in the GUI code
213 { (char *) CMD_HEADER, process_header }, // Handled in HEADER MODEM COMMAND
214 { (char *) CMD_PATH, process_path }, // Handled internally
215 { (char *) CMD_PROTO, process_proto }, // Handled in the GUI code
216 #endif
217 { (char *) 0, 0}
218 };
219
220 #if 0 // Unused Functions, Do not remove code.
221 /** ********************************************************
222 * \brief Enable/Disable protocol use (AMP-2).
223 * \param sp Access to ScritpParsing members.
224 * \param sc Access to SCRIPT_COMMANDS structure variables.
225 * \return 0 (no error) Other (error)
226 ***********************************************************/
227 static int process_proto(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
228 {
229 bool flag = sp->proto(); // Logic inverted for syntax reasons.
230
231 if(flag) {
232 btn_enable_tx_unproto->value(false);
233 progStatus.enable_tx_unproto = false;
234 } else {
235 btn_enable_tx_unproto->value(true);
236 progStatus.enable_tx_unproto = true;
237 }
238
239 return 0;
240 }
241
242 /** ********************************************************
243 * \brief Not used.
244 * \param sp Access to ScritpParsing members.
245 * \param sc Access to SCRIPT_COMMANDS structure variables.
246 * \return 0 (no error) Other (error)
247 ***********************************************************/
248 static int process_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
249 {
250 btn_enable_header_modem->value(sp->header_modem_enable());
251 progStatus.use_header_modem = sp->header_modem_enable();
252
253 return 0;
254 }
255
256 /** ********************************************************
257 * \brief Assign Call to.
258 * \param sp Access to ScritpParsing members.
259 * \param sc Access to SCRIPT_COMMANDS structure variables.
260 * \return 0 (no error) Other (error)
261 * \par Note:
262 * This string storage can be assigned to anything. User
263 * should follow the limitations imposed by the rules
264 * of the host country.
265 ***********************************************************/
266 static int process_callto(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
267 {
268 return 0; // Leave this in place. cAmp panel data update conflict.
269
270 if(!sp->call_to().empty()) {
271 txt_tx_send_to->value(sp->call_to().c_str());
272 }
273
274 return 0;
275 }
276 #endif // #if 0 Unused Functions, Do not remove code.
277
278 /** ********************************************************
279 * \brief Trim leading and trailing spaces from string.
280 * \param s String to modify
281 * \return s modified string.
282 ***********************************************************/
trim(std::string & s)283 static inline std::string &trim(std::string &s) {
284 char *buffer = (char *)0;
285 char *dst = (char *)0;
286 char *end = (char *)0;
287 char *src = (char *)0;
288 long count = s.size();
289
290 buffer = new char[count + 1];
291 if(!buffer) return s;
292
293 memcpy(buffer, s.c_str(), count);
294 buffer[count] = 0;
295
296 dst = src = buffer;
297 end = &buffer[count];
298
299 while(src < end) {
300 if(*src > ' ') break;
301 src++;
302 }
303
304 if(src > dst) {
305 while((dst < end) && (src < end))
306 *dst++ = *src++;
307 *dst = 0;
308 }
309
310 while(end >= buffer) {
311 if(*end > ' ') break;
312 *end-- = 0;
313 }
314
315 s.assign(buffer);
316
317 delete [] buffer;
318
319 return s;
320 }
321
322 /** ********************************************************
323 * \brief Assign auto load queue flag for timed events.
324 * \param sp Access to ScritpParsing members.
325 * \param sc Access to SCRIPT_COMMANDS structure variables.
326 * \return 0 (no error) Other (error)
327 ***********************************************************/
process_auto_load_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)328 static int process_auto_load_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
329 {
330 bool value = sp->auto_load_queue();
331 progStatus.auto_load_queue = value;
332 btn_auto_load_queue->value(value);
333
334 return 0;
335 }
336
337 /** ********************************************************
338 * \brief Assign base conversion type.
339 * \param sp Access to ScritpParsing members.
340 * \param sc Access to SCRIPT_COMMANDS structure variables.
341 * \return 0 (no error) Other (error)
342 ***********************************************************/
process_base(ScriptParsing * sp,SCRIPT_COMMANDS * sc)343 static int process_base(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
344 {
345 return 0; // Leave this in place. cAmp panel data update conflict.
346
347 char *base_string = (char *)0;
348 int base = sp->base();
349 int index = 0;
350
351 switch(base) {
352 case 64:
353 base_string = (char *) "base64";
354 index = 1;
355 break;
356
357 case 128:
358 base_string = (char *) "base128";
359 index = 2;
360 break;
361
362 case 256:
363 base_string = (char *) "base256";
364 index = 3;
365 break;
366
367 default:
368 LOG_INFO("Unknown base encoder selected (%d)", base);
369 return -1;
370 }
371
372 progStatus.encoder = index;
373 encoders->value(base_string);
374
375 return 0;
376 }
377
378 /** ********************************************************
379 * \brief Assign block size.
380 * \param sp Access to ScritpParsing members.
381 * \param sc Access to SCRIPT_COMMANDS structure variables.
382 * \return 0 (no error) Other (error)
383 ***********************************************************/
process_blocks(ScriptParsing * sp,SCRIPT_COMMANDS * sc)384 static int process_blocks(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
385 {
386 int blocks = sp->blocks();
387 int mask = ~0x0f;
388 int value = 0;
389
390 if((blocks >= CNT_BLOCK_SIZE_MINIMUM) && (blocks <= CNT_BLOCK_SIZE_MAXIMUM)) {
391 value = blocks & mask;
392 cnt_blocksize->value(value);
393 progStatus.blocksize = value;
394 }
395
396 return 0;
397 }
398
399 /** ********************************************************
400 * \brief Assign Call from.
401 * \param sp Access to ScritpParsing members.
402 * \param sc Access to SCRIPT_COMMANDS structure variables.
403 * \return 0 (no error) Other (error)
404 * \par Note:
405 * This string storage can be assigned to anything. User
406 * should follow the limitations imposed by the rules
407 * of the host country.
408 ***********************************************************/
process_callfrom(ScriptParsing * sp,SCRIPT_COMMANDS * sc)409 static int process_callfrom(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
410 {
411 if(!sp->call_from().empty()) {
412 txt_tx_mycall->value(sp->call_from().c_str());
413 progStatus.my_call.assign(sp->call_from());
414 }
415
416 return 0;
417 }
418
419 /** ********************************************************
420 * \brief Set flag to clear the missing report queue after
421 * the retransmitting of the missed data.
422 * \param sp Access to ScritpParsing members.
423 * \param sc Access to SCRIPT_COMMANDS structure variables.
424 * \return 0 (no error) Other (error)
425 ***********************************************************/
process_clear_missing(ScriptParsing * sp,SCRIPT_COMMANDS * sc)426 static int process_clear_missing(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
427 {
428 bool value = sp->clear_missing();
429 progStatus.clear_tosend_on_tx_blocks = value;
430 btn_clear_tosend_on_tx_blocks->value(value);
431
432 return 0;
433 }
434
435 /** ********************************************************
436 * \brief Clear the receive queue.
437 * \param sp Access to ScritpParsing members.
438 * \param sc Access to SCRIPT_COMMANDS structure variables.
439 * \return 0 (no error) Other (error)
440 ***********************************************************/
process_clear_rx_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)441 static int process_clear_rx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
442 {
443 int count = rx_queue->size();
444 if(count) {
445 rx_queue->select(1);
446 receive_remove_from_queue(true);
447 }
448
449 return 0;
450 }
451
452 /** ********************************************************
453 * \brief Clear the transmit queue.
454 * \param sp Access to ScritpParsing members.
455 * \param sc Access to SCRIPT_COMMANDS structure variables.
456 * \return 0 (no error) Other (error)
457 ***********************************************************/
process_clear_tx_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)458 static int process_clear_tx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
459 {
460 int count = tx_queue->size();
461 if(count) {
462 tx_queue->select(1);
463 tx_removefile(true);
464 }
465
466 return 0;
467 }
468
469 /** ********************************************************
470 * \brief Enable/Disable Compression. Compression may or may
471 * not be enabled as file size takes precedence.
472 * \param sp Access to ScritpParsing members.
473 * \param sc Access to SCRIPT_COMMANDS structure variables.
474 * \return 0 (no error) Other (error)
475 ***********************************************************/
process_compression(ScriptParsing * sp,SCRIPT_COMMANDS * sc)476 static int process_compression(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
477 {
478 bool value = sp->comp();
479 progStatus.use_compression = value;
480 btn_use_compression->value(value);
481 return 0;
482 }
483
484 /** ********************************************************
485 * \brief
486 * \param sp Access to ScritpParsing members.
487 * \param sc Access to SCRIPT_COMMANDS structure variables.
488 * \return 0 (no error) Other (error)
489 ***********************************************************/
process_event_times(ScriptParsing * sp,SCRIPT_COMMANDS * sc)490 static int process_event_times(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
491 {
492 std::string event_time;
493
494 event_time.assign(sp->event_times());
495 if(event_time.empty()) return 0;
496
497 event_time = trim(event_time);
498 txt_repeat_times->value(event_time.c_str());
499 progStatus.repeat_times.assign(event_time);
500
501 return 0;
502 }
503
504 /** ********************************************************
505 * \brief
506 * \param sp Access to ScritpParsing members.
507 * \param sc Access to SCRIPT_COMMANDS structure variables.
508 * \return 0 (no error) Other (error)
509 ***********************************************************/
process_event_timed(ScriptParsing * sp,SCRIPT_COMMANDS * sc)510 static int process_event_timed(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
511 {
512 bool value = sp->event_timed();
513
514 btn_repeat_at_times->value(value);
515 btn_repeat_at_times->do_callback();
516
517 if(value)
518 sp->event_forever(false);
519
520 return 0;
521 }
522
523 /** ********************************************************
524 * \brief
525 * \param sp Access to ScritpParsing members.
526 * \param sc Access to SCRIPT_COMMANDS structure variables.
527 * \return 0 (no error) Other (error)
528 ***********************************************************/
process_event_type(ScriptParsing * sp,SCRIPT_COMMANDS * sc)529 static int process_event_type(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
530 {
531 int event_type = sp->event_type();
532 char *cPtr = (char *)0;
533
534 switch(event_type) {
535 case et_5_min:
536 case et_15_min:
537 case et_30_min:
538 case et_hourly:
539 case et_even_hours:
540 case et_odd_hours:
541 case et_repeat_at:
542 case et_one_time_at:
543 case et_continious_at:
544 progStatus.repeat_every = event_type;
545 cPtr = (char *) event_types[event_type];
546 if(cPtr) {
547 cbo_repeat_every->value(cPtr);
548 }
549 }
550
551 return 0;
552 }
553
554 /** ********************************************************
555 * \brief Enable/Disable Events (all kinds)
556 * \param sp Access to ScritpParsing members.
557 * \param sc Access to SCRIPT_COMMANDS structure variables.
558 * \return 0 (no error) Other (error)
559 **********************************************************/
process_event(ScriptParsing * sp,SCRIPT_COMMANDS * sc)560 static int process_event(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
561 {
562 bool value = sp->event();
563 int results = 1;
564 int warn = 0;
565
566 warn = sp->event_forever() | btn_repeat_forever->value();
567
568 if(value && warn)
569 results = fl_choice2(_("Enable Events?\nIMMEDIATE TRANSMISSION WILL OCCUR!"),
570 _("No"), _("Yes"), NULL);
571
572 warn = sp->event_timed() | btn_repeat_at_times->value();
573
574 if(value && warn)
575 results = fl_choice2(_("Enable Events?\nImmediate Transmission is possible!"),
576 _("No"), _("Yes"), NULL);
577
578 if(results) {
579 do_events->value(value);
580 do_events->do_callback();
581 }
582
583 return 0;
584 }
585
586 /** ********************************************************
587 * \brief Enable/Disable forever events
588 * \param sp Access to ScritpParsing members.
589 * \param sc Access to SCRIPT_COMMANDS structure variables.
590 * \return 0 (no error) Other (error)
591 **********************************************************/
process_event_forever(ScriptParsing * sp,SCRIPT_COMMANDS * sc)592 static int process_event_forever(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
593 {
594
595 bool repeat_forever = sp->event_forever();
596 btn_repeat_forever->value(repeat_forever);
597 btn_repeat_forever->do_callback();
598 if(repeat_forever)
599 sp->event_timed(false);
600
601 return 0;
602 }
603
604 /** ********************************************************
605 * \brief Add a file to the transmit queue.
606 * \param sp Access to ScritpParsing members.
607 * \param sc Access to SCRIPT_COMMANDS structure variables.
608 * \return 0 (no error) Other (error)
609 ***********************************************************/
process_file(ScriptParsing * sp,SCRIPT_COMMANDS * sc)610 static int process_file(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
611 {
612 addfile(sp, sc);
613
614 return 0;
615 }
616
617 /** ********************************************************
618 * \brief Select the Hamcast modem for each of the 4 positions
619 * available.
620 * \param sp Access to ScritpParsing members.
621 * \param sc Access to SCRIPT_COMMANDS structure variables.
622 * \return 0 (no error) Other (error)
623 ***********************************************************/
process_hamcast_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)624 static int process_hamcast_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
625 {
626 if(!sc->args[0]) return -1;
627
628 int modem_index = atoi(sc->args[0]);
629
630 if(modem_index < 1 || modem_index > 4) return -1;
631
632 switch(modem_index) {
633 case 1:
634 btn_hamcast_mode_enable_1->value(sp->hamcast_modem_1_enable());
635 progStatus.hamcast_mode_enable_1 = sp->hamcast_modem_1_enable();
636
637 if(!sp->hamcast_modem_1().empty()) {
638 cbo_hamcast_mode_selection_1->value(sp->hamcast_modem_1().c_str());
639 progStatus.hamcast_mode_selection_1 = cbo_hamcast_mode_selection_1->index();
640 }
641 break;
642
643 case 2:
644 btn_hamcast_mode_enable_2->value(sp->hamcast_modem_2_enable());
645 progStatus.hamcast_mode_enable_2 = sp->hamcast_modem_2_enable();
646
647 if(!sp->hamcast_modem_2().empty()) {
648 cbo_hamcast_mode_selection_2->value(sp->hamcast_modem_2().c_str());
649 progStatus.hamcast_mode_selection_2 = cbo_hamcast_mode_selection_2->index();
650 }
651 break;
652
653 case 3:
654 btn_hamcast_mode_enable_3->value(sp->hamcast_modem_3_enable());
655 progStatus.hamcast_mode_enable_3 = sp->hamcast_modem_3_enable();
656
657 if(!sp->hamcast_modem_3().empty()) {
658 cbo_hamcast_mode_selection_3->value(sp->hamcast_modem_3().c_str());
659 progStatus.hamcast_mode_selection_3 = cbo_hamcast_mode_selection_3->index();
660 }
661 break;
662
663 case 4:
664 btn_hamcast_mode_enable_4->value(sp->hamcast_modem_4_enable());
665 progStatus.hamcast_mode_enable_4 = sp->hamcast_modem_4_enable();
666
667 if(!sp->hamcast_modem_4().empty()) {
668 cbo_hamcast_mode_selection_4->value(sp->hamcast_modem_4().c_str());
669 progStatus.hamcast_mode_selection_4 = cbo_hamcast_mode_selection_4->index();
670 }
671 break;
672
673 }
674
675 return 0;
676 }
677
678 /** ********************************************************
679 * \brief Enable/Disable Hamcast operation during event
680 triggered operations.
681 * \param sp Access to ScritpParsing members.
682 * \param sc Access to SCRIPT_COMMANDS structure variables.
683 * \return 0 (no error) Other (error)
684 ***********************************************************/
process_hamcast(ScriptParsing * sp,SCRIPT_COMMANDS * sc)685 static int process_hamcast(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
686 {
687 btn_hamcast_mode_cycle->value(sp->hamcast());
688 progStatus.hamcast_mode_cycle = sp->hamcast();
689 return 0;
690 }
691
692 /** ********************************************************
693 * \brief Enable/Disable Header modem and select the header
694 * modem used for transmitting.
695 * \param sp Access to ScritpParsing members.
696 * \param sc Access to SCRIPT_COMMANDS structure variables.
697 * \return 0 (no error) Other (error)
698 ***********************************************************/
process_header_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)699 static int process_header_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
700 {
701 btn_enable_header_modem->value(sp->header_modem_enable());
702 progStatus.use_header_modem = sp->header_modem_enable();
703
704 if(!sp->header_modem().empty()) {
705 cbo_header_modes->value(sp->header_modem().c_str());
706 progStatus.header_selected_mode = cbo_header_modes->index();
707 }
708
709 return 0;
710 }
711
712 /** ********************************************************
713 * \brief Number of times the header data is repeated.
714 * \param sp Access to ScritpParsing members.
715 * \param sc Access to SCRIPT_COMMANDS structure variables.
716 * \return 0 (no error) Other (error)
717 ***********************************************************/
process_header_repeat(ScriptParsing * sp,SCRIPT_COMMANDS * sc)718 static int process_header_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
719 {
720 int value = sp->hdr_repeat();
721 int min = cnt_repeat_header->minimum();
722 int max = cnt_repeat_header->maximum();
723
724 if(value > max) value = max;
725 if(value < min) value = min;
726
727 cnt_repeat_header->value(value);
728 progStatus.repeat_header = value;
729
730 return 0;
731 }
732
733 /** ********************************************************
734 * \brief Set the information field in the configuration panel
735 * \param sp Access to ScritpParsing members.
736 * \param sc Access to SCRIPT_COMMANDS structure variables.
737 * \return 0 (no error) Other (error)
738 ***********************************************************/
process_info(ScriptParsing * sp,SCRIPT_COMMANDS * sc)739 static int process_info(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
740 {
741 if(!sp->info().empty()) {
742 txt_tx_myinfo->value(sp->info().c_str());
743 progStatus.my_info.assign(sp->info());
744 }
745
746 return 0;
747 }
748
749 /** ********************************************************
750 * \brief Enable/Diable Inhibit header modem on fills.
751 * \param sp Access to ScritpParsing members.
752 * \param sc Access to SCRIPT_COMMANDS structure variables.
753 * \return 0 (no error) Other (error)
754 ***********************************************************/
process_inhibit_header(ScriptParsing * sp,SCRIPT_COMMANDS * sc)755 static int process_inhibit_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
756 {
757 btn_disable_header_modem_on_block_fills->value(sp->inhibit_header());
758 progStatus.disable_header_modem_on_block_fills = sp->inhibit_header();
759
760 return 0;
761 }
762
763 /** ********************************************************
764 * \brief Enable/Disable Interval timer
765 * \param sp Access to ScritpParsing members.
766 * \param sc Access to SCRIPT_COMMANDS structure variables.
767 * \return 0 (no error) Other (error)
768 ***********************************************************/
process_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)769 static int process_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
770 {
771 btn_enable_txrx_interval->value(sp->interval());
772 progStatus.use_txrx_interval = sp->interval();
773
774 return 0;
775 }
776
777 /** ********************************************************
778 * \brief Flag event load queue to load from tx/ direcotry
779 * \param sp Access to ScritpParsing members.
780 * \param sc Access to SCRIPT_COMMANDS structure variables.
781 * \return 0 (no error) Other (error)
782 ***********************************************************/
process_load_txdir(ScriptParsing * sp,SCRIPT_COMMANDS * sc)783 static int process_load_txdir(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
784 {
785 btn_load_from_tx_folder->value(sp->load_txdir());
786 progStatus.load_from_tx_folder = sp->load_txdir();
787
788 return 0;
789 }
790
791 /** ********************************************************
792 * \brief Select transmit modem
793 * \param sp Access to ScritpParsing members.
794 * \param sc Access to SCRIPT_COMMANDS structure variables.
795 * \return 0 (no error) Other (error)
796 ***********************************************************/
process_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)797 static int process_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
798 {
799 if(!sp->modem().empty()) {
800 cbo_modes->put_value(sp->modem().c_str());
801 progStatus.selected_mode = cbo_modes->index();
802 cbo_modes->do_callback();
803 }
804
805 return 0;
806 }
807
808 /** ********************************************************
809 * \brief Set the filename and path of the event queue load script.
810 * \param sp Access to ScritpParsing members.
811 * \param sc Access to SCRIPT_COMMANDS structure variables.
812 * \return 0 (no error) Other (error)
813 ***********************************************************/
process_queue_filepath(ScriptParsing * sp,SCRIPT_COMMANDS * sc)814 static int process_queue_filepath(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
815 {
816 if(sp->queue_filepath().empty()) return 0;
817
818 txt_auto_load_queue_path->value(sp->queue_filepath().c_str());
819 progStatus.auto_load_queue_path.assign(sp->queue_filepath());
820 return 0;
821 }
822
823 /** ********************************************************
824 * \brief Reset Configuration panel attributes
825 * \param sp Access to ScritpParsing members.
826 * \param sc Access to SCRIPT_COMMANDS structure variables.
827 * \return 0 (no error) Other (error)
828 ***********************************************************/
process_reset(ScriptParsing * sp,SCRIPT_COMMANDS * sc)829 static int process_reset(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
830 {
831 int reset_type = sp->reset();
832
833 switch(reset_type) {
834 case RESET_ALL:
835
836 sp->call_to("");
837 txt_tx_mycall->value("");
838 progStatus.my_call.clear();
839
840 sp->info("");
841 txt_tx_myinfo->value("");
842 progStatus.my_info.clear();
843
844 case RESET_PARTIAL:
845
846 sp->interval(false);
847 btn_enable_txrx_interval->value(false);
848 progStatus.use_txrx_interval = false;
849
850 sp->sync_with_flamp(false);
851 btn_sync_mode_flamp_fldigi->value(false);
852 progStatus.sync_mode_flamp_fldigi = false;
853
854 sp->sync_with_fldigi(false);
855 btn_sync_mode_fldigi_flamp->value(false);
856 progStatus.sync_mode_fldigi_flamp = false;
857
858 sp->sync_with_prior(false);
859 btn_fldigi_xmt_mode_change->value(false);
860 progStatus.fldigi_xmt_mode_change = false;
861
862 sp->tx_report(false);
863 btn_enable_tx_on_report->value(false);
864 progStatus.use_txrx_interval = false;
865
866 sp->warn_user(false);
867 btn_enable_delete_warning->value(false);
868 progStatus.use_tx_on_report = false;
869
870 sp->clear_missing(false);
871 btn_clear_tosend_on_tx_blocks->value(false);
872 progStatus.clear_tosend_on_tx_blocks = false;
873
874 sp->inhibit_header(false);
875 btn_disable_header_modem_on_block_fills->value(false);
876 progStatus.disable_header_modem_on_block_fills = false;
877
878 sp->header_modem_enable(false);
879 btn_enable_header_modem->value(false);
880 progStatus.use_header_modem = false;
881
882 sp->proto(true);
883 btn_enable_tx_unproto->value(false);
884 progStatus.enable_tx_unproto = false;
885
886 sp->unproto_markers(false);
887 btn_enable_unproto_markers->value(false);
888 progStatus.enable_unproto_markers = false;
889
890 sp->load_txdir(false);
891 btn_load_from_tx_folder->value(false);
892 progStatus.load_from_tx_folder = false;
893
894 sp->event(false);
895 btn_repeat_at_times->value(false);
896 progStatus.repeat_at_times = false;
897
898 sp->queue_filepath("");
899 txt_auto_load_queue_path->value("");
900 progStatus.auto_load_queue_path.clear();
901
902 sp->auto_load_queue(false);
903 btn_auto_load_queue->value(false);
904 progStatus.auto_load_queue = false;
905
906 sp->event_times("");
907 txt_repeat_times->value("");
908 progStatus.repeat_times.clear();
909
910 sp->hamcast_modem_1_enable(false);
911 btn_hamcast_mode_enable_1->value(false);
912 progStatus.hamcast_mode_enable_1 = false;
913
914 sp->hamcast_modem_2_enable(false);
915 btn_hamcast_mode_enable_2->value(false);
916 progStatus.hamcast_mode_enable_2 = false;
917
918 sp->hamcast_modem_3_enable(false);
919 btn_hamcast_mode_enable_3->value(false);
920 progStatus.hamcast_mode_enable_3 = false;
921
922 sp->hamcast_modem_4_enable(false);
923 btn_hamcast_mode_enable_4->value(false);
924 progStatus.hamcast_mode_enable_4 = false;
925
926 sp->hamcast(false);
927 btn_hamcast_mode_cycle->value(false);
928 progStatus.hamcast_mode_cycle = false;
929
930 sp->event_forever(false);
931 btn_repeat_forever->value(false);
932 btn_repeat_forever->do_callback(); // Requires callback()
933
934 sp->event_timed(false);
935 btn_repeat_at_times->value(false);
936 btn_repeat_at_times->do_callback(); // Requires callback()
937
938 do_events->value(false);
939 do_events->do_callback(); // Requires callback()
940
941 default:;
942 }
943
944 return 0;
945 }
946
947 /** ********************************************************
948 * \brief Set the receive interval in seconds
949 * \param sp Access to ScritpParsing members.
950 * \param sc Access to SCRIPT_COMMANDS structure variables.
951 * \return 0 (no error) Other (error)
952 ***********************************************************/
process_rx_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)953 static int process_rx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
954 {
955 int max = cnt_rx_interval_secs->maximum();
956 int min = cnt_rx_interval_secs->minimum();
957 int value = sp->rx_interval();
958
959 if(value > max) value = max;
960 if(value < min) value = min;
961
962 cnt_rx_interval_secs->value(value);
963 progStatus.rx_interval_seconds = value;
964
965 return 0;
966 }
967
968 /** ********************************************************
969 * \brief Set the sync modes between FLAMP and FLDIGI
970 * \param sp Access to ScritpParsing members.
971 * \param sc Access to SCRIPT_COMMANDS structure variables.
972 * \return 0 (no error) Other (error)
973 ***********************************************************/
process_sync_with(ScriptParsing * sp,SCRIPT_COMMANDS * sc)974 static int process_sync_with(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
975 {
976 std::string str;
977
978 str.assign(sc->args[0]);
979
980 if(str.empty()) return 0;
981
982 int i = 0;
983 int c = (int) str.size();
984
985 for(i = 0; i < c; i++)
986 str[i] = toupper(str[i]);
987
988 if(strncmp(str.c_str(), "FLDIGI", 6) == 0) {
989 btn_sync_mode_flamp_fldigi->value(sp->sync_with_fldigi());
990 progStatus.sync_mode_flamp_fldigi = sp->sync_with_fldigi();
991 btn_sync_mode_flamp_fldigi->do_callback();
992 return 0;
993 }
994
995 if(strncmp(str.c_str(), "FLAMP", 5) == 0) {
996 btn_sync_mode_fldigi_flamp->value(sp->sync_with_flamp());
997 progStatus.sync_mode_fldigi_flamp = sp->sync_with_flamp();
998 btn_sync_mode_fldigi_flamp->do_callback();
999 return 0;
1000 }
1001
1002 if(strncmp(str.c_str(), "PRIOR", 5) == 0) {
1003 btn_fldigi_xmt_mode_change->value(sp->sync_with_prior());
1004 progStatus.fldigi_xmt_mode_change = sp->sync_with_prior();
1005 btn_fldigi_xmt_mode_change->do_callback();
1006 return 0;
1007 }
1008
1009 return -1;
1010 }
1011
1012 /** ********************************************************
1013 * \brief Set the transmit interval in minutes.
1014 * \param sp Access to ScritpParsing members.
1015 * \param sc Access to SCRIPT_COMMANDS structure variables.
1016 * \return 0 (no error) Other (error)
1017 ***********************************************************/
process_tx_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1018 static int process_tx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1019 {
1020 float max = cnt_tx_interval_mins->maximum();
1021 float min = cnt_tx_interval_mins->minimum();
1022 float value = sp->tx_interval();
1023
1024 if(value > max) value = max;
1025 if(value < min) value = min;
1026
1027 cnt_tx_interval_mins->value(value);
1028 progStatus.tx_interval_minutes = value;
1029 set_txt_tx_interval();
1030
1031 return 0;
1032 }
1033
1034 /** ********************************************************
1035 * \brief Enable/Disable transmit on report
1036 * \param sp Access to ScritpParsing members.
1037 * \param sc Access to SCRIPT_COMMANDS structure variables.
1038 * \return 0 (no error) Other (error)
1039 ***********************************************************/
process_tx_report(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1040 static int process_tx_report(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1041 {
1042 btn_enable_tx_on_report->value(sp->tx_report());
1043 progStatus.use_tx_on_report = sp->tx_report();
1044
1045 return 0;
1046 }
1047
1048 /** ********************************************************
1049 * \brief Enable/Disable unproto start and end markers.
1050 * \param sp Access to ScritpParsing members.
1051 * \param sc Access to SCRIPT_COMMANDS structure variables.
1052 * \return 0 (no error) Other (error)
1053 ***********************************************************/
process_unproto_markers(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1054 static int process_unproto_markers(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1055 {
1056 btn_enable_unproto_markers->value(sp->unproto_markers());
1057 progStatus.enable_unproto_markers = sp->unproto_markers();
1058
1059 return 0;
1060 }
1061
1062 /** ********************************************************
1063 * \brief Enable/Disable dialog box warning when deleting
1064 * transmit queue items.
1065 * \param sp Access to ScritpParsing members.
1066 * \param sc Access to SCRIPT_COMMANDS structure variables.
1067 * \return 0 (no error) Other (error)
1068 ***********************************************************/
process_warn_user(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1069 static int process_warn_user(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1070 {
1071 btn_enable_delete_warning->value(sp->warn_user());
1072 progStatus.enable_delete_warning = sp->warn_user();
1073
1074 return 0;
1075 }
1076
1077 /** ********************************************************
1078 * \brief Set the number of time the non header data is sent.
1079 * \param sp Access to ScritpParsing members.
1080 * \param sc Access to SCRIPT_COMMANDS structure variables.
1081 * \return 0 (no error) Other (error)
1082 ***********************************************************/
process_xmit_repeat(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1083 static int process_xmit_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1084 {
1085 int max = cnt_repeat_nbr->maximum();
1086 int min = cnt_repeat_nbr->minimum();
1087 int value = sp->xmit_repeat();
1088
1089 if(value > max) value = max;
1090 if(value < min) value = min;
1091
1092 cnt_repeat_nbr->value(value);
1093 progStatus.repeatNN = value;
1094
1095
1096 return 0;
1097 }
1098
1099 /** ********************************************************
1100 * \brief Call back function when executing a configuration script.
1101 * Called from the File->Execute Config Script menu item.
1102 * \param void
1103 ***********************************************************/
script_execute(const char * filename,bool queue_flag)1104 void script_execute(const char *filename, bool queue_flag)
1105 {
1106 int count = 0;
1107 int index = 0;
1108 SCRIPT_CODES error = script_no_errors;
1109 ScriptParsing *sp = 0;
1110 static std::string script_filename = "";
1111
1112 if(!filename) {
1113 LOG_INFO("Script file name (path) null pointer");
1114 return;
1115 }
1116
1117 script_filename.assign(filename);
1118
1119 if(script_filename.empty()) {
1120 LOG_INFO("Script file name (path) invalid");
1121 return;
1122 }
1123
1124 sp = new ScriptParsing;
1125
1126 if(!sp) {
1127 LOG_INFO("ScriptParsing Class Allocation Fail (%s)", script_filename.c_str());
1128 return;
1129 }
1130
1131 index = 0;
1132 // All commands support callback functions.
1133 while(callback_functions[index].command) {
1134 sp->assign_callback(callback_functions[index].command, callback_functions[index].func);
1135 index++;
1136 }
1137
1138 count = 0;
1139 while(s_modes[count]) {
1140 if(count > 100) break;
1141 count++;
1142 }
1143
1144 // Assign "validation parameters" to the following functions.
1145 sp->assign_valid_parameters("MODEM", (const char **) s_modes, count);
1146 sp->assign_valid_parameters("HEADER MODEM", (const char **) s_modes, count);
1147 sp->assign_valid_parameters("HAMCAST MODEM", (const char **) s_modes, count);
1148
1149 // Limit command set depending on queue_flag
1150
1151 if(queue_flag) {
1152 sp->file_type(QUEUE_COMMAND);
1153 } else {
1154 sp->file_type(SCRIPT_COMMAND);
1155 }
1156
1157 // LOG_INFO("Executing Script:%s", script_filename.c_str());
1158
1159 error = sp->parse_commands((char *) script_filename.c_str());
1160
1161 if(error != script_no_errors) {
1162 LOG_INFO("Error(s) in processing script file: %s", script_filename.c_str());
1163 fl_alert("%s", "Script File contains Error(s)\nSee Log file for details.");
1164 }
1165
1166 if(sp)
1167 delete sp;
1168 }
1169
1170 /** ********************************************************
1171 * \brief Call back function when executing a configuration script.
1172 * Called from the File->Execute Config Script menu item.
1173 * \param void
1174 ***********************************************************/
cb_scripts(bool reset_path=false)1175 void cb_scripts(bool reset_path = false)
1176 {
1177 pthread_mutex_lock(&mutex_script_io);
1178
1179 static bool first_time = true;
1180 static char script_filename[FL_PATH_MAX + 1];
1181 std::string new_path = "";
1182
1183 if(reset_path || first_time) {
1184 memset(script_filename, 0, sizeof(script_filename));
1185 strncpy(script_filename, flamp_script_dir.c_str(), FL_PATH_MAX);
1186 int len = strnlen(script_filename, FL_PATH_MAX);
1187
1188 if(len > 0) {
1189 len--;
1190 if(script_filename[len] == PATH_CHAR_SEPERATOR);
1191 else strncat(script_filename, PATH_SEPERATOR, FL_PATH_MAX);
1192 } else {
1193 return;
1194 }
1195
1196 first_time = false;
1197 }
1198
1199 const char *p = FSEL::select((char *)"Script Files", (char *)"*.txt", \
1200 script_filename);
1201
1202 if(p) {
1203 memset(script_filename, 0, sizeof(script_filename));
1204 strncpy(script_filename, p, FL_PATH_MAX);
1205
1206 Fl::lock();
1207 script_execute(script_filename, false);
1208 Fl::unlock();
1209
1210 show_selected_xmt(1);
1211 }
1212
1213 pthread_mutex_unlock(&mutex_script_io);
1214 }
1215
1216 /** ********************************************************
1217 * \brief Call back function when executing a queue script.
1218 * \param void
1219 ***********************************************************/
cb_load_tx_queue(void)1220 void cb_load_tx_queue(void)
1221 {
1222 std::string script_filename;
1223 script_filename.assign(txt_auto_load_queue_path->value());
1224
1225 if(progStatus.load_from_tx_folder) {
1226 auto_load_tx_queue_from_tx_directory();
1227 } else {
1228 std::string script_filename;
1229 script_filename.assign(txt_auto_load_queue_path->value());
1230
1231 if(script_filename.empty()) {
1232 LOG_INFO("Queue Load file list (path) not assigned");
1233 return;
1234 }
1235
1236 pthread_mutex_lock(&mutex_script_io);
1237 strncpy(call_script.filename, script_filename.c_str(), FL_PATH_MAX-1);
1238 call_script.queueflag = true;
1239 Fl::awake(script_execute, (void *)&call_script);
1240 pthread_mutex_unlock(&mutex_script_io);
1241 }
1242
1243 show_selected_xmt(0);
1244 }
1245
1246
1247 /** ********************************************************
1248 * \brief Hander for FL:awake call.
1249 * \param void
1250 ***********************************************************/
script_execute(void * v)1251 void script_execute(void *v) {
1252 CALL_SCRIPT *s = (CALL_SCRIPT *)v;
1253 if(!s) return;
1254 Fl::lock();
1255 script_execute(s->filename, s->queueflag);
1256 Fl::unlock();
1257 }
1258
1259
1260