Legacy API can receive CAN now

pull/4/head
Paul Hollinsky 2018-10-08 21:43:32 -04:00
parent b3471890eb
commit ba9813021e
11 changed files with 142 additions and 42 deletions

View File

@ -212,6 +212,16 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng
return true;
}
bool icsneo_settingsRefresh(const neodevice_t* device) {
if(!icsneo_isValidNeoDevice(device))
return false;
if(!device->device->settings) // Settings are not available for this device
return false;
return device->device->settings->refresh();
}
bool icsneo_settingsApply(const neodevice_t* device) {
if(!icsneo_isValidNeoDevice(device))
return false;

View File

@ -44,6 +44,8 @@ extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, s
extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength);
extern bool DLLExport icsneo_settingsRefresh(const neodevice_t* device);
extern bool DLLExport icsneo_settingsApply(const neodevice_t* device);
extern bool DLLExport icsneo_settingsApplyTemporary(const neodevice_t* device);
@ -108,6 +110,9 @@ fn_icsneo_setPollingMessageLimit icsneo_setPollingMessageLimit;
typedef bool(*fn_icsneo_getProductName)(const neodevice_t* device, char* str, size_t* maxLength);
fn_icsneo_getProductName icsneo_getProductName;
typedef bool(*fn_icsneo_settingsRefresh)(const neodevice_t* device);
fn_icsneo_settingsRefresh icsneo_settingsRefresh;
typedef bool(*fn_icsneo_settingsApply)(const neodevice_t* device);
fn_icsneo_settingsApply icsneo_settingsApply;
@ -153,6 +158,7 @@ int icsneo_init() {
ICSNEO_IMPORTASSERT(icsneo_getPollingMessageLimit);
ICSNEO_IMPORTASSERT(icsneo_setPollingMessageLimit);
ICSNEO_IMPORTASSERT(icsneo_getProductName);
ICSNEO_IMPORTASSERT(icsneo_settingsRefresh);
ICSNEO_IMPORTASSERT(icsneo_settingsApply);
ICSNEO_IMPORTASSERT(icsneo_settingsApplyTemporary);
ICSNEO_IMPORTASSERT(icsneo_settingsApplyDefaults);

View File

@ -1,9 +1,21 @@
#ifndef __cplusplus
#error "icsneoc.cpp must be compiled with a C++ compiler!"
#endif
#define ICSNEOC_MAKEDLL
#include "api/icsneolegacy/include/icsneolegacy.h"
#undef ICSNEOC_MAKEDLL
#include "api/icsneoc/include/icsneoc.h"
#include "communication/include/network.h"
#include <map>
using namespace icsneo;
typedef uint64_t legacymaphandle_t;
static std::map<legacymaphandle_t, neodevice_t> neodevices;
static NeoDevice OldNeoDeviceFromNew(const neodevice_t* newnd) {
NeoDevice oldnd = { 0 };
oldnd.DeviceType = newnd->type;
@ -39,26 +51,43 @@ int icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int*
count = bufferSize;
*pNumDevices = (int)count;
for(int i = 0; i < count; i++)
pNeoDevice[i] = OldNeoDeviceFromNew(&devices[i]);
for(int i = 0; i < count; i++) {
pNeoDevice[i] = OldNeoDeviceFromNew(&devices[i]); // Write out into user memory
neodevices[uint64_t(devices[i].handle) << 32 | icsneo_serialStringToNum(devices[i].serial)] = devices[i]; // Fill the look up table
}
return 1;
}
int icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void* hObject, unsigned char* bNetworkIDs, int bConfigRead, int bSyncToPC) {
// TODO Implement
int icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void** hObject, unsigned char* bNetworkIDs, int bConfigRead, int bSyncToPC) {
if(pNeoDevice == nullptr || hObject == nullptr)
return false;
neodevice_t* device;
try {
device = &neodevices.at(uint64_t(pNeoDevice->Handle) << 32 | pNeoDevice->SerialNumber);
} catch(std::out_of_range& e) {
return false;
}
*hObject = device;
if(!icsneo_openDevice(device))
return false;
icsneo_setPollingMessageLimit(device, 20000);
icsneo_enableMessagePolling(device);
return icsneo_goOnline(device);
}
int icsneoClosePort(void* hObject, int* pNumberOfErrors) {
// TODO Implement
if(!icsneoValidateHObject(hObject))
return false;
neodevice_t* device = (neodevice_t*)hObject;
return icsneo_closeDevice(device);
}
void icsneoFreeObject(void* hObject) {
// TODO Implement
return;
}
// Memory is now managed automatically, this function is unneeded
void icsneoFreeObject(void* hObject) { (void)hObject; return; }
int icsneoSerialNumberToString(unsigned long serial, char* data, unsigned long data_size) {
size_t length = (size_t)data_size;
@ -67,8 +96,38 @@ int icsneoSerialNumberToString(unsigned long serial, char* data, unsigned long d
//Message Functions
int icsneoGetMessages(void* hObject, icsSpyMessage* pMsg, int* pNumberOfMessages, int* pNumberOfErrors) {
// TODO Implement
static neomessage_t messages[20000];
if(!icsneoValidateHObject(hObject))
return false;
neodevice_t* device = (neodevice_t*)hObject;
size_t messageCount = 20000;
if(!icsneo_getMessages(device, messages, &messageCount))
return false;
*pNumberOfMessages = (int)messageCount;
*pNumberOfErrors = 0;
memset(pMsg, 0, sizeof(icsSpyMessage) * messageCount);
for(size_t i = 0; i < messageCount; i++) {
icsSpyMessage& oldmsg = pMsg[i];
neomessage_t& newmsg = messages[i];
oldmsg.NumberBytesData = (uint8_t)min(newmsg.length, 255);
oldmsg.NumberBytesHeader = 4;
oldmsg.ExtraDataPtr = (void*)newmsg.data;
memcpy(oldmsg.Data, newmsg.data, min(newmsg.length, 8));
oldmsg.ArbIDOrHeader = *(uint32_t*)newmsg.header;
oldmsg.ExtraDataPtrEnabled = newmsg.length > 8;
oldmsg.NetworkID = newmsg.netid;
switch(Network::Type(newmsg.type)) {
case Network::Type::CAN:
oldmsg.Protocol = SPY_PROTOCOL_CAN;
break;
// TODO Handle this better
}
}
return true;
}
int icsneoTxMessages(void* hObject, icsSpyMessage* pMsg, int lNetworkID, int lNumMessages) {
@ -76,7 +135,7 @@ int icsneoTxMessages(void* hObject, icsSpyMessage* pMsg, int lNetworkID, int lNu
return false;
}
int icsneoTxMessagesEx(void* hObject,icsSpyMessage* pMsg, unsigned int lNetworkID, unsigned int lNumMessages, unsigned int* NumTxed, unsigned int zero2) {
int icsneoTxMessagesEx(void* hObject, icsSpyMessage* pMsg, unsigned int lNetworkID, unsigned int lNumMessages, unsigned int* NumTxed, unsigned int zero2) {
// TODO Implement
return false;
}
@ -214,7 +273,7 @@ int icsneoGetErrorMessages(void* hObject, int* pErrorMsgs, int* pNumberOfErrors)
return false;
}
int icsneoGetErrorInfo(int lErrorNumber, TCHAR*szErrorDescriptionShort, TCHAR*szErrorDescriptionLong, int* lMaxLengthShort, int* lMaxLengthLong,int* lErrorSeverity,int* lRestartNeeded) {
int icsneoGetErrorInfo(int lErrorNumber, TCHAR* szErrorDescriptionShort, TCHAR* szErrorDescriptionLong, int* lMaxLengthShort, int* lMaxLengthLong, int* lErrorSeverity, int* lRestartNeeded) {
// TODO Implement
return false;
}
@ -235,14 +294,21 @@ int icsneoISO15765_TransmitMessage(void* hObject, unsigned long ulNetworkID, stC
return false;
}
int icsneoISO15765_ReceiveMessage(void* hObject,int ulNetworkID, stCM_ISO157652_RxMessage* pMsg) {
int icsneoISO15765_ReceiveMessage(void* hObject, int ulNetworkID, stCM_ISO157652_RxMessage* pMsg) {
// TODO Implement
return false;
}
//General Utility Functions
int icsneoValidateHObject(void* hObject) {
// TODO Implement
for(auto it = neodevices.begin(); it != neodevices.end(); it++) {
if(&it->second == hObject) {
neodevice_t* device = (neodevice_t*)hObject;
if(icsneo_isValidNeoDevice(device))
return true;
}
}
return false;
}
@ -329,8 +395,14 @@ int icsneoOpenPort(int lPortNumber, int lPortType, int lDriverType, unsigned cha
}
int icsneoEnableNetworkCom(void* hObject, int Enable) {
// TODO Implement
if(!icsneoValidateHObject(hObject))
return false;
neodevice_t* device = (neodevice_t*)hObject;
if(Enable)
return icsneo_goOnline(device);
else
return icsneo_goOffline(device);
}
int icsneoFindAllCOMDevices(int lDriverType, int lGetSerialNumbers, int lStopAtFirst, int lUSBCommOnly, int* p_lDeviceTypes, int* p_lComPorts, int* p_lSerialNumbers, int*lNumDevices) {

View File

@ -14,10 +14,10 @@ extern "C" {
//Basic Functions
extern int DLLExport icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int* pNumDevices);
extern int DLLExport icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void* hObject, unsigned char* bNetworkIDs, int bConfigRead, int bSyncToPC);
extern int DLLExport icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void** hObject, unsigned char* bNetworkIDs, int bConfigRead, int bSyncToPC);
extern int DLLExport icsneoClosePort(void* hObject, int* pNumberOfErrors);
extern void DLLExport icsneoFreeObject(void* hObject);
extern int DLLExport icsneoSerialNumberToString(unsigned long serial, char*data,unsigned long data_size);
extern int DLLExport icsneoSerialNumberToString(unsigned long serial, char* data, unsigned long data_size);
//Message Functions
extern int DLLExport icsneoGetMessages(void* hObject, icsSpyMessage* pMsg, int* pNumberOfMessages, int* pNumberOfErrors);

View File

@ -15,6 +15,7 @@ bool ICommunication::read(std::vector<uint8_t>& bytes, size_t limit) {
size_t actuallyRead = readQueue.try_dequeue_bulk(bytes.data(), limit);
if(bytes.size() > actuallyRead)
bytes.resize(actuallyRead);
return true;

View File

@ -112,16 +112,19 @@ public:
LSFTCAN2 = 99,
HW_COM_Latency_Test = 512,
Device_Status = 513,
Any = 0xfffe, // Never actually set as type, but used as flag for filtering
Invalid = 0xffff
};
enum class Type {
Invalid,
Internal, // Used for statuses that don't actually need to be transferred to the client application
CAN,
LIN,
FlexRay,
MOST,
Ethernet,
Other,
Invalid
Any // Never actually set as type, but used as flag for filtering
};
static const char* GetTypeString(Type type) {
switch(type) {
@ -135,6 +138,8 @@ public:
return "MOST";
case Type::Other:
return "Other";
case Type::Internal:
return "Internal";
case Type::Invalid:
default:
return "Invalid Type";
@ -173,7 +178,12 @@ public:
case NetID::MOST50:
case NetID::MOST150:
return Type::MOST;
case NetID::RED:
case NetID::Reset_Status:
case NetID::Device_Status:
return Type::Internal;
case NetID::Invalid:
case NetID::Any:
return Type::Invalid;
default:
return Type::Other;

View File

@ -9,14 +9,14 @@ namespace icsneo {
class MessageFilter {
public:
MessageFilter() : matchAny(true) {}
MessageFilter() {}
MessageFilter(Network::Type type) : type(type) {}
MessageFilter(Network::NetID netid) : netid(netid) {}
virtual ~MessageFilter() {}
// When getting "all" types of messages, include the ones marked as "internal only"
bool includeInternalInAny = false;
virtual bool match(const std::shared_ptr<Message>& message) const {
if(matchAny)
return true;
if(!matchType(message->network.getType()))
return false;
if(!matchNetID(message->network.getNetID()))
@ -25,18 +25,16 @@ public:
}
private:
bool matchAny = false;
Network::Type type = Network::Type::Invalid; // Matching a type of invalid will match any
Network::Type type = Network::Type::Any;
bool matchType(Network::Type mtype) const {
if(type == Network::Type::Invalid)
if(type == Network::Type::Any && (mtype != Network::Type::Internal || includeInternalInAny))
return true;
return type == mtype;
}
Network::NetID netid = Network::NetID::Invalid; // Matching a netid of invalid will match any
Network::NetID netid = Network::NetID::Any;
bool matchNetID(Network::NetID mnetid) const {
if(netid == Network::NetID::Invalid)
if(netid == Network::NetID::Any)
return true;
return netid == mnetid;
}

View File

@ -106,6 +106,7 @@ bool Device::getMessages(std::vector<std::shared_ptr<Message>>& container, size_
size_t actuallyRead = pollingContainer.try_dequeue_bulk(container.data(), limit);
if(container.size() > actuallyRead)
container.resize(actuallyRead);
return true;

View File

@ -42,12 +42,12 @@ uint16_t IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settin
return gs_crc;
}
void IDeviceSettings::refresh(bool ignoreChecksum) {
bool IDeviceSettings::refresh(bool ignoreChecksum) {
std::vector<uint8_t> rxSettings;
bool ret = com->getSettingsSync(rxSettings);
if(ret) {
if(rxSettings.size() < 6) // We need to at least have the header of GLOBAL_SETTINGS
return;
return false;
constexpr size_t gs_size = 3 * sizeof(uint16_t);
size_t rxLen = rxSettings.size() - gs_size;
@ -59,17 +59,17 @@ void IDeviceSettings::refresh(bool ignoreChecksum) {
if(gs_version != 5) {
std::cout << "gs_version was " << gs_version << " instead of 5.\nPlease update your firmware." << std::endl;
return;
return false;
}
if(rxLen != gs_len) {
std::cout << "rxLen was " << rxLen << " and gs_len was " << gs_len << " while reading settings" << std::endl;
return;
return false;
}
if(!ignoreChecksum && gs_chksum != CalculateGSChecksum(rxSettings)) {
std::cout << "Checksum mismatch while reading settings" << std::endl;
return;
return false;
}
settings = std::move(rxSettings);
@ -79,6 +79,8 @@ void IDeviceSettings::refresh(bool ignoreChecksum) {
std::cout << "Settings size was " << settings.size() << " bytes but it should be " << structSize << " bytes for this device" << std::endl;
settingsLoaded = false;
}
return settingsLoaded;
}
}

View File

@ -285,7 +285,7 @@ public:
virtual ~IDeviceSettings() {}
bool ok() { return settingsLoaded; }
void refresh(bool ignoreChecksum = false); // Get from device
bool refresh(bool ignoreChecksum = false); // Get from device
// Send to device, if temporary device keeps settings in volatile RAM until power cycle, otherwise saved to EEPROM
bool apply(bool temporary = false);

View File

@ -21,8 +21,8 @@ typedef int32_t neodevice_handle_t;
#pragma pack(push, 1)
typedef struct {
devicehandle_t device;
neodevice_handle_t handle;
devicehandle_t device; // Pointer back to the C++ device object
neodevice_handle_t handle; // Handle for use by the underlying driver
devicetype_t type;
char serial[7];
} neodevice_t;