PageRenderTime 57ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/olad/OlaServerServiceImpl.cpp

https://code.google.com/
C++ | 920 lines | 681 code | 137 blank | 102 comment | 135 complexity | e9bad8642fd6710dad7cdce6288e5569 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. *
  16. * OlaServerServiceImpl.cpp
  17. * Implemtation of the OlaServerService interface. This is the class that
  18. * handles all the RPCs on the server side.
  19. * Copyright (C) 2005 - 2008 Simon Newton
  20. */
  21. #include <algorithm>
  22. #include <string>
  23. #include <vector>
  24. #include "common/protocol/Ola.pb.h"
  25. #include "ola/Callback.h"
  26. #include "ola/CallbackRunner.h"
  27. #include "ola/DmxBuffer.h"
  28. #include "ola/ExportMap.h"
  29. #include "ola/Logging.h"
  30. #include "ola/rdm/UIDSet.h"
  31. #include "ola/rdm/RDMCommand.h"
  32. #include "ola/timecode/TimeCode.h"
  33. #include "ola/timecode/TimeCodeEnums.h"
  34. #include "olad/Client.h"
  35. #include "olad/Device.h"
  36. #include "olad/DeviceManager.h"
  37. #include "olad/DmxSource.h"
  38. #include "olad/OlaServerServiceImpl.h"
  39. #include "olad/Plugin.h"
  40. #include "olad/PluginManager.h"
  41. #include "olad/Port.h"
  42. #include "olad/PortManager.h"
  43. #include "olad/Universe.h"
  44. #include "olad/UniverseStore.h"
  45. namespace ola {
  46. using google::protobuf::RpcController;
  47. using ola::proto::Ack;
  48. using ola::proto::DeviceConfigReply;
  49. using ola::proto::DeviceConfigRequest;
  50. using ola::proto::DeviceInfo;
  51. using ola::proto::DeviceInfoReply;
  52. using ola::proto::DeviceInfoRequest;
  53. using ola::proto::DmxData;
  54. using ola::proto::MergeModeRequest;
  55. using ola::proto::OptionalUniverseRequest;
  56. using ola::proto::PatchPortRequest;
  57. using ola::proto::PluginDescriptionReply;
  58. using ola::proto::PluginDescriptionRequest;
  59. using ola::proto::PluginInfo;
  60. using ola::proto::PluginListReply;
  61. using ola::proto::PluginListRequest;
  62. using ola::proto::PortInfo;
  63. using ola::proto::RegisterDmxRequest;
  64. using ola::proto::UniverseInfo;
  65. using ola::proto::UniverseInfoReply;
  66. using ola::proto::UniverseNameRequest;
  67. using ola::proto::UniverseRequest;
  68. using ola::CallbackRunner;
  69. using ola::rdm::UIDSet;
  70. using ola::rdm::RDMResponse;
  71. typedef CallbackRunner<google::protobuf::Closure> ClosureRunner;
  72. OlaServerServiceImpl::~OlaServerServiceImpl() {
  73. }
  74. /*
  75. * Returns the current DMX values for a particular universe
  76. */
  77. void OlaServerServiceImpl::GetDmx(
  78. RpcController* controller,
  79. const UniverseRequest* request,
  80. DmxData* response,
  81. google::protobuf::Closure* done) {
  82. ClosureRunner runner(done);
  83. Universe *universe = m_universe_store->GetUniverse(request->universe());
  84. if (!universe)
  85. return MissingUniverseError(controller);
  86. const DmxBuffer buffer = universe->GetDMX();
  87. response->set_data(buffer.Get());
  88. response->set_universe(request->universe());
  89. }
  90. /*
  91. * Register a client to receive DMX data.
  92. */
  93. void OlaServerServiceImpl::RegisterForDmx(
  94. RpcController* controller,
  95. const RegisterDmxRequest* request,
  96. Ack*,
  97. google::protobuf::Closure* done,
  98. Client *client) {
  99. ClosureRunner runner(done);
  100. Universe *universe = m_universe_store->GetUniverseOrCreate(
  101. request->universe());
  102. if (!universe)
  103. return MissingUniverseError(controller);
  104. if (request->action() == ola::proto::REGISTER) {
  105. universe->AddSinkClient(client);
  106. } else {
  107. universe->RemoveSinkClient(client);
  108. }
  109. }
  110. /*
  111. * Update the DMX values for a particular universe
  112. */
  113. void OlaServerServiceImpl::UpdateDmxData(
  114. RpcController* controller,
  115. const DmxData* request,
  116. Ack*,
  117. google::protobuf::Closure* done,
  118. Client *client) {
  119. ClosureRunner runner(done);
  120. Universe *universe = m_universe_store->GetUniverse(request->universe());
  121. if (!universe)
  122. return MissingUniverseError(controller);
  123. if (client) {
  124. DmxBuffer buffer;
  125. buffer.Set(request->data());
  126. uint8_t priority = DmxSource::PRIORITY_DEFAULT;
  127. if (request->has_priority()) {
  128. priority = request->priority();
  129. priority = std::max(DmxSource::PRIORITY_MIN, priority);
  130. priority = std::min(DmxSource::PRIORITY_MAX, priority);
  131. }
  132. DmxSource source(buffer, *m_wake_up_time, priority);
  133. client->DMXRecieved(request->universe(), source);
  134. universe->SourceClientDataChanged(client);
  135. }
  136. }
  137. /*
  138. * Handle a streaming DMX update, we don't send responses for this
  139. */
  140. void OlaServerServiceImpl::StreamDmxData(
  141. RpcController*,
  142. const ::ola::proto::DmxData* request,
  143. ::ola::proto::STREAMING_NO_RESPONSE*,
  144. ::google::protobuf::Closure*,
  145. Client *client) {
  146. Universe *universe = m_universe_store->GetUniverse(request->universe());
  147. if (!universe)
  148. return;
  149. if (client) {
  150. DmxBuffer buffer;
  151. buffer.Set(request->data());
  152. uint8_t priority = DmxSource::PRIORITY_DEFAULT;
  153. if (request->has_priority()) {
  154. priority = request->priority();
  155. priority = std::max(DmxSource::PRIORITY_MIN, priority);
  156. priority = std::min(DmxSource::PRIORITY_MAX, priority);
  157. }
  158. DmxSource source(buffer, *m_wake_up_time, priority);
  159. client->DMXRecieved(request->universe(), source);
  160. universe->SourceClientDataChanged(client);
  161. }
  162. }
  163. /*
  164. * Sets the name of a universe
  165. */
  166. void OlaServerServiceImpl::SetUniverseName(
  167. RpcController* controller,
  168. const UniverseNameRequest* request,
  169. Ack*,
  170. google::protobuf::Closure* done) {
  171. ClosureRunner runner(done);
  172. Universe *universe = m_universe_store->GetUniverse(request->universe());
  173. if (!universe)
  174. return MissingUniverseError(controller);
  175. universe->SetName(request->name());
  176. }
  177. /*
  178. * Set the merge mode for a universe
  179. */
  180. void OlaServerServiceImpl::SetMergeMode(
  181. RpcController* controller,
  182. const MergeModeRequest* request,
  183. Ack*,
  184. google::protobuf::Closure* done) {
  185. ClosureRunner runner(done);
  186. Universe *universe = m_universe_store->GetUniverse(request->universe());
  187. if (!universe)
  188. return MissingUniverseError(controller);
  189. Universe::merge_mode mode = request->merge_mode() == ola::proto::HTP ?
  190. Universe::MERGE_HTP : Universe::MERGE_LTP;
  191. universe->SetMergeMode(mode);
  192. }
  193. /*
  194. * Patch a port to a universe
  195. */
  196. void OlaServerServiceImpl::PatchPort(
  197. RpcController* controller,
  198. const PatchPortRequest* request,
  199. Ack*,
  200. google::protobuf::Closure* done) {
  201. ClosureRunner runner(done);
  202. AbstractDevice *device =
  203. m_device_manager->GetDevice(request->device_alias());
  204. if (!device)
  205. return MissingDeviceError(controller);
  206. bool result;
  207. if (request->is_output()) {
  208. OutputPort *port = device->GetOutputPort(request->port_id());
  209. if (!port)
  210. return MissingPortError(controller);
  211. if (request->action() == ola::proto::PATCH)
  212. result = m_port_manager->PatchPort(port, request->universe());
  213. else
  214. result = m_port_manager->UnPatchPort(port);
  215. } else {
  216. InputPort *port = device->GetInputPort(request->port_id());
  217. if (!port)
  218. return MissingPortError(controller);
  219. if (request->action() == ola::proto::PATCH)
  220. result = m_port_manager->PatchPort(port, request->universe());
  221. else
  222. result = m_port_manager->UnPatchPort(port);
  223. }
  224. if (!result)
  225. controller->SetFailed("Patch port request failed");
  226. }
  227. /*
  228. * Set the priority of a set of ports
  229. */
  230. void OlaServerServiceImpl::SetPortPriority(
  231. RpcController* controller,
  232. const ola::proto::PortPriorityRequest* request,
  233. Ack*,
  234. google::protobuf::Closure* done) {
  235. ClosureRunner runner(done);
  236. AbstractDevice *device =
  237. m_device_manager->GetDevice(request->device_alias());
  238. if (!device)
  239. return MissingDeviceError(controller);
  240. bool status;
  241. bool inherit_mode = true;
  242. uint8_t value = 0;
  243. if (request->priority_mode() == PRIORITY_MODE_OVERRIDE) {
  244. if (request->has_priority()) {
  245. inherit_mode = false;
  246. value = request->priority();
  247. } else {
  248. OLA_INFO << "In Set Port Priority, override mode was set but the value "
  249. "wasn't specified";
  250. controller->SetFailed(
  251. "Invalid SetPortPriority request, see logs for more info");
  252. return;
  253. }
  254. }
  255. if (request->is_output()) {
  256. OutputPort *port = device->GetOutputPort(request->port_id());
  257. if (!port)
  258. return MissingPortError(controller);
  259. if (inherit_mode)
  260. status = m_port_manager->SetPriorityInherit(port);
  261. else
  262. status = m_port_manager->SetPriorityOverride(port, value);
  263. } else {
  264. InputPort *port = device->GetInputPort(request->port_id());
  265. if (!port)
  266. return MissingPortError(controller);
  267. if (inherit_mode)
  268. status = m_port_manager->SetPriorityInherit(port);
  269. else
  270. status = m_port_manager->SetPriorityOverride(port, value);
  271. }
  272. if (!status)
  273. controller->SetFailed(
  274. "Invalid SetPortPriority request, see logs for more info");
  275. }
  276. /*
  277. * Returns information on the active universes.
  278. */
  279. void OlaServerServiceImpl::GetUniverseInfo(
  280. RpcController* controller,
  281. const OptionalUniverseRequest* request,
  282. UniverseInfoReply* response,
  283. google::protobuf::Closure* done) {
  284. ClosureRunner runner(done);
  285. UniverseInfo *universe_info;
  286. if (request->has_universe()) {
  287. // return info for a single universe
  288. Universe *universe = m_universe_store->GetUniverse(request->universe());
  289. if (!universe)
  290. return MissingUniverseError(controller);
  291. universe_info = response->add_universe();
  292. universe_info->set_universe(universe->UniverseId());
  293. universe_info->set_name(universe->Name());
  294. universe_info->set_merge_mode(universe->MergeMode() == Universe::MERGE_HTP
  295. ? ola::proto::HTP: ola::proto::LTP);
  296. universe_info->set_input_port_count(universe->InputPortCount());
  297. universe_info->set_output_port_count(universe->OutputPortCount());
  298. universe_info->set_rdm_devices(universe->UIDCount());
  299. } else {
  300. // return all
  301. vector<Universe*> uni_list;
  302. m_universe_store->GetList(&uni_list);
  303. vector<Universe*>::const_iterator iter;
  304. for (iter = uni_list.begin(); iter != uni_list.end(); ++iter) {
  305. universe_info = response->add_universe();
  306. universe_info->set_universe((*iter)->UniverseId());
  307. universe_info->set_name((*iter)->Name());
  308. universe_info->set_merge_mode((*iter)->MergeMode() == Universe::MERGE_HTP
  309. ? ola::proto::HTP: ola::proto::LTP);
  310. universe_info->set_input_port_count((*iter)->InputPortCount());
  311. universe_info->set_output_port_count((*iter)->OutputPortCount());
  312. universe_info->set_rdm_devices((*iter)->UIDCount());
  313. }
  314. }
  315. }
  316. /*
  317. * Return info on available plugins
  318. */
  319. void OlaServerServiceImpl::GetPlugins(
  320. RpcController*,
  321. const PluginListRequest*,
  322. PluginListReply* response,
  323. google::protobuf::Closure* done) {
  324. ClosureRunner runner(done);
  325. vector<AbstractPlugin*> plugin_list;
  326. vector<AbstractPlugin*>::const_iterator iter;
  327. m_plugin_manager->Plugins(&plugin_list);
  328. for (iter = plugin_list.begin(); iter != plugin_list.end(); ++iter)
  329. AddPlugin(*iter, response);
  330. }
  331. /*
  332. * Return the description for a plugin.
  333. */
  334. void OlaServerServiceImpl::GetPluginDescription(
  335. RpcController* controller,
  336. const ola::proto::PluginDescriptionRequest* request,
  337. ola::proto::PluginDescriptionReply* response,
  338. google::protobuf::Closure* done) {
  339. ClosureRunner runner(done);
  340. AbstractPlugin *plugin =
  341. m_plugin_manager->GetPlugin((ola_plugin_id) request->plugin_id());
  342. if (plugin) {
  343. response->set_name(plugin->Name());
  344. response->set_description(plugin->Description());
  345. } else {
  346. controller->SetFailed("Plugin not loaded");
  347. }
  348. }
  349. /*
  350. * Return information on available devices
  351. */
  352. void OlaServerServiceImpl::GetDeviceInfo(RpcController*,
  353. const DeviceInfoRequest* request,
  354. DeviceInfoReply* response,
  355. google::protobuf::Closure* done) {
  356. ClosureRunner runner(done);
  357. vector<device_alias_pair> device_list = m_device_manager->Devices();
  358. vector<device_alias_pair>::const_iterator iter;
  359. for (iter = device_list.begin(); iter != device_list.end(); ++iter) {
  360. if (request->has_plugin_id()) {
  361. if (iter->device->Owner()->Id() == request->plugin_id() ||
  362. request->plugin_id() == ola::OLA_PLUGIN_ALL)
  363. AddDevice(iter->device, iter->alias, response);
  364. } else {
  365. AddDevice(iter->device, iter->alias, response);
  366. }
  367. }
  368. }
  369. /*
  370. * Handle a GetCandidatePorts request
  371. */
  372. void OlaServerServiceImpl::GetCandidatePorts(
  373. RpcController* controller,
  374. const ola::proto::OptionalUniverseRequest* request,
  375. ola::proto::DeviceInfoReply* response,
  376. google::protobuf::Closure* done) {
  377. ClosureRunner runner(done);
  378. vector<device_alias_pair> device_list = m_device_manager->Devices();
  379. vector<device_alias_pair>::const_iterator iter;
  380. Universe *universe = NULL;
  381. if (request->has_universe()) {
  382. universe = m_universe_store->GetUniverse(request->universe());
  383. if (!universe)
  384. return MissingUniverseError(controller);
  385. }
  386. vector<InputPort*> input_ports;
  387. vector<OutputPort*> output_ports;
  388. vector<InputPort*>::const_iterator input_iter;
  389. vector<OutputPort*>::const_iterator output_iter;
  390. for (iter = device_list.begin(); iter != device_list.end(); ++iter) {
  391. AbstractDevice *device = iter->device;
  392. input_ports.clear();
  393. output_ports.clear();
  394. device->InputPorts(&input_ports);
  395. device->OutputPorts(&output_ports);
  396. bool seen_input_port = false;
  397. bool seen_output_port = false;
  398. unsigned int unpatched_input_ports = 0;
  399. unsigned int unpatched_output_ports = 0;
  400. if (universe) {
  401. for (input_iter = input_ports.begin(); input_iter != input_ports.end();
  402. input_iter++) {
  403. if ((*input_iter)->GetUniverse() == universe)
  404. seen_input_port = true;
  405. else if (!(*input_iter)->GetUniverse())
  406. unpatched_input_ports++;
  407. }
  408. for (output_iter = output_ports.begin();
  409. output_iter != output_ports.end(); output_iter++) {
  410. if ((*output_iter)->GetUniverse() == universe)
  411. seen_output_port = true;
  412. else if (!(*output_iter)->GetUniverse())
  413. unpatched_output_ports++;
  414. }
  415. } else {
  416. unpatched_input_ports = input_ports.size();
  417. unpatched_output_ports = output_ports.size();
  418. }
  419. bool can_bind_more_input_ports = (
  420. (!seen_output_port || device->AllowLooping()) &&
  421. (!seen_input_port || device->AllowMultiPortPatching()));
  422. bool can_bind_more_output_ports = (
  423. (!seen_input_port || device->AllowLooping()) &&
  424. (!seen_output_port || device->AllowMultiPortPatching()));
  425. if ((unpatched_input_ports == 0 || !can_bind_more_input_ports) &&
  426. (unpatched_output_ports == 0 || !can_bind_more_output_ports))
  427. continue;
  428. // go ahead and create the device at this point
  429. DeviceInfo *device_info = response->add_device();
  430. device_info->set_device_alias(iter->alias);
  431. device_info->set_device_name(device->Name());
  432. device_info->set_device_id(device->UniqueId());
  433. if (device->Owner())
  434. device_info->set_plugin_id(device->Owner()->Id());
  435. for (input_iter = input_ports.begin(); input_iter != input_ports.end();
  436. ++input_iter) {
  437. if ((*input_iter)->GetUniverse())
  438. continue;
  439. if (!can_bind_more_input_ports)
  440. break;
  441. PortInfo *port_info = device_info->add_input_port();
  442. PopulatePort(**input_iter, port_info);
  443. if (!device->AllowMultiPortPatching())
  444. break;
  445. }
  446. for (output_iter = output_ports.begin(); output_iter != output_ports.end();
  447. ++output_iter) {
  448. if ((*output_iter)->GetUniverse())
  449. continue;
  450. if (!can_bind_more_output_ports)
  451. break;
  452. PortInfo *port_info = device_info->add_output_port();
  453. PopulatePort(**output_iter, port_info);
  454. if (!device->AllowMultiPortPatching())
  455. break;
  456. }
  457. }
  458. }
  459. /*
  460. * Handle a ConfigureDevice request
  461. */
  462. void OlaServerServiceImpl::ConfigureDevice(RpcController* controller,
  463. const DeviceConfigRequest* request,
  464. DeviceConfigReply* response,
  465. google::protobuf::Closure* done) {
  466. AbstractDevice *device =
  467. m_device_manager->GetDevice(request->device_alias());
  468. if (!device) {
  469. MissingDeviceError(controller);
  470. done->Run();
  471. return;
  472. }
  473. device->Configure(controller,
  474. request->data(),
  475. response->mutable_data(), done);
  476. }
  477. /*
  478. * Fetch the UID list for a universe
  479. */
  480. void OlaServerServiceImpl::GetUIDs(RpcController* controller,
  481. const ola::proto::UniverseRequest* request,
  482. ola::proto::UIDListReply* response,
  483. google::protobuf::Closure* done) {
  484. ClosureRunner runner(done);
  485. Universe *universe = m_universe_store->GetUniverse(request->universe());
  486. if (!universe)
  487. return MissingUniverseError(controller);
  488. response->set_universe(universe->UniverseId());
  489. UIDSet uid_set;
  490. universe->GetUIDs(&uid_set);
  491. UIDSet::Iterator iter = uid_set.Begin();
  492. for (; iter != uid_set.End(); ++iter) {
  493. ola::proto::UID *uid = response->add_uid();
  494. uid->set_esta_id(iter->ManufacturerId());
  495. uid->set_device_id(iter->DeviceId());
  496. }
  497. }
  498. /*
  499. * Force RDM discovery for a universe
  500. */
  501. void OlaServerServiceImpl::ForceDiscovery(
  502. RpcController* controller,
  503. const ola::proto::DiscoveryRequest* request,
  504. ola::proto::UIDListReply *response,
  505. google::protobuf::Closure* done) {
  506. Universe *universe = m_universe_store->GetUniverse(request->universe());
  507. if (universe) {
  508. unsigned int universe_id = request->universe();
  509. universe->RunRDMDiscovery(
  510. NewSingleCallback(this,
  511. &OlaServerServiceImpl::RDMDiscoveryComplete,
  512. universe_id,
  513. done,
  514. response),
  515. request->full());
  516. } else {
  517. ClosureRunner runner(done);
  518. MissingUniverseError(controller);
  519. }
  520. }
  521. /*
  522. * Handle an RDM Command
  523. */
  524. void OlaServerServiceImpl::RDMCommand(
  525. RpcController* controller,
  526. const ::ola::proto::RDMRequest* request,
  527. ola::proto::RDMResponse* response,
  528. google::protobuf::Closure* done,
  529. const UID *uid,
  530. class Client *client) {
  531. Universe *universe = m_universe_store->GetUniverse(request->universe());
  532. if (!universe) {
  533. MissingUniverseError(controller);
  534. done->Run();
  535. return;
  536. }
  537. UID source_uid = uid ? *uid : m_uid;
  538. UID destination(request->uid().esta_id(),
  539. request->uid().device_id());
  540. ola::rdm::RDMRequest *rdm_request = NULL;
  541. if (request->is_set()) {
  542. rdm_request = new ola::rdm::RDMSetRequest(
  543. source_uid,
  544. destination,
  545. 0, // transaction #
  546. 1, // port id
  547. 0, // message count
  548. request->sub_device(),
  549. request->param_id(),
  550. reinterpret_cast<const uint8_t*>(request->data().data()),
  551. request->data().size());
  552. } else {
  553. rdm_request = new ola::rdm::RDMGetRequest(
  554. source_uid,
  555. destination,
  556. 0, // transaction #
  557. 1, // port id
  558. 0, // message count
  559. request->sub_device(),
  560. request->param_id(),
  561. reinterpret_cast<const uint8_t*>(request->data().data()),
  562. request->data().size());
  563. }
  564. ola::rdm::RDMCallback *callback =
  565. NewSingleCallback(
  566. this,
  567. &OlaServerServiceImpl::HandleRDMResponse,
  568. response,
  569. done,
  570. request->include_raw_response());
  571. m_broker->SendRDMRequest(client, universe, rdm_request, callback);
  572. }
  573. /*
  574. * Set this client's source UID
  575. */
  576. void OlaServerServiceImpl::SetSourceUID(
  577. RpcController*,
  578. const ::ola::proto::UID* request,
  579. ola::proto::Ack*,
  580. google::protobuf::Closure* done) {
  581. ClosureRunner runner(done);
  582. UID source_uid(request->esta_id(), request->device_id());
  583. m_uid = source_uid;
  584. }
  585. /**
  586. * Send Timecode
  587. */
  588. void OlaServerServiceImpl::SendTimeCode(RpcController* controller,
  589. const ::ola::proto::TimeCode* request,
  590. ::ola::proto::Ack*,
  591. ::google::protobuf::Closure* done) {
  592. ClosureRunner runner(done);
  593. ola::timecode::TimeCode time_code(
  594. static_cast<ola::timecode::TimeCodeType>(request->type()),
  595. request->hours(),
  596. request->minutes(),
  597. request->seconds(),
  598. request->frames());
  599. if (time_code.IsValid()) {
  600. m_device_manager->SendTimeCode(time_code);
  601. } else {
  602. controller->SetFailed("Invalid TimeCode");
  603. }
  604. }
  605. // Private methods
  606. //-----------------------------------------------------------------------------
  607. /*
  608. * Handle an RDM Response, this includes broadcast messages, messages that
  609. * timed out and normal response messages.
  610. */
  611. void OlaServerServiceImpl::HandleRDMResponse(
  612. ola::proto::RDMResponse* response,
  613. google::protobuf::Closure* done,
  614. bool include_raw_packets,
  615. ola::rdm::rdm_response_code code,
  616. const RDMResponse *rdm_response,
  617. const vector<string> &packets) {
  618. ClosureRunner runner(done);
  619. response->set_response_code(
  620. static_cast<ola::proto::RDMResponseCode>(code));
  621. if (code == ola::rdm::RDM_COMPLETED_OK) {
  622. if (!rdm_response) {
  623. OLA_WARN << "RDM code was ok but response was NULL";
  624. response->set_response_code(static_cast<ola::proto::RDMResponseCode>(
  625. ola::rdm::RDM_INVALID_RESPONSE));
  626. } else {
  627. uint8_t response_type = rdm_response->ResponseType();
  628. if (response_type <= ola::rdm::RDM_NACK_REASON) {
  629. response->set_response_type(
  630. static_cast<ola::proto::RDMResponseType>(response_type));
  631. response->set_message_count(rdm_response->MessageCount());
  632. response->set_param_id(rdm_response->ParamId());
  633. response->set_sub_device(rdm_response->SubDevice());
  634. if (rdm_response->CommandClass() ==
  635. ola::rdm::RDMCommand::GET_COMMAND_RESPONSE) {
  636. response->set_command_class(ola::proto::RDM_GET_RESPONSE);
  637. } else if (rdm_response->CommandClass() ==
  638. ola::rdm::RDMCommand::SET_COMMAND_RESPONSE) {
  639. response->set_command_class(ola::proto::RDM_SET_RESPONSE);
  640. } else {
  641. OLA_WARN << "Unknown command class 0x" << std::hex <<
  642. rdm_response->CommandClass();
  643. }
  644. if (rdm_response->ParamData() && rdm_response->ParamDataSize()) {
  645. const string data(
  646. reinterpret_cast<const char*>(rdm_response->ParamData()),
  647. rdm_response->ParamDataSize());
  648. response->set_data(data);
  649. } else {
  650. response->set_data("");
  651. }
  652. } else if (response) {
  653. OLA_WARN <<
  654. "RDM response present, but response type is invalid, was 0x" <<
  655. std::hex << static_cast<int>(response_type);
  656. response->set_response_code(static_cast<ola::proto::RDMResponseCode>(
  657. ola::rdm::RDM_INVALID_RESPONSE));
  658. }
  659. }
  660. }
  661. delete rdm_response;
  662. if (include_raw_packets) {
  663. vector<string>::const_iterator iter = packets.begin();
  664. for (; iter != packets.end(); ++iter) {
  665. response->add_raw_response(*iter);
  666. }
  667. }
  668. }
  669. /**
  670. * Called when RDM discovery completes
  671. */
  672. void OlaServerServiceImpl::RDMDiscoveryComplete(
  673. unsigned int universe_id,
  674. google::protobuf::Closure* done,
  675. ola::proto::UIDListReply *response,
  676. const UIDSet &uids) {
  677. ClosureRunner runner(done);
  678. response->set_universe(universe_id);
  679. UIDSet::Iterator iter = uids.Begin();
  680. for (; iter != uids.End(); ++iter) {
  681. ola::proto::UID *uid = response->add_uid();
  682. uid->set_esta_id(iter->ManufacturerId());
  683. uid->set_device_id(iter->DeviceId());
  684. }
  685. }
  686. void OlaServerServiceImpl::MissingUniverseError(RpcController* controller) {
  687. controller->SetFailed("Universe doesn't exist");
  688. }
  689. void OlaServerServiceImpl::MissingDeviceError(RpcController* controller) {
  690. controller->SetFailed("Device doesn't exist");
  691. }
  692. void OlaServerServiceImpl::MissingPluginError(RpcController* controller) {
  693. controller->SetFailed("Plugin doesn't exist");
  694. }
  695. void OlaServerServiceImpl::MissingPortError(RpcController* controller) {
  696. controller->SetFailed("Port doesn't exist");
  697. }
  698. /*
  699. * Add this device to the DeviceInfo response
  700. */
  701. void OlaServerServiceImpl::AddPlugin(AbstractPlugin *plugin,
  702. PluginListReply* response) const {
  703. PluginInfo *plugin_info = response->add_plugin();
  704. plugin_info->set_plugin_id(plugin->Id());
  705. plugin_info->set_name(plugin->Name());
  706. }
  707. /*
  708. * Add this device to the DeviceInfo response
  709. */
  710. void OlaServerServiceImpl::AddDevice(AbstractDevice *device,
  711. unsigned int alias,
  712. DeviceInfoReply* response) const {
  713. DeviceInfo *device_info = response->add_device();
  714. device_info->set_device_alias(alias);
  715. device_info->set_device_name(device->Name());
  716. device_info->set_device_id(device->UniqueId());
  717. if (device->Owner())
  718. device_info->set_plugin_id(device->Owner()->Id());
  719. vector<InputPort*> input_ports;
  720. device->InputPorts(&input_ports);
  721. vector<InputPort*>::const_iterator input_iter;
  722. for (input_iter = input_ports.begin(); input_iter != input_ports.end();
  723. ++input_iter) {
  724. PortInfo *port_info = device_info->add_input_port();
  725. PopulatePort(**input_iter, port_info);
  726. }
  727. vector<OutputPort*> output_ports;
  728. device->OutputPorts(&output_ports);
  729. vector<OutputPort*>::const_iterator output_iter;
  730. for (output_iter = output_ports.begin(); output_iter != output_ports.end();
  731. ++output_iter) {
  732. PortInfo *port_info = device_info->add_output_port();
  733. PopulatePort(**output_iter, port_info);
  734. }
  735. }
  736. template <class PortClass>
  737. void OlaServerServiceImpl::PopulatePort(const PortClass &port,
  738. PortInfo *port_info) const {
  739. port_info->set_port_id(port.PortId());
  740. port_info->set_priority_capability(port.PriorityCapability());
  741. port_info->set_description(port.Description());
  742. if (port.GetUniverse()) {
  743. port_info->set_active(true);
  744. port_info->set_universe(port.GetUniverse()->UniverseId());
  745. } else {
  746. port_info->set_active(false);
  747. }
  748. if (port.PriorityCapability() != CAPABILITY_NONE)
  749. port_info->set_priority(port.GetPriority());
  750. if (port.PriorityCapability() == CAPABILITY_FULL)
  751. port_info->set_priority_mode(port.GetPriorityMode());
  752. }
  753. // OlaClientService
  754. // ----------------------------------------------------------------------------
  755. OlaClientService::~OlaClientService() {
  756. if (m_uid)
  757. delete m_uid;
  758. }
  759. /*
  760. * Set this client's source UID
  761. */
  762. void OlaClientService::SetSourceUID(
  763. RpcController* controller,
  764. const ::ola::proto::UID* request,
  765. ola::proto::Ack* response,
  766. google::protobuf::Closure* done) {
  767. UID source_uid(request->esta_id(), request->device_id());
  768. if (!m_uid)
  769. m_uid = new UID(source_uid);
  770. else
  771. *m_uid = source_uid;
  772. done->Run();
  773. (void) controller;
  774. (void) response;
  775. }
  776. // OlaServerServiceImplFactory
  777. // ----------------------------------------------------------------------------
  778. OlaClientService *OlaClientServiceFactory::New(
  779. Client *client,
  780. OlaServerServiceImpl *impl) {
  781. return new OlaClientService(client, impl);
  782. };
  783. } // ola