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

OpenLightingProject / ola / 6370547479

01 Oct 2023 12:26PM UTC coverage: 45.025% (-0.02%) from 45.048%
6370547479

push

github

web-flow
Merge pull request #1898 from peternewman/mac-type-tests

Add the ability to set a universe to blackout instead via ola_set_dmx

7603 of 17646 branches covered (0.0%)

13 of 13 new or added lines in 1 file covered. (100.0%)

21415 of 47562 relevant lines covered (45.03%)

55.48 hits per line

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

11.87
/olad/OlaServerServiceImpl.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
 * OlaServerServiceImpl.cpp
17
 * Implementation of the OlaServerService interface. This is the class that
18
 * handles all the RPCs on the server side.
19
 * Copyright (C) 2005 Simon Newton
20
 */
21

22
#include <algorithm>
23
#include <string>
24
#include <vector>
25
#include "common/protocol/Ola.pb.h"
26
#include "common/rpc/RpcSession.h"
27
#include "ola/Callback.h"
28
#include "ola/CallbackRunner.h"
29
#include "ola/DmxBuffer.h"
30
#include "ola/Logging.h"
31
#include "ola/rdm/RDMCommand.h"
32
#include "ola/rdm/UIDSet.h"
33
#include "ola/strings/Format.h"
34
#include "ola/timecode/TimeCode.h"
35
#include "ola/timecode/TimeCodeEnums.h"
36
#include "olad/ClientBroker.h"
37
#include "olad/Device.h"
38
#include "olad/DmxSource.h"
39
#include "olad/OlaServerServiceImpl.h"
40
#include "olad/Plugin.h"
41
#include "olad/PluginManager.h"
42
#include "olad/Port.h"
43
#include "olad/Universe.h"
44
#include "olad/plugin_api/Client.h"
45
#include "olad/plugin_api/DeviceManager.h"
46
#include "olad/plugin_api/PortManager.h"
47
#include "olad/plugin_api/UniverseStore.h"
48

49
namespace ola {
50

51
using ola::CallbackRunner;
52
using ola::proto::Ack;
53
using ola::proto::DeviceConfigReply;
54
using ola::proto::DeviceConfigRequest;
55
using ola::proto::DeviceInfo;
56
using ola::proto::DeviceInfoReply;
57
using ola::proto::DeviceInfoRequest;
58
using ola::proto::DmxData;
59
using ola::proto::MergeModeRequest;
60
using ola::proto::OptionalUniverseRequest;
61
using ola::proto::PatchPortRequest;
62
using ola::proto::PluginDescriptionReply;
63
using ola::proto::PluginDescriptionRequest;
64
using ola::proto::PluginInfo;
65
using ola::proto::PluginListReply;
66
using ola::proto::PluginListRequest;
67
using ola::proto::PortInfo;
68
using ola::proto::RegisterDmxRequest;
69
using ola::proto::UniverseInfo;
70
using ola::proto::UniverseInfoReply;
71
using ola::proto::UniverseNameRequest;
72
using ola::proto::UniverseRequest;
73
using ola::rdm::RDMRequest;
74
using ola::rdm::RDMResponse;
75
using ola::rdm::UID;
76
using ola::rdm::UIDSet;
77
using ola::rpc::RpcController;
78
using std::string;
79
using std::vector;
80

81
namespace {
82

83
template<typename RequestType>
84

85
RDMRequest::OverrideOptions RDMRequestOptionsFromProto(
×
86
    const RequestType &request) {
87
  RDMRequest::OverrideOptions options;
×
88

89
  if (!request.has_options()) {
×
90
    return options;
×
91
  }
92

93
  const ola::proto::RDMRequestOverrideOptions &proto_options =
94
      request.options();
×
95
  if (proto_options.has_sub_start_code()) {
×
96
    options.sub_start_code = proto_options.sub_start_code();
×
97
  }
98
  if (proto_options.has_message_length()) {
×
99
    options.SetMessageLength(proto_options.message_length());
×
100
  }
101
  if (proto_options.has_message_count()) {
×
102
    options.message_count = proto_options.message_count();
×
103
  }
104
  if (proto_options.has_checksum()) {
×
105
    options.SetChecksum(proto_options.checksum());
×
106
  }
107
  return options;
×
108
}
109
}  // namespace
110

111
typedef CallbackRunner<ola::rpc::RpcService::CompletionCallback> ClosureRunner;
112

113
OlaServerServiceImpl::OlaServerServiceImpl(
6✔
114
    UniverseStore *universe_store,
115
    DeviceManager *device_manager,
116
    PluginManager *plugin_manager,
117
    PortManager *port_manager,
118
    ClientBroker *broker,
119
    const TimeStamp *wake_up_time,
120
    ReloadPluginsCallback *reload_plugins_callback)
6✔
121
    : m_universe_store(universe_store),
6✔
122
      m_device_manager(device_manager),
6✔
123
      m_plugin_manager(plugin_manager),
6✔
124
      m_port_manager(port_manager),
6✔
125
      m_broker(broker),
6✔
126
      m_wake_up_time(wake_up_time),
6✔
127
      m_reload_plugins_callback(reload_plugins_callback) {
6✔
128
}
6✔
129

130
void OlaServerServiceImpl::GetDmx(
4✔
131
    RpcController* controller,
132
    const UniverseRequest* request,
133
    DmxData* response,
134
    ola::rpc::RpcService::CompletionCallback* done) {
135
  ClosureRunner runner(done);
4✔
136
  Universe *universe = m_universe_store->GetUniverse(request->universe());
4✔
137
  if (!universe) {
4✔
138
    return MissingUniverseError(controller);
2✔
139
  }
140

141
  const DmxBuffer buffer = universe->GetDMX();
2✔
142
  response->set_data(buffer.Get());
4✔
143
  response->set_universe(request->universe());
2✔
144
}
4✔
145

146
void OlaServerServiceImpl::RegisterForDmx(
6✔
147
    RpcController* controller,
148
    const RegisterDmxRequest* request,
149
    Ack*,
150
    ola::rpc::RpcService::CompletionCallback* done) {
151
  ClosureRunner runner(done);
6✔
152
  Universe *universe = m_universe_store->GetUniverseOrCreate(
6✔
153
      request->universe());
6✔
154
  if (!universe) {
6✔
155
    return MissingUniverseError(controller);
×
156
  }
157

158
  Client *client = GetClient(controller);
6✔
159
  if (request->action() == ola::proto::REGISTER) {
6✔
160
    universe->AddSinkClient(client);
3✔
161
  } else {
162
    universe->RemoveSinkClient(client);
3✔
163
  }
164
}
6✔
165

166
void OlaServerServiceImpl::UpdateDmxData(
4✔
167
    RpcController* controller,
168
    const DmxData* request,
169
    Ack*,
170
    ola::rpc::RpcService::CompletionCallback* done) {
171
  ClosureRunner runner(done);
4✔
172
  Universe *universe = m_universe_store->GetUniverse(request->universe());
4✔
173
  if (!universe) {
4✔
174
    return MissingUniverseError(controller);
1✔
175
  }
176

177
  Client *client = GetClient(controller);
3✔
178
  DmxBuffer buffer;
3✔
179
  buffer.Set(request->data());
3✔
180

181
  uint8_t priority = ola::dmx::SOURCE_PRIORITY_DEFAULT;
3✔
182
  if (request->has_priority()) {
3✔
183
    priority = request->priority();
×
184
    priority = std::max(static_cast<uint8_t>(ola::dmx::SOURCE_PRIORITY_MIN),
×
185
                        priority);
186
    priority = std::min(static_cast<uint8_t>(ola::dmx::SOURCE_PRIORITY_MAX),
×
187
                        priority);
188
  }
189
  DmxSource source(buffer, *m_wake_up_time, priority);
3✔
190
  client->DMXReceived(request->universe(), source);
3✔
191
  universe->SourceClientDataChanged(client);
3✔
192
}
4✔
193

194
void OlaServerServiceImpl::StreamDmxData(
×
195
    RpcController *controller,
196
    const ola::proto::DmxData* request,
197
    ola::proto::STREAMING_NO_RESPONSE*,
198
    ola::rpc::RpcService::CompletionCallback*) {
199
  Universe *universe = m_universe_store->GetUniverse(request->universe());
×
200

201
  if (!universe) {
×
202
    return;
×
203
  }
204

205
  Client *client = GetClient(controller);
×
206
  DmxBuffer buffer;
×
207
  buffer.Set(request->data());
×
208

209
  uint8_t priority = ola::dmx::SOURCE_PRIORITY_DEFAULT;
×
210
  if (request->has_priority()) {
×
211
    priority = request->priority();
×
212
    priority = std::max(static_cast<uint8_t>(ola::dmx::SOURCE_PRIORITY_MIN),
×
213
                        priority);
214
    priority = std::min(static_cast<uint8_t>(ola::dmx::SOURCE_PRIORITY_MAX),
×
215
                        priority);
216
  }
217
  DmxSource source(buffer, *m_wake_up_time, priority);
×
218
  client->DMXReceived(request->universe(), source);
×
219
  universe->SourceClientDataChanged(client);
×
220
}
×
221

222
void OlaServerServiceImpl::SetUniverseName(
3✔
223
    RpcController* controller,
224
    const UniverseNameRequest* request,
225
    Ack*,
226
    ola::rpc::RpcService::CompletionCallback* done) {
227
  ClosureRunner runner(done);
3✔
228
  Universe *universe = m_universe_store->GetUniverse(request->universe());
3✔
229
  if (!universe) {
3✔
230
    return MissingUniverseError(controller);
1✔
231
  }
232

233
  universe->SetName(request->name());
2✔
234
}
3✔
235

236
void OlaServerServiceImpl::SetMergeMode(
3✔
237
    RpcController* controller,
238
    const MergeModeRequest* request,
239
    Ack*,
240
    ola::rpc::RpcService::CompletionCallback* done) {
241
  ClosureRunner runner(done);
3✔
242
  Universe *universe = m_universe_store->GetUniverse(request->universe());
3✔
243
  if (!universe) {
3✔
244
    return MissingUniverseError(controller);
1✔
245
  }
246

247
  Universe::merge_mode mode = request->merge_mode() == ola::proto::HTP ?
2✔
248
    Universe::MERGE_HTP : Universe::MERGE_LTP;
2✔
249
  universe->SetMergeMode(mode);
2✔
250
}
3✔
251

252
void OlaServerServiceImpl::PatchPort(
×
253
    RpcController* controller,
254
    const PatchPortRequest* request,
255
    Ack*,
256
    ola::rpc::RpcService::CompletionCallback* done) {
257
  ClosureRunner runner(done);
×
258
  AbstractDevice *device =
×
259
    m_device_manager->GetDevice(request->device_alias());
×
260

261
  if (!device) {
×
262
    return MissingDeviceError(controller);
×
263
  }
264

265
  bool result;
×
266
  if (request->is_output()) {
×
267
    OutputPort *port = device->GetOutputPort(request->port_id());
×
268
    if (!port) {
×
269
      return MissingPortError(controller);
×
270
    }
271

272
    if (request->action() == ola::proto::PATCH) {
×
273
      result = m_port_manager->PatchPort(port, request->universe());
×
274
    } else {
275
      result = m_port_manager->UnPatchPort(port);
×
276
    }
277
  } else {
278
    InputPort *port = device->GetInputPort(request->port_id());
×
279
    if (!port) {
×
280
      return MissingPortError(controller);
×
281
    }
282

283
    if (request->action() == ola::proto::PATCH) {
×
284
      result = m_port_manager->PatchPort(port, request->universe());
×
285
    } else {
286
      result = m_port_manager->UnPatchPort(port);
×
287
    }
288
  }
289

290
  if (!result) {
×
291
    controller->SetFailed("Patch port request failed");
×
292
  }
293
}
×
294

295
void OlaServerServiceImpl::SetPortPriority(
×
296
    RpcController* controller,
297
    const ola::proto::PortPriorityRequest* request,
298
    Ack*,
299
    ola::rpc::RpcService::CompletionCallback* done) {
300
  ClosureRunner runner(done);
×
301
  AbstractDevice *device =
×
302
      m_device_manager->GetDevice(request->device_alias());
×
303

304
  if (!device) {
×
305
    return MissingDeviceError(controller);
×
306
  }
307

308
  bool status;
×
309

310
  bool inherit_mode = true;
×
311
  uint8_t value = 0;
×
312
  if (request->priority_mode() == PRIORITY_MODE_STATIC) {
×
313
    if (request->has_priority()) {
×
314
      inherit_mode = false;
×
315
      value = request->priority();
×
316
    } else {
317
      OLA_INFO << "In Set Port Priority, override mode was set but the value "
×
318
                  "wasn't specified";
×
319
      controller->SetFailed(
×
320
          "Invalid SetPortPriority request, see logs for more info");
321
      return;
×
322
    }
323
  }
324

325
  if (request->is_output()) {
×
326
    OutputPort *port = device->GetOutputPort(request->port_id());
×
327
    if (!port) {
×
328
      return MissingPortError(controller);
×
329
    }
330

331
    if (inherit_mode) {
×
332
      status = m_port_manager->SetPriorityInherit(port);
×
333
    } else {
334
      status = m_port_manager->SetPriorityStatic(port, value);
×
335
    }
336
  } else {
337
    InputPort *port = device->GetInputPort(request->port_id());
×
338
    if (!port) {
×
339
      return MissingPortError(controller);
×
340
    }
341

342
    if (inherit_mode) {
×
343
      status = m_port_manager->SetPriorityInherit(port);
×
344
    } else {
345
      status = m_port_manager->SetPriorityStatic(port, value);
×
346
    }
347
  }
348

349
  if (!status) {
×
350
    controller->SetFailed(
×
351
        "Invalid SetPortPriority request, see logs for more info");
352
  }
353
}
×
354

355
void OlaServerServiceImpl::AddUniverse(
×
356
    const Universe * universe,
357
    ola::proto::UniverseInfoReply *universe_info_reply) const {
358
  UniverseInfo *universe_info = universe_info_reply->add_universe();
×
359
  universe_info->set_universe(universe->UniverseId());
×
360
  universe_info->set_name(universe->Name());
×
361
  universe_info->set_merge_mode(universe->MergeMode() == Universe::MERGE_HTP
×
362
      ? ola::proto::HTP : ola::proto::LTP);
363
  universe_info->set_input_port_count(universe->InputPortCount());
×
364
  universe_info->set_output_port_count(universe->OutputPortCount());
×
365
  universe_info->set_rdm_devices(universe->UIDCount());
×
366

367
  std::vector<InputPort*> input_ports;
×
368
  std::vector<InputPort*>::const_iterator input_it;
×
369
  universe->InputPorts(&input_ports);
×
370
  for (input_it = input_ports.begin();
×
371
       input_it != input_ports.end();
×
372
       input_it++) {
×
373
    PortInfo *pi = universe_info->add_input_ports();
×
374
    PopulatePort(**input_it, pi);
×
375
  }
376

377
  std::vector<OutputPort*> output_ports;
×
378
  std::vector<OutputPort*>::const_iterator output_it;
×
379
  universe->OutputPorts(&output_ports);
×
380
  for (output_it = output_ports.begin();
×
381
       output_it != output_ports.end();
×
382
       output_it++) {
×
383
    PortInfo *pi = universe_info->add_output_ports();
×
384
    PopulatePort(**output_it, pi);
×
385
  }
386
}
×
387

388
void OlaServerServiceImpl::GetUniverseInfo(
×
389
    RpcController* controller,
390
    const OptionalUniverseRequest* request,
391
    UniverseInfoReply* response,
392
    ola::rpc::RpcService::CompletionCallback* done) {
393
  ClosureRunner runner(done);
×
394

395
  if (request->has_universe()) {
×
396
    // return info for a single universe
397
    Universe *universe = m_universe_store->GetUniverse(request->universe());
×
398
    if (!universe) {
×
399
      return MissingUniverseError(controller);
×
400
    }
401

402
    AddUniverse(universe, response);
×
403
  } else {
404
    // return all
405
    vector<Universe*> uni_list;
×
406
    m_universe_store->GetList(&uni_list);
×
407
    vector<Universe*>::const_iterator iter;
×
408

409
    for (iter = uni_list.begin(); iter != uni_list.end(); ++iter) {
×
410
      AddUniverse(*iter, response);
×
411
    }
412
  }
×
413
}
×
414

415
void OlaServerServiceImpl::GetPlugins(
×
416
    RpcController*,
417
    const PluginListRequest*,
418
    PluginListReply* response,
419
    ola::rpc::RpcService::CompletionCallback* done) {
420
  ClosureRunner runner(done);
×
421
  vector<AbstractPlugin*> plugin_list;
×
422
  vector<AbstractPlugin*>::const_iterator iter;
×
423
  m_plugin_manager->Plugins(&plugin_list);
×
424

425
  for (iter = plugin_list.begin(); iter != plugin_list.end(); ++iter) {
×
426
    PluginInfo *plugin_info = response->add_plugin();
×
427
    AddPlugin(*iter, plugin_info);
×
428
  }
429
}
×
430

431
void OlaServerServiceImpl::ReloadPlugins(
×
432
    RpcController*,
433
    const ::ola::proto::PluginReloadRequest*,
434
    Ack*,
435
    ola::rpc::RpcService::CompletionCallback* done) {
436
  ClosureRunner runner(done);
×
437
  if (m_reload_plugins_callback.get()) {
×
438
    m_reload_plugins_callback->Run();
×
439
  } else {
440
    OLA_WARN << "No plugin reload callback provided!";
×
441
  }
442
}
×
443

444
void OlaServerServiceImpl::GetPluginDescription(
×
445
    RpcController* controller,
446
    const ola::proto::PluginDescriptionRequest* request,
447
    ola::proto::PluginDescriptionReply* response,
448
    ola::rpc::RpcService::CompletionCallback* done) {
449
  ClosureRunner runner(done);
×
450
  AbstractPlugin *plugin =
×
451
    m_plugin_manager->GetPlugin((ola_plugin_id) request->plugin_id());
×
452

453
  if (plugin) {
×
454
    response->set_name(plugin->Name());
×
455
    response->set_description(plugin->Description());
×
456
  } else {
457
    controller->SetFailed("Plugin not loaded");
×
458
  }
459
}
×
460

461
void OlaServerServiceImpl::GetPluginState(
×
462
    RpcController* controller,
463
    const ola::proto::PluginStateRequest* request,
464
    ola::proto::PluginStateReply* response,
465
    ola::rpc::RpcService::CompletionCallback* done) {
466
  ClosureRunner runner(done);
×
467
  ola_plugin_id plugin_id = (ola_plugin_id) request->plugin_id();
×
468
  AbstractPlugin *plugin = m_plugin_manager->GetPlugin(plugin_id);
×
469

470
  if (plugin) {
×
471
    response->set_name(plugin->Name());
×
472
    response->set_enabled(plugin->IsEnabled());
×
473
    response->set_active(m_plugin_manager->IsActive(plugin_id));
×
474
    response->set_preferences_source(plugin->PreferenceConfigLocation());
×
475
    vector<AbstractPlugin*> conflict_list;
×
476
    m_plugin_manager->GetConflictList(plugin_id, &conflict_list);
×
477
    vector<AbstractPlugin*>::const_iterator iter = conflict_list.begin();
×
478
    for (; iter != conflict_list.end(); ++iter) {
×
479
      PluginInfo *plugin_info = response->add_conflicts_with();
×
480
      AddPlugin(*iter, plugin_info);
×
481
    }
482
  } else {
×
483
    controller->SetFailed("Plugin not loaded");
×
484
  }
485
}
×
486

487
void OlaServerServiceImpl::SetPluginState(
×
488
    RpcController *controller,
489
    const ola::proto::PluginStateChangeRequest* request,
490
    Ack*,
491
    ola::rpc::RpcService::CompletionCallback* done) {
492
  ClosureRunner runner(done);
×
493
  ola_plugin_id plugin_id = (ola_plugin_id) request->plugin_id();
×
494
  AbstractPlugin *plugin = m_plugin_manager->GetPlugin(plugin_id);
×
495

496
  if (plugin) {
×
497
    OLA_DEBUG << "SetPluginState to " << request->enabled()
×
498
              << " for plugin " << plugin->Name();
×
499
    if (request->enabled()) {
×
500
      if (!m_plugin_manager->EnableAndStartPlugin(plugin_id)) {
×
501
        controller->SetFailed("Failed to start plugin: " + plugin->Name());
×
502
      }
503
    } else {
504
      m_plugin_manager->DisableAndStopPlugin(plugin_id);
×
505
    }
506
  }
507
}
×
508

509
void OlaServerServiceImpl::GetDeviceInfo(
×
510
    RpcController*,
511
    const DeviceInfoRequest* request,
512
    DeviceInfoReply* response,
513
    ola::rpc::RpcService::CompletionCallback* done) {
514
  ClosureRunner runner(done);
×
515
  vector<device_alias_pair> device_list = m_device_manager->Devices();
×
516
  vector<device_alias_pair>::const_iterator iter;
×
517

518
  for (iter = device_list.begin(); iter != device_list.end(); ++iter) {
×
519
    if (request->has_plugin_id()) {
×
520
      if (iter->device->Owner()->Id() == request->plugin_id() ||
×
521
          request->plugin_id() == ola::OLA_PLUGIN_ALL) {
×
522
        AddDevice(iter->device, iter->alias, response);
×
523
      }
524
    } else {
525
      AddDevice(iter->device, iter->alias, response);
×
526
    }
527
  }
528
}
×
529

530
void OlaServerServiceImpl::GetCandidatePorts(
×
531
    RpcController* controller,
532
    const ola::proto::OptionalUniverseRequest* request,
533
    ola::proto::DeviceInfoReply* response,
534
    ola::rpc::RpcService::CompletionCallback* done) {
535
  ClosureRunner runner(done);
×
536
  vector<device_alias_pair> device_list = m_device_manager->Devices();
×
537
  vector<device_alias_pair>::const_iterator iter;
×
538

539
  Universe *universe = NULL;
×
540

541
  if (request->has_universe()) {
×
542
    universe = m_universe_store->GetUniverse(request->universe());
×
543

544
    if (!universe) {
×
545
      return MissingUniverseError(controller);
×
546
    }
547
  }
548

549
  vector<InputPort*> input_ports;
×
550
  vector<OutputPort*> output_ports;
×
551
  vector<InputPort*>::const_iterator input_iter;
×
552
  vector<OutputPort*>::const_iterator output_iter;
×
553

554
  for (iter = device_list.begin(); iter != device_list.end(); ++iter) {
×
555
    AbstractDevice *device = iter->device;
×
556
    input_ports.clear();
×
557
    output_ports.clear();
×
558
    device->InputPorts(&input_ports);
×
559
    device->OutputPorts(&output_ports);
×
560

561
    bool seen_input_port = false;
×
562
    bool seen_output_port = false;
×
563
    unsigned int unpatched_input_ports = 0;
×
564
    unsigned int unpatched_output_ports = 0;
×
565

566
    if (universe) {
×
567
      for (input_iter = input_ports.begin(); input_iter != input_ports.end();
×
568
           input_iter++) {
×
569
        if ((*input_iter)->GetUniverse() == universe) {
×
570
          seen_input_port = true;
571
        } else if (!(*input_iter)->GetUniverse()) {
×
572
          unpatched_input_ports++;
×
573
        }
574
      }
575

576
      for (output_iter = output_ports.begin();
×
577
           output_iter != output_ports.end(); output_iter++) {
×
578
        if ((*output_iter)->GetUniverse() == universe) {
×
579
          seen_output_port = true;
580
        } else if (!(*output_iter)->GetUniverse()) {
×
581
          unpatched_output_ports++;
×
582
        }
583
      }
584
    } else {
585
      unpatched_input_ports = input_ports.size();
×
586
      unpatched_output_ports = output_ports.size();
×
587
    }
588

589
    bool can_bind_more_input_ports = (
×
590
      (!seen_output_port || device->AllowLooping()) &&
×
591
      (!seen_input_port || device->AllowMultiPortPatching()));
×
592

593
    bool can_bind_more_output_ports = (
×
594
      (!seen_input_port || device->AllowLooping()) &&
×
595
      (!seen_output_port || device->AllowMultiPortPatching()));
×
596

597
    if ((unpatched_input_ports == 0 || !can_bind_more_input_ports) &&
×
598
        (unpatched_output_ports == 0 || !can_bind_more_output_ports)) {
×
599
      continue;
×
600
    }
601

602
    // go ahead and create the device at this point
603
    DeviceInfo *device_info = response->add_device();
×
604
    device_info->set_device_alias(iter->alias);
×
605
    device_info->set_device_name(device->Name());
×
606
    device_info->set_device_id(device->UniqueId());
×
607

608
    if (device->Owner()) {
×
609
      device_info->set_plugin_id(device->Owner()->Id());
×
610
    }
611

612
    for (input_iter = input_ports.begin(); input_iter != input_ports.end();
×
613
         ++input_iter) {
×
614
      if ((*input_iter)->GetUniverse()) {
×
615
        continue;
×
616
      }
617
      if (!can_bind_more_input_ports) {
×
618
        break;
619
      }
620

621
      PortInfo *port_info = device_info->add_input_port();
×
622
      PopulatePort(**input_iter, port_info);
×
623

624
      if (!device->AllowMultiPortPatching()) {
×
625
        break;
626
      }
627
    }
628

629
    for (output_iter = output_ports.begin(); output_iter != output_ports.end();
×
630
        ++output_iter) {
×
631
      if ((*output_iter)->GetUniverse()) {
×
632
        continue;
×
633
      }
634
      if (!can_bind_more_output_ports) {
×
635
        break;
636
      }
637

638
      PortInfo *port_info = device_info->add_output_port();
×
639
      PopulatePort(**output_iter, port_info);
×
640

641
      if (!device->AllowMultiPortPatching()) {
×
642
        break;
643
      }
644
    }
645
  }
646
}
×
647

648
void OlaServerServiceImpl::ConfigureDevice(
×
649
    RpcController* controller,
650
    const DeviceConfigRequest* request,
651
    DeviceConfigReply* response,
652
    ola::rpc::RpcService::CompletionCallback* done) {
653
  AbstractDevice *device =
×
654
      m_device_manager->GetDevice(request->device_alias());
×
655
  if (!device) {
×
656
    MissingDeviceError(controller);
×
657
    done->Run();
×
658
    return;
×
659
  }
660

661
  device->Configure(controller, request->data(),
×
662
                    response->mutable_data(), done);
663
}
664

665
void OlaServerServiceImpl::GetUIDs(
×
666
    RpcController* controller,
667
    const ola::proto::UniverseRequest* request,
668
    ola::proto::UIDListReply* response,
669
    ola::rpc::RpcService::CompletionCallback* done) {
670
  ClosureRunner runner(done);
×
671
  Universe *universe = m_universe_store->GetUniverse(request->universe());
×
672
  if (!universe) {
×
673
    return MissingUniverseError(controller);
×
674
  }
675

676
  response->set_universe(universe->UniverseId());
×
677
  UIDSet uid_set;
×
678
  universe->GetUIDs(&uid_set);
×
679

680
  UIDSet::Iterator iter = uid_set.Begin();
×
681
  for (; iter != uid_set.End(); ++iter) {
×
682
    ola::proto::UID *uid = response->add_uid();
×
683
    SetProtoUID(*iter, uid);
×
684
  }
685
}
×
686

687
void OlaServerServiceImpl::ForceDiscovery(
×
688
    RpcController* controller,
689
    const ola::proto::DiscoveryRequest* request,
690
    ola::proto::UIDListReply *response,
691
    ola::rpc::RpcService::CompletionCallback* done) {
692
  Universe *universe = m_universe_store->GetUniverse(request->universe());
×
693

694
  if (universe) {
×
695
    unsigned int universe_id = request->universe();
×
696
    m_broker->RunRDMDiscovery(
×
697
        GetClient(controller),
×
698
        universe,
699
        request->full(),
×
700
        NewSingleCallback(this,
×
701
                          &OlaServerServiceImpl::RDMDiscoveryComplete,
702
                          universe_id,
703
                          done,
704
                          response));
705
  } else {
706
    ClosureRunner runner(done);
×
707
    MissingUniverseError(controller);
×
708
  }
×
709
}
×
710

711
void OlaServerServiceImpl::RDMCommand(
×
712
    RpcController* controller,
713
    const ola::proto::RDMRequest* request,
714
    ola::proto::RDMResponse* response,
715
    ola::rpc::RpcService::CompletionCallback* done) {
716
  Universe *universe = m_universe_store->GetUniverse(request->universe());
×
717
  if (!universe) {
×
718
    MissingUniverseError(controller);
×
719
    done->Run();
×
720
    return;
×
721
  }
722

723
  Client *client = GetClient(controller);
×
724
  UID source_uid = client->GetUID();
×
725

726
  UID destination(request->uid().esta_id(),
×
727
                  request->uid().device_id());
×
728

729
  RDMRequest::OverrideOptions options = RDMRequestOptionsFromProto(*request);
×
730

731
  ola::rdm::RDMRequest *rdm_request = NULL;
×
732
  if (request->is_set()) {
×
733
    rdm_request = new ola::rdm::RDMSetRequest(
×
734
        source_uid,
735
        destination,
736
        universe->GetRDMTransactionNumber(),
×
737
        1,  // port id
738
        request->sub_device(),
×
739
        request->param_id(),
×
740
        reinterpret_cast<const uint8_t*>(request->data().data()),
×
741
        request->data().size(),
×
742
        options);
×
743
  } else {
744
    rdm_request = new ola::rdm::RDMGetRequest(
×
745
        source_uid,
746
        destination,
747
        universe->GetRDMTransactionNumber(),
×
748
        1,  // port id
749
        request->sub_device(),
×
750
        request->param_id(),
×
751
        reinterpret_cast<const uint8_t*>(request->data().data()),
×
752
        request->data().size(),
×
753
        options);
×
754
  }
755

756
  ola::rdm::RDMCallback *callback =
×
757
    NewSingleCallback(
×
758
        this,
759
        &OlaServerServiceImpl::HandleRDMResponse,
760
        response,
761
        done,
762
        request->include_raw_response());
×
763

764
  m_broker->SendRDMRequest(client, universe, rdm_request, callback);
×
765
}
766

767
void OlaServerServiceImpl::RDMDiscoveryCommand(
×
768
    RpcController* controller,
769
    const ola::proto::RDMDiscoveryRequest* request,
770
    ola::proto::RDMResponse* response,
771
    ola::rpc::RpcService::CompletionCallback* done) {
772
  Universe *universe = m_universe_store->GetUniverse(request->universe());
×
773
  if (!universe) {
×
774
    MissingUniverseError(controller);
×
775
    done->Run();
×
776
    return;
×
777
  }
778

779
  Client *client = GetClient(controller);
×
780
  UID source_uid = client->GetUID();
×
781

782
  UID destination(request->uid().esta_id(),
×
783
                  request->uid().device_id());
×
784

785
  RDMRequest::OverrideOptions options = RDMRequestOptionsFromProto(*request);
×
786

787
  ola::rdm::RDMRequest *rdm_request = new ola::rdm::RDMDiscoveryRequest(
×
788
      source_uid,
789
      destination,
790
      universe->GetRDMTransactionNumber(),
×
791
      1,  // port id
792
      request->sub_device(),
×
793
      request->param_id(),
×
794
      reinterpret_cast<const uint8_t*>(request->data().data()),
×
795
      request->data().size(),
×
796
      options);
×
797

798
  ola::rdm::RDMCallback *callback =
×
799
    NewSingleCallback(
×
800
        this,
801
        &OlaServerServiceImpl::HandleRDMResponse,
802
        response,
803
        done,
804
        request->include_raw_response());
×
805

806
  m_broker->SendRDMRequest(client, universe, rdm_request, callback);
×
807
}
808

809
void OlaServerServiceImpl::SetSourceUID(
×
810
    RpcController *controller,
811
    const ola::proto::UID* request,
812
    Ack*,
813
    ola::rpc::RpcService::CompletionCallback* done) {
814
  ClosureRunner runner(done);
×
815

816
  UID source_uid(request->esta_id(), request->device_id());
×
817
  GetClient(controller)->SetUID(source_uid);
×
818
}
×
819

820
void OlaServerServiceImpl::SendTimeCode(
×
821
    RpcController* controller,
822
    const ola::proto::TimeCode* request,
823
    Ack*,
824
    ola::rpc::RpcService::CompletionCallback* done) {
825
  ClosureRunner runner(done);
×
826
  ola::timecode::TimeCode time_code(
×
827
      static_cast<ola::timecode::TimeCodeType>(request->type()),
×
828
      request->hours(),
×
829
      request->minutes(),
×
830
      request->seconds(),
×
831
      request->frames());
×
832

833
  if (time_code.IsValid()) {
×
834
    m_device_manager->SendTimeCode(time_code);
×
835
  } else {
836
    controller->SetFailed("Invalid TimeCode");
×
837
  }
838
}
×
839

840

841
// Private methods
842
//-----------------------------------------------------------------------------
843
/*
844
 * Handle an RDM Response, this includes broadcast messages, messages that
845
 * timed out and normal response messages.
846
 */
847
void OlaServerServiceImpl::HandleRDMResponse(
×
848
    ola::proto::RDMResponse* response,
849
    ola::rpc::RpcService::CompletionCallback* done,
850
    bool include_raw_packets,
851
    ola::rdm::RDMReply *reply) {
852
  ClosureRunner runner(done);
×
853
  response->set_response_code(
×
854
      static_cast<ola::proto::RDMResponseCode>(reply->StatusCode()));
×
855

856
  if (reply->StatusCode() == ola::rdm::RDM_COMPLETED_OK) {
×
857
    if (!reply->Response()) {
×
858
      // No response returned.
859
      OLA_WARN << "RDM code was ok but response was NULL";
×
860
      response->set_response_code(static_cast<ola::proto::RDMResponseCode>(
×
861
            ola::rdm::RDM_INVALID_RESPONSE));
862
    } else if (reply->Response()->ResponseType() <= ola::rdm::RDM_NACK_REASON) {
×
863
      // Valid RDM Response code.
864
      SetProtoUID(reply->Response()->SourceUID(),
×
865
                  response->mutable_source_uid());
866
      SetProtoUID(reply->Response()->DestinationUID(),
×
867
                  response->mutable_dest_uid());
868
      response->set_transaction_number(reply->Response()->TransactionNumber());
×
869
      response->set_response_type(static_cast<ola::proto::RDMResponseType>(
×
870
          reply->Response()->ResponseType()));
×
871
      response->set_message_count(reply->Response()->MessageCount());
×
872
      response->set_sub_device(reply->Response()->SubDevice());
×
873

874
      switch (reply->Response()->CommandClass()) {
×
875
        case ola::rdm::RDMCommand::DISCOVER_COMMAND_RESPONSE:
×
876
          response->set_command_class(ola::proto::RDM_DISCOVERY_RESPONSE);
×
877
          break;
878
        case ola::rdm::RDMCommand::GET_COMMAND_RESPONSE:
×
879
          response->set_command_class(ola::proto::RDM_GET_RESPONSE);
×
880
          break;
881
        case ola::rdm::RDMCommand::SET_COMMAND_RESPONSE:
×
882
          response->set_command_class(ola::proto::RDM_SET_RESPONSE);
×
883
          break;
884
        default:
×
885
          OLA_WARN << "Unknown command class "
×
886
                   << strings::ToHex(static_cast<unsigned int>(
×
887
                         reply->Response()->CommandClass()));
×
888
      }
889

890
      response->set_param_id(reply->Response()->ParamId());
×
891

892
      if (reply->Response()->ParamData() &&
×
893
          reply->Response()->ParamDataSize()) {
×
894
        response->set_data(
×
895
            reinterpret_cast<const char*>(reply->Response()->ParamData()),
×
896
            reply->Response()->ParamDataSize());
×
897
      }
898
    } else {
899
      // Invalid RDM Response code.
900
      OLA_WARN << "RDM response present, but response type is invalid, was "
×
901
               << strings::ToHex(reply->Response()->ResponseType());
×
902
      response->set_response_code(ola::proto::RDM_INVALID_RESPONSE);
×
903
    }
904
  }
905

906
  if (include_raw_packets) {
×
907
    vector<rdm::RDMFrame>::const_iterator iter = reply->Frames().begin();
×
908
    for (; iter != reply->Frames().end(); ++iter) {
×
909
      ola::proto::RDMFrame *frame = response->add_raw_frame();
×
910
      frame->set_raw_response(iter->data.data(), iter->data.size());
×
911
      ola::proto::RDMFrameTiming *timing = frame->mutable_timing();
×
912
      timing->set_response_delay(iter->timing.response_time);
×
913
      timing->set_break_time(iter->timing.break_time);
×
914
      timing->set_mark_time(iter->timing.mark_time);
×
915
      timing->set_data_time(iter->timing.data_time);
×
916
    }
917
  }
918
}
×
919

920

921
/**
922
 * Called when RDM discovery completes
923
 */
924
void OlaServerServiceImpl::RDMDiscoveryComplete(
×
925
    unsigned int universe_id,
926
    ola::rpc::RpcService::CompletionCallback* done,
927
    ola::proto::UIDListReply *response,
928
    const UIDSet &uids) {
929
  ClosureRunner runner(done);
×
930

931
  response->set_universe(universe_id);
×
932
  UIDSet::Iterator iter = uids.Begin();
×
933
  for (; iter != uids.End(); ++iter) {
×
934
    ola::proto::UID *uid = response->add_uid();
×
935
    SetProtoUID(*iter, uid);
×
936
  }
937
}
×
938

939

940
void OlaServerServiceImpl::MissingUniverseError(RpcController* controller) {
5✔
941
  controller->SetFailed("Universe doesn't exist");
5✔
942
}
5✔
943

944
void OlaServerServiceImpl::MissingDeviceError(RpcController* controller) {
×
945
  controller->SetFailed("Device doesn't exist");
×
946
}
×
947

948

949
void OlaServerServiceImpl::MissingPluginError(RpcController* controller) {
×
950
  controller->SetFailed("Plugin doesn't exist");
×
951
}
×
952

953

954
void OlaServerServiceImpl::MissingPortError(RpcController* controller) {
×
955
  controller->SetFailed("Port doesn't exist");
×
956
}
×
957

958

959
/*
960
 * Add this device to the DeviceInfo response
961
 */
962
void OlaServerServiceImpl::AddPlugin(AbstractPlugin *plugin,
×
963
                                     PluginInfo* plugin_info) const {
964
  plugin_info->set_plugin_id(plugin->Id());
×
965
  plugin_info->set_name(plugin->Name());
×
966
  plugin_info->set_active(m_plugin_manager->IsActive(plugin->Id()));
×
967
  plugin_info->set_enabled(m_plugin_manager->IsEnabled(plugin->Id()));
×
968
}
×
969

970

971
/*
972
 * Add this device to the DeviceInfo response
973
 */
974
void OlaServerServiceImpl::AddDevice(AbstractDevice *device,
×
975
                                     unsigned int alias,
976
                                     DeviceInfoReply* response) const {
977
  DeviceInfo *device_info = response->add_device();
×
978
  device_info->set_device_alias(alias);
×
979
  device_info->set_device_name(device->Name());
×
980
  device_info->set_device_id(device->UniqueId());
×
981

982
  if (device->Owner()) {
×
983
    device_info->set_plugin_id(device->Owner()->Id());
×
984
  }
985

986
  vector<InputPort*> input_ports;
×
987
  device->InputPorts(&input_ports);
×
988
  vector<InputPort*>::const_iterator input_iter;
×
989

990
  for (input_iter = input_ports.begin(); input_iter != input_ports.end();
×
991
       ++input_iter) {
×
992
    PortInfo *port_info = device_info->add_input_port();
×
993
    PopulatePort(**input_iter, port_info);
×
994
  }
995

996
  vector<OutputPort*> output_ports;
×
997
  device->OutputPorts(&output_ports);
×
998
  vector<OutputPort*>::const_iterator output_iter;
×
999

1000
  for (output_iter = output_ports.begin(); output_iter != output_ports.end();
×
1001
      ++output_iter) {
×
1002
    PortInfo *port_info = device_info->add_output_port();
×
1003
    PopulatePort(**output_iter, port_info);
×
1004
  }
1005
}
×
1006

1007

1008
template <class PortClass>
1009
void OlaServerServiceImpl::PopulatePort(const PortClass &port,
×
1010
                                        PortInfo *port_info) const {
1011
  port_info->set_port_id(port.PortId());
×
1012
  port_info->set_priority_capability(port.PriorityCapability());
×
1013
  port_info->set_description(port.Description());
×
1014

1015
  if (port.GetUniverse()) {
×
1016
    port_info->set_active(true);
×
1017
    port_info->set_universe(port.GetUniverse()->UniverseId());
×
1018
  } else {
1019
    port_info->set_active(false);
×
1020
  }
1021

1022
  if (port.PriorityCapability() != CAPABILITY_NONE) {
×
1023
    port_info->set_priority_mode(port.GetPriorityMode());
×
1024
    if (port.GetPriorityMode() == PRIORITY_MODE_STATIC) {
×
1025
      port_info->set_priority(port.GetPriority());
×
1026
    }
1027
  }
1028

1029
  port_info->set_supports_rdm(port.SupportsRDM());
×
1030
}
×
1031

1032
void OlaServerServiceImpl::SetProtoUID(const ola::rdm::UID &uid,
×
1033
                                       ola::proto::UID *pb_uid) {
1034
  pb_uid->set_esta_id(uid.ManufacturerId());
×
1035
  pb_uid->set_device_id(uid.DeviceId());
×
1036
}
×
1037

1038
Client* OlaServerServiceImpl::GetClient(ola::rpc::RpcController *controller) {
9✔
1039
  return reinterpret_cast<Client*>(controller->Session()->GetData());
9✔
1040
}
1041
}  // namespace ola
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

© 2025 Coveralls, Inc