Merge remote-tracking branch 'origin/master' into js-add-fire3-to-finder
commit
13ec2bca98
|
|
@ -175,12 +175,14 @@ set(SRC_FILES
|
||||||
communication/message/ethphymessage.cpp
|
communication/message/ethphymessage.cpp
|
||||||
communication/packet/flexraypacket.cpp
|
communication/packet/flexraypacket.cpp
|
||||||
communication/packet/canpacket.cpp
|
communication/packet/canpacket.cpp
|
||||||
|
communication/packet/a2bpacket.cpp
|
||||||
communication/packet/ethernetpacket.cpp
|
communication/packet/ethernetpacket.cpp
|
||||||
communication/packet/versionpacket.cpp
|
communication/packet/versionpacket.cpp
|
||||||
communication/packet/iso9141packet.cpp
|
communication/packet/iso9141packet.cpp
|
||||||
communication/packet/ethphyregpacket.cpp
|
communication/packet/ethphyregpacket.cpp
|
||||||
communication/packet/logicaldiskinfopacket.cpp
|
communication/packet/logicaldiskinfopacket.cpp
|
||||||
communication/packet/wivicommandpacket.cpp
|
communication/packet/wivicommandpacket.cpp
|
||||||
|
communication/packet/scriptstatuspacket.cpp
|
||||||
communication/decoder.cpp
|
communication/decoder.cpp
|
||||||
communication/encoder.cpp
|
communication/encoder.cpp
|
||||||
communication/ethernetpacketizer.cpp
|
communication/ethernetpacketizer.cpp
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@
|
||||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||||
#include "icsneo/communication/message/wiviresponsemessage.h"
|
#include "icsneo/communication/message/wiviresponsemessage.h"
|
||||||
|
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||||
|
#include "icsneo/communication/message/a2bmessage.h"
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/packet/canpacket.h"
|
#include "icsneo/communication/packet/canpacket.h"
|
||||||
|
#include "icsneo/communication/packet/a2bpacket.h"
|
||||||
#include "icsneo/communication/packet/ethernetpacket.h"
|
#include "icsneo/communication/packet/ethernetpacket.h"
|
||||||
#include "icsneo/communication/packet/flexraypacket.h"
|
#include "icsneo/communication/packet/flexraypacket.h"
|
||||||
#include "icsneo/communication/packet/iso9141packet.h"
|
#include "icsneo/communication/packet/iso9141packet.h"
|
||||||
|
|
@ -18,6 +21,7 @@
|
||||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||||
#include "icsneo/communication/packet/logicaldiskinfopacket.h"
|
#include "icsneo/communication/packet/logicaldiskinfopacket.h"
|
||||||
#include "icsneo/communication/packet/wivicommandpacket.h"
|
#include "icsneo/communication/packet/wivicommandpacket.h"
|
||||||
|
#include "icsneo/communication/packet/scriptstatuspacket.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
@ -317,10 +321,30 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case Network::NetID::ScriptStatus: {
|
||||||
|
result = ScriptStatus::DecodeToMessage(packet->data);
|
||||||
|
if(!result) {
|
||||||
|
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case Network::Type::A2B: {
|
||||||
|
result = HardwareA2BPacket::DecodeToMessage(packet->data);
|
||||||
|
|
||||||
|
if(!result) {
|
||||||
|
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||||
|
return false; // A nullptr was returned, the packet was not long enough to decode
|
||||||
|
}
|
||||||
|
|
||||||
|
A2BMessage& msg = *static_cast<A2BMessage*>(result.get());
|
||||||
|
msg.network = packet->network;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the moment other types of messages will automatically be decoded as raw messages
|
// For the moment other types of messages will automatically be decoded as raw messages
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include "icsneo/communication/packet/a2bpacket.h"
|
||||||
|
#include "icsneo/communication/message/a2bmessage.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
std::shared_ptr<Message> HardwareA2BPacket::DecodeToMessage(const std::vector<uint8_t> &bytestream)
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr uint8_t coreMiniMessageHeaderSize = 28;
|
||||||
|
|
||||||
|
if(bytestream.size() < coreMiniMessageHeaderSize)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto getSampleFromBytes = [](uint8_t bytesPerSample, const uint8_t *bytes) {
|
||||||
|
A2BPCMSample result = 0;
|
||||||
|
|
||||||
|
for(auto i = 0; i < bytesPerSample; i++)
|
||||||
|
{
|
||||||
|
result |= bytes[i] << (i * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const HardwareA2BPacket *data = (const HardwareA2BPacket*)bytestream.data();
|
||||||
|
|
||||||
|
uint32_t totalPackedLength = static_cast<uint32_t>(bytestream.size()) - static_cast<uint32_t>(coreMiniMessageHeaderSize); // First 28 bytes are message header.
|
||||||
|
|
||||||
|
uint8_t bytesPerChannel = data->header.channelSize16 ? 2 : 4;
|
||||||
|
uint8_t numChannels = data->header.channelNum;
|
||||||
|
uint8_t bitDepth = data->header.channelSize16 ? A2BPCM_L16 : A2BPCM_L24;
|
||||||
|
bool monitor = data->header.monitor;
|
||||||
|
|
||||||
|
std::shared_ptr<A2BMessage> msg = std::make_shared<A2BMessage>(bitDepth, bytesPerChannel, numChannels, monitor);
|
||||||
|
|
||||||
|
const uint8_t *bytes = bytestream.data();
|
||||||
|
bytes+=coreMiniMessageHeaderSize;
|
||||||
|
|
||||||
|
uint8_t channel = 0;
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < totalPackedLength; i += 2 * static_cast<uint32_t>(bytesPerChannel), bytes += 2 * bytesPerChannel, channel = (channel + 1) % numChannels)
|
||||||
|
{
|
||||||
|
|
||||||
|
msg->addSample(
|
||||||
|
getSampleFromBytes(bytesPerChannel, bytes),
|
||||||
|
A2BMessage::A2BDirection::DownStream,
|
||||||
|
channel
|
||||||
|
);
|
||||||
|
|
||||||
|
msg->addSample(
|
||||||
|
getSampleFromBytes(bytesPerChannel, bytes + bytesPerChannel),
|
||||||
|
A2BMessage::A2BDirection::UpStream,
|
||||||
|
channel
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "icsneo/communication/packet/scriptstatuspacket.h"
|
||||||
|
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
std::shared_ptr<ScriptStatusMessage> ScriptStatus::DecodeToMessage(const std::vector<uint8_t>& bytestream){
|
||||||
|
if(bytestream.size() != sizeof(ScriptStatus))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto msg = std::make_shared<ScriptStatusMessage>();
|
||||||
|
const auto& decoded = *reinterpret_cast<const ScriptStatus*>(bytestream.data());
|
||||||
|
msg->isCoreminiRunning = decoded.status.isRunning;
|
||||||
|
msg->sectorOverflows = decoded.sectorOverflows;
|
||||||
|
msg->numRemainingSectorBuffers = decoded.numRemainingSectorBuffers;
|
||||||
|
msg->lastSector = decoded.lastSector;
|
||||||
|
msg->readBinSize = decoded.readBinSize;
|
||||||
|
msg->minSector = decoded.minSector;
|
||||||
|
msg->maxSector = decoded.maxSector;
|
||||||
|
msg->currentSector = decoded.currentSector;
|
||||||
|
msg->coreminiCreateTime = ((uint64_t)decoded.coreminiCreateTimeMsb << 32) | decoded.coreminiCreateTimeLsb;
|
||||||
|
msg->fileChecksum = decoded.fileChecksum;
|
||||||
|
msg->coreminiVersion = decoded.coreminiVersion;
|
||||||
|
msg->coreminiHeaderSize = decoded.coreminiHeaderSize;
|
||||||
|
msg->diagnosticErrorCode = decoded.diagErrCode;
|
||||||
|
msg->diagnosticErrorCodeCount = decoded.diagErrCodeCount;
|
||||||
|
msg->maxCoreminiSizeKB = decoded.maxCoreminiSizeKB;
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "icsneo/disk/fat.h"
|
#include "icsneo/disk/fat.h"
|
||||||
#include "icsneo/communication/packet/wivicommandpacket.h"
|
#include "icsneo/communication/packet/wivicommandpacket.h"
|
||||||
#include "icsneo/communication/message/wiviresponsemessage.h"
|
#include "icsneo/communication/message/wiviresponsemessage.h"
|
||||||
|
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
@ -410,6 +411,83 @@ bool Device::goOffline() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t Device::prepareScriptLoad() {
|
||||||
|
if(!isOpen()) {
|
||||||
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::CoreMiniPreLoad);
|
||||||
|
|
||||||
|
if(!com->sendCommand(Command::CoreMiniPreload))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int8_t retVal = 0;
|
||||||
|
while(retVal == 0)
|
||||||
|
{
|
||||||
|
auto generic = com->waitForMessageSync(filter, std::chrono::milliseconds(1000));
|
||||||
|
|
||||||
|
if(!generic) {
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto resp = std::static_pointer_cast<RawMessage>(generic);
|
||||||
|
retVal = (int8_t)resp->data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::startScript()
|
||||||
|
{
|
||||||
|
if(!isOpen()) {
|
||||||
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LocationSdCard = 1; //Only support starting a coremini in an SDCard
|
||||||
|
auto generic = com->sendCommand(Command::LoadCoreMini, LocationSdCard);
|
||||||
|
|
||||||
|
if(!generic)
|
||||||
|
{
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::stopScript()
|
||||||
|
{
|
||||||
|
if(!isOpen()) {
|
||||||
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto generic = com->sendCommand(Command::ClearCoreMini);
|
||||||
|
|
||||||
|
if(!generic)
|
||||||
|
{
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::clearScript()
|
||||||
|
{
|
||||||
|
if(!stopScript())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<uint8_t> clearData(512, 0xCD);
|
||||||
|
uint64_t ScriptLocation = 0; //We only support a coremini in an SDCard, which is at the very beginning of the card
|
||||||
|
auto written = writeLogicalDisk(ScriptLocation, clearData.data(), clearData.size());
|
||||||
|
|
||||||
|
return written > 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
||||||
if(!isOpen()) {
|
if(!isOpen()) {
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
|
@ -1076,6 +1154,246 @@ bool Device::allowSleep(bool remoteWakeup) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::scriptStatusThreadBody()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(scriptStatusMutex);
|
||||||
|
|
||||||
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
while(!stopScriptStatusThread)
|
||||||
|
{
|
||||||
|
if(first) // Skip the first wait
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
stopScriptStatusCv.wait_for(lk, std::chrono::seconds(10));
|
||||||
|
|
||||||
|
const auto resp = getScriptStatus();
|
||||||
|
|
||||||
|
//If value changed/was inserted, notify callback
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::CoreMiniRunning, resp->isCoreminiRunning))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::CoreMiniRunning, resp->isCoreminiRunning);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::SectorOverflow, resp->sectorOverflows))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::SectorOverflow, resp->sectorOverflows);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::RemainingSectors, resp->numRemainingSectorBuffers))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::RemainingSectors, resp->numRemainingSectorBuffers);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool logging = false;
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::LastSector, resp->lastSector))
|
||||||
|
{
|
||||||
|
logging = true;
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::LastSector, resp->lastSector);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::Logging, logging))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::Logging, logging);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::ReadBinSize, resp->readBinSize))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::ReadBinSize, resp->readBinSize);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::MinSector, resp->minSector))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::MinSector, resp->minSector);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::MaxSector, resp->maxSector))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::MaxSector, resp->maxSector);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::CurrentSector, resp->currentSector))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::CurrentSector, resp->currentSector);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::CoreMiniCreateTime, resp->coreminiCreateTime))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::CoreMiniCreateTime, resp->coreminiCreateTime);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::FileChecksum, resp->fileChecksum))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::FileChecksum, resp->fileChecksum);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::CoreMiniVersion, resp->coreminiVersion))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::CoreMiniVersion, resp->coreminiVersion);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::CoreMiniHeaderSize, resp->coreminiHeaderSize))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::CoreMiniHeaderSize, resp->coreminiHeaderSize);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::DiagnosticErrorCode, resp->diagnosticErrorCode))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::DiagnosticErrorCode, resp->diagnosticErrorCode);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::DiagnosticErrorCodeCount, resp->diagnosticErrorCodeCount))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::DiagnosticErrorCodeCount, resp->diagnosticErrorCodeCount);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateScriptStatusValue(ScriptStatus::MaxCoreMiniSize, resp->maxCoreminiSizeKB))
|
||||||
|
{
|
||||||
|
lk.unlock();
|
||||||
|
notifyScriptStatusCallback(ScriptStatus::MaxCoreMiniSize, resp->maxCoreminiSizeKB);
|
||||||
|
lk.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ScriptStatusMessage> Device::getScriptStatus() const
|
||||||
|
{
|
||||||
|
static std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Message::Type::ScriptStatus);
|
||||||
|
|
||||||
|
const auto generic = com->waitForMessageSync([this]() {
|
||||||
|
return com->sendCommand(Command::ScriptStatus);
|
||||||
|
}, filter, std::chrono::milliseconds(3000));
|
||||||
|
|
||||||
|
if(!generic || generic->type != Message::Type::ScriptStatus) {
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::static_pointer_cast<ScriptStatusMessage>(generic);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::updateScriptStatusValue(ScriptStatus key, uint64_t value)
|
||||||
|
{
|
||||||
|
auto pair = scriptStatusValues.find(key);
|
||||||
|
if(pair != scriptStatusValues.end())
|
||||||
|
{
|
||||||
|
if(pair->second != value)
|
||||||
|
{
|
||||||
|
//Value changed
|
||||||
|
scriptStatusValues[key] = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//Value didn't change
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Value was inserted
|
||||||
|
scriptStatusValues.insert(std::make_pair(key, value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::notifyScriptStatusCallback(ScriptStatus key, uint64_t value)
|
||||||
|
{
|
||||||
|
auto callbackList = scriptStatusCallbacks.find(key);
|
||||||
|
if(callbackList != scriptStatusCallbacks.end())
|
||||||
|
{
|
||||||
|
for(const auto& callback : callbackList->second)
|
||||||
|
{
|
||||||
|
if(callback) {
|
||||||
|
try {
|
||||||
|
callback(value);
|
||||||
|
} catch(...) {
|
||||||
|
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lifetime Device::addScriptStatusCallback(ScriptStatus key, ScriptStatusCallback cb)
|
||||||
|
{
|
||||||
|
if(!isOpen()) {
|
||||||
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lk(scriptStatusMutex);
|
||||||
|
if(!scriptStatusThread.joinable()) {
|
||||||
|
// Start the thread
|
||||||
|
stopScriptStatusThread = false;
|
||||||
|
scriptStatusThread = std::thread([this]() { scriptStatusThreadBody(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = 0;
|
||||||
|
std::vector<ScriptStatusCallback> callbackList;
|
||||||
|
auto callbackPair = scriptStatusCallbacks.find(key);
|
||||||
|
if(callbackPair != scriptStatusCallbacks.end())
|
||||||
|
callbackList = callbackPair->second;
|
||||||
|
|
||||||
|
if(idx == callbackList.size())
|
||||||
|
callbackList.push_back(std::move(cb));
|
||||||
|
else callbackList[idx] = std::move(cb);
|
||||||
|
|
||||||
|
scriptStatusCallbacks.insert_or_assign(key, callbackList);
|
||||||
|
|
||||||
|
return Lifetime([this, key, idx](){
|
||||||
|
std::unique_lock<std::mutex> lk2(scriptStatusMutex);
|
||||||
|
auto callbackList = scriptStatusCallbacks.find(key);
|
||||||
|
if(callbackList != scriptStatusCallbacks.end())
|
||||||
|
callbackList->second[idx] = ScriptStatusCallback();
|
||||||
|
stopScriptStatusThreadIfNecessary(std::move(lk2));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk)
|
||||||
|
{
|
||||||
|
for(const auto& callbackList : scriptStatusCallbacks)
|
||||||
|
{
|
||||||
|
for(const auto& callback : callbackList.second)
|
||||||
|
{
|
||||||
|
if(callback)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stopScriptStatusThread = true;
|
||||||
|
lk.unlock();
|
||||||
|
stopScriptStatusCv.notify_all();
|
||||||
|
scriptStatusThread.join();
|
||||||
|
scriptStatusThread = std::thread();
|
||||||
|
}
|
||||||
|
|
||||||
Lifetime Device::suppressDisconnects() {
|
Lifetime Device::suppressDisconnects() {
|
||||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||||
heartbeatSuppressedByUser++;
|
heartbeatSuppressedByUser++;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ enum class Command : uint8_t {
|
||||||
EnableNetworkCommunicationEx = 0x08,
|
EnableNetworkCommunicationEx = 0x08,
|
||||||
NeoReadMemory = 0x40,
|
NeoReadMemory = 0x40,
|
||||||
NeoWriteMemory = 0x41,
|
NeoWriteMemory = 0x41,
|
||||||
|
ClearCoreMini = 0x42,
|
||||||
|
LoadCoreMini = 0x43,
|
||||||
RequestSerialNumber = 0xA1,
|
RequestSerialNumber = 0xA1,
|
||||||
GetMainVersion = 0xA3, // Previously known as RED_CMD_APP_VERSION_REQ
|
GetMainVersion = 0xA3, // Previously known as RED_CMD_APP_VERSION_REQ
|
||||||
SetSettings = 0xA4, // Previously known as RED_CMD_SET_BAUD_REQ, follow up with SaveSettings to write to EEPROM
|
SetSettings = 0xA4, // Previously known as RED_CMD_SET_BAUD_REQ, follow up with SaveSettings to write to EEPROM
|
||||||
|
|
@ -25,9 +27,11 @@ enum class Command : uint8_t {
|
||||||
RequestBitSmash = 0xDC, // Previously known as RED_CMD_CM_BITSMASH
|
RequestBitSmash = 0xDC, // Previously known as RED_CMD_CM_BITSMASH
|
||||||
WiVICommand = 0xDD, // Previously known as RED_CMD_WIVI_COMM
|
WiVICommand = 0xDD, // Previously known as RED_CMD_WIVI_COMM
|
||||||
GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST
|
GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST
|
||||||
|
ScriptStatus = 0xE0, // Previously known as RED_CMD_SCRIPT_STATUS
|
||||||
MiscControl = 0xE7,
|
MiscControl = 0xE7,
|
||||||
Extended = 0xF0,
|
Extended = 0xF0,
|
||||||
FlexRayControl = 0xF3,
|
FlexRayControl = 0xF3,
|
||||||
|
CoreMiniPreload = 0xF4, // Previously known as RED_CMD_COREMINI_PRELOAD
|
||||||
PHYControlRegisters = 0xEF
|
PHYControlRegisters = 0xEF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
#ifndef __A2BMESSAGE_H_
|
||||||
|
#define __A2BMESSAGE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
|
||||||
|
#define A2BMESSAGE_UPSTREAM 1
|
||||||
|
#define A2BMESSAGE_DOWNSTREAM 0
|
||||||
|
|
||||||
|
#define A2BPCM_L16 16
|
||||||
|
#define A2BPCM_L24 24
|
||||||
|
|
||||||
|
#define A2BPCM_SAMPLERATE_44100 44100
|
||||||
|
#define A2BPCM_SAMPLERATE_48000 48000
|
||||||
|
|
||||||
|
namespace icsneo
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef uint32_t A2BPCMSample;
|
||||||
|
typedef std::vector<A2BPCMSample> ChannelBuffer;
|
||||||
|
|
||||||
|
class A2BMessage : public Frame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class A2BDirection : uint8_t
|
||||||
|
{
|
||||||
|
DownStream = 0,
|
||||||
|
UpStream = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
A2BMessage() = delete;
|
||||||
|
|
||||||
|
A2BMessage(uint8_t bitDepth, uint8_t bytesPerSample, uint8_t numChannels, bool monitor) :
|
||||||
|
mBitDepth(bitDepth),
|
||||||
|
mBytesPerSample(bytesPerSample),
|
||||||
|
mMonitor(monitor)
|
||||||
|
{
|
||||||
|
downstream.resize(numChannels);
|
||||||
|
upstream.resize(numChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addSample(A2BPCMSample &&sample, A2BDirection dir, uint8_t channel)
|
||||||
|
{
|
||||||
|
if(dir == A2BDirection::DownStream)
|
||||||
|
{
|
||||||
|
downstream[channel].push_back(std::move(sample));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upstream[channel].push_back(std::move(sample));
|
||||||
|
}
|
||||||
|
totalSamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const A2BPCMSample *getSamples(A2BDirection dir, uint8_t channel) const
|
||||||
|
{
|
||||||
|
if(channel >= getNumChannels())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dir == A2BDirection::DownStream)
|
||||||
|
{
|
||||||
|
return downstream[channel].data();
|
||||||
|
}
|
||||||
|
return upstream[channel].data();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<A2BPCMSample> getSample(A2BDirection dir, uint8_t channel, uint32_t sampleIndex) const
|
||||||
|
{
|
||||||
|
const A2BPCMSample *samples = getSamples(dir, channel);
|
||||||
|
auto numSamplesInChannel = getNumSamplesInChannel(dir, channel);
|
||||||
|
|
||||||
|
if(
|
||||||
|
samples == nullptr ||
|
||||||
|
sampleIndex >= numSamplesInChannel.value_or(0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples[sampleIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::size_t> getNumSamplesInChannel(A2BDirection dir, uint8_t channel) const
|
||||||
|
{
|
||||||
|
if(channel >= getNumChannels())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dir == A2BDirection::DownStream)
|
||||||
|
{
|
||||||
|
return downstream[channel].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return upstream[channel].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getNumSamples() const
|
||||||
|
{
|
||||||
|
return totalSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getNumChannels() const
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(downstream.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getBitDepth() const
|
||||||
|
{
|
||||||
|
return mBitDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getBytesPerSample() const
|
||||||
|
{
|
||||||
|
return mBytesPerSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMonitor() const
|
||||||
|
{
|
||||||
|
return mMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<ChannelBuffer> downstream;
|
||||||
|
std::vector<ChannelBuffer> upstream;
|
||||||
|
size_t totalSamples = 0;
|
||||||
|
|
||||||
|
uint8_t mBitDepth;
|
||||||
|
uint8_t mBytesPerSample;
|
||||||
|
bool mMonitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -30,6 +30,7 @@ public:
|
||||||
LogicalDiskInfo = 0x8008,
|
LogicalDiskInfo = 0x8008,
|
||||||
ExtendedResponse = 0x8009,
|
ExtendedResponse = 0x8009,
|
||||||
WiVICommandResponse = 0x800a,
|
WiVICommandResponse = 0x800a,
|
||||||
|
ScriptStatus = 0x800b,
|
||||||
};
|
};
|
||||||
|
|
||||||
Message(Type t) : type(t) {}
|
Message(Type t) : type(t) {}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef __SCRIPTSTATUSMESSAGE_H
|
||||||
|
#define __SCRIPTSTATUSMESSAGE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
#include "icsneo/communication/packet/scriptstatuspacket.h"
|
||||||
|
|
||||||
|
namespace icsneo
|
||||||
|
{
|
||||||
|
//Response to Command::ScriptStatus
|
||||||
|
class ScriptStatusMessage : public Message {
|
||||||
|
public:
|
||||||
|
ScriptStatusMessage() : Message( Message::Type::ScriptStatus ) {}
|
||||||
|
|
||||||
|
bool isCoreminiRunning = false;
|
||||||
|
uint32_t sectorOverflows = 0;
|
||||||
|
uint32_t numRemainingSectorBuffers = 0;
|
||||||
|
int32_t lastSector = 0;
|
||||||
|
int32_t readBinSize = 0;
|
||||||
|
int32_t minSector = 0;
|
||||||
|
int32_t maxSector = 0;
|
||||||
|
int32_t currentSector = 0;
|
||||||
|
uint64_t coreminiCreateTime = 0;
|
||||||
|
uint16_t fileChecksum = 0;
|
||||||
|
uint16_t coreminiVersion = 0;
|
||||||
|
uint16_t coreminiHeaderSize = 0;
|
||||||
|
uint8_t diagnosticErrorCode = 0;
|
||||||
|
uint8_t diagnosticErrorCodeCount = 0;
|
||||||
|
uint16_t maxCoreminiSizeKB = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif //__SCRIPTSTATUSMESSAGE_H
|
||||||
|
|
@ -119,9 +119,11 @@ public:
|
||||||
LSFTCAN2 = 99,
|
LSFTCAN2 = 99,
|
||||||
LogicalDiskInfo = 187,
|
LogicalDiskInfo = 187,
|
||||||
WiVICommand = 221,
|
WiVICommand = 221,
|
||||||
|
ScriptStatus = 224,
|
||||||
EthPHYControl = 239,
|
EthPHYControl = 239,
|
||||||
ExtendedCommand = 240,
|
ExtendedCommand = 240,
|
||||||
FlexRayControl = 243,
|
FlexRayControl = 243,
|
||||||
|
CoreMiniPreLoad = 244,
|
||||||
HW_COM_Latency_Test = 512,
|
HW_COM_Latency_Test = 512,
|
||||||
DeviceStatus = 513,
|
DeviceStatus = 513,
|
||||||
UDP = 514,
|
UDP = 514,
|
||||||
|
|
@ -147,6 +149,7 @@ public:
|
||||||
SWCAN = 8,
|
SWCAN = 8,
|
||||||
ISO9141 = 9,
|
ISO9141 = 9,
|
||||||
I2C = 10,
|
I2C = 10,
|
||||||
|
A2B = 11,
|
||||||
Any = 0xFE, // Never actually set as type, but used as flag for filtering
|
Any = 0xFE, // Never actually set as type, but used as flag for filtering
|
||||||
Other = 0xFF
|
Other = 0xFF
|
||||||
};
|
};
|
||||||
|
|
@ -234,6 +237,8 @@ public:
|
||||||
return "Single Wire CAN";
|
return "Single Wire CAN";
|
||||||
case Type::I2C:
|
case Type::I2C:
|
||||||
return "I²C";
|
return "I²C";
|
||||||
|
case Type::A2B:
|
||||||
|
return "A2B";
|
||||||
case Type::Invalid:
|
case Type::Invalid:
|
||||||
default:
|
default:
|
||||||
return "Invalid Type";
|
return "Invalid Type";
|
||||||
|
|
@ -278,7 +283,9 @@ public:
|
||||||
case NetID::ReadSettings:
|
case NetID::ReadSettings:
|
||||||
case NetID::LogicalDiskInfo:
|
case NetID::LogicalDiskInfo:
|
||||||
case NetID::WiVICommand:
|
case NetID::WiVICommand:
|
||||||
|
case NetID::ScriptStatus:
|
||||||
case NetID::EthPHYControl:
|
case NetID::EthPHYControl:
|
||||||
|
case NetID::CoreMiniPreLoad:
|
||||||
case NetID::ExtendedCommand:
|
case NetID::ExtendedCommand:
|
||||||
case NetID::NeoMemorySDRead:
|
case NetID::NeoMemorySDRead:
|
||||||
case NetID::NeoMemoryWriteDone:
|
case NetID::NeoMemoryWriteDone:
|
||||||
|
|
@ -318,6 +325,9 @@ public:
|
||||||
case NetID::I2C3:
|
case NetID::I2C3:
|
||||||
case NetID::I2C4:
|
case NetID::I2C4:
|
||||||
return Type::I2C;
|
return Type::I2C;
|
||||||
|
case NetID::A2B1:
|
||||||
|
case NetID::A2B2:
|
||||||
|
return Type::A2B;
|
||||||
default:
|
default:
|
||||||
return Type::Other;
|
return Type::Other;
|
||||||
}
|
}
|
||||||
|
|
@ -520,6 +530,10 @@ public:
|
||||||
return "Logical Disk Information";
|
return "Logical Disk Information";
|
||||||
case NetID::WiVICommand:
|
case NetID::WiVICommand:
|
||||||
return "WiVI Command";
|
return "WiVI Command";
|
||||||
|
case NetID::ScriptStatus:
|
||||||
|
return "Script Status";
|
||||||
|
case NetID::CoreMiniPreLoad:
|
||||||
|
return "CoreMini PreLoad";
|
||||||
case NetID::EthPHYControl:
|
case NetID::EthPHYControl:
|
||||||
return "Ethernet PHY Register Control";
|
return "Ethernet PHY Register Control";
|
||||||
case NetID::ExtendedCommand:
|
case NetID::ExtendedCommand:
|
||||||
|
|
@ -928,9 +942,11 @@ private:
|
||||||
#define ICSNEO_NETID_LSFTCAN2 99
|
#define ICSNEO_NETID_LSFTCAN2 99
|
||||||
#define ICSNEO_NETID_LOGICAL_DISK_INFO 187
|
#define ICSNEO_NETID_LOGICAL_DISK_INFO 187
|
||||||
#define ICSNEO_NETID_WIVI_COMMAND 221
|
#define ICSNEO_NETID_WIVI_COMMAND 221
|
||||||
|
#define ICSNEO_NETID_SCRIPT_STATUS 224
|
||||||
#define ICSNEO_NETID_ETH_PHY_CONTROL 239
|
#define ICSNEO_NETID_ETH_PHY_CONTROL 239
|
||||||
#define ICSNEO_NETID_EXTENDED_COMMAND 240
|
#define ICSNEO_NETID_EXTENDED_COMMAND 240
|
||||||
#define ICSNEO_NETID_FLEXRAY_CONTROL 243
|
#define ICSNEO_NETID_FLEXRAY_CONTROL 243
|
||||||
|
#define ICSNEO_NETID_COREMINI_PRELOAD 244
|
||||||
#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512
|
#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512
|
||||||
#define ICSNEO_NETID_DEVICE_STATUS 513
|
#define ICSNEO_NETID_DEVICE_STATUS 513
|
||||||
#define ICSNEO_NETID_UDP 514
|
#define ICSNEO_NETID_UDP 514
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef __A2BPACKET_H__
|
||||||
|
#define __A2BPACKET_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
typedef uint16_t icscm_bitfield;
|
||||||
|
|
||||||
|
struct HardwareA2BPacket {
|
||||||
|
|
||||||
|
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// CxA2B
|
||||||
|
icscm_bitfield channelNum : 8;
|
||||||
|
icscm_bitfield channelSize16 : 1;
|
||||||
|
icscm_bitfield : 7;
|
||||||
|
|
||||||
|
// CxA2B2
|
||||||
|
icscm_bitfield monitor : 1;
|
||||||
|
icscm_bitfield txmsg : 1;
|
||||||
|
icscm_bitfield errIndicator : 1;
|
||||||
|
icscm_bitfield syncFrame : 1;
|
||||||
|
icscm_bitfield upstream : 1;
|
||||||
|
icscm_bitfield : 11;
|
||||||
|
icscm_bitfield rfu2;
|
||||||
|
} header;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
#ifndef __SCRIPTSTATUSPACKET_H
|
||||||
|
#define __SCRIPTSTATUSPACKET_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/packet.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#pragma pack(push,2)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
|
||||||
|
#pragma warning(disable: 4200) // nonstandard extension used: zero-sized array in struct/union
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
namespace icsneo
|
||||||
|
{
|
||||||
|
|
||||||
|
class ScriptStatusMessage;
|
||||||
|
|
||||||
|
struct CoreMiniStatus
|
||||||
|
{
|
||||||
|
uint32_t justReset : 1;
|
||||||
|
uint32_t communicationEnabled : 1;
|
||||||
|
uint32_t isRunning : 1;
|
||||||
|
uint32_t checksumFailed : 1;
|
||||||
|
uint32_t licenseFailed : 1;
|
||||||
|
uint32_t versionMismatch : 1;
|
||||||
|
uint32_t bootOff : 1;
|
||||||
|
uint32_t hardwareFailure : 1; // To check SRAM failure (for now)
|
||||||
|
uint32_t isPassiveConnect : 1; // Always zero. Set to one when neoVI connection is passive,i.e. no async traffic
|
||||||
|
uint32_t usbCommunicationEnabled : 1; // Set to one when USB Host PC has enabled communication.
|
||||||
|
uint32_t linuxCommunicationEnabled : 1; // Set to one when Android (Linux) has enabled communication.
|
||||||
|
uint32_t tooBig : 1;
|
||||||
|
uint32_t hidUsbState : 1;
|
||||||
|
uint32_t fpgaUsbState : 1;
|
||||||
|
uint32_t filesystem : 1;
|
||||||
|
uint32_t isEncrypted : 1;
|
||||||
|
uint32_t reserved : 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScriptStatus
|
||||||
|
{
|
||||||
|
static std::shared_ptr<ScriptStatusMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||||
|
|
||||||
|
CoreMiniStatus status;
|
||||||
|
uint32_t sectorOverflows;
|
||||||
|
uint32_t numRemainingSectorBuffers;
|
||||||
|
int32_t lastSector;
|
||||||
|
int32_t readBinSize;
|
||||||
|
int32_t minSector;
|
||||||
|
int32_t maxSector;
|
||||||
|
int32_t currentSector;
|
||||||
|
uint32_t coreminiCreateTimeMsb;
|
||||||
|
uint32_t coreminiCreateTimeLsb;
|
||||||
|
uint16_t zero2;
|
||||||
|
uint16_t zero3;
|
||||||
|
uint16_t fileChecksum;
|
||||||
|
uint16_t coreminiVersion;
|
||||||
|
uint16_t coreminiHeaderSize;
|
||||||
|
uint16_t coreminiEngineMinVersion; // This firmware min version
|
||||||
|
uint16_t coreminiScriptMinEngineVers; // Current loaded script's min engine requirements.
|
||||||
|
uint8_t eolResults1;
|
||||||
|
uint8_t eolResults2;
|
||||||
|
uint8_t eolResults3;
|
||||||
|
uint8_t zero6;
|
||||||
|
uint8_t diagErrCode;
|
||||||
|
uint8_t diagErrCodeCount;
|
||||||
|
/* FPGA version Fpga reports to HID over SPI */
|
||||||
|
uint8_t spiFpgaVers1;
|
||||||
|
uint8_t spiFpgaVers2;
|
||||||
|
uint16_t maxCoreminiSizeKB;
|
||||||
|
uint16_t maxCoreminiFlashSizeKB;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace icsneo
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif //__SCRIPTSTATUSPACKET_H
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <unordered_map>
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/eventmanager.h"
|
||||||
#include "icsneo/api/lifetime.h"
|
#include "icsneo/api/lifetime.h"
|
||||||
#include "icsneo/device/neodevice.h"
|
#include "icsneo/device/neodevice.h"
|
||||||
|
|
@ -29,6 +30,7 @@
|
||||||
#include "icsneo/communication/io.h"
|
#include "icsneo/communication/io.h"
|
||||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||||
#include "icsneo/communication/message/wiviresponsemessage.h"
|
#include "icsneo/communication/message/wiviresponsemessage.h"
|
||||||
|
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||||
#include "icsneo/device/extensions/flexray/controller.h"
|
#include "icsneo/device/extensions/flexray/controller.h"
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
||||||
#include "icsneo/communication/message/ethphymessage.h"
|
#include "icsneo/communication/message/ethphymessage.h"
|
||||||
|
|
@ -125,6 +127,19 @@ public:
|
||||||
virtual bool goOnline();
|
virtual bool goOnline();
|
||||||
virtual bool goOffline();
|
virtual bool goOffline();
|
||||||
|
|
||||||
|
enum class PreloadReturn : uint8_t
|
||||||
|
{
|
||||||
|
Pending,
|
||||||
|
Ok,
|
||||||
|
OKEncrypted,
|
||||||
|
NoScript,
|
||||||
|
};
|
||||||
|
|
||||||
|
int8_t prepareScriptLoad();
|
||||||
|
bool startScript();
|
||||||
|
bool stopScript();
|
||||||
|
bool clearScript();
|
||||||
|
|
||||||
// Message polling related functions
|
// Message polling related functions
|
||||||
bool enableMessagePolling();
|
bool enableMessagePolling();
|
||||||
bool disableMessagePolling();
|
bool disableMessagePolling();
|
||||||
|
|
@ -332,6 +347,129 @@ public:
|
||||||
*/
|
*/
|
||||||
bool allowSleep(bool remoteWakeup = false);
|
bool allowSleep(bool remoteWakeup = false);
|
||||||
|
|
||||||
|
enum class ScriptStatus {
|
||||||
|
CoreMiniRunning = 0,
|
||||||
|
SectorOverflow = 1,
|
||||||
|
RemainingSectors = 2,
|
||||||
|
LastSector = 3,
|
||||||
|
ReadBinSize = 4,
|
||||||
|
MinSector = 5,
|
||||||
|
MaxSector = 6,
|
||||||
|
CurrentSector = 7,
|
||||||
|
CoreMiniCreateTime = 8,
|
||||||
|
FileChecksum = 9,
|
||||||
|
CoreMiniVersion = 10,
|
||||||
|
CoreMiniHeaderSize = 11,
|
||||||
|
DiagnosticErrorCode = 12,
|
||||||
|
DiagnosticErrorCodeCount = 13,
|
||||||
|
MaxCoreMiniSize = 14,
|
||||||
|
Logging = 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::function< void(uint64_t value) > ScriptStatusCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all current script status values
|
||||||
|
*/
|
||||||
|
std::shared_ptr<ScriptStatusMessage> getScriptStatus() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when VSSAL script running state changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addCoreMiniRunningCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::CoreMiniRunning, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the number of times a sector was dropped due to lack of space
|
||||||
|
* in firmware's filesystem buffer changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addSectorOverflowsCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::SectorOverflow, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when number of sectors of space left in firmware's local file system buffer changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addNumberRemainingSectorsCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::RemainingSectors, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when last sector that was written to changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addLastSectorCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::LastSector, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the size of the ReadBin changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addReadBinSizeCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::ReadBinSize, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the first sector address of logged data changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addMinSectorCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::MinSector, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the last sector address of logged data changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addMaxSectorCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::MaxSector, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the sector that is about to be written changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addCurrentSectorCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::CurrentSector, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the VSSAL script create time changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addCoreMiniCreateTimeCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::CoreMiniCreateTime, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the VSSAL script checksum changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addFileChecksumCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::FileChecksum, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the VSSAL script version changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addCoreMiniVersionCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::CoreMiniVersion, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the VSSAL script header size changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addCoreMiniHeaderSizeCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::CoreMiniHeaderSize, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the firmware diagnostic error code changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addDiagnosticErrorCodeCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::DiagnosticErrorCode, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the firmware diagnostic error code count changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addDiagnosticErrorCodeCountCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::DiagnosticErrorCodeCount, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the maximum size a VSSAL script can be changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addMaxCoreMiniSizeCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::MaxCoreMiniSize, std::move(cb)); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a callback to be called when the device logging state changes
|
||||||
|
*/
|
||||||
|
NODISCARD("If the Lifetime is not held, the callback will be immediately removed")
|
||||||
|
Lifetime addLoggingCallback(ScriptStatusCallback cb) { return addScriptStatusCallback(ScriptStatus::Logging, std::move(cb)); }
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<FlexRay::Controller>> getFlexRayControllers() const { return {}; }
|
virtual std::vector<std::shared_ptr<FlexRay::Controller>> getFlexRayControllers() const { return {}; }
|
||||||
|
|
||||||
void addExtension(std::shared_ptr<DeviceExtension>&& extension);
|
void addExtension(std::shared_ptr<DeviceExtension>&& extension);
|
||||||
|
|
@ -441,8 +579,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Settings>
|
template<typename Settings>
|
||||||
std::unique_ptr<IDeviceSettings> makeSettings(std::shared_ptr<Communication> com) {
|
std::unique_ptr<IDeviceSettings> makeSettings(std::shared_ptr<Communication> comm) {
|
||||||
return std::unique_ptr<IDeviceSettings>(new Settings(com));
|
return std::unique_ptr<IDeviceSettings>(new Settings(comm));
|
||||||
}
|
}
|
||||||
virtual void setupSettings(IDeviceSettings&) {}
|
virtual void setupSettings(IDeviceSettings&) {}
|
||||||
|
|
||||||
|
|
@ -529,6 +667,20 @@ private:
|
||||||
std::vector< std::pair<SleepRequestedCallback, bool /* notified */> > sleepRequestedCallbacks;
|
std::vector< std::pair<SleepRequestedCallback, bool /* notified */> > sleepRequestedCallbacks;
|
||||||
void wiviThreadBody();
|
void wiviThreadBody();
|
||||||
void stopWiVIThreadIfNecessary(std::unique_lock<std::mutex> lk);
|
void stopWiVIThreadIfNecessary(std::unique_lock<std::mutex> lk);
|
||||||
|
|
||||||
|
//Script status
|
||||||
|
std::atomic<bool> stopScriptStatusThread{false};
|
||||||
|
std::condition_variable stopScriptStatusCv;
|
||||||
|
mutable std::mutex scriptStatusMutex;
|
||||||
|
std::thread scriptStatusThread;
|
||||||
|
std::unordered_map<ScriptStatus, std::vector<ScriptStatusCallback>> scriptStatusCallbacks;
|
||||||
|
std::unordered_map<ScriptStatus, uint64_t> scriptStatusValues;
|
||||||
|
Lifetime addScriptStatusCallback(ScriptStatus, ScriptStatusCallback);
|
||||||
|
bool updateScriptStatusValue(ScriptStatus, uint64_t newValue);
|
||||||
|
void notifyScriptStatusCallback(ScriptStatus, uint64_t);
|
||||||
|
void scriptStatusThreadBody();
|
||||||
|
void stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "icsneo/communication/message/iso9141message.h"
|
#include "icsneo/communication/message/iso9141message.h"
|
||||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||||
#include "icsneo/communication/message/ethphymessage.h"
|
#include "icsneo/communication/message/ethphymessage.h"
|
||||||
|
#include "icsneo/communication/message/a2bmessage.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue