Skip to content

Commit

Permalink
j2534 Staff
Browse files Browse the repository at this point in the history
  • Loading branch information
GSofya committed Oct 20, 2023
1 parent 727d38f commit 925f01a
Show file tree
Hide file tree
Showing 7 changed files with 1,145 additions and 0 deletions.
13 changes: 13 additions & 0 deletions j2534_OverIP/ExDbg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "ExDbg.h"


ExDbg::ExDbg()
{
//log_file_name_ = "C:\\Dev\\log.txt";
this->_client_path = getProcessPath();
this->_crc32_id = (long)crc32(this->_client_path);

_pipe_client = new ExPipeClient("\\\\.\\pipe\\exj2534_overip_pipe");
_pipe_client->connect();

}
125 changes: 125 additions & 0 deletions j2534_OverIP/cbor_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "cbor_utils.h"
#include "expipeclient.h"

bool cbor_utils::map_put_int(cn_cbor* cb_map /* map */, uint32_t key, uint32_t value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), cn_cbor_int_create(value, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_string(cn_cbor* cb_map /* map */, uint32_t key, const char * value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), cn_cbor_string_create(value, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_data(cn_cbor* cb_map /* map */, uint32_t key, const uint8_t* data, uint32_t len)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), cn_cbor_data_create(data, len, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_array(cn_cbor* cb_map /* map */, uint32_t key, cn_cbor* value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), value, &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::arr_append_cbor(cn_cbor* cb_array /* array */, cn_cbor* value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_array_append(cb_array, value, &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_PASSTHRU_MSG(cn_cbor* cb_map /* map */, uint32_t key, uint32_t msgs_count, const PASSTHRU_MSG * msgs)
{
cn_cbor_errback cn_errback = {0};
cn_cbor* cb_map_root = cn_cbor_map_create(&cn_errback);
cn_cbor* cb_array = cn_cbor_array_create(&cn_errback);

// zero param in map is array length
cn_cbor_map_put(cb_map_root, cn_cbor_int_create(0, &cn_errback), cn_cbor_int_create(msgs_count, &cn_errback), &cn_errback);

for(int i = 0; i < msgs_count; i++)
{
/*
uint32_t ProtocolID;
uint32_t RxStatus;
uint32_t TxFlags;
uint32_t Timestamp;
uint32_t DataSize;
uint32_t ExtraDataIndex;
unsigned char Data[4128];
*/
cn_cbor* cb_map_elem = cn_cbor_map_create(&cn_errback);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param1, msgs[i].ProtocolID);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param2, msgs[i].RxStatus);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param3, msgs[i].TxFlags);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param4, msgs[i].Timestamp);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param5, msgs[i].DataSize);
cbor_utils::map_put_int(cb_map_elem, ExPipeClient::KEY_Param6, msgs[i].ExtraDataIndex);
cbor_utils::map_put_data(cb_map_elem, ExPipeClient::KEY_Param7, msgs[i].Data, msgs[i].DataSize);
cbor_utils::arr_append_cbor(cb_array, cb_map_elem);
}

// first param is the array itself
cbor_utils::map_put_array(cb_map_root, 1, cb_array);

//put this map with array into root map
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), cb_map_root, &cn_errback);

return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_string(cn_cbor* cb_map, const char * key, const char * value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_string_create(key, &cn_errback), cn_cbor_string_create(value, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_bool(cn_cbor* cb_map /* map */, const char * key, bool value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_string_create(key, &cn_errback), cn_cbor_bool_create(value, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_map(cn_cbor* cb_map /* map */, const char * key, cn_cbor* value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_string_create(key, &cn_errback), value, &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::map_put_map(cn_cbor* cb_map /* map */, uint32_t key, cn_cbor* value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_map_put(cb_map, cn_cbor_int_create(key, &cn_errback), value, &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

bool cbor_utils::arr_put_string(cn_cbor* cb_array, const char * value)
{
cn_cbor_errback cn_errback = {0};
cn_cbor_array_append(cb_array, cn_cbor_string_create(value, &cn_errback), &cn_errback);
return cn_errback.err == CN_CBOR_NO_ERROR;
}

std::vector<uint8_t> cbor_utils::cbor_to_data(cn_cbor * cb)
{
std::vector<uint8_t> cbor_data;
auto cbor_size = cn_cbor_encoder_write(nullptr, 0, 0, cb);
if(cbor_size != -1)
{
cbor_data.resize(cbor_size);
cn_cbor_encoder_write(cbor_data.data(), 0, cbor_size, cb);
}

return cbor_data;
}
190 changes: 190 additions & 0 deletions j2534_OverIP/expipeclient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include "ExPipeClient.h"
#include <cn-cbor/cn-cbor.h>
#include <future>
#include <chrono>

ExPipeClient::ExPipeClient(const std::string& name) : pipe(INVALID_HANDLE_VALUE), name(name)
{

}

ExPipeClient::~ExPipeClient() {
if (pipe != INVALID_HANDLE_VALUE) {
CloseHandle(pipe);
}
}

bool ExPipeClient::connect() {
const int maxAttempts = 3;
const std::chrono::seconds sleepDuration(10); // Sleep for 1 second between attempts

//auto future = std::async(std::launch::async, [=]() {
for (int attempt = 0; attempt < maxAttempts; ++attempt) {
printf("connect to named pipe attempt %d\n", attempt);
pipe = CreateFileA(
name.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);

if (pipe != INVALID_HANDLE_VALUE) {
// Successfully connected to the named pipe
printf("Successfully connected to the named pipe\n");
return true;
}

DWORD error = GetLastError();
if (error == ERROR_FILE_NOT_FOUND)
{
// The named pipe does not exist, so start the server application
// Read the path of the server application from the registry
printf("The named pipe does not exist, so start the server application\n");
HKEY hKey;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\PassThruSupport.04.04\\XplatformsPassThruOverIP", 0, KEY_READ, &hKey) == ERROR_SUCCESS ||
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\PassThruSupport.05.00\\XplatformsPassThruOverIP", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
char path[MAX_PATH];
DWORD pathSize = sizeof(path);
if (RegQueryValueExA(hKey, "ConfigApplication", NULL, NULL, (LPBYTE)path, &pathSize) == ERROR_SUCCESS) {
// Start the server application
printf("Start the server application %s\n", path);
STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (!CreateProcessA(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
// Failed to start the server application
printf("Failed to start the server application. Error: %d\n", GetLastError());
return false;
} else {
// Successfully started the server application
printf("Successfully started the server application %s\n", path);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
RegCloseKey(hKey);
}
} else if (error == ERROR_PIPE_BUSY) {
// The pipe is busy, all instances are connected
// Wait for a while and then try again
printf("The named pipe is busy, waiting for a while and then try again\n");
} else {
// Some other error occurred
printf("ExPipeClient CreateFile Failed! Error: %d\n", (int)error);
return false;
}

// Sleep for a while and then try again
std::this_thread::sleep_for(sleepDuration);
}

// Reached the maximum number of attempts without successfully connecting
printf("ExPipeClient Failed to connect to named pipe after %d attempts\n", maxAttempts);
return false;
// });

printf("future.get!");
//return future.get();
}



void ExPipeClient::disconnect() {
if (pipe != INVALID_HANDLE_VALUE) {
CloseHandle(pipe);
pipe = INVALID_HANDLE_VALUE;
}
}

void ExPipeClient::send(const ExPipeClient::Message& msg)
{
cn_cbor_errback cn_errback = {0};
cn_cbor* cb = cn_cbor_map_create(&cn_errback);

cn_cbor_map_put(cb, cn_cbor_string_create("id", &cn_errback), cn_cbor_int_create(msg.id, &cn_errback), &cn_errback);
cn_cbor_map_put(cb, cn_cbor_string_create("type", &cn_errback), cn_cbor_int_create(msg.type, &cn_errback), &cn_errback);
cn_cbor_map_put(cb, cn_cbor_string_create("data_type", &cn_errback), cn_cbor_int_create(msg.data_type, &cn_errback), &cn_errback);
cn_cbor_map_put(cb, cn_cbor_string_create("path", &cn_errback), cn_cbor_string_create(msg.path.c_str(), &cn_errback), &cn_errback);
cn_cbor_map_put(cb, cn_cbor_string_create("message", &cn_errback), cn_cbor_string_create(msg.message.c_str(), &cn_errback), &cn_errback);
cn_cbor_map_put(cb, cn_cbor_string_create("data", &cn_errback), cn_cbor_data_create(reinterpret_cast<const uint8_t*>(msg.data.data()), msg.data.size(), &cn_errback), &cn_errback);

auto cbor_size = cn_cbor_encoder_write(nullptr, 0, 0, cb);
if(cbor_size != -1)
{
uint8_t * cbor = new uint8_t[cbor_size];
memset(cbor,0,cbor_size);
cn_cbor_encoder_write(cbor, 0, cbor_size, cb);

// Write the message length (as a 4-byte integer) before the message
DWORD bytesWritten;
int size = static_cast<int>(cbor_size);
if (!WriteFile(pipe, &size, sizeof(size), &bytesWritten, nullptr) ||
bytesWritten != sizeof(size)) {
// Handle error
printf("Can't WRITE SIZE TO PIPE!!!!");
delete[] cbor;
return;
}

// Write the message
if (!WriteFile(pipe, cbor, cbor_size, &bytesWritten, nullptr) ||
bytesWritten != cbor_size) {
// Handle error
printf("Can't WRITE TO PIPE!!!!");
}

delete[] cbor;
}
}


ExPipeClient::Message ExPipeClient::receive() {
DWORD bytesRead;
DWORD bytesAvailable;

// Check how many bytes are available to be read
if (!PeekNamedPipe(pipe, NULL, 0, NULL, &bytesAvailable, NULL)) {
// Handle error
}

// If not enough bytes are available to read the size of the message, return an empty message
if (bytesAvailable < sizeof(int)) {
return ExPipeClient::Message{};
}

int size;
if (!ReadFile(pipe, &size, sizeof(size), &bytesRead, nullptr) || bytesRead != sizeof(size)) {
// Handle error
}

// Check again how many bytes are available to be read
if (!PeekNamedPipe(pipe, NULL, 0, NULL, &bytesAvailable, NULL)) {
// Handle error
}

// If not enough bytes are available to read the message, return an empty message
if (bytesAvailable < size) {
return ExPipeClient::Message{};
}

std::vector<char> buffer(size);
if (!ReadFile(pipe, buffer.data(), size, &bytesRead, nullptr) || bytesRead != size) {
// Handle error
}

cn_cbor_errback errp;
cn_cbor* cb = cn_cbor_decode((const uint8_t*)buffer.data(), bytesRead, &errp);
ExPipeClient::Message msg;
msg.path = cn_cbor_mapget_string(cb, "path")->v.str;
msg.id = cn_cbor_mapget_string(cb, "id")->v.sint;
msg.type = cn_cbor_mapget_string(cb, "type")->v.sint;
msg.message = cn_cbor_mapget_string(cb, "message")->v.str;
cn_cbor* data_cb = cn_cbor_mapget_string(cb, "data");
msg.data = std::vector<uint8_t>(data_cb->v.str, data_cb->v.str + data_cb->length);

return msg;
}


48 changes: 48 additions & 0 deletions j2534_OverIP/expipeclient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef EXPIPECLIENT_H
#define EXPIPECLIENT_H

#include <windows.h>
#include <string>
#include <vector>
#include <cn-cbor/cn-cbor.h>

class ExPipeClient {
public:
enum {KEY_FuncName, KEY_Param1, KEY_Param2, KEY_Param3, KEY_Param4, KEY_Param5, KEY_Param6, KEY_Param7};

enum {KEY_PassThruOpen = 10, KEY_PassThruClose, KEY_PassThruSelect, KEY_PassThruConnect, KEY_PassThruDisconnect, KEY_PassThruGetLastError, KEY_PassThruIoctl,
KEY_PassThruReadMsgs, KEY_PassThruReadVersion, KEY_PassThruSetProgrammingVoltage, KEY_PassThruStartMsgFilter, KEY_PassThruStartPeriodicMsg, KEY_PassThruStopMsgFilter,
KEY_PassThruStopPeriodicMsg, KEY_PassThruScanForDevices, KEY_PassThruGetNextDevice, KEY_PassThruWriteMsgs, KEY_PassThruExConfigureWiFi, KEY_PassThruExDeviceWatchdog,
KEY_PassThruExDownloadCypheredFlashData, KEY_PassThruExEraseFlash, KEY_PassThruExInitiateCypheredFlashDownload, KEY_PassThruExReadFlash, KEY_PassThruExResetFlash,
KEY_PassThruExRunSelfTest, KEY_PassThruExWriteFlash, KEY_PassThruLoadFirmware, KEY_PassThruRecoverFirmware, KEY_PassThruReadIPSetup, KEY_PassThruWriteIPSetup,
KEY_PassThruReadPCSetup, KEY_PassThruGetPointer, KEY_PassThruGetNextCarDAQ, KEY_PassThruReadDetails, KEY_PassThruQueueMsgs};

public:
struct Message {
uint32_t id; // crc32 sum from 'path' parameter
uint32_t type; // type of the message
uint32_t data_type; // type of data. 0 = string, 1 = cbor, 2 = cbor j2534 functions struct
int64_t timestamp;
std::string path; // name of the client
std::string message;
std::vector<uint8_t> data; // unknown custom data
};

explicit ExPipeClient(const std::string& name);
~ExPipeClient();

// Deleted copy constructor and assignment operator
ExPipeClient(const ExPipeClient&) = delete;
ExPipeClient& operator=(const ExPipeClient&) = delete;

bool connect();
void disconnect();
void send(const Message& msg);
Message receive();

private:
HANDLE pipe;
std::string name;
};

#endif // EXPIPECLIENT_H
Loading

0 comments on commit 925f01a

Please sign in to comment.