• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenLightingProject / ola / 24609165193

18 Apr 2026 04:41PM UTC coverage: 44.824% (-0.04%) from 44.864%
24609165193

Pull #1607

github

web-flow
Merge 8a6e128cd into c6196f753
Pull Request #1607: Various minor improvements to the example programs

8554 of 19875 branches covered (43.04%)

0 of 47 new or added lines in 3 files covered. (0.0%)

112 existing lines in 4 files now uncovered.

22105 of 49315 relevant lines covered (44.82%)

50.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/examples/ola-client.cpp
1
/*
2
 * This program is free software; you can redistribute it and/or modify
3
 * it under the terms of the GNU General Public License as published by
4
 * the Free Software Foundation; either version 2 of the License, or
5
 * (at your option) any later version.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU Library General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15
 *
16
 * ola-client.cpp
17
 * The multi purpose ola client.
18
 * Copyright (C) 2005 Simon Newton
19
 */
20

21
#include <errno.h>
22
#include <getopt.h>
23
#include <ola/DmxBuffer.h>
24
#include <ola/Logging.h>
25
#include <ola/base/Init.h>
26
#include <ola/base/SysExits.h>
27
#include <ola/client/ClientWrapper.h>
28
#include <ola/client/OlaClient.h>
29
#include <ola/file/Util.h>
30
#include <ola/io/SelectServer.h>
31
#include <olad/PortConstants.h>
32

33

34
#include <iostream>
35
#include <iomanip>
36
#include <string>
37
#include <vector>
38

39
using ola::NewSingleCallback;
40
using ola::client::OlaClient;
41
using ola::client::OlaClientWrapper;
42
using ola::client::OlaDevice;
43
using ola::client::OlaInputPort;
44
using ola::client::OlaOutputPort;
45
using ola::client::OlaPlugin;
46
using ola::client::OlaUniverse;
47
using ola::client::Result;
48
using ola::io::SelectServer;
49
using std::cerr;
50
using std::cout;
51
using std::endl;
52
using std::setw;
53
using std::string;
54
using std::vector;
55

56
static const int INVALID_VALUE = -1;
57

58
/*
59
 * The mode is determined by the name in which we were called
60
 */
61
typedef enum {
62
  DEVICE_INFO,
63
  DEVICE_PATCH,
64
  PLUGIN_INFO,
65
  PLUGIN_STATE,
66
  UNIVERSE_INFO,
67
  UNIVERSE_NAME,
68
  UNI_MERGE,
69
  SET_DMX,
70
  SET_PORT_PRIORITY,
71
} mode;
72

73

74
typedef struct {
75
  mode m;          // mode
76
  int uni;         // universe id
77
  unsigned int plugin_id;   // plugin id
78
  bool help;       // show the help
79
  int device_id;   // device id
80
  int port_id;     // port id
81
  ola::client::PortDirection port_direction;  // input or output
82
  ola::client::PatchAction patch_action;      // patch or unpatch
83
  OlaUniverse::merge_mode merge_mode;  // the merge mode
84
  string cmd;      // argv[0]
85
  string uni_name;  // universe name
86
  bool blackout;
87
  string dmx;      // DMX string
88
  bool extended;
89
  ola::port_priority_mode priority_mode;  // port priority mode
90
  uint8_t priority_value;  // port priority value
91
  bool list_plugin_ids;
92
  bool list_universe_ids;
93
  string state;      // plugin enable/disable state
94
} options;
×
95

96

97
/**
98
 * A Helper function to display a list of ports
99
 */
100
template<class PortClass>
101
void ListPorts(const vector<PortClass> &ports, bool input) {
×
102
  typename vector<PortClass>::const_iterator port_iter;
×
103
  for (port_iter = ports.begin(); port_iter != ports.end(); ++port_iter) {
×
104
    cout << "  port " << port_iter->Id() << ", ";
×
105

106
    if (input) {
×
107
      cout << "IN";
×
108
    } else {
109
      cout << "OUT";
×
110
    }
111

112
    if (!port_iter->Description().empty()) {
×
113
      cout << " " << port_iter->Description();
×
114
    }
115

116
    switch (port_iter->PriorityCapability()) {
×
117
      case ola::CAPABILITY_STATIC:
×
118
        cout << ", priority " << static_cast<int>(port_iter->Priority());
×
119
        break;
120
      case ola::CAPABILITY_FULL:
×
121
        cout << ", priority ";
×
122
        if (port_iter->PriorityMode() == ola::PRIORITY_MODE_INHERIT) {
×
123
          cout << "inherited";
×
124
        } else {
125
          cout << "override " << static_cast<int>(port_iter->Priority());
×
126
        }
127
        break;
128
      default:
129
        break;
130
    }
131

132
    if (port_iter->IsActive()) {
×
133
      cout << ", patched to universe " << port_iter->Universe();
×
134
    }
135

136
    if (port_iter->SupportsRDM()) {
×
137
      cout << ", RDM supported";
×
138
    }
139
    cout << endl;
×
140
  }
141
}
×
142

143

144
/*
145
 * This is called when we receive universe results from the client
146
 * @param list_ids_only show ids only
147
 * @param extended show extended info about each universe
148
 * @param universes a vector of OlaUniverses
149
 */
150
void DisplayUniverses(SelectServer *ss,
×
151
                      bool list_ids_only,
152
                      bool extended,
153
                      const Result &result,
154
                      const vector <OlaUniverse> &universes) {
155
  vector<OlaUniverse>::const_iterator iter;
×
156

NEW
157
  string divider = string(58 + (extended ? 41 : 0), '-');
×
158

159
  if (!result.Success()) {
×
160
    cerr << result.Error() << endl;
×
161
    ss->Terminate();
×
162
    return;
×
163
  }
164

165
  if (list_ids_only) {
×
166
    for (iter = universes.begin(); iter != universes.end(); ++iter) {
×
167
      cout << iter->Id() << endl;
×
168
    }
169
  } else {
NEW
170
    cout << setw(5) << "Id" << "\t" << setw(30) << "Name" << "\t";
×
NEW
171
    if (extended) {
×
NEW
172
      cout << setw(10);
×
173
    } else {
174
      // By default keep the double tab for backwards compatibility of anyone
175
      // parsing the shell, not that we'd recommend that
NEW
176
      cout << "\t";
×
177
    }
NEW
178
    cout << "Merge Mode";
×
NEW
179
    if (extended) {
×
NEW
180
      cout << "\t" << setw(11) << "Input Ports" << "\t" << setw(12)
×
NEW
181
           << "Output Ports" << "\t" << setw(11) << "RDM Devices";
×
182
    }
NEW
183
    cout << endl;
×
NEW
184
    cout << divider << endl;
×
185

186
    for (iter = universes.begin(); iter != universes.end(); ++iter) {
×
187
      cout << setw(5) << iter->Id() << "\t" << setw(30) << iter->Name()
×
NEW
188
           << "\t";
×
NEW
189
      if (extended) {
×
NEW
190
        cout << setw(10);
×
191
      } else {
192
        // By default keep the double tab for backwards compatibility of anyone
193
        // parsing the shell, not that we'd recommend that
NEW
194
        cout << "\t";
×
195
      }
NEW
196
        cout << (iter->MergeMode() == OlaUniverse::MERGE_HTP ? "HTP" : "LTP");
×
NEW
197
      if (extended) {
×
NEW
198
        cout << "\t" << setw(11) << iter->InputPortCount() << "\t" << setw(12)
×
NEW
199
             << iter->OutputPortCount() << "\t" << setw(11)
×
NEW
200
             << iter->RDMDeviceCount();
×
201
      }
NEW
202
      cout << endl;
×
203
    }
204

NEW
205
    cout << divider << endl;
×
206
  }
207

208
  ss->Terminate();
×
UNCOV
209
}
×
210

211

212
/*
213
 * @param list_ids_only show ids only
214
 * @params plugins a vector of OlaPlugins
215
 */
216
void DisplayPlugins(SelectServer *ss,
×
217
                    bool list_ids_only,
218
                    const Result &result,
219
                    const vector <OlaPlugin> &plugins) {
220
  vector<OlaPlugin>::const_iterator iter;
×
221

222
  if (!result.Success()) {
×
223
    cerr << result.Error() << endl;
×
224
    ss->Terminate();
×
225
    return;
×
226
  }
227

228
  if (list_ids_only) {
×
229
    for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
×
230
      cout << iter->Id() << endl;
×
231
    }
232
  } else {
233
    cout << setw(5) << "Id" << "\tPlugin Name" << endl;
×
234
    cout << "--------------------------------------" << endl;
×
235

236
    for (iter = plugins.begin(); iter != plugins.end(); ++iter) {
×
237
      cout << setw(5) << iter->Id() << "\t" << iter->Name() << endl;
×
238
    }
239

240
    cout << "--------------------------------------" << endl;
×
241
  }
242

243
  ss->Terminate();
×
244
}
245

246

247
/*
248
 * Print a plugin description
249
 */
250
void DisplayPluginDescription(SelectServer *ss,
×
251
                              const Result &result,
252
                              const string &description) {
253
  if (!result.Success()) {
×
254
    cerr << result.Error() << endl;
×
255
  } else {
256
    cout << description << endl;
×
257
  }
258
  ss->Terminate();
×
259
  return;
×
260
}
261

262

263
/*
264
 * Print a plugin state
265
 */
266
void DisplayPluginState(SelectServer *ss,
×
267
                        const Result &result,
268
                        const ola::client::PluginState &state) {
269
  if (!result.Success()) {
×
270
    cerr << result.Error() << endl;
×
271
  } else {
272
    cout << state.name << endl;
×
273
    cout << "Enabled: " << (state.enabled ? "True" : "False") << endl;
×
274
    cout << "Active: " << (state.active ? "True" : "False") << endl;
×
275
    vector<OlaPlugin>::const_iterator iter = state.conflicting_plugins.begin();
×
276
    cout << "Conflicts with:" << endl;
×
277
    for (; iter != state.conflicting_plugins.end(); ++iter) {
×
278
      cout << "  " << iter->Name() << "(" << iter->Id() << ")" << endl;
×
279
    }
280
  }
281
  ss->Terminate();
×
282
  return;
×
283
}
284

285

286
/*
287
 * @param devices a vector of OlaDevices
288
 */
289
void DisplayDevices(SelectServer *ss,
×
290
                    const Result &result,
291
                    const vector <OlaDevice> &devices) {
292
  vector<OlaDevice>::const_iterator iter;
×
293

294
  if (!result.Success()) {
×
295
    cerr << result.Error() << endl;
×
296
    ss->Terminate();
×
297
    return;
×
298
  }
299

300
  for (iter = devices.begin(); iter != devices.end(); ++iter) {
×
301
    cout << "Device " << iter->Alias() << ": " << iter->Name() << endl;
×
302
    vector<OlaInputPort> input_ports = iter->InputPorts();
×
303
    ListPorts(input_ports, true);
×
304
    vector<OlaOutputPort> output_ports = iter->OutputPorts();
×
305
    ListPorts(output_ports, false);
×
306
  }
×
307
  ss->Terminate();
×
308
}
309

310
/*
311
 * Called when a generic set command completes
312
 */
313
void HandleAck(SelectServer *ss, const Result &result) {
×
314
  if (!result.Success()) {
×
315
    cerr << result.Error() << endl;
×
316
  }
317
  ss->Terminate();
×
318
}
×
319

320
/*
321
 * Init options
322
 */
323
void InitOptions(options *opts) {
×
324
  opts->m = DEVICE_INFO;
×
325
  opts->uni = INVALID_VALUE;
×
326
  opts->plugin_id = ola::OLA_PLUGIN_ALL;
×
327
  opts->help = false;
×
NEW
328
  opts->blackout = false;
×
NEW
329
  opts->extended = false;
×
330
  opts->list_plugin_ids = false;
×
331
  opts->list_universe_ids = false;
×
332
  opts->patch_action = ola::client::PATCH;
×
333
  opts->port_id = INVALID_VALUE;
×
334
  opts->port_direction = ola::client::OUTPUT_PORT;
×
335
  opts->device_id = INVALID_VALUE;
×
336
  opts->merge_mode = OlaUniverse::MERGE_HTP;
×
337
  opts->blackout = false;
×
338
  opts->priority_mode = ola::PRIORITY_MODE_INHERIT;
×
339
  opts->priority_value = 0;
×
UNCOV
340
}
×
341

342

343
/*
344
 * Decide what mode we're running in
345
 */
346
void SetMode(options *opts) {
×
UNCOV
347
  string cmd_name = ola::file::FilenameFromPathOrPath(opts->cmd);
×
348
  // To skip the lt prefix during development
UNCOV
349
  ola::StripPrefix(&cmd_name, "lt-");
×
350
#ifdef _WIN32
351
  // Strip the extension
352
  size_t extension = cmd_name.find(".");
353
  if (extension != string::npos) {
354
    cmd_name = cmd_name.substr(0, extension);
355
  }
356
#endif  // _WIN32
357

358
  if (cmd_name == "ola_plugin_info") {
×
359
    opts->m = PLUGIN_INFO;
×
360
  } else if (cmd_name == "ola_plugin_state") {
×
361
    opts->m = PLUGIN_STATE;
×
362
  } else if (cmd_name == "ola_patch") {
×
363
    opts->m = DEVICE_PATCH;
×
UNCOV
364
  } else if (cmd_name == "ola_ptch") {
×
365
    // Working around Windows UAC
366
    opts->m = DEVICE_PATCH;
×
367
  } else if (cmd_name == "ola_uni_info") {
×
368
    opts->m = UNIVERSE_INFO;
×
369
  } else if (cmd_name == "ola_uni_name") {
×
370
    opts->m = UNIVERSE_NAME;
×
371
  } else if (cmd_name == "ola_uni_merge") {
×
372
    opts->m = UNI_MERGE;
×
373
  } else if (cmd_name == "ola_set_dmx") {
×
374
    opts->m = SET_DMX;
×
375
  } else if (cmd_name == "ola_set_priority") {
×
UNCOV
376
    opts->m = SET_PORT_PRIORITY;
×
377
  }
UNCOV
378
}
×
379

380

381
/*
382
 * parse our cmd line options
383
 */
384
void ParseOptions(int argc, char *argv[], options *opts) {
×
UNCOV
385
  enum {
×
386
    LIST_PLUGIN_IDS_OPTION = 256,
387
    LIST_UNIVERSE_IDS_OPTION,
388
  };
389

UNCOV
390
  static struct option long_options[] = {
×
391
      {"blackout", no_argument, 0, 'b'},
392
      {"dmx", required_argument, 0, 'd'},
393
      {"extended", no_argument, 0, 'e'},
394
      {"help", no_argument, 0, 'h'},
395
      {"ltp", no_argument, 0, 'l'},
396
      {"name", required_argument, 0, 'n'},
397
      {"plugin-id", required_argument, 0, 'p'},
398
      {"state", required_argument, 0, 's'},
399
      {"universe", required_argument, 0, 'u'},
400
      {"list-plugin-ids", no_argument, 0, LIST_PLUGIN_IDS_OPTION},
401
      {"list-universe-ids", no_argument, 0, LIST_UNIVERSE_IDS_OPTION},
402
      {0, 0, 0, 0}
403
    };
404

405
  int c;
×
UNCOV
406
  int option_index = 0;
×
407

408
  while (1) {
×
UNCOV
409
    c = getopt_long(argc, argv, "ld:bn:u:p:s:hv", long_options, &option_index);
×
410

UNCOV
411
    if (c == -1)
×
412
      break;
413

UNCOV
414
    switch (c) {
×
415
      case 0:
416
        break;
NEW
417
      case 'b':
×
NEW
418
        opts->blackout = true;
×
419
        break;
×
420
      case 'd':
×
UNCOV
421
        opts->dmx = optarg;
×
422
        break;
NEW
423
      case 'e':
×
424
        opts->extended = true;
×
425
        break;
×
426
      case 'h':
×
427
        opts->help = true;
×
428
        break;
×
429
      case 'l':
×
430
        opts->merge_mode = OlaUniverse::MERGE_LTP;
×
431
        break;
×
432
      case 'n':
×
UNCOV
433
        opts->uni_name = optarg;
×
434
        break;
435
      case 'p':
×
436
        opts->plugin_id = atoi(optarg);
×
437
        break;
×
438
      case 's':
×
UNCOV
439
        opts->state = optarg;
×
440
        break;
441
      case 'u':
×
442
        opts->uni = atoi(optarg);
×
443
        break;
×
444
      case LIST_PLUGIN_IDS_OPTION:
×
445
        opts->list_plugin_ids = true;
×
446
        break;
×
447
      case LIST_UNIVERSE_IDS_OPTION:
×
448
        opts->list_universe_ids = true;
×
UNCOV
449
        break;
×
450
      case '?':
451
        break;
452
      default:
453
        break;
454
    }
455
  }
UNCOV
456
}
×
457

458

459
/*
460
 * parse our cmd line options for the patch command
461
 */
462
int ParsePatchOptions(int argc, char *argv[], options *opts) {
×
UNCOV
463
  static struct option long_options[] = {
×
464
      {"device", required_argument, 0, 'd'},
465
      {"help", no_argument, 0, 'h'},
466
      {"input", no_argument, 0, 'i'},
467
      {"patch", no_argument, 0, 'a'},
468
      {"port", required_argument, 0, 'p'},
469
      {"universe", required_argument, 0, 'u'},
470
      {"unpatch", no_argument, 0, 'r'},
471
      {0, 0, 0, 0}
472
    };
473

474
  int c;
×
UNCOV
475
  int option_index = 0;
×
476

477
  while (1) {
×
UNCOV
478
    c = getopt_long(argc, argv, "ard:p:u:hi", long_options, &option_index);
×
479

UNCOV
480
    if (c == -1) {
×
481
      break;
482
    }
483

UNCOV
484
    switch (c) {
×
485
      case 0:
486
        break;
487
      case 'a':
×
488
        opts->patch_action = ola::client::PATCH;
×
489
        break;
×
490
      case 'd':
×
491
        opts->device_id = atoi(optarg);
×
492
        break;
×
493
      case 'p':
×
494
        opts->port_id = atoi(optarg);
×
495
        break;
×
496
      case 'r':
×
497
        opts->patch_action = ola::client::UNPATCH;
×
498
        break;
×
499
      case 'u':
×
500
        opts->uni = atoi(optarg);
×
501
        break;
×
502
      case 'h':
×
503
        opts->help = true;
×
504
        break;
×
505
      case 'i':
×
506
        opts->port_direction = ola::client::INPUT_PORT;
×
UNCOV
507
        break;
×
508
      case '?':
509
        break;
510
      default:
511
        break;
512
    }
513
  }
UNCOV
514
  return 0;
×
515
}
516

517

518
/*
519
 * parse our cmd line options for the set priority command
520
 */
521
int ParseSetPriorityOptions(int argc, char *argv[], options *opts) {
×
UNCOV
522
  static struct option long_options[] = {
×
523
      {"device", required_argument, 0, 'd'},
524
      {"help", no_argument, 0, 'h'},
525
      {"input", no_argument, 0, 'i'},
526
      {"port", required_argument, 0, 'p'},
527
      {"override", required_argument, 0, 'o'},
528
      {0, 0, 0, 0}
529
    };
530

531
  int c;
×
UNCOV
532
  int option_index = 0;
×
533

534
  while (1) {
×
UNCOV
535
    c = getopt_long(argc, argv, "d:p:o:hi", long_options, &option_index);
×
536

UNCOV
537
    if (c == -1) {
×
538
      break;
539
    }
540

UNCOV
541
    switch (c) {
×
542
      case 0:
543
        break;
544
      case 'd':
×
545
        opts->device_id = atoi(optarg);
×
546
        break;
×
547
      case 'h':
×
548
        opts->help = true;
×
549
        break;
×
550
      case 'i':
×
551
        opts->port_direction = ola::client::INPUT_PORT;
×
552
        break;
×
553
      case 'o':
×
554
        opts->priority_mode = ola::PRIORITY_MODE_STATIC;
×
555
        opts->priority_value = atoi(optarg);
×
556
        break;
×
557
      case 'p':
×
558
        opts->port_id = atoi(optarg);
×
UNCOV
559
        break;
×
560
      case '?':
561
        break;
562
      default:
563
        break;
564
    }
565
  }
UNCOV
566
  return 0;
×
567
}
568

569

570
/*
571
 * help message for device info
572
 */
573
void DisplayDeviceInfoHelp(const options &opts) {
×
UNCOV
574
  cout << "Usage: " << opts.cmd << " [--plugin-id <plugin_id>]\n"
×
575
          "\n"
576
          "Show information on the devices loaded by olad.\n"
577
          "\n"
578
          "  -h, --help                  Display this help message and exit.\n"
579
          "  -p, --plugin-id <plugin-id> Show only devices owned by this "
580
          "plugin.\n"
×
581
       << endl;
×
UNCOV
582
}
×
583

584

585
/*
586
 * Display the Patch help
587
 */
588
void DisplayPatchHelp(const options &opts) {
×
UNCOV
589
  cout << "Usage: " << opts.cmd
×
590
       << " [--patch | --unpatch] --device <dev> --port <port> "
591
          "[--universe <uni>]\n"
592
          "\n"
593
          "Control ola port <-> universe mappings.\n"
594
          "\n"
595
          "  -a, --patch              Patch this port (default).\n"
596
          "  -d, --device <device>    Id of device to patch.\n"
597
          "  -h, --help               Display this help message and exit.\n"
598
          "  -p, --port <port>        Id of the port to patch.\n"
599
          "  -r, --unpatch            Unpatch this port.\n"
600
          "  -i, --input              Patch the input port (default is "
601
          "output).\n"
602
          "  -u, --universe <uni>     Id of the universe to patch to (default "
603
          "0).\n"
×
604
       << endl;
×
UNCOV
605
}
×
606

607

608
/*
609
 * help message for plugin info
610
 */
611
void DisplayPluginInfoHelp(const options &opts) {
×
UNCOV
612
  cout << "Usage: " << opts.cmd << " [--plugin-id <plugin-id>]\n"
×
613
          "\n"
614
          "Get info on the plugins loaded by olad. Called without arguments"
615
          " this will\n"
616
          "display the plugins loaded by olad. When used with --plugin-id this"
617
          " will\n"
618
          "display the specified plugin's description.\n"
619
          "\n"
620
          "  -h, --help                  Display this help message and exit.\n"
621
          "  -p, --plugin-id <plugin_id> Id of the plugin to fetch the "
622
          "description of\n"
623
          "  --list-plugin-ids           List plugin Ids only.\n"
×
624
       << endl;
×
UNCOV
625
}
×
626

627

628
/*
629
 * help message for plugin state
630
 */
631
void DisplayPluginStateHelp(const options &opts) {
×
UNCOV
632
  cout << "Usage: " << opts.cmd
×
633
       << " --plugin-id <plugin-id> [--state <enable|disable>]\n"
634
          "\n"
635
          "Displays the enabled/disabled state for a plugin and the list of "
636
          "plugins\n"
637
          "this plugin will conflict with.\n"
638
          "\n"
639
          "  -h, --help                  Display this help message and exit.\n"
640
          "  -p, --plugin-id <plugin-id> Id of the plugin to fetch the state "
641
          "of\n"
642
          "  -s, --state <enable|disable> State to set a plugin to\n"
×
643
      << endl;
×
UNCOV
644
}
×
645

646

647
/*
648
 * help message for uni info
649
 */
650
void DisplayUniverseInfoHelp(const options &opts) {
×
UNCOV
651
  cout << "Usage: " << opts.cmd
×
652
       << "\n"
653
          "Shows info on the active universes in use.\n"
654
          "\n"
655
          "  -h, --help          Display this help message and exit.\n"
656
          "  --extended          Show port counts and RDM devices too.\n"
657
          "  --list-universe-ids List universe Ids only.\n"
×
658
       << endl;
×
UNCOV
659
}
×
660

661

662
/*
663
 * Help message for set uni name
664
 */
665
void DisplayUniverseNameHelp(const options &opts) {
×
UNCOV
666
  cout << "Usage: " << opts.cmd << " --name <name> --universe <uni>\n"
×
667
          "\n"
668
          "Set a name for the specified universe\n"
669
          "\n"
670
          "  -h, --help                Display this help message and exit.\n"
671
          "  -n, --name <name>         Name for the universe.\n"
672
          "  -u, --universe <universe> Id of the universe to name.\n"
×
673
       << endl;
×
UNCOV
674
}
×
675

676

677
/*
678
 * Help message for set uni merge mode
679
 */
680
void DisplayUniverseMergeHelp(const options &opts) {
×
UNCOV
681
  cout << "Usage: " << opts.cmd << " --universe <uni> [--ltp]\n"
×
682
          "\n"
683
          "Change the merge mode for the specified universe. Without --ltp "
684
          "it will\n"
685
          "revert to HTP mode.\n"
686
          "\n"
687
          "  -h, --help                Display this help message and exit.\n"
688
          "  -l, --ltp                 Change to LTP mode.\n"
689
          "  -u, --universe <universe> Id of the universe to change.\n"
×
690
       << endl;
×
UNCOV
691
}
×
692

693

694

695
/*
696
 * Help message for set dmx
697
 */
698
void DisplaySetDmxHelp(const options &opts) {
×
UNCOV
699
  cout << "Usage: " << opts.cmd << " --universe <universe> [ --dmx <values> ] "
×
700
          "[ --blackout ]\n"
701
          "\n"
702
          "Sets the DMX values for a universe.\n"
703
          "\n"
704
          "  -h, --help                Display this help message and exit.\n"
705
          "  -u, --universe <universe> Universe number, e.g. 0.\n"
706
          "  -d, --dmx <values>        Comma separated DMX values, e.g. "
707
          "0,255,128 sets first channel to 0, second channel to 255"
708
          " and third channel to 128.\n"
709
          "  -b, --blackout            Send a universe to blackout instead.\n"
×
710
       << endl;
×
UNCOV
711
}
×
712

713
/*
714
 * Display the Patch help
715
 */
716
void DisplaySetPriorityHelp(const options &opts) {
×
UNCOV
717
  cout << "Usage: " << opts.cmd
×
718
       << " --device <dev> --port <port> [--override <value>]\n"
719
          "\n"
720
          "Set a port's priority, without the --override flag this will set "
721
          "the port\n"
722
          " to inherit mode.\n"
723
          "\n"
724
          "  -d, --device <device>    Id of device to set priority for.\n"
725
          "  -h, --help               Display this help message and exit.\n"
726
          "  -i, --input              Set an input port\n"
727
          "  -o, --override <value>   Set the port priority to a static "
728
          "value.\n"
729
          "  -p, --port <port>        Id of the port to set priority for.\n"
×
730
       << endl;
×
UNCOV
731
}
×
732

733

734

735
/*
736
 * Display the help message
737
 */
738
void DisplayHelpAndExit(const options &opts) {
×
739
  switch (opts.m) {
×
740
    case DEVICE_INFO:
×
741
      DisplayDeviceInfoHelp(opts);
×
742
      break;
×
743
    case DEVICE_PATCH:
×
744
      DisplayPatchHelp(opts);
×
745
      break;
×
746
    case PLUGIN_INFO:
×
747
      DisplayPluginInfoHelp(opts);
×
748
      break;
×
749
    case PLUGIN_STATE:
×
750
      DisplayPluginStateHelp(opts);
×
751
      break;
×
752
    case UNIVERSE_INFO:
×
753
      DisplayUniverseInfoHelp(opts);
×
754
      break;
×
755
    case UNIVERSE_NAME:
×
756
      DisplayUniverseNameHelp(opts);
×
757
      break;
×
758
    case UNI_MERGE:
×
759
      DisplayUniverseMergeHelp(opts);
×
760
      break;
×
761
    case SET_DMX:
×
762
      DisplaySetDmxHelp(opts);
×
763
      break;
×
764
    case SET_PORT_PRIORITY:
×
UNCOV
765
      DisplaySetPriorityHelp(opts);
×
766
  }
UNCOV
767
  exit(0);
×
768
}
769

770

771
/*
772
 * Send a fetch device info request
773
 * @param client the ola client
774
 * @param opts the const options
775
 */
776
int FetchDeviceInfo(OlaClientWrapper *wrapper, const options &opts) {
×
777
  SelectServer *ss = wrapper->GetSelectServer();
×
778
  OlaClient *client = wrapper->GetClient();
×
UNCOV
779
  client->FetchDeviceInfo((ola::ola_plugin_id) opts.plugin_id,
×
780
                          NewSingleCallback(&DisplayDevices, ss));
UNCOV
781
  return 0;
×
782
}
783

784

785
void Patch(OlaClientWrapper *wrapper, const options &opts) {
×
786
  SelectServer *ss = wrapper->GetSelectServer();
×
787
  OlaClient *client = wrapper->GetClient();
×
788
  if (opts.device_id == INVALID_VALUE || opts.port_id == INVALID_VALUE) {
×
789
    DisplayPatchHelp(opts);
×
UNCOV
790
    exit(1);
×
791
  }
792

793
  if (opts.patch_action == ola::client::PATCH  && opts.uni == INVALID_VALUE) {
×
794
    DisplayPatchHelp(opts);
×
UNCOV
795
    exit(1);
×
796
  }
797
  client->Patch(opts.device_id,
×
798
                opts.port_id,
×
799
                opts.port_direction,
×
UNCOV
800
                opts.patch_action, opts.uni,
×
801
                NewSingleCallback(&HandleAck, ss));
UNCOV
802
}
×
803

804

805
/*
806
 * Fetch information on plugins.
807
 */
808
int FetchPluginInfo(OlaClientWrapper *wrapper, const options &opts) {
×
809
  SelectServer *ss = wrapper->GetSelectServer();
×
810
  OlaClient *client = wrapper->GetClient();
×
811
  if (opts.plugin_id > 0) {
×
812
    client->FetchPluginDescription(
×
UNCOV
813
        (ola::ola_plugin_id) opts.plugin_id,
×
814
        NewSingleCallback(&DisplayPluginDescription, ss));
815
  } else {
816
    client->FetchPluginList(
×
UNCOV
817
        NewSingleCallback(&DisplayPlugins, ss, opts.list_plugin_ids));
×
818
  }
UNCOV
819
  return 0;
×
820
}
821

822

823
/*
824
 * Fetch the state of a plugin.
825
 */
826
int FetchPluginState(OlaClientWrapper *wrapper, const options &opts) {
×
827
  SelectServer *ss = wrapper->GetSelectServer();
×
828
  OlaClient *client = wrapper->GetClient();
×
829
  if (opts.plugin_id == 0) {
×
830
    DisplayPluginStateHelp(opts);
×
UNCOV
831
    exit(1);
×
832
  }
833
  if (!opts.state.empty()) {
×
834
    bool state;
×
835
    if (ola::StringToBoolTolerant(opts.state, &state)) {
×
836
      cout << "Setting state to " << (state ? "enabled" : "disabled") << endl;
×
837
      client->SetPluginState(
×
UNCOV
838
          (ola::ola_plugin_id) opts.plugin_id,
×
839
          state,
840
          NewSingleCallback(&HandleAck, ss));
841
    } else {
842
      cerr << "Invalid state: " << opts.state << endl;
×
843
      DisplayPluginStateHelp(opts);
×
UNCOV
844
      exit(1);
×
845
    }
846
  } else {
UNCOV
847
    client->FetchPluginState((ola::ola_plugin_id) opts.plugin_id,
×
848
                             NewSingleCallback(&DisplayPluginState, ss));
849
  }
UNCOV
850
  return 0;
×
851
}
852

853

854
/*
855
 * Send a fetch universe info request
856
 * @param client the ola client
857
 * @param opts the const options
858
 */
NEW
859
int FetchUniverseInfo(OlaClientWrapper *wrapper, const options &opts) {
×
NEW
860
  SelectServer *ss = wrapper->GetSelectServer();
×
NEW
861
  OlaClient *client = wrapper->GetClient();
×
NEW
862
  if (opts.extended && opts.list_universe_ids) {
×
863
    // These are mutually exclusive
NEW
864
    DisplayUniverseInfoHelp(opts);
×
NEW
865
    exit(1);
×
866
  }
867

NEW
868
  client->FetchUniverseList(NewSingleCallback(&DisplayUniverses,
×
869
                                              ss,
NEW
870
                                              opts.list_universe_ids,
×
871
                                              opts.extended));
NEW
872
  return 0;
×
873
}
874

875

876
/*
877
 * send a set name request
878
 * @param client the ola client
879
 * @param opts the const options
880
 */
881
int SetUniverseName(OlaClientWrapper *wrapper, const options &opts) {
×
882
  SelectServer *ss = wrapper->GetSelectServer();
×
883
  OlaClient *client = wrapper->GetClient();
×
884
  if (opts.uni == INVALID_VALUE) {
×
885
    DisplayUniverseNameHelp(opts);
×
UNCOV
886
    exit(1);
×
887
  }
UNCOV
888
  client->SetUniverseName(opts.uni, opts.uni_name,
×
889
                          NewSingleCallback(&HandleAck, ss));
UNCOV
890
  return 0;
×
891
}
892

893

894
/*
895
 * send a set name request
896
 * @param client the ola client
897
 * @param opts the const options
898
 */
UNCOV
899
int SetUniverseMergeMode(OlaClientWrapper *wrapper,
×
900
                         const options &opts) {
901
  SelectServer *ss = wrapper->GetSelectServer();
×
902
  OlaClient *client = wrapper->GetClient();
×
903
  if (opts.uni == INVALID_VALUE) {
×
904
    DisplayUniverseMergeHelp(opts);
×
UNCOV
905
    exit(1);
×
906
  }
907
  client->SetUniverseMergeMode(
×
UNCOV
908
      opts.uni, opts.merge_mode,
×
909
      NewSingleCallback(&HandleAck, ss));
UNCOV
910
  return 0;
×
911
}
912

913

914
/*
915
 * Send a DMX message
916
 * @param client the ola client
917
 * @param opts the options
918
 */
919
int SendDmx(OlaClientWrapper *wrapper, const options &opts) {
×
920
  SelectServer *ss = wrapper->GetSelectServer();
×
921
  OlaClient *client = wrapper->GetClient();
×
922
  ola::DmxBuffer buffer;
×
923
  bool status = false;
×
924
  if (opts.blackout) {
×
UNCOV
925
    status = buffer.Blackout();
×
926
  } else {
UNCOV
927
    status = buffer.SetFromString(opts.dmx);
×
928
  }
929

930
  // A dmx string and blackout are mutually exclusive
931
  if (opts.uni < 0 || !status || (opts.blackout && !opts.dmx.empty()) ||
×
932
      buffer.Size() == 0) {
×
933
    DisplaySetDmxHelp(opts);
×
UNCOV
934
    exit(1);
×
935
  }
936

937
  ola::client::SendDMXArgs args(NewSingleCallback(&HandleAck, ss));
×
938
  client->SendDMX(opts.uni, buffer, args);
×
939
  return 0;
×
UNCOV
940
}
×
941

942

943
/*
944
 * Set the priority of a port
945
 */
946
void SetPortPriority(OlaClientWrapper *wrapper, const options &opts) {
×
947
  SelectServer *ss = wrapper->GetSelectServer();
×
UNCOV
948
  OlaClient *client = wrapper->GetClient();
×
949

950
  if (opts.device_id == INVALID_VALUE || opts.port_id == INVALID_VALUE) {
×
951
    DisplaySetPriorityHelp(opts);
×
UNCOV
952
    exit(1);
×
953
  }
954

955
  if (opts.priority_mode == ola::PRIORITY_MODE_INHERIT) {
×
956
    client->SetPortPriorityInherit(
×
UNCOV
957
        opts.device_id, opts.port_id, opts.port_direction,
×
958
        NewSingleCallback(&HandleAck, ss));
959
  } else if (opts.priority_mode == ola::PRIORITY_MODE_STATIC) {
×
960
    client->SetPortPriorityOverride(
×
UNCOV
961
        opts.device_id, opts.port_id, opts.port_direction, opts.priority_value,
×
962
        NewSingleCallback(&HandleAck, ss));
963
  } else {
UNCOV
964
    DisplaySetPriorityHelp(opts);
×
965
  }
UNCOV
966
}
×
967

968

969
/*
970
 * Main
971
 */
972
int main(int argc, char *argv[]) {
×
973
  ola::InitLogging(ola::OLA_LOG_WARN, ola::OLA_LOG_STDERR);
×
974
  if (!ola::NetworkInit()) {
×
975
    OLA_WARN << "Network initialization failed." << endl;
×
UNCOV
976
    exit(ola::EXIT_UNAVAILABLE);
×
977
  }
978
  OlaClientWrapper ola_client;
×
UNCOV
979
  options opts;
×
980

981
  InitOptions(&opts);
×
UNCOV
982
  opts.cmd = argv[0];
×
983

984
  // decide how we should behave
UNCOV
985
  SetMode(&opts);
×
986

987
  if (opts.m == DEVICE_PATCH) {
×
988
    ParsePatchOptions(argc, argv, &opts);
×
989
  } else if (opts.m == SET_PORT_PRIORITY) {
×
UNCOV
990
    ParseSetPriorityOptions(argc, argv, &opts);
×
991
  } else {
UNCOV
992
    ParseOptions(argc, argv, &opts);
×
993
  }
994

995
  if (opts.help) {
×
UNCOV
996
    DisplayHelpAndExit(opts);
×
997
  }
998

999
  if (!ola_client.Setup()) {
×
1000
    OLA_FATAL << "Setup failed";
×
UNCOV
1001
    exit(1);
×
1002
  }
1003

1004
  switch (opts.m) {
×
1005
    case DEVICE_INFO:
×
UNCOV
1006
      FetchDeviceInfo(&ola_client, opts);
×
1007
      break;
1008
    case DEVICE_PATCH:
×
UNCOV
1009
      Patch(&ola_client, opts);
×
1010
      break;
1011
    case PLUGIN_INFO:
×
UNCOV
1012
      FetchPluginInfo(&ola_client, opts);
×
1013
      break;
1014
    case PLUGIN_STATE:
×
UNCOV
1015
      FetchPluginState(&ola_client, opts);
×
1016
      break;
NEW
1017
    case UNIVERSE_INFO:
×
UNCOV
1018
      FetchUniverseInfo(&ola_client, opts);
×
1019
      break;
1020
    case UNIVERSE_NAME:
×
UNCOV
1021
      SetUniverseName(&ola_client, opts);
×
1022
      break;
1023
    case UNI_MERGE:
×
UNCOV
1024
      SetUniverseMergeMode(&ola_client, opts);
×
1025
      break;
1026
    case SET_DMX:
×
UNCOV
1027
      SendDmx(&ola_client, opts);
×
1028
      break;
1029
    case SET_PORT_PRIORITY:
×
UNCOV
1030
      SetPortPriority(&ola_client, opts);
×
1031
  }
1032

1033
  ola_client.GetSelectServer()->Run();
×
1034
  return 0;
×
UNCOV
1035
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc