@@ -83,12 +83,12 @@ struct ServiceDescription
8383 std::vector<uintptr_t > addresses;
8484 };
8585
86- struct Sca
86+ struct ScaSequence
8787 {
88- std::vector<std::pair< uint32_t , uint32_t > > commandDataPairs;
88+ std::vector<Sca::CommandData > commandDataPairs;
8989 };
9090
91- boost::variant<Register, Sca > type;
91+ boost::variant<Register, ScaSequence > type;
9292};
9393
9494// / Class that handles adding/removing publishers
@@ -151,8 +151,8 @@ class PublisherRegistry
151151 << type.addresses .size () << " address(es) at interval "
152152 << mDescription .interval .count () << " ms" << endm;
153153 },
154- [&](const ServiceDescription::Sca & type){
155- registerValues.resize (1 ) ; // SCA publisher only publishes 1 value
154+ [&](const ServiceDescription::ScaSequence & type){
155+ registerValues.resize (type. commandDataPairs . size () * 2 ) ; // Two result 32-bit integers per pair
156156
157157 getInfoLogger () << " Starting SCA publisher '" << mDescription .dnsName << " ' with "
158158 << type.commandDataPairs .size () << " commands(s) at interval "
@@ -183,17 +183,14 @@ class PublisherRegistry
183183 registerValues.at (i) = channel.readRegister (index);
184184 }
185185 },
186- [&](const ServiceDescription::Sca & type){
186+ [&](const ServiceDescription::ScaSequence & type){
187187 auto sca = Sca (channel, channel.getCardType ());
188-
189188 for (size_t i = 0 ; i < type.commandDataPairs .size (); ++i) {
190189 const auto & pair = type.commandDataPairs [i];
191- sca.write (pair.first , pair.second );
192- if (i+1 == type.commandDataPairs .size ()) {
193- // Last one, we do a read. This result is published.
194- auto result = sca.read ();
195- registerValues.at (0 ) = channel.readRegister (result.data );
196- }
190+ sca.write (pair);
191+ auto result = sca.read ();
192+ registerValues[i*2 ] = result.command ;
193+ registerValues[i*2 + 1 ] = result.data ;
197194 }
198195 }
199196 );
@@ -296,6 +293,8 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
296293 [&](auto parameter){return registerWrite (parameter, bar0);});
297294 auto serverPublishStart = makeServer (names.publishStartCommandRpc (),
298295 [&](auto parameter){return publishStartCommand (parameter, mCommandQueue );});
296+ auto serverPublishScaStart = makeServer (names.publishScaStartCommandRpc (),
297+ [&](auto parameter){return publishScaStartCommand (parameter, mCommandQueue );});
299298 auto serverPublishStop = makeServer (names.publishStopCommandRpc (),
300299 [&](auto parameter){return publishStopCommand (parameter, mCommandQueue );});
301300 auto serverScaRead = makeServer (names.scaRead (),
@@ -347,6 +346,16 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
347346 }
348347 }
349348
349+ // / Try to add a command to the queue
350+ static bool tryAddToQueue (const CommandVariant& command, CommandQueue& queue)
351+ {
352+ if (!queue.write (command)) {
353+ getInfoLogger () << " command queue was full!" << endm;
354+ return false ;
355+ }
356+ return true ;
357+ }
358+
350359 // / RPC handler for register reads
351360 static std::string registerRead (const std::string& parameter, ChannelSharedPtr channel)
352361 {
@@ -387,7 +396,7 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
387396 }
388397
389398 // / RPC handler for publish commands
390- static std::string publishStartCommand (const std::string& parameter, CommandQueue& commandQueue )
399+ static std::string publishStartCommand (const std::string& parameter, CommandQueue& queue )
391400 {
392401 getInfoLogger () << " Received publish command: '" << parameter << " '" << endm;
393402 auto params = split (parameter, " ;" );
@@ -397,19 +406,39 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
397406 description.dnsName = params.at (0 );
398407 description.interval = std::chrono::milliseconds (int64_t (b::lexical_cast<double >(params.at (2 )) * 1000.0 ));
399408
400- if (!commandQueue.write (CommandPublishStart{std::move (description)})) {
401- getInfoLogger () << " command queue was full!" << endm;
409+ tryAddToQueue (CommandPublishStart{description}, queue);
410+ return " " ;
411+ }
412+
413+ // / RPC handler for SCA publish commands
414+ static std::string publishScaStartCommand (const std::string& parameter, CommandQueue& queue)
415+ {
416+ getInfoLogger () << " Received SCA publish command: '" << parameter << " '" << endm;
417+
418+ auto params = split (parameter, " ;" );
419+
420+ // Convert command-data pair string sequence to binary format
421+ ServiceDescription::ScaSequence sca;
422+ auto commandDataPairStrings = split (params.at (1 ), " \n " );
423+ sca.commandDataPairs .resize (commandDataPairStrings.size ());
424+ for (size_t i = 0 ; i < commandDataPairStrings.size (); ++i) {
425+ sca.commandDataPairs [i] = stringToScaCommandDataPair (commandDataPairStrings[i]);
402426 }
427+
428+ ServiceDescription description;
429+ description.type = sca;
430+ description.dnsName = params.at (0 );
431+ description.interval = std::chrono::milliseconds (int64_t (b::lexical_cast<double >(params.at (2 )) * 1000.0 ));
432+
433+ tryAddToQueue (CommandPublishStart{description}, queue);
403434 return " " ;
404435 }
405436
406437 // / RPC handler for publish stop commands
407- static std::string publishStopCommand (const std::string& parameter, CommandQueue& commandQueue )
438+ static std::string publishStopCommand (const std::string& parameter, CommandQueue& queue )
408439 {
409440 getInfoLogger () << " Received stop command: '" << parameter << " '" << endm;
410- if (!commandQueue.write (CommandPublishStop{parameter})) {
411- getInfoLogger () << " command queue was full!" << endm;
412- }
441+ tryAddToQueue (CommandPublishStop{parameter}, queue);
413442 return " " ;
414443 }
415444
@@ -461,26 +490,18 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
461490 std::stringstream resultBuffer;
462491 auto sca = Sca (*bar2, bar2->getCardType ());
463492
464- for (std::string token : tokenizer (parameter, sep)) {
493+ for (const std::string& token : tokenizer (parameter, sep)) {
465494 // Walk through the tokens, these should be the pairs (or comments).
466495 if (token.find (' #' ) == 0 ) {
467496 // We have a comment, skip this token
468497 continue ;
469498 } else {
470- // The pairs are comma-separated, so we split them.
471- std::vector<std::string> pair = split (token, " ," );
472- if (pair.size () != 2 ) {
473- BOOST_THROW_EXCEPTION (
474- AlfException () << ErrorInfo::Message (" SCA command-data pair not formatted correctly" ));
475- }
476- auto command = convertHexString (pair[0 ]);
477- auto data = convertHexString (pair[1 ]);
478-
499+ auto commandData = stringToScaCommandDataPair (token);
479500 try {
480- sca.write (command, data );
501+ sca.write (commandData );
481502 auto result = sca.read ();
482- getInfoLogger () << (b::format (" cmd=0x%x data=0x%x result=0x%x" ) % command % data % result. data ). str ()
483- << endm;
503+ getInfoLogger () << (b::format (" cmd=0x%x data=0x%x result=0x%x" ) % commandData. command % commandData. data %
504+ result. data ). str () << endm;
484505 resultBuffer << std::hex << result.data << ' \n ' ;
485506 } catch (const ScaException &e) {
486507 // If an SCA error occurs, we stop executing the sequence of commands and return the results as far as we got
@@ -494,6 +515,20 @@ class ProgramAliceLowlevelFrontendServer: public AliceO2::Common::Program
494515 return resultBuffer.str ();
495516 }
496517
518+ static Sca::CommandData stringToScaCommandDataPair (const std::string& string)
519+ {
520+ // The pairs are comma-separated, so we split them.
521+ std::vector<std::string> pair = split (string, " ," );
522+ if (pair.size () != 2 ) {
523+ BOOST_THROW_EXCEPTION (
524+ AlfException () << ErrorInfo::Message (" SCA command-data pair not formatted correctly" ));
525+ }
526+ Sca::CommandData commandData;
527+ commandData.command = convertHexString (pair[0 ]);
528+ commandData.data = convertHexString (pair[1 ]);
529+ return commandData;
530+ };
531+
497532 int mSerialNumber = 0 ;
498533 CommandQueue mCommandQueue ;
499534 double mTemperature = 40 ;
0 commit comments