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

OpenLightingProject / ola / 24609206502

18 Apr 2026 04:43PM UTC coverage: 44.825% (-0.04%) from 44.864%
24609206502

Pull #1607

github

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

8554 of 19875 branches covered (43.04%)

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

12 existing lines in 4 files now uncovered.

22105 of 49314 relevant lines covered (44.82%)

47.85 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->priority_mode = ola::PRIORITY_MODE_INHERIT;
×
338
  opts->priority_value = 0;
×
339
}
×
340

341

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

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

379

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

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

404
  int c;
×
405
  int option_index = 0;
×
406

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

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

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

457

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

473
  int c;
×
474
  int option_index = 0;
×
475

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

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

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

516

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

530
  int c;
×
531
  int option_index = 0;
×
532

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

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

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

568

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

583

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

606

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

626

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

645

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

660

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

675

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

692

693

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

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

732

733

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

769

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

783

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

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

803

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

821

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

852

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

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

874

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

892

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

912

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

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

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

941

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

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

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

967

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

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

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

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

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

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

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

1032
  ola_client.GetSelectServer()->Run();
×
1033
  return 0;
×
1034
}
×
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