38 #include <condition_variable>
43 #include "EoProtocol.h"
44 #include "EoProtocolMN.h"
58 static std::mutex
mtx;
83 void load(eOprotIP_t _ip, eOprotID32_t _id, std::uint32_t _s)
94 void load(eOprotIP_t _ip,
const std::vector<eOprotID32_t> &_ids, std::uint32_t _s)
107 bool wait(std::uint16_t &numofrxrops,
double timeout = 0.5)
110 const int timeout_millis =
static_cast<int>(1000.0 * timeout);
112 bool r = (
cv_semaphore.wait_for(lck, std::chrono::milliseconds(timeout_millis)) == cv_status::no_timeout);
134 std::multimap<std::uint64_t, askTransaction*>
themap {};
155 void insert(
askTransaction *transaction,
const eOprotIP_t ip,
const eOprotID32_t
id, std::uint32_t &assignedsignature)
158 transaction->
load(ip,
id, assignedsignature);
159 std::uint64_t key =
static_cast<std::uint64_t
>(assignedsignature);
160 themap.insert(std::make_pair(key, transaction));
165 transaction->
load(ip,
id, eo_rop_SIGNATUREdummy);
166 std::uint64_t key = (
static_cast<std::uint64_t
>(ip) << 32) |
static_cast<std::uint64_t
>(id);
167 themap.insert(std::make_pair(key, transaction));
170 void insert(
askTransaction *transaction,
const eOprotIP_t ip,
const std::vector<eOprotID32_t> &ids, std::uint32_t &assignedsignature)
173 transaction->
load(ip, ids, assignedsignature);
174 std::uint64_t key =
static_cast<std::uint64_t
>(assignedsignature);
175 themap.insert(std::make_pair(key, transaction));
178 void remove(
const std::uint32_t signature)
180 std::uint64_t key =
static_cast<std::uint64_t
>(signature);
184 bool alert(
const std::uint32_t signature)
187 if(
true ==
themap.empty())
189 yDebug() <<
"theNVmanager::Impl::Data::alert(): themap is empty()";
193 std::uint64_t key =
static_cast<std::uint64_t
>(signature);
194 std::multimap<std::uint64_t, askTransaction*>::iterator it =
themap.find(key);
198 yDebug() <<
"theNVmanager::Impl::Data::alert(): signature not found" << signature;
202 (*it).second->post();
207 void remove(
const eOprotIP_t ip,
const eOprotID32_t
id)
209 std::uint64_t key = (
static_cast<std::uint64_t
>(ip) << 32) |
static_cast<std::uint64_t
>(id);
213 bool alert(
const eOprotIP_t ip,
const eOprotID32_t
id)
216 if(
true ==
themap.empty())
218 yDebug() <<
"theNVmanager::Impl::Data::alert(): themap is empty()";
222 std::uint64_t key = (
static_cast<std::uint64_t
>(ip) << 32) |
static_cast<std::uint64_t
>(id);
223 std::multimap<std::uint64_t, askTransaction*>::iterator it =
themap.find(key);
227 yDebug() <<
"theNVmanager::Impl::Data::alert(): key not found" << key;
231 (*it).second->post();
271 bool supported(
const eOprotIP_t ipv4,
const eOprotID32_t id32);
273 size_t sizeofnv(
const eOprotID32_t id32);
291 bool setcheck(
eth::HostTransceiver *t,
const eOprotID32_t id32,
const void *value,
const unsigned int retries,
double waitbeforecheck,
double timeout);
296 bool ping(
eth::HostTransceiver *t, eoprot_version_t &mnprotversion,
const double timeout = 0.5,
const unsigned int retries = 20);
300 bool ask(
eth::HostTransceiver *t,
const std::vector<eOprotID32_t> &id32s,
const std::vector<void*> &values,
const double timeout);
302 bool check(
eth::HostTransceiver *t,
const eOprotID32_t id32,
const void *value,
const double timeout,
const unsigned int retries);
305 bool onarrival(
const ropCode ropcode,
const eOprotIP_t ipv4,
const eOprotID32_t id32,
const std::uint32_t signature);
336 eoprot_ID2information(id32, nvinfo,
sizeof(nvinfo));
344 return (
nullptr == t) ? false :
true;
361 return eoprot_variable_sizeof_get(eoprot_board_localboard, id32);
373 eo_common_ipv4addr_to_string(ipv4, ipinfo,
sizeof(ipinfo));
374 yError(
"theNVmanager::Impl::transceiverZ() cannot obtain from TheEthManager a EthResource * for IP = %s", ipinfo);
457 yError() <<
"theNVmanager::Impl::validparameters() called with an invalid ID in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32);
464 yError() <<
"theNVmanager::Impl::validparameters(res, ipv4, id32, value) found invalid params in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString;
478 for(
int i=0; i<id32s.size(); i++)
483 yError() <<
"theNVmanager::Impl::validparameters(vector<>) called with an invalid ID in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32s[i]);
488 if((0 == id32s.size()) || (id32s.size() != values.size()))
491 yError() <<
"theNVmanager::Impl::validparameters(vector<>) found invalid params in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString;
508 yError() <<
"theNVmanager::Impl::validparameters() called with an invalid ID in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32);
515 yError() <<
"theNVmanager::Impl::validparameters(res, ipv4, id32, value) found invalid params in BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString;
530 if(
false == validparameters(t, id32, value))
536 int maxattempts = retries + 1;
538 for(attempt=0; (attempt<maxattempts) && (
false ==
done); attempt++)
540 if(
false ==
set(t, id32, value))
543 yWarning() <<
"theNVmanager::Impl::setcheck() had an error while calling set() in BOARD" <<
props.boardnameString <<
"with IP" <<
props.ipv4addrString <<
"at attempt #" << attempt+1;
548 SystemClock::delaySystem(waitbeforecheck);
550 if(
false ==
check(t, id32, value, timeout, 0))
553 yWarning() <<
"theNVmanager::Impl::setcheck() had an error while calling check() in BOARD" <<
props.boardnameString <<
"with IP" <<
props.ipv4addrString <<
"at attempt #" << attempt+1;
568 yWarning() <<
"theNVmanager::Impl::setcheck() has set and verified ID" << getid32string(id32) <<
"in BOARD" <<
props.boardnameString <<
"with IP" <<
props.ipv4addrString <<
"at attempt #" << attempt;
581 yError() <<
"FATAL: theNVmanager::Impl::setcheck() could not set and verify ID" << getid32string(id32) <<
"in BOARD" <<
props.boardnameString <<
"with IP" <<
props.ipv4addrString <<
" even after " << attempt <<
"attempts";
591 if(
false == validparameters(t, id32, value))
598 std::uint16_t size = sizeofnv(id32);
599 std::uint8_t * vv =
new std::uint8_t[size];
601 for(
int i=0; i<(retries+1); i++)
603 if(
true ==
ask(t, id32,
reinterpret_cast<void*
>(vv), timeout))
605 if(0 == std::memcmp(value, vv, size))
622 const eOprotIP_t ipv4 = t->
getIPv4();
627 yError() <<
"theNVmanager::Impl::wait() fails because the following ipv4-id32 is not supported: ipv4 =" <<
props.ipv4addrString <<
"id32 =" << getid32string(id32);
637 data.insert(transaction, ipv4, id32);
641 std::uint16_t numberOfReceivedROPs = 0;
643 if(
false == transaction->
wait(numberOfReceivedROPs, timeout))
649 data.remove(ipv4, id32);
655 yError() <<
"theNVmanager::Impl::wait() had a timeout for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32);
661 data.remove(ipv4, id32);
672 if(
false == validparameters(t, id32, value))
679 if(
false == t->
read(id32, value))
682 yError() <<
"theNVmanager::Impl::ask() fails t->read() for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32);
692 if(
false ==
set(t, id32cmd,
cmd))
695 yError() <<
"theNVmanager::Impl::command() fails a set() to IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32cmd);
702 yError() <<
"theNVmanager::Impl::command() fails a wait() from IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32rep);
706 if(
false ==
read(t, id32rep, rep))
709 yError() <<
"theNVmanager::Impl::command() fails a read() for IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32rep);
731 eOprotID32_t id32 = eoprot_ID_get(eoprot_endpoint_management, eoprot_entity_mn_comm, 0, eoprot_tag_mn_comm_status_managementprotocolversion);
732 bool replied =
false;
737 yError() <<
"theNVmanager::Impl::ping() fails because the following ipv4-id32 is not supported: ipv4 =" <<
props.ipv4addrString <<
"id32 =" << getid32string(id32);
741 for(
int i=0; i<(1+retries); i++)
743 if(
true ==
ask(t, id32, &mnprotversion, timeout))
757 if(
false == validparameters(t, id32, value))
759 yError() <<
"theNVmanager::Impl::ask() called with invalid parameters";
766 std::uint32_t assignedsignature = 0;
770 data.insert(transaction, t->
getIPv4(), id32, assignedsignature);
776 if(
false == t->
addROPask(id32, assignedsignature))
779 yError() <<
"theNVmanager::Impl::ask() fails res->addROPask() to BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32);
783 data.remove(assignedsignature);
792 std::uint16_t numberOfReceivedROPs = 0;
794 if(
false == transaction->
wait(numberOfReceivedROPs, timeout))
800 data.remove(assignedsignature);
806 yError() <<
"theNVmanager::Impl::ask() had a timeout for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32);
812 data.remove(assignedsignature);
818 if(
false == t->
read(id32, value))
821 yError() <<
"theNVmanager::Impl::ask() fails res->getLocalValue() for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32);
912 const eOprotIP_t ipv4 = t->
getIPv4();
914 if(
false == validparameters(t, id32s, values))
924 std::uint32_t assignedsignature = 0;
928 data.insert(transaction, ipv4, id32s, assignedsignature);
934 for(
int i=0; i<id32s.size(); i++)
936 if(
false == t->
addROPask(id32s[i], assignedsignature))
939 yError() <<
"theNVmanager::Impl::ask() fails t->addROPask() to BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32s[i]);
943 data.remove(assignedsignature);
953 std::uint16_t numberOfReceivedROPs = 0;
955 if(
false == transaction->
wait(numberOfReceivedROPs))
961 data.remove(assignedsignature);
967 yError() <<
"theNVmanager::Impl::ask() had a timeout for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"w/ multiple NVs. Received only" << numberOfReceivedROPs <<
"out of" << id32s.size();
975 data.remove(assignedsignature);
981 for(
int i=0; i<id32s.size(); i++)
983 if(
false == t->
read(id32s[i], values[i]))
986 yError() <<
"theNVmanager::Impl::ask() fails res->getLocalValue() for BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"and nv" << getid32string(id32s[i]);
1006 yError() <<
"theNVmanager::Impl::set() fails t->addSetROP() to BOARD" <<
props.boardnameString <<
"IP" <<
props.ipv4addrString <<
"for nv" << getid32string(id32);
1016 if((eo_rop_SIGNATUREdummy == signature) || (signature >= 0xaa000000))
1026 static double tprev = SystemClock::nowSystem();
1027 double tcurr = SystemClock::nowSystem();
1029 double delta = tcurr - tprev;
1038 eo_common_ipv4addr_to_string(ipv4, ipinfo,
sizeof(ipinfo));
1039 yDebug() <<
"theNVmanager::Impl::onarrival() called for unsupported IP" << ipinfo <<
"for nv" << getid32string(id32) <<
"w/ signature" << signature;
1051 if(
false == signatureisvalid(signature))
1053 yDebug() <<
"theNVmanager::Impl::onarrival() has found a false signature";
1060 data.alert(signature);
1076 data.alert(ipv4, id32);
1104 eth::theNVmanager::theNVmanager()
1143 return pImpl->supported(ipv4);
1148 return pImpl->supported(ipv4, id32);
1153 return pImpl->sizeofnv(id32);
1156 bool eth::theNVmanager::ping(
const eOprotIP_t ipv4, eoprot_version_t &mnprotversion,
const double timeout,
const unsigned int retries)
1159 return pImpl->ping(t, mnprotversion, timeout, retries);
1165 return pImpl->ask(t, id32, value, timeout);
1170 return pImpl->ask(t, id32, value, timeout);
1175 bool eth::theNVmanager::ask(
const eOprotIP_t ipv4,
const std::vector<eOprotID32_t> &id32s,
const std::vector<void*> &values,
const double timeout)
1178 return pImpl->ask(t, id32s, values, timeout);
1183 return pImpl->ask(t, id32s, values, timeout);
1188 return pImpl->set(t, id32, value);
1194 return pImpl->set(t, id32, value);
1200 return pImpl->check(t, id32, value, timeout, retries);
1203 bool eth::theNVmanager::check(
const eOprotIP_t ipv4,
const eOprotID32_t id32,
const void *value,
const double timeout,
const unsigned int retries)
1206 return pImpl->check(t, id32, value, timeout, retries);
1210 bool eth::theNVmanager::setcheck(
const eOprotIP_t ipv4,
const eOprotID32_t id32,
const void *value,
const unsigned int retries,
double waitbeforecheck,
double timeout)
1213 return pImpl->setcheck(t, id32, value, retries, waitbeforecheck, timeout);
1218 return pImpl->setcheck(t, id32, value, retries, waitbeforecheck, timeout);
1223 return pImpl->onarrival(ropcode, ipv4, id32, signature);
1239 return pImpl->command(t, id32cmd,
cmd, id32rep, rep, timeout);
virtual const Properties & getProperties()=0
virtual HostTransceiver * getTransceiver()=0
eth::AbstractEthResource * getEthResource(eOipv4addr_t ipv4)
static TheEthManager * instance()
bool supported(const eOprotIP_t ipv4)
bool check(const eOprotIP_t ipv4, const eOprotID32_t id32, const void *value, const double timeout=0.5, const unsigned int retries=0)
bool onarrival(const ropCode ropcode, const eOprotIP_t ipv4, const eOprotID32_t id32, const std::uint32_t signature)
static theNVmanager & getInstance()
size_t sizeOfNV(const eOprotID32_t id32)
bool setcheck(const eOprotIP_t ipv4, const eOprotID32_t id32, const void *value, const unsigned int retries=10, double waitbeforecheck=0.001, double timeout=0.5)
bool ask(const eOprotIP_t ipv4, const eOprotID32_t id32, void *value, const double timeout=0.5)
bool command(const eOprotIP_t ipv4, const eOprotID32_t id32cmd, const void *cmd, const eOprotID32_t id32rep, void *rep, double timeout=0.5)
bool ping(const eOprotIP_t ipv4, eoprot_version_t &mnprotversion, const double timeout=0.5, const unsigned int retries=20)
bool set(const eOprotIP_t ipv4, const eOprotID32_t id32, const void *value)
FirmwareUpdaterCore * self
bool addROPask(const eOprotID32_t id32, const uint32_t signature=eo_rop_SIGNATUREdummy)
bool addROPset(const eOprotID32_t id32, const void *data, const uint32_t signature=eo_rop_SIGNATUREdummy)
bool isID32supported(const eOprotID32_t id32)
AbstractEthResource * getResource()
bool read(const eOprotID32_t id32, void *data)
bool read(yarp::os::Searchable &cfgtotal, pc104Data &pc104data)
void insert(askTransaction *transaction, const eOprotIP_t ip, const eOprotID32_t id, std::uint32_t &assignedsignature)
bool alert(const eOprotIP_t ip, const eOprotID32_t id)
void remove(const std::uint32_t signature)
std::uint32_t uniquesignature()
void insert(askTransaction *transaction, const eOprotIP_t ip, const eOprotID32_t id)
std::multimap< std::uint64_t, askTransaction * > themap
void insert(askTransaction *transaction, const eOprotIP_t ip, const std::vector< eOprotID32_t > &ids, std::uint32_t &assignedsignature)
void remove(const eOprotIP_t ip, const eOprotID32_t id)
bool alert(const std::uint32_t signature)
void load(eOprotIP_t _ip, const std::vector< eOprotID32_t > &_ids, std::uint32_t _s)
void load(eOprotIP_t _ip, eOprotID32_t _id, std::uint32_t _s)
std::condition_variable cv_semaphore
std::uint16_t expectedrops
bool wait(std::uint16_t &numofrxrops, double timeout=0.5)
std::uint16_t receivedrops
const eth::AbstractEthResource::Properties & getboardproperties(eth::HostTransceiver *t)
bool ask(eth::HostTransceiver *t, const eOprotID32_t id32, void *value, const double timeout)
bool setcheck(eth::HostTransceiver *t, const eOprotID32_t id32, const void *value, const unsigned int retries, double waitbeforecheck, double timeout)
bool check(eth::HostTransceiver *t, const eOprotID32_t id32, const void *value, const double timeout, const unsigned int retries)
eth::AbstractEthResource * ethresource(const eOprotIP_t ipv4)
bool supported(const eOprotIP_t ipv4)
string getid32string(eOprotID32_t id32)
bool wait(const ropCode ropcode, eth::HostTransceiver *t, const eOprotID32_t id32, const double timeout)
bool read(eth::HostTransceiver *t, const eOprotID32_t id32, void *value)
bool command(eth::HostTransceiver *t, const eOprotID32_t id32cmd, const void *cmd, const eOprotID32_t id32rep, void *rep, double timeout=0.5)
eth::AbstractEthResource * ethresourceID32s(const eOprotIP_t ipv4, const std::vector< eOprotID32_t > &id32s)
bool onarrival(const ropCode ropcode, const eOprotIP_t ipv4, const eOprotID32_t id32, const std::uint32_t signature)
eth::AbstractEthResource * ethresourceID32(const eOprotIP_t ipv4, const eOprotID32_t id32)
bool set(eth::HostTransceiver *t, const eOprotID32_t id32, const void *value)
size_t sizeofnv(const eOprotID32_t id32)
bool signatureisvalid(const std::uint32_t signature)
bool ping(eth::HostTransceiver *t, eoprot_version_t &mnprotversion, const double timeout=0.5, const unsigned int retries=20)
eth::HostTransceiver * transceiver(eth::AbstractEthResource *res)
bool validparameters(eth::HostTransceiver *t, const eOprotID32_t id32, void *value)