Updates to the legacy API

* Added transmit

* Added support for the new style icsneoFindDevices() call

* Added support for blocking wait for message

* CAN FD and XTD 29-bit CAN Support
pull/4/head
Paul Hollinsky 2019-01-03 16:57:29 -05:00
parent 814dc7d174
commit 61c16f4dfc
5 changed files with 149 additions and 31 deletions

View File

@ -154,6 +154,7 @@ target_link_libraries(icsneoc icsneocpp)
add_library(icsneolegacy SHARED add_library(icsneolegacy SHARED
api/icsneolegacy/icsneolegacy.cpp api/icsneolegacy/icsneolegacy.cpp
api/icsneolegacy/icsneolegacyextra.cpp
api/icsneoc/icsneoc.cpp api/icsneoc/icsneoc.cpp
) )
target_include_directories(icsneolegacy target_include_directories(icsneolegacy

View File

@ -1,5 +1,5 @@
#ifndef __cplusplus #ifndef __cplusplus
#error "icsneoc.cpp must be compiled with a C++ compiler!" #error "icsneolegacy.cpp must be compiled with a C++ compiler!"
#endif #endif
#define NOMINMAX #define NOMINMAX
@ -18,7 +18,6 @@
#pragma warning(disable : 4100) // unreferenced formal parameter #pragma warning(disable : 4100) // unreferenced formal parameter
#endif #endif
using namespace icsneo; using namespace icsneo;
typedef uint64_t legacymaphandle_t; typedef uint64_t legacymaphandle_t;
@ -35,7 +34,66 @@ static NeoDevice OldNeoDeviceFromNew(const neodevice_t* newnd) {
return oldnd; return oldnd;
} }
static void NeoMessageToSpyMessage(const neomessage_t& newmsg, icsSpyMessage& oldmsg) {
memset(&oldmsg, 0, sizeof(icsSpyMessage));
oldmsg.NumberBytesData = (uint8_t)std::min(newmsg.length, (size_t)255);
oldmsg.NumberBytesHeader = 4;
oldmsg.ExtraDataPtr = (void*)newmsg.data;
memcpy(oldmsg.Data, newmsg.data, std::min(newmsg.length, (size_t)8));
oldmsg.ArbIDOrHeader = *(uint32_t*)newmsg.header;
oldmsg.ExtraDataPtrEnabled = newmsg.length > 8;
oldmsg.NetworkID = (uint8_t)newmsg.netid; // Note: NetID remapping from the original API is not supported
oldmsg.StatusBitField = newmsg.status.statusBitfield[0];
oldmsg.StatusBitField2 = newmsg.status.statusBitfield[1];
oldmsg.StatusBitField3 = newmsg.status.statusBitfield[2];
oldmsg.StatusBitField4 = newmsg.status.statusBitfield[3];
switch(Network::Type(newmsg.type)) {
case Network::Type::CAN:
oldmsg.Protocol = newmsg.status.canfdFDF ? SPY_PROTOCOL_CANFD : SPY_PROTOCOL_CAN;
break;
case Network::Type::Ethernet:
oldmsg.Protocol = SPY_PROTOCOL_ETHERNET;
break;
}
}
//Basic Functions //Basic Functions
int icsneoFindDevices(NeoDeviceEx* devs, int* devCount, unsigned int* devTypes, unsigned int devTypeCount, POptionsFindNeoEx*, unsigned int*) {
constexpr size_t MAX_DEVICES = 255;
if(devCount == nullptr)
return 0;
unsigned int devTypesDefault[] = { NEODEVICE_ALL };
if(devTypes == nullptr || devTypeCount == 0) {
devTypes = devTypesDefault;
devTypeCount = 1;
}
size_t count = MAX_DEVICES;
if(devs == nullptr) { // Size query
icsneo_findAllDevices(nullptr, &count);
*devCount = (int)count;
return 1;
}
size_t bufferSize = (size_t)*devCount;
if(*devCount < 0 || bufferSize > MAX_DEVICES)
return 0;
neodevice_t devices[MAX_DEVICES];
icsneo_findAllDevices(devices, &count);
if(bufferSize < count)
count = bufferSize;
*devCount = (int)count;
for(size_t i = 0; i < count; i++) {
devs[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 icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int* pNumDevices) { int icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int* pNumDevices) {
constexpr size_t MAX_DEVICES = 255; constexpr size_t MAX_DEVICES = 255;
size_t count = MAX_DEVICES; size_t count = MAX_DEVICES;
@ -117,41 +175,59 @@ int icsneoGetMessages(void* hObject, icsSpyMessage* pMsg, int* pNumberOfMessages
*pNumberOfMessages = (int)messageCount; *pNumberOfMessages = (int)messageCount;
*pNumberOfErrors = 0; *pNumberOfErrors = 0;
memset(pMsg, 0, sizeof(icsSpyMessage) * messageCount); for(size_t i = 0; i < messageCount; i++)
for(size_t i = 0; i < messageCount; i++) { NeoMessageToSpyMessage(messages[i], pMsg[i]);
icsSpyMessage& oldmsg = pMsg[i];
neomessage_t& newmsg = messages[i];
oldmsg.NumberBytesData = (uint8_t)std::min(newmsg.length, (size_t)255);
oldmsg.NumberBytesHeader = 4;
oldmsg.ExtraDataPtr = (void*)newmsg.data;
memcpy(oldmsg.Data, newmsg.data, std::min(newmsg.length, (size_t)8));
oldmsg.ArbIDOrHeader = *(uint32_t*)newmsg.header;
oldmsg.ExtraDataPtrEnabled = newmsg.length > 8;
oldmsg.NetworkID = (uint8_t)newmsg.netid; // TODO Handling for this?
switch(Network::Type(newmsg.type)) {
case Network::Type::CAN:
oldmsg.Protocol = SPY_PROTOCOL_CAN;
break;
// TODO Handle this better
}
}
return true; return true;
} }
int icsneoTxMessages(void* hObject, icsSpyMessage* pMsg, int lNetworkID, int lNumMessages) { int icsneoTxMessages(void* hObject, icsSpyMessage* pMsg, int lNetworkID, int lNumMessages) {
// TODO Implement if(!icsneoValidateHObject(hObject))
return false; return false;
neodevice_t* device = (neodevice_t*)hObject;
std::vector<uint8_t> data;
neomessage_t newmsg = {};
newmsg.netid = (uint16_t)lNetworkID;
memcpy(newmsg.header, &pMsg[0].ArbIDOrHeader, sizeof(newmsg.header));
for(int i = 0; i < lNumMessages; i++)
data.insert(data.end(), pMsg[i].Data, pMsg[i].Data + pMsg[i].NumberBytesData);
newmsg.data = data.data();
newmsg.length = data.size();
newmsg.status.statusBitfield[0] = pMsg[0].StatusBitField;
newmsg.status.statusBitfield[1] = pMsg[0].StatusBitField2;
newmsg.status.statusBitfield[2] = pMsg[0].StatusBitField3;
newmsg.status.statusBitfield[3] = pMsg[0].StatusBitField4;
if(pMsg[0].Protocol == SPY_PROTOCOL_CANFD)
newmsg.status.canfdFDF = true;
return icsneo_transmit(device, &newmsg);
} }
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 if(!icsneoValidateHObject(hObject))
return false; return false;
neodevice_t* device = (neodevice_t*)hObject;
neomessage_t newmsg;
*NumTxed = 0;
for(unsigned int i = 0; i < lNumMessages; i++) {
const icsSpyMessage& oldmsg = pMsg[i];
newmsg = {};
newmsg.netid = (uint16_t)lNetworkID;
memcpy(newmsg.header, &oldmsg.ArbIDOrHeader, sizeof(newmsg.header));
newmsg.length = oldmsg.NumberBytesData | (oldmsg.NodeID << 8);
if (oldmsg.ExtraDataPtrEnabled)
newmsg.data = reinterpret_cast<const uint8_t*>(oldmsg.ExtraDataPtr);
else
newmsg.data = oldmsg.Data;
newmsg.status.statusBitfield[0] = oldmsg.StatusBitField;
newmsg.status.statusBitfield[1] = oldmsg.StatusBitField2;
newmsg.status.statusBitfield[2] = oldmsg.StatusBitField3;
newmsg.status.statusBitfield[3] = oldmsg.StatusBitField4;
if(oldmsg.Protocol == SPY_PROTOCOL_CANFD)
newmsg.status.canfdFDF = true;
if(icsneo_transmit(device, &newmsg))
(*NumTxed)++;
} }
return lNumMessages == *NumTxed;
int icsneoWaitForRxMessagesWithTimeOut(void* hObject, unsigned int iTimeOut) {
// TODO Implement
return false;
} }
int icsneoEnableNetworkRXQueue(void* hObject, int iEnable) { int icsneoEnableNetworkRXQueue(void* hObject, int iEnable) {
@ -302,7 +378,9 @@ int icsneoSetBitRate(void* hObject, int BitRate, int NetworkID) {
if(!icsneoValidateHObject(hObject)) if(!icsneoValidateHObject(hObject))
return false; return false;
neodevice_t* device = (neodevice_t*)hObject; neodevice_t* device = (neodevice_t*)hObject;
return icsneo_setBaudrate(device, (uint16_t)NetworkID, BitRate); if(!icsneo_setBaudrate(device, (uint16_t)NetworkID, BitRate))
return false;
return icsneo_settingsApply(device);
} }
int icsneoGetDeviceParameters(void* hObject, char* pParameter, char* pValues, short ValuesLength) { int icsneoGetDeviceParameters(void* hObject, char* pParameter, char* pValues, short ValuesLength) {

View File

@ -0,0 +1,28 @@
// Legacy functions which access the C++ objects directly
// idevicesettings.h (from Device) and icsnVC40.h cannot be included together, hence this file
#ifndef __cplusplus
#error "icsneolegacyextra.cpp must be compiled with a C++ compiler!"
#endif
#include "icsneo/device/device.h"
#define ICSNEOC_MAKEDLL
#include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting
#undef ICSNEOC_MAKEDLL
#include <chrono>
using namespace icsneo;
extern "C" {
extern int DLLExport icsneoValidateHObject(void* hObject);
extern int DLLExport icsneoWaitForRxMessagesWithTimeOut(void* hObject, unsigned int iTimeOut);
}
int icsneoWaitForRxMessagesWithTimeOut(void* hObject, unsigned int iTimeOut) {
if(!icsneoValidateHObject(hObject))
return false;
neodevice_t* device = (neodevice_t*)hObject;
if(device->device->getCurrentMessageCount() != 0)
return true;
return bool(device->device->com->waitForMessageSync(MessageFilter(), std::chrono::milliseconds(iTimeOut)));
}

View File

@ -1057,6 +1057,16 @@ typedef struct{
int MaxAllowedClients; int MaxAllowedClients;
} NeoDevice; } NeoDevice;
typedef struct {
NeoDevice neoDevice;
unsigned long FirmwareMajor;
unsigned long FirmwareMinor;
unsigned long Status; // 1=CM Running 2=Bootloader
unsigned long Reserved[16]; // may be expanded in future revisions
} NeoDeviceEx;
typedef void POptionsFindNeoEx;
typedef struct { // Matching C structure typedef struct { // Matching C structure
unsigned long StatusValue; // 4 unsigned long StatusValue; // 4
unsigned long StatusMask; // 4 unsigned long StatusMask; // 4

View File

@ -13,6 +13,7 @@ extern "C" {
#endif #endif
//Basic Functions //Basic Functions
extern int DLLExport icsneoFindDevices(NeoDeviceEx* pNeoDeviceEx, int* pNumDevices, unsigned int* DeviceTypes, unsigned int numDeviceTypes,POptionsFindNeoEx* pOptionsNeoEx, unsigned int* reserved);
extern int DLLExport icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int* pNumDevices); 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 int DLLExport icsneoClosePort(void* hObject, int* pNumberOfErrors);