Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aaa858b903 |
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ LIBS=deps/tomlc99/libtoml.a deps/ptQueue/out/ptQueue.a deps/wsServer/libws.a
|
|||||||
LIBS_HEADERS=deps/ $(OPENSSL_INCLUDE)
|
LIBS_HEADERS=deps/ $(OPENSSL_INCLUDE)
|
||||||
STATIC_LIBS=crypto
|
STATIC_LIBS=crypto
|
||||||
STANDART=c23
|
STANDART=c23
|
||||||
OPTIMIZE=-Og
|
OPTIMIZE=-O3
|
||||||
TARGET=main
|
TARGET=main
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
hmmmm_scripts
Submodule
1
hmmmm_scripts
Submodule
Submodule hmmmm_scripts added at 9cc7b36cbb
21
inc/base_device.h
Normal file
21
inc/base_device.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef __BASE_DEVICE_H__
|
||||||
|
#define __BASE_DEVICE_H__
|
||||||
|
|
||||||
|
#include "hmmmm.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* specs;
|
||||||
|
device_lib_t* lib;
|
||||||
|
device_public_context_t* ctx;
|
||||||
|
uint64_t clockCycleLimit;
|
||||||
|
uint64_t clockCycleCounter;
|
||||||
|
} device_handle_t;
|
||||||
|
|
||||||
|
|
||||||
|
device_handle_t* openBaseDeviceFromConfig(const char* configPath, char* errbuf);
|
||||||
|
device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf);
|
||||||
|
conf_dev_t* openBaseDeviceConfig(const char* configPath, char* errbuf);
|
||||||
|
void closeBaseDevice(device_handle_t* devHandle);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __BASE_DEVICE_H__
|
||||||
10
inc/client.h
10
inc/client.h
@@ -2,25 +2,17 @@
|
|||||||
#define __CLIENT_H__
|
#define __CLIENT_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "sized_ptr.h"
|
|
||||||
|
|
||||||
#include "wsServer/include/ws.h"
|
#include "wsServer/include/ws.h"
|
||||||
#include "ptQueue/inc/ptQueue.h"
|
#include "ptQueue/inc/ptQueue.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ws_cli_conn_t clientId;
|
ws_cli_conn_t clientId;
|
||||||
uint64_t seatId;
|
|
||||||
uint8_t isAuthed;
|
uint8_t isAuthed;
|
||||||
ptQueue* incomeQ;
|
ptQueue* incomeQ;
|
||||||
// ptQueue* outcomeQ;
|
ptQueue* outcomeQ;
|
||||||
uint64_t connectedAt;
|
uint64_t connectedAt;
|
||||||
uint32_t streamRegIterator;
|
uint32_t streamRegIterator;
|
||||||
uint64_t orphanedAt;
|
|
||||||
uint64_t orphanedDeadTimeout;
|
|
||||||
SizedPtr* fallbackOutcomeQ;
|
|
||||||
size_t fallbackOutcomeQPadding;
|
|
||||||
} ClientContext;
|
} ClientContext;
|
||||||
|
|
||||||
#endif //ifndef __CLIENT_H__
|
#endif //ifndef __CLIENT_H__
|
||||||
41
inc/compose_device.h
Normal file
41
inc/compose_device.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef __COMPOSE_DEVICE_H__
|
||||||
|
#define __COMPOSE_DEVICE_H__
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t limiter;
|
||||||
|
} clock_conf_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char** baseAt;
|
||||||
|
char* baseSeg;
|
||||||
|
char** target;
|
||||||
|
uint64_t projectionShift;
|
||||||
|
|
||||||
|
} projection_conf_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
char** baseAt;
|
||||||
|
char** pointAt;
|
||||||
|
uint64_t addr;
|
||||||
|
char* seg;
|
||||||
|
|
||||||
|
} intercept_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
clock_conf_t clockConf;
|
||||||
|
conf_dev_t** baseConfigs;
|
||||||
|
projection_conf_t** projections;
|
||||||
|
intercept_conf_t** intercepts;
|
||||||
|
} compose_dev_conf_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
device_handle_t** devHandlers;
|
||||||
|
} compose_dev_handle_t;
|
||||||
|
|
||||||
|
compose_dev_conf_t* openComposeDeviceConfig(const char* configPath, char* errbuf);
|
||||||
|
device_handle_t** openComposeDevice(compose_dev_conf_t* conf, char* errbuf);
|
||||||
|
|
||||||
|
#endif // ifndef __COMPOSE_DEVICE_H__
|
||||||
36
inc/config.h
Normal file
36
inc/config.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __HMMMM_CONFIG_H__
|
||||||
|
#define __HMMMM_CONFIG_H__
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* name;
|
||||||
|
size_t start;
|
||||||
|
size_t len;
|
||||||
|
uint8_t wordLen;
|
||||||
|
uint8_t isExecutable;
|
||||||
|
} conf_mem_seg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
conf_mem_seg_t** memSegConfs;
|
||||||
|
} conf_mem_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char** id;
|
||||||
|
char** clockId;
|
||||||
|
uint64_t clockDivider;
|
||||||
|
uint64_t clockMultipler;
|
||||||
|
conf_mem_t* memConf;
|
||||||
|
char* libPath;
|
||||||
|
} conf_dev_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void freeMemSegConf(conf_mem_seg_t* memSegConf);
|
||||||
|
void freeMemConf(conf_mem_t* memConf);
|
||||||
|
void freeConf(conf_dev_t* conf);
|
||||||
|
void freeComposeId(char** id);
|
||||||
|
uint8_t compareComposeId(char** idA, char** idB);
|
||||||
|
|
||||||
|
#endif // ifndef __HMMMM_CONFIG_H__
|
||||||
@@ -38,7 +38,6 @@ typedef struct {
|
|||||||
ptQueue* regQueue;
|
ptQueue* regQueue;
|
||||||
uint8_t* accessToken;
|
uint8_t* accessToken;
|
||||||
EmulContext* emulContext;
|
EmulContext* emulContext;
|
||||||
_Atomic (uint64_t) seatCounter;
|
|
||||||
} ServerContext;
|
} ServerContext;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
0
inc/executor/executor.h
Normal file
0
inc/executor/executor.h
Normal file
33
inc/hmmmm.h
Normal file
33
inc/hmmmm.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __HMMMMM__
|
||||||
|
#define __HMMMMM__
|
||||||
|
#include "libhmmmm.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void* (*extractPcounterPtr)(device_public_context_t* devContext);
|
||||||
|
|
||||||
|
size_t (*extractPcounter)(device_public_context_t* devContext);
|
||||||
|
size_t (*extractOpcode)(device_mem_t* devMem, size_t _programCounter);
|
||||||
|
uint8_t (*extractPcounterSizeWords)();
|
||||||
|
|
||||||
|
|
||||||
|
} instruction_simul_handlers_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t devType;
|
||||||
|
device_public_context_t* (*init)(void*, char* errbuf);
|
||||||
|
uint8_t (*makeDeviceTick)(device_public_context_t* devInfo);
|
||||||
|
void* extendedHandlers;
|
||||||
|
device_public_context_t* devContext;
|
||||||
|
void* _dlhandl;
|
||||||
|
void* (*parseSpecsFromConfig)(const conf_dev_t* devConf, char* errbuf);
|
||||||
|
void (*freeSpecs)(void* specs);
|
||||||
|
void (*freeDevMem)(device_mem_t* mem);
|
||||||
|
void (*fillSmartReadSpecs)(void* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount);
|
||||||
|
void (*fillSmartWriteSpecs)(void* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount);
|
||||||
|
} device_lib_t;
|
||||||
|
|
||||||
|
device_lib_t* loadDeviceLib(const char *libpath, char* errbuf);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __HMMMMM__
|
||||||
37
inc/libdevice.h
Normal file
37
inc/libdevice.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef __LIBDEVICE_H__
|
||||||
|
#define __LIBDEVICE_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "libmem.h"
|
||||||
|
|
||||||
|
#define SMART_ADDR_TYPE_GLOBAL 1
|
||||||
|
#define SMART_ADDR_TYPE_SEGMENTED 2
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t addr;
|
||||||
|
uint8_t segno;
|
||||||
|
uint64_t localAddr;
|
||||||
|
uint8_t addrType;
|
||||||
|
mem_h_read_func* handler;
|
||||||
|
uint64_t ident;
|
||||||
|
} smart_read_spec_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t addr;
|
||||||
|
uint8_t segno;
|
||||||
|
uint64_t localAddr;
|
||||||
|
uint8_t addrType;
|
||||||
|
mem_h_write_func handler;
|
||||||
|
uint64_t ident;
|
||||||
|
} smart_write_spec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
device_mem_t* deviceMem;
|
||||||
|
void* deviceInfo;
|
||||||
|
} device_public_context_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __LIBDEVICE_H__
|
||||||
|
|
||||||
14
inc/libhmmmm.h
Normal file
14
inc/libhmmmm.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __LIB_HMMMMM__
|
||||||
|
#define __LIB_HMMMMM__
|
||||||
|
|
||||||
|
#include "libmem.h"
|
||||||
|
#include "libdevice.h"
|
||||||
|
|
||||||
|
#define EXTENDED_DEVICE_TYPE_DUMMY 0
|
||||||
|
#define EXTENDED_DEVICE_TYPE_INSTR_SIMUL 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ifndef __LIB_HMMMMM__
|
||||||
52
inc/libmem.h
Normal file
52
inc/libmem.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#ifndef __LIBMEM_H__
|
||||||
|
#define __LIBMEM_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define GET_BIT(n, b) ((n >> b) & 1)
|
||||||
|
|
||||||
|
// Internal mem handlers
|
||||||
|
typedef void* (*mem_h_read_func)(uint64_t ident, uint64_t addr, void* rawCells);
|
||||||
|
typedef void (*mem_h_write_func)(uint64_t ident, uint64_t addr, void* rawCells, void* data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mem_h_read_func func;
|
||||||
|
uint64_t ident;
|
||||||
|
} mem_h_read_handler;
|
||||||
|
typedef struct {
|
||||||
|
mem_h_write_func func;
|
||||||
|
uint64_t ident;
|
||||||
|
} mem_h_write_handler;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void* rawCells;
|
||||||
|
void** cells;
|
||||||
|
uint64_t smartAddrReadMask;
|
||||||
|
uint64_t smartAddrWriteMask;
|
||||||
|
mem_h_read_handler* smartAddrReadHandlers;
|
||||||
|
mem_h_write_handler* smartAddrWriteHandlers;
|
||||||
|
char** memsegNames;
|
||||||
|
uint64_t* memsegShifts;
|
||||||
|
uint64_t* memreadCellAddrs;
|
||||||
|
uint64_t* memwriteCellAddrs;
|
||||||
|
uint8_t memreadLen;
|
||||||
|
uint8_t memwriteLen;
|
||||||
|
} device_mem_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t len;
|
||||||
|
uint8_t wordLen;
|
||||||
|
char* name;
|
||||||
|
} memseg_spec_t;
|
||||||
|
|
||||||
|
|
||||||
|
// External handlers
|
||||||
|
typedef void* (*ext_h_read_func)(uint64_t addr, void* rawCells, void* devContext);
|
||||||
|
typedef void (*ext_h_write_func)(uint64_t addr, void* rawCells, void* data, void* devContext);
|
||||||
|
|
||||||
|
#endif // ifndef __LIBMEM_H__
|
||||||
@@ -6,6 +6,6 @@
|
|||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
void broadcastClients(EmulContext* emulContext, uint8_t* msg, size_t msgLen);
|
void broadcastClients(EmulContext* emulContext, uint8_t* msg, size_t msgLen);
|
||||||
void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ClientContext* client, uint8_t* msg, size_t msgLen);
|
void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ws_cli_conn_t clientIdx, uint8_t* msg, size_t msgLen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
#define CTRL_TYPE_EXEC 0b0001
|
#define CTRL_TYPE_EXEC 0b0001
|
||||||
#define CTRL_TYPE_NOTIF_STATE 0b0010
|
#define CTRL_TYPE_NOTIF_STATE 0b0010
|
||||||
#define CTRL_TYPE_LIST_ORPHANED 0b1001
|
|
||||||
#define CTRL_TYPE_LOAD_FAILED 0b1010
|
|
||||||
#define CTRL_TYPE_SETUP_CONNECTION 0b1011
|
|
||||||
|
|
||||||
#define NOTIF_TYPE_EXEC 0b0000
|
#define NOTIF_TYPE_EXEC 0b0000
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "proto/msg.h"
|
#include "proto/msg.h"
|
||||||
#include "proto/dial.h"
|
#include "proto/dial.h"
|
||||||
|
|
||||||
void handleIncomingControlMessage(BaseMessage* msg, ClientContext* ctx, EmulContext* emulContext);
|
void handleIncomingControlMessage(BaseMessage* msg, EmulContext* emulContext);
|
||||||
|
|
||||||
|
|
||||||
#endif //ifndef __PROTO_HANDLERS_CONTROL_H__
|
#endif //ifndef __PROTO_HANDLERS_CONTROL_H__
|
||||||
@@ -3,10 +3,9 @@
|
|||||||
|
|
||||||
#include "wsServer/include/ws.h"
|
#include "wsServer/include/ws.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ClientContext* client;
|
ws_cli_conn_t clientIdx;
|
||||||
uint8_t* msg;
|
uint8_t* msg;
|
||||||
size_t msgLen;
|
size_t msgLen;
|
||||||
} OutgoingMessage;
|
} OutgoingMessage;
|
||||||
@@ -20,10 +19,8 @@ typedef struct {
|
|||||||
} BaseMessage;
|
} BaseMessage;
|
||||||
|
|
||||||
BaseMessage* parseMessage(const uint8_t* bytes, size_t size);
|
BaseMessage* parseMessage(const uint8_t* bytes, size_t size);
|
||||||
void fillHead(uint64_t nonce, uint8_t packetType, uint8_t payloadHeader, uint8_t* outmsg);
|
|
||||||
uint8_t* createControlNotifyMessage(uint64_t nonce, uint64_t clockCounter, uint8_t newEmulState, size_t* lenOut);
|
uint8_t* createControlNotifyMessage(uint64_t nonce, uint64_t clockCounter, uint8_t newEmulState, size_t* lenOut);
|
||||||
uint8_t* createDoneRegMessage(uint64_t nonce, uint8_t X, uint64_t devId, uint64_t segId, uint64_t startAddr, uint64_t segLength, uint32_t regId, size_t* lenOut);
|
uint8_t* createDoneRegMessage(uint64_t nonce, uint8_t X, uint64_t devId, uint64_t segId, uint64_t startAddr, uint64_t segLength, uint32_t regId, size_t* lenOut);
|
||||||
uint8_t* createStreamSegmentPush(uint8_t mode, uint32_t regId, uint64_t clockCounter, uint8_t* payload, size_t payloadLen, size_t* lenOut);
|
uint8_t* createStreamSegmentPush(uint8_t mode, uint32_t regId, uint64_t clockCounter, uint8_t* payload, size_t payloadLen, size_t* lenOut);
|
||||||
uint8_t* createClientSetup(uint64_t nonce, ClientContext* ctx, size_t* lenOut);
|
|
||||||
|
|
||||||
#endif //ifndef __PROTO_MSG_H__
|
#endif //ifndef __PROTO_MSG_H__
|
||||||
276
src/base_device.c
Normal file
276
src/base_device.c
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "tomlc99/toml.h"
|
||||||
|
|
||||||
|
#include "base_device.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
device_handle_t* openBaseDeviceFromConfig(const char* configPath, char* errbuf)
|
||||||
|
{
|
||||||
|
char intErrbuf[1024];
|
||||||
|
|
||||||
|
conf_dev_t *devConf = openBaseDeviceConfig(configPath, intErrbuf);
|
||||||
|
if (devConf == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to read device config: %s", intErrbuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_handle_t* ret = openBaseDevice(devConf, intErrbuf);
|
||||||
|
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
freeConf(devConf);
|
||||||
|
free(devConf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeBaseDevice(device_handle_t* devHandle)
|
||||||
|
{
|
||||||
|
if(devHandle->ctx != NULL)
|
||||||
|
{
|
||||||
|
if(devHandle->specs != NULL)
|
||||||
|
{
|
||||||
|
devHandle->lib->freeSpecs(devHandle->specs);
|
||||||
|
}
|
||||||
|
if(devHandle->ctx->deviceMem != NULL)
|
||||||
|
{
|
||||||
|
devHandle->lib->freeDevMem(devHandle->ctx->deviceMem);
|
||||||
|
}
|
||||||
|
free(devHandle->ctx);
|
||||||
|
}
|
||||||
|
if(devHandle->lib->extendedHandlers != NULL)
|
||||||
|
{
|
||||||
|
free(devHandle->lib->extendedHandlers);
|
||||||
|
}
|
||||||
|
dlclose(devHandle->lib->_dlhandl);
|
||||||
|
free(devHandle->lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
||||||
|
{
|
||||||
|
device_handle_t* ret = malloc(sizeof(device_handle_t));
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device handle struct");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char intErrbuf[512];
|
||||||
|
|
||||||
|
device_lib_t* devLib = loadDeviceLib(devConf->libPath, intErrbuf);
|
||||||
|
if (devLib == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load device library %s: %s", devConf->libPath, intErrbuf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* devSpecs = devLib->parseSpecsFromConfig(devConf, intErrbuf);
|
||||||
|
|
||||||
|
if (devSpecs == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "device config parse error: %s", intErrbuf);
|
||||||
|
dlclose(devLib->_dlhandl);
|
||||||
|
free(ret);
|
||||||
|
free(devLib);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ret->lib = devLib;
|
||||||
|
ret->specs = devSpecs;
|
||||||
|
ret->clockCycleCounter = 0;
|
||||||
|
ret->clockCycleLimit = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
conf_mem_seg_t** parseMemToml(const toml_table_t* memTable)
|
||||||
|
{
|
||||||
|
uint16_t memSegIdx = 0;
|
||||||
|
const char* memSegKey = toml_key_in(memTable, 0);
|
||||||
|
while (memSegKey && memSegIdx < 0xFFFF)
|
||||||
|
{
|
||||||
|
memSegIdx++;
|
||||||
|
memSegKey = toml_key_in(memTable, memSegIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_mem_seg_t** segConfigs = malloc(sizeof(conf_mem_seg_t*) * ((size_t)memSegIdx + 1));
|
||||||
|
if (segConfigs == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
segConfigs[memSegIdx] = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < memSegIdx; i++)
|
||||||
|
{
|
||||||
|
segConfigs[i] = (conf_mem_seg_t*)malloc(sizeof(conf_mem_seg_t));
|
||||||
|
memSegKey = toml_key_in(memTable, (int)i);
|
||||||
|
|
||||||
|
if (segConfigs[i] == NULL || memSegKey == NULL)
|
||||||
|
{
|
||||||
|
if (segConfigs[i] != NULL)
|
||||||
|
{
|
||||||
|
free(segConfigs[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
for(size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
free(segConfigs[j]->name);
|
||||||
|
free(segConfigs[j]);
|
||||||
|
}
|
||||||
|
free(segConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
segConfigs[i]->name = (char*)malloc(strlen(memSegKey) + 1);
|
||||||
|
if (segConfigs[i]->name == NULL)
|
||||||
|
{
|
||||||
|
for(size_t j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
if (j < i)
|
||||||
|
free(segConfigs[j]->name);
|
||||||
|
free(segConfigs[j]);
|
||||||
|
}
|
||||||
|
free(segConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(segConfigs[i]->name, memSegKey);
|
||||||
|
|
||||||
|
toml_table_t* segTable = toml_table_in(memTable, memSegKey);
|
||||||
|
if (segTable == NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
for(size_t j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
free(segConfigs[j]->name);
|
||||||
|
free(segConfigs[j]);
|
||||||
|
}
|
||||||
|
free(segConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t startDatum = toml_int_in(segTable, "start");
|
||||||
|
toml_datum_t lenDatum = toml_int_in(segTable, "len");
|
||||||
|
toml_datum_t wordLenDatum = toml_int_in(segTable, "wordLen");
|
||||||
|
toml_datum_t executableDatum = toml_bool_in(segTable, "executable");
|
||||||
|
|
||||||
|
if (!startDatum.ok || !lenDatum.ok || !wordLenDatum.ok)
|
||||||
|
{
|
||||||
|
for(size_t j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
free(segConfigs[j]->name);
|
||||||
|
free(segConfigs[j]);
|
||||||
|
}
|
||||||
|
free(segConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
segConfigs[i]->start = (size_t)startDatum.u.i;
|
||||||
|
segConfigs[i]->len = (size_t)lenDatum.u.i;
|
||||||
|
segConfigs[i]->wordLen = (uint8_t)wordLenDatum.u.i;
|
||||||
|
segConfigs[i]->isExecutable = 0;
|
||||||
|
if (executableDatum.ok)
|
||||||
|
{
|
||||||
|
segConfigs[i]->isExecutable = executableDatum.u.b != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return segConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
conf_dev_t* openBaseDeviceConfig(const char* configPath, char* errbuf)
|
||||||
|
{
|
||||||
|
conf_dev_t* ret = malloc(sizeof(conf_dev_t));
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device conf struct");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->id = NULL;
|
||||||
|
ret->clockDivider = 1;
|
||||||
|
ret->clockMultipler = 1;
|
||||||
|
ret->clockId = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
ret->memConf = malloc(sizeof(conf_mem_t));
|
||||||
|
if (ret->memConf == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device memory conf struct");
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char intErrbuf[1024];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FILE *fp = fopen (configPath, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
sprintf(errbuf, "unable to open config file %s", configPath);
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
toml_table_t* conf = toml_parse_file(fp, intErrbuf, sizeof(intErrbuf));
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
|
sprintf(errbuf, "cannot parse - %s", intErrbuf);
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t* devBlock = toml_table_in(conf, "dev");
|
||||||
|
if (!devBlock) {
|
||||||
|
sprintf(errbuf, "missing [dev]");
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t* memTable = toml_table_in(conf, "mem");
|
||||||
|
if (!memTable) {
|
||||||
|
sprintf(errbuf, "missing [mem]");
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t libpathBlock = toml_string_in(devBlock, "libpath");
|
||||||
|
if (!libpathBlock.ok) {
|
||||||
|
sprintf(errbuf, "unable to read dev.libpath");
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_mem_seg_t** memSegConfs = parseMemToml(memTable);
|
||||||
|
if (memSegConfs == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to parse mem segments");
|
||||||
|
free(ret->memConf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->memConf->memSegConfs = memSegConfs;
|
||||||
|
ret->libPath = libpathBlock.u.s;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
529
src/compose_device.c
Normal file
529
src/compose_device.c
Normal file
@@ -0,0 +1,529 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tomlc99/toml.h"
|
||||||
|
|
||||||
|
#include "base_device.h"
|
||||||
|
#include "compose_device.h"
|
||||||
|
|
||||||
|
|
||||||
|
// void fillDevClockConfig(const toml_table_t* clockTable, conf_dev_t** devConfs)
|
||||||
|
// {
|
||||||
|
// uint16_t clockSegIdx = 0;
|
||||||
|
// uint16_t clockSegSkips = 0;
|
||||||
|
// const char* clockSegKey = toml_key_in(clockTable, 0);
|
||||||
|
// while (clockSegKey && (clockSegIdx + clockSegSkips) < 0xFFFF)
|
||||||
|
// {
|
||||||
|
// clockSegKey = toml_key_in(clockTable, clockSegIdx + clockSegSkips + 1);
|
||||||
|
// if(strcmp(clockSegKey, "limiter") != 0)
|
||||||
|
// {
|
||||||
|
// clockSegIdx++;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// clockSegSkips++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
char** appendId(char** prev, const char* cur, char* errbuf)
|
||||||
|
{
|
||||||
|
if(prev == NULL)
|
||||||
|
{
|
||||||
|
prev = malloc(sizeof(char*) * 2);
|
||||||
|
if(prev == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate id");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
prev[0] = NULL;
|
||||||
|
prev[1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t clockIdLen = 0;
|
||||||
|
while (prev[clockIdLen] != NULL){clockIdLen++;}
|
||||||
|
|
||||||
|
clockIdLen++;
|
||||||
|
|
||||||
|
char** new = realloc(prev, sizeof(char*) * (clockIdLen + 1));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to reallocate id");
|
||||||
|
freeComposeId(prev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
prev = new;
|
||||||
|
|
||||||
|
prev[clockIdLen] = NULL;
|
||||||
|
size_t idLen = strlen(cur);
|
||||||
|
prev[clockIdLen - 1] = malloc(sizeof(char) * (idLen + 1));
|
||||||
|
if(prev[clockIdLen - 1] == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate new id entry");
|
||||||
|
freeComposeId(prev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(prev[clockIdLen - 1], cur);
|
||||||
|
prev[clockIdLen - 1][idLen] = '\0';
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_dev_t** parseDevToml(const toml_table_t* devTable, const toml_table_t* clockTable, char* errbuf)
|
||||||
|
{
|
||||||
|
uint16_t devSegIdx = 0;
|
||||||
|
const char* devSegKey = toml_key_in(devTable, 0);
|
||||||
|
while (devSegKey && devSegIdx < 0xFFFF)
|
||||||
|
{
|
||||||
|
devSegIdx++;
|
||||||
|
devSegKey = toml_key_in(devTable, devSegIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_dev_t** deviceConfigs = malloc(sizeof(conf_dev_t*) * (devSegIdx + 1));
|
||||||
|
if(deviceConfigs == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceConfigs[devSegIdx] = NULL;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < devSegIdx; i++)
|
||||||
|
{
|
||||||
|
devSegKey = toml_key_in(devTable, (int)i);
|
||||||
|
if(devSegKey == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load device key %lu", i);
|
||||||
|
for(size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
freeConf(deviceConfigs[j]);
|
||||||
|
free(deviceConfigs[j]);
|
||||||
|
}
|
||||||
|
free(deviceConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
toml_datum_t devpathDatum = toml_string_in(devTable, devSegKey);
|
||||||
|
if(!devpathDatum.ok || !devpathDatum.u.s)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to get device path for %s", devSegKey);
|
||||||
|
|
||||||
|
for(size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
freeConf(deviceConfigs[j]);
|
||||||
|
free(deviceConfigs[j]);
|
||||||
|
}
|
||||||
|
free(deviceConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char intErrbuf[1024];
|
||||||
|
|
||||||
|
conf_dev_t* conf = openBaseDeviceConfig(devpathDatum.u.s, intErrbuf);
|
||||||
|
if(conf == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load config for %s: %s", devSegKey, intErrbuf);
|
||||||
|
|
||||||
|
for(size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
freeConf(deviceConfigs[j]);
|
||||||
|
free(deviceConfigs[j]);
|
||||||
|
}
|
||||||
|
free(deviceConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->id = NULL;
|
||||||
|
conf->id = appendId(conf->id, devSegKey, intErrbuf);
|
||||||
|
|
||||||
|
|
||||||
|
if(conf->id == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device %s name field", devSegKey);
|
||||||
|
for(size_t j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
freeConf(deviceConfigs[j]);
|
||||||
|
free(deviceConfigs[j]);
|
||||||
|
}
|
||||||
|
free(deviceConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceConfigs[i] = conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(clockTable != NULL)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < devSegIdx; i++)
|
||||||
|
{
|
||||||
|
conf_dev_t* conf = deviceConfigs[i];
|
||||||
|
toml_table_t* devClockTable = toml_table_in(clockTable, conf->id[0]);
|
||||||
|
if(devClockTable == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t dividerDatum = toml_int_in(devClockTable, "divider");
|
||||||
|
if(dividerDatum.ok)
|
||||||
|
{
|
||||||
|
conf->clockDivider = (uint64_t)dividerDatum.u.i;
|
||||||
|
}
|
||||||
|
toml_datum_t multiplerDatum = toml_int_in(devClockTable, "multipler");
|
||||||
|
if(multiplerDatum.ok)
|
||||||
|
{
|
||||||
|
conf->clockMultipler = (uint64_t)multiplerDatum.u.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t srcDatum = toml_string_in(devClockTable, "src");
|
||||||
|
if(srcDatum.ok && srcDatum.u.s != NULL)
|
||||||
|
{
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
conf->clockId = appendId(conf->clockId, srcDatum.u.s, intErrbuf);
|
||||||
|
if(conf->clockId == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to append clock id for %s: %s", conf->id[0], intErrbuf);
|
||||||
|
for(size_t j = 0; j <= i; j++)
|
||||||
|
{
|
||||||
|
freeConf(deviceConfigs[j]);
|
||||||
|
free(deviceConfigs[j]);
|
||||||
|
}
|
||||||
|
free(deviceConfigs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceConfigs;
|
||||||
|
}
|
||||||
|
void freeProjectionConfig(projection_conf_t* conf)
|
||||||
|
{
|
||||||
|
if(conf == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
freeComposeId(conf->target);
|
||||||
|
freeComposeId(conf->baseAt);
|
||||||
|
if(conf->baseSeg != NULL)
|
||||||
|
{
|
||||||
|
free(conf->baseSeg);
|
||||||
|
}
|
||||||
|
conf->target = NULL;
|
||||||
|
conf->baseAt = NULL;
|
||||||
|
conf->baseSeg = NULL;
|
||||||
|
free(conf);
|
||||||
|
}
|
||||||
|
void freeProjectionConfigs(projection_conf_t** confs)
|
||||||
|
{
|
||||||
|
if(confs == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t i = 0;
|
||||||
|
while(confs[i] != NULL)
|
||||||
|
{
|
||||||
|
freeProjectionConfig(confs[i]);
|
||||||
|
confs[i] = NULL;
|
||||||
|
}
|
||||||
|
free(confs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
projection_conf_t* parseDeviceProjectionConf(const toml_table_t* deviceProjectionTable, char* errbuf)
|
||||||
|
{
|
||||||
|
toml_datum_t baseAtDatum = toml_string_in(deviceProjectionTable, "base_at");
|
||||||
|
if(!baseAtDatum.ok || baseAtDatum.u.s == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "missing 'base_at'");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t baseSegDatum = toml_string_in(deviceProjectionTable, "base_seg");
|
||||||
|
if(!baseSegDatum.ok || baseSegDatum.u.s == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "missing 'base_seg'");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_datum_t projectionShiftDatum = toml_int_in(deviceProjectionTable, "projection_shift");
|
||||||
|
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
|
||||||
|
projection_conf_t* ret = malloc(sizeof(projection_conf_t));
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate projection conf");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret->baseAt = NULL;
|
||||||
|
ret->baseSeg = NULL;
|
||||||
|
ret->target = NULL;
|
||||||
|
ret->projectionShift = 0;
|
||||||
|
|
||||||
|
if(projectionShiftDatum.ok)
|
||||||
|
{
|
||||||
|
ret->projectionShift = (uint64_t)projectionShiftDatum.u.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->baseAt = appendId(ret->baseAt, baseAtDatum.u.s, intErrbuf);
|
||||||
|
if(ret->baseAt == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to append base_at id");
|
||||||
|
freeProjectionConfig(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret->baseSeg = malloc(strlen(baseSegDatum.u.s));
|
||||||
|
if(ret->baseSeg == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to fill base_seg");
|
||||||
|
freeProjectionConfig(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(ret->baseSeg, baseSegDatum.u.s);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
projection_conf_t** parseDeviceProjectionConfs(const toml_table_t* deviceProjectionsTable, char* errbuf)
|
||||||
|
{
|
||||||
|
uint16_t projSegIdx = 0;
|
||||||
|
const char* projSegKey = toml_key_in(deviceProjectionsTable, 0);
|
||||||
|
while (projSegKey && projSegIdx < 0xFFFF)
|
||||||
|
{
|
||||||
|
projSegIdx++;
|
||||||
|
projSegKey = toml_key_in(deviceProjectionsTable, projSegIdx);
|
||||||
|
}
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
|
||||||
|
projection_conf_t** ret = malloc(sizeof(projection_conf_t*) * (projSegIdx + 1));
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device projections confs");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = 0; i <= projSegIdx; i++){ret[i] = NULL;}
|
||||||
|
|
||||||
|
for(size_t i = 0; i < projSegIdx; i++)
|
||||||
|
{
|
||||||
|
projSegKey = toml_key_in(deviceProjectionsTable, (int)i);
|
||||||
|
if(projSegKey == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load device projection key %lu", i);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t* projTable = toml_table_in(deviceProjectionsTable, projSegKey);
|
||||||
|
if(projTable == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to open device %s projection table", projSegKey);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[i] = parseDeviceProjectionConf(projTable, intErrbuf);
|
||||||
|
if(ret[i] == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load device %s projection configs: %s", projSegKey, intErrbuf);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[i]->target = appendId(ret[i]->target, projSegKey, intErrbuf);
|
||||||
|
if(ret[i]->target == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to append projection target id: %s", intErrbuf);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
projection_conf_t** parseProjectionConfs(const toml_table_t* projectionTable, char* errbuf)
|
||||||
|
{
|
||||||
|
uint16_t devicesProjSegIdx = 0;
|
||||||
|
const char* devicesProjSegKey = toml_key_in(projectionTable, 0);
|
||||||
|
while (devicesProjSegKey && devicesProjSegIdx < 0xFFFF)
|
||||||
|
{
|
||||||
|
devicesProjSegIdx++;
|
||||||
|
devicesProjSegKey = toml_key_in(projectionTable, devicesProjSegIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
|
||||||
|
size_t totalRetSize = 0;
|
||||||
|
projection_conf_t** ret = malloc(sizeof(projection_conf_t*));
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate base projection conf array");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret[0] = NULL;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < devicesProjSegIdx; i++)
|
||||||
|
{
|
||||||
|
devicesProjSegKey = toml_key_in(projectionTable, (int)i);
|
||||||
|
if(devicesProjSegKey == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load proj key %lu", i);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml_table_t* deviceProjTable = toml_table_in(projectionTable, devicesProjSegKey);
|
||||||
|
if(deviceProjTable == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to open device projection table");
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
projection_conf_t** devProjections = parseDeviceProjectionConfs(deviceProjTable, intErrbuf);
|
||||||
|
|
||||||
|
if(devProjections == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to parse device %s projection rules: %s", devicesProjSegKey, intErrbuf);
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size_t dlen = 0;
|
||||||
|
while(devProjections[dlen] != NULL)
|
||||||
|
{
|
||||||
|
devProjections[dlen]->target = appendId(devProjections[dlen]->target, devicesProjSegKey, intErrbuf);
|
||||||
|
if(devProjections[dlen]->target == NULL)
|
||||||
|
{
|
||||||
|
freeProjectionConfigs(ret);
|
||||||
|
freeProjectionConfigs(devProjections);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dlen++;
|
||||||
|
}
|
||||||
|
ret = realloc(ret, sizeof(projection_conf_t*) * (dlen + totalRetSize + 1));
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to reallocate full projection array");
|
||||||
|
freeProjectionConfigs(devProjections);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i <= dlen; i++)
|
||||||
|
{
|
||||||
|
ret[totalRetSize + i] = devProjections[i];
|
||||||
|
}
|
||||||
|
totalRetSize += dlen;
|
||||||
|
ret[totalRetSize] = NULL;
|
||||||
|
free(devProjections);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_dev_conf_t* openComposeDeviceConfig(const char* configPath, char* errbuf)
|
||||||
|
{
|
||||||
|
compose_dev_conf_t* ret = malloc(sizeof(compose_dev_conf_t));
|
||||||
|
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device struct");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
FILE *fp = fopen (configPath, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
sprintf(errbuf, "unable to open config file %s", configPath);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
toml_table_t* conf = toml_parse_file(fp, intErrbuf, sizeof(intErrbuf));
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
|
||||||
|
toml_table_t* devTable = toml_table_in(conf, "dev");
|
||||||
|
if (!devTable) {
|
||||||
|
sprintf(errbuf, "missing [dev]");
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret->projections = NULL;
|
||||||
|
|
||||||
|
toml_table_t* memTable = toml_table_in(conf, "mem");
|
||||||
|
if(memTable)
|
||||||
|
{
|
||||||
|
toml_table_t* projectionTable = toml_table_in(memTable, "projection");
|
||||||
|
if(projectionTable)
|
||||||
|
{
|
||||||
|
ret->projections = parseProjectionConfs(projectionTable, intErrbuf);
|
||||||
|
if(ret->projections == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load projections: %s", intErrbuf);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toml_table_t* clockTable = toml_table_in(conf, "clock");
|
||||||
|
|
||||||
|
|
||||||
|
conf_dev_t** devHandlers = parseDevToml(devTable, clockTable, intErrbuf);
|
||||||
|
|
||||||
|
if(devHandlers == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to load devices configs: %s", intErrbuf);
|
||||||
|
freeProjectionConfigs(ret->projections);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->baseConfigs = devHandlers;
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
device_handle_t** openComposeDevice(compose_dev_conf_t* conf, char* errbuf)
|
||||||
|
{
|
||||||
|
size_t devIdx = 0;
|
||||||
|
while(conf->baseConfigs[devIdx] != NULL){devIdx++;}
|
||||||
|
|
||||||
|
device_handle_t** devHandlers = malloc(sizeof(device_handle_t*) * (devIdx + 1));
|
||||||
|
|
||||||
|
if(devHandlers == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate dev handlers");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
devHandlers[devIdx] = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < devIdx; i++)
|
||||||
|
{
|
||||||
|
conf_dev_t* devConf = conf->baseConfigs[i];
|
||||||
|
char intErrbuf[1024] = {0};
|
||||||
|
device_handle_t* devHandle = openBaseDevice(devConf, intErrbuf);
|
||||||
|
if(devHandle == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to open base device %s: %s", devConf->id[0], intErrbuf);
|
||||||
|
for(size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
closeBaseDevice(devHandlers[j]);
|
||||||
|
free(devHandlers[j]);
|
||||||
|
}
|
||||||
|
free(devHandlers);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
devHandlers[i] = devHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return devHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
86
src/config.c
Normal file
86
src/config.c
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
void xfree(void* p)
|
||||||
|
{
|
||||||
|
if(p != NULL)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeComposeId(char** id)
|
||||||
|
{
|
||||||
|
if(id == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t i = 0;
|
||||||
|
while(id[i] != NULL)
|
||||||
|
{
|
||||||
|
free(id[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
free(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t compareComposeId(char** idA, char** idB)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while(idA[i] != NULL && idB[i] != NULL)
|
||||||
|
{
|
||||||
|
if(strcmp(idA[i], idB[i]) != 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return idA[i] == NULL && idB[i] == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeMemSegConf(conf_mem_seg_t* memSegConf)
|
||||||
|
{
|
||||||
|
if(memSegConf == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xfree(memSegConf->name);
|
||||||
|
}
|
||||||
|
void freeMemConf(conf_mem_t* memConf)
|
||||||
|
{
|
||||||
|
if(memConf == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < 0xFF && memConf->memSegConfs[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
freeMemSegConf(memConf->memSegConfs[i]);
|
||||||
|
}
|
||||||
|
xfree(memConf->memSegConfs);
|
||||||
|
free(memConf);
|
||||||
|
}
|
||||||
|
void freeConf(conf_dev_t* conf)
|
||||||
|
{
|
||||||
|
if(conf == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(conf->clockId != NULL)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while(conf->clockId[i] != NULL)
|
||||||
|
{
|
||||||
|
free(conf->clockId[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
free(conf->clockId);
|
||||||
|
}
|
||||||
|
freeComposeId(conf->id);
|
||||||
|
xfree(conf->libPath);
|
||||||
|
freeMemConf(conf->memConf);
|
||||||
|
free(conf);
|
||||||
|
}
|
||||||
0
src/executor/executor.c
Normal file
0
src/executor/executor.c
Normal file
238
src/hmmmm.c
Normal file
238
src/hmmmm.c
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
#include "hmmmm.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef size_t (*_dlib_pubExtractPcounter_t)(device_public_context_t* devContext);
|
||||||
|
typedef size_t (*_dlib_pubExtractOpcode_t)(device_mem_t* devMem, size_t _programCounter);
|
||||||
|
|
||||||
|
typedef uint8_t(*_dlib_pubExtractPcounterSizeWords_t)();
|
||||||
|
|
||||||
|
typedef device_public_context_t* (*_dlib_dev_init_t)(void* specs, char* errbuf);
|
||||||
|
|
||||||
|
typedef uint8_t (*_dlib_makeDeviceTick_t)(device_public_context_t* devInfo);
|
||||||
|
|
||||||
|
typedef uint8_t (*_dlib_deviceType_t)();
|
||||||
|
|
||||||
|
typedef void* (*_dlib_pubExtractPcounterPtr_t)(device_public_context_t* devContext);
|
||||||
|
|
||||||
|
typedef void* (*_dlib_parseSpecsFromConfig_t)(const conf_dev_t* devConf, char* errbuf);
|
||||||
|
|
||||||
|
typedef void (*_dlib_freeSpecs_t)(void* specs);
|
||||||
|
typedef void (*_dlib_freeDevMem_t)(device_mem_t* mem);
|
||||||
|
|
||||||
|
typedef void (*_dlib_fillSmartReadSpecs_t)(void* specs, smart_read_spec_t* smartReadSpecs, uint64_t smartReadSpecsCount);
|
||||||
|
typedef void (*_dlib_fillSmartWriteSpecs_t)(void* specs, smart_write_spec_t* smartWriteSpecs, uint64_t smartWriteSpecsCount);
|
||||||
|
|
||||||
|
instruction_simul_handlers_t* _fillInstructionSimul(void* handle)
|
||||||
|
{
|
||||||
|
instruction_simul_handlers_t* ret = malloc(sizeof(instruction_simul_handlers_t));
|
||||||
|
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dlib_pubExtractPcounterPtr_t _dlib_pubExtractPcounterPtr = (_dlib_pubExtractPcounterPtr_t)(uintptr_t)dlsym(handle, "pubExtractPcounterPtr");
|
||||||
|
|
||||||
|
const char *dlib_pubExtractPcounterPtr_error = dlerror();
|
||||||
|
if (dlib_pubExtractPcounterPtr_error) {
|
||||||
|
dlclose(handle);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->extractPcounterPtr = _dlib_pubExtractPcounterPtr;
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_pubExtractPcounter_t _dlib_pubExtractPcounter = (_dlib_pubExtractPcounter_t)(uintptr_t)dlsym(handle, "pubExtractPcounter");
|
||||||
|
|
||||||
|
const char *dlib_pubExtractPcounter_error = dlerror();
|
||||||
|
if (dlib_pubExtractPcounter_error) {
|
||||||
|
dlclose(handle);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->extractPcounter = _dlib_pubExtractPcounter;
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_pubExtractOpcode_t _dlib_pubExtractOpcode = (_dlib_pubExtractOpcode_t)(uintptr_t)dlsym(handle, "pubExtractOpcode");
|
||||||
|
|
||||||
|
const char *dlib_pubExtractOpcode_error = dlerror();
|
||||||
|
if (dlib_pubExtractOpcode_error) {
|
||||||
|
dlclose(handle);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->extractOpcode = _dlib_pubExtractOpcode;
|
||||||
|
|
||||||
|
_dlib_pubExtractPcounterSizeWords_t _dlib_pubExtractPcounterSizeWords = (_dlib_pubExtractPcounterSizeWords_t)(uintptr_t)dlsym(handle, "pubExtractPcounterSizeWords");
|
||||||
|
|
||||||
|
const char *dlib_pubExtractPcounterSizeWords_error = dlerror();
|
||||||
|
if (dlib_pubExtractPcounterSizeWords_error) {
|
||||||
|
dlclose(handle);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->extractPcounterSizeWords = _dlib_pubExtractPcounterSizeWords;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||||
|
{
|
||||||
|
device_lib_t* dev = malloc(sizeof(device_lib_t));
|
||||||
|
|
||||||
|
if (dev == NULL)
|
||||||
|
{
|
||||||
|
sprintf(errbuf, "unable to allocate device lib struct");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *handle = dlopen(libpath, RTLD_NOW);
|
||||||
|
|
||||||
|
if (!handle) {
|
||||||
|
sprintf(errbuf, "unable to open dl handle");
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlerror();
|
||||||
|
|
||||||
|
_dlib_dev_init_t _dlib_dev_init = (_dlib_dev_init_t)(uintptr_t)dlsym(handle, "init");
|
||||||
|
|
||||||
|
const char *dlsym_init_error = dlerror();
|
||||||
|
if (dlsym_init_error) {
|
||||||
|
sprintf(errbuf, "unable to find init symbol: %s", dlsym_init_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dlib_makeDeviceTick_t _dlib_makeDeviceTick = (_dlib_makeDeviceTick_t)(uintptr_t)dlsym(handle, "makeDeviceTick");
|
||||||
|
|
||||||
|
|
||||||
|
const char *dlsym_maketick_error = dlerror();
|
||||||
|
if (dlsym_maketick_error) {
|
||||||
|
sprintf(errbuf, "unable to find makeDeviceTick symbol: %s", dlsym_maketick_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_parseSpecsFromConfig_t _dlib_parseSpecsFromConfig = (_dlib_parseSpecsFromConfig_t)(uintptr_t)dlsym(handle, "parseSpecsFromConfig");
|
||||||
|
|
||||||
|
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
||||||
|
if (_dlib_parseSpecsFromConfig_error) {
|
||||||
|
sprintf(errbuf, "unable to find parseSpecsFromConfig symbol: %s", _dlib_parseSpecsFromConfig_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_fillSmartReadSpecs_t _dlib_fillSmartReadSpecs = (_dlib_fillSmartReadSpecs_t)(uintptr_t)dlsym(handle, "fillSmartReadSpecs");
|
||||||
|
|
||||||
|
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
||||||
|
if (_dlib_fillSmartReadSpecs_error) {
|
||||||
|
sprintf(errbuf, "unable to find fillSmartReadSpecs symbol: %s", _dlib_fillSmartReadSpecs_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_fillSmartWriteSpecs_t _dlib_fillSmartWriteSpecs = (_dlib_fillSmartWriteSpecs_t)(uintptr_t)dlsym(handle, "fillSmartWriteSpecs");
|
||||||
|
|
||||||
|
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
||||||
|
if (_dlib_fillSmartWriteSpecs_error) {
|
||||||
|
sprintf(errbuf, "unable to find fillSmartWriteSpecs symbol: %s", _dlib_fillSmartWriteSpecs_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_deviceType_t _dlib_deviceType = (_dlib_deviceType_t)(uintptr_t)dlsym(handle, "pubDeviceType");
|
||||||
|
|
||||||
|
const char *dlib_deviceType_error = dlerror();
|
||||||
|
if (dlib_deviceType_error) {
|
||||||
|
sprintf(errbuf, "unable to find pubDeviceType symbol: %s", dlib_deviceType_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_freeSpecs_t _dlib_freeSpecs = (_dlib_freeSpecs_t)(uintptr_t)dlsym(handle, "freeDevSpecs");
|
||||||
|
|
||||||
|
const char *dlib_freeSpecs_error = dlerror();
|
||||||
|
if (dlib_freeSpecs_error) {
|
||||||
|
sprintf(errbuf, "unable to find freeSpecs symbol: %s", dlib_freeSpecs_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_dlib_freeDevMem_t _dlib_freeDevMem = (_dlib_freeDevMem_t)(uintptr_t)dlsym(handle, "freeDevSpecs");
|
||||||
|
|
||||||
|
const char *dlib_freeDevMem_error = dlerror();
|
||||||
|
if (dlib_freeDevMem_error) {
|
||||||
|
sprintf(errbuf, "unable to find freeDevMem symbol: %s", dlib_freeDevMem_error);
|
||||||
|
dlclose(handle);
|
||||||
|
free(dev);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->devContext = NULL;
|
||||||
|
dev->init = _dlib_dev_init;
|
||||||
|
dev->makeDeviceTick = _dlib_makeDeviceTick;
|
||||||
|
dev->parseSpecsFromConfig = _dlib_parseSpecsFromConfig;
|
||||||
|
dev->fillSmartReadSpecs = _dlib_fillSmartReadSpecs;
|
||||||
|
dev->fillSmartWriteSpecs = _dlib_fillSmartWriteSpecs;
|
||||||
|
dev->freeSpecs = _dlib_freeSpecs;
|
||||||
|
dev->freeDevMem = _dlib_freeDevMem;
|
||||||
|
|
||||||
|
uint8_t devType = _dlib_deviceType();
|
||||||
|
|
||||||
|
dev->devType = devType;
|
||||||
|
|
||||||
|
if (devType == EXTENDED_DEVICE_TYPE_DUMMY)
|
||||||
|
{
|
||||||
|
dev->extendedHandlers = NULL;
|
||||||
|
}
|
||||||
|
else if (devType == EXTENDED_DEVICE_TYPE_INSTR_SIMUL)
|
||||||
|
{
|
||||||
|
dev->extendedHandlers = _fillInstructionSimul(handle);
|
||||||
|
if (dev->extendedHandlers == NULL)
|
||||||
|
{
|
||||||
|
free(dev);
|
||||||
|
dlclose(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(dev);
|
||||||
|
dlclose(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->_dlhandl = handle;
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
@@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
void removeLinkedListEntry(LinkedListEntry** head, LinkedListEntry* entry)
|
void removeLinkedListEntry(LinkedListEntry** head, LinkedListEntry* entry)
|
||||||
{
|
{
|
||||||
if(entry == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// check for head
|
// check for head
|
||||||
if(entry->prevEntry != NULL)
|
if(entry->prevEntry != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
857
src/main.c
857
src/main.c
@@ -7,21 +7,37 @@
|
|||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
// #define OPCODE_WORDSIZE 2
|
||||||
|
// #define MEM_CELL_WORDS 1
|
||||||
|
|
||||||
|
// #include "abc.h"
|
||||||
|
// #include "instr.h"
|
||||||
|
// #include "mem.h"
|
||||||
|
// #include "runner.h"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
// #include "runner.h"
|
||||||
|
#include "hmmmm.h"
|
||||||
|
|
||||||
#include "my_mutex.h"
|
#include "my_mutex.h"
|
||||||
|
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "tomlc99/toml.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "compose_device.h"
|
||||||
|
|
||||||
#include "linkedlist.h"
|
#include "linkedlist.h"
|
||||||
|
|
||||||
#include "ptQueue/inc/ptQueue.h"
|
#include "ptQueue/inc/ptQueue.h"
|
||||||
#include "wsServer/include/ws.h"
|
#include "wsServer/include/ws.h"
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -49,6 +65,93 @@
|
|||||||
#include "proto/pack.h"
|
#include "proto/pack.h"
|
||||||
|
|
||||||
|
|
||||||
|
void printMemory(void* cells, uint64_t cellsCount)
|
||||||
|
{
|
||||||
|
|
||||||
|
for(uint64_t i = 0; i < cellsCount; i++)
|
||||||
|
{
|
||||||
|
printf("%lu: 0x%04X", i, ((uint8_t*)cells)[i]);
|
||||||
|
|
||||||
|
// uint8_t wasRead = 0;
|
||||||
|
// for (uint8_t j = 0; j < mem->memreadLen; j++)
|
||||||
|
// {
|
||||||
|
// if(mem->memreadCellAddrs[j] == i)
|
||||||
|
// {
|
||||||
|
// wasRead = 1;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// uint8_t wasWrite = 0;
|
||||||
|
// for (uint8_t j = 0; j < mem->memwriteLen; j++)
|
||||||
|
// {
|
||||||
|
// if(mem->memwriteCellAddrs[j] == i)
|
||||||
|
// {
|
||||||
|
// wasWrite = 1;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (wasRead == 1)
|
||||||
|
// {
|
||||||
|
// printf("\t[was read]");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// printf("\t[was not read]");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (wasWrite == 1)
|
||||||
|
// {
|
||||||
|
// printf("\t[was written]");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// printf("\t[was not written]");
|
||||||
|
// }
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void dummyWriteHandler(uint64_t ident, uint64_t addr, void* rawCells, void* data)
|
||||||
|
{
|
||||||
|
// printf("Intercepted write on 0x%lx: 0x%02x\n", addr, *((uint8_t*)data));
|
||||||
|
printf("Intercepted write on 0x%lx: ", addr);
|
||||||
|
printf("0b");
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
printf("%d", (*((uint8_t*)data) >> (7 - i)) & 1);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
((uint8_t*)rawCells)[addr] = *((uint8_t*)data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ext_h_read_func* interceptReadRouter;
|
||||||
|
ext_h_write_func* interceptWriteRouter;
|
||||||
|
void** iterceptDevContextRouter;
|
||||||
|
|
||||||
|
void* readExt(uint64_t ident, uint64_t addr, void* rawCells)
|
||||||
|
{
|
||||||
|
void* devContext = iterceptDevContextRouter[ident];
|
||||||
|
ext_h_read_func tgt = interceptReadRouter[ident];
|
||||||
|
return tgt(addr, rawCells, devContext);
|
||||||
|
}
|
||||||
|
void writeExt(uint64_t ident, uint64_t addr, void* rawCells, void* data)
|
||||||
|
{
|
||||||
|
void* devContext = iterceptDevContextRouter[ident];
|
||||||
|
ext_h_write_func tgt = interceptWriteRouter[ident];
|
||||||
|
tgt(addr, rawCells, data, devContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// void *threadMain(void *param);
|
||||||
|
|
||||||
void my_sleep(int microseconds) {
|
void my_sleep(int microseconds) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@@ -76,102 +179,18 @@ void* outgoingMain(void* args)
|
|||||||
OutgoingMessage* messages = curBuf->ptr;
|
OutgoingMessage* messages = curBuf->ptr;
|
||||||
for(size_t i = 0; i < curBuf->size; i++)
|
for(size_t i = 0; i < curBuf->size; i++)
|
||||||
{
|
{
|
||||||
|
// my_sleep(100000);
|
||||||
|
|
||||||
OutgoingMessage *outMsg = &messages[i];
|
OutgoingMessage *outMsg = &messages[i];
|
||||||
if(outMsg->msg == NULL && outMsg->msgLen != 0)
|
if(outMsg->msg == NULL)
|
||||||
{
|
{
|
||||||
panic("Got double read on buf %d while writing on buf %d\n", currBufIdx, currWritingIdxPtr);
|
panic("Got double read on buf %d while writing on buf %d\n", currBufIdx, currWritingIdxPtr);
|
||||||
}
|
}
|
||||||
|
// printf("\t%lu -> [%lu]\n", outMsg->msgLen, outMsg->clientIdx);
|
||||||
ClientContext* client = outMsg->client;
|
ws_sendframe_bin(outMsg->clientIdx, (const char*)outMsg->msg, outMsg->msgLen);
|
||||||
|
// printf("running free on buf %d message %lu\n", currBufIdx, i);
|
||||||
SizedPtr* fallbackMsgQueuePtr = client->fallbackOutcomeQ;
|
|
||||||
OutgoingMessage* fallbackMsgQueue = (OutgoingMessage*)fallbackMsgQueuePtr->ptr;
|
|
||||||
|
|
||||||
// try to deliver failed message
|
|
||||||
|
|
||||||
if (ws_get_state(client->clientId) == WS_STATE_OPEN)
|
|
||||||
{
|
|
||||||
|
|
||||||
while(client->orphanedAt != 0 && client->fallbackOutcomeQ->size > client->fallbackOutcomeQPadding)
|
|
||||||
{
|
|
||||||
printf("Trying to resend clients fallbacked packets\n");
|
|
||||||
OutgoingMessage* fallbackedMessage = &fallbackMsgQueue[client->fallbackOutcomeQPadding];
|
|
||||||
int written = ws_sendframe_bin(client->clientId, (const char*)fallbackedMessage->msg, fallbackedMessage->msgLen);
|
|
||||||
if(written == -1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(fallbackedMessage->msg);
|
|
||||||
fallbackedMessage->msg = NULL;
|
|
||||||
client->fallbackOutcomeQPadding++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for all delivered
|
|
||||||
if(client->fallbackOutcomeQPadding >= client->fallbackOutcomeQ->size)
|
|
||||||
{
|
|
||||||
// clear fallback queue if all delivered
|
|
||||||
client->fallbackOutcomeQ->size = 0;
|
|
||||||
|
|
||||||
// was a fluke, remove orphaned time
|
|
||||||
client->orphanedAt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to send original message
|
|
||||||
int written = -1;
|
|
||||||
|
|
||||||
|
|
||||||
if(outMsg->msg == NULL)
|
|
||||||
{
|
|
||||||
printf("removed client %lu\n", client->seatId);
|
|
||||||
for(size_t j = 0; j < client->fallbackOutcomeQ->size; j++)
|
|
||||||
{
|
|
||||||
free(fallbackMsgQueue[j].msg);
|
|
||||||
}
|
|
||||||
free(client->fallbackOutcomeQ->ptr);
|
|
||||||
free(client->fallbackOutcomeQ);
|
|
||||||
ptQueueFree(client->incomeQ);
|
|
||||||
free(client);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(client->orphanedAt == 0)
|
|
||||||
{
|
|
||||||
// printf("send is allowed for client %lu (seat %lu)\n", client->clientId, client->seatId);
|
|
||||||
// try only with an active connection
|
|
||||||
written = ws_sendframe_bin(client->clientId, (const char*)outMsg->msg, outMsg->msgLen);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// printf("no send is allowed for client %lu (seat %lu)\n", client->clientId, client->seatId);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if(written == -1)
|
|
||||||
{
|
|
||||||
// printf("No data was sent for client %lu (seat %lu)\n", client->clientId, client->seatId);
|
|
||||||
// dispatch message to failed if not sent
|
|
||||||
if(fallbackMsgQueuePtr->size + 1 < fallbackMsgQueuePtr->allocatedSize)
|
|
||||||
{
|
|
||||||
fallbackMsgQueue[fallbackMsgQueuePtr->size] = *outMsg;
|
|
||||||
fallbackMsgQueuePtr->size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set orphaned time
|
|
||||||
if(client->orphanedAt == 0 && fallbackMsgQueuePtr->size > 8)
|
|
||||||
{
|
|
||||||
printf("Set client as orphaned\n");
|
|
||||||
client->orphanedAt = (uint64_t)time(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(outMsg->msg);
|
free(outMsg->msg);
|
||||||
outMsg->msg = NULL;
|
outMsg->msg = NULL;
|
||||||
}
|
// printf("done free on buf %d message %lu\n", currBufIdx, i);
|
||||||
}
|
}
|
||||||
curBuf->size = 0;
|
curBuf->size = 0;
|
||||||
atomic_store(&outBufs->readRequestIdx, currBufIdx);
|
atomic_store(&outBufs->readRequestIdx, currBufIdx);
|
||||||
@@ -233,13 +252,14 @@ void dispatchStreamSegment(EmulContext* emulContext, StreamReg* reg, uint8_t* me
|
|||||||
{
|
{
|
||||||
size_t mlen = 0;
|
size_t mlen = 0;
|
||||||
uint8_t* msg = createStreamSegmentPush(reg->mode, reg->regId, *emulContext->clockCounter, mem + reg->startAddr, reg->segLen, &mlen);
|
uint8_t* msg = createStreamSegmentPush(reg->mode, reg->regId, *emulContext->clockCounter, mem + reg->startAddr, reg->segLen, &mlen);
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, reg->clientContext, msg, mlen);
|
dispatchOutgoingMessage(emulContext->outBufs, reg->clientContext->clientId, msg, mlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg* deviceRegs, uint8_t* mem, uint64_t* addrs, size_t addrsLen, uint8_t mode)
|
void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg* deviceRegs, uint8_t* mem, uint64_t* addrs, size_t addrsLen, uint8_t mode)
|
||||||
{
|
{
|
||||||
if(deviceRegs->regCount == 0)
|
if(deviceRegs->regCount == 0)
|
||||||
{
|
{
|
||||||
|
// printf("No stream regs\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StreamReg** dispatchRegs = alloca(sizeof(StreamReg*) * deviceRegs->regCount);
|
StreamReg** dispatchRegs = alloca(sizeof(StreamReg*) * deviceRegs->regCount);
|
||||||
@@ -275,6 +295,11 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(dispatchRegsCnt == 0)
|
||||||
|
// {
|
||||||
|
// printf("No memory dispatched\n");
|
||||||
|
// }
|
||||||
|
|
||||||
for(size_t i = 0; i < dispatchRegsCnt; i++)
|
for(size_t i = 0; i < dispatchRegsCnt; i++)
|
||||||
{
|
{
|
||||||
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
||||||
@@ -316,10 +341,10 @@ int main(int argc, char** argv)
|
|||||||
uint8_t emulState = EMUL_STATE_STILL;
|
uint8_t emulState = EMUL_STATE_STILL;
|
||||||
|
|
||||||
|
|
||||||
uint8_t* device0mem = malloc(sizeof(uint8_t) * 1024 * 1024);
|
uint8_t* device0mem = malloc(sizeof(uint8_t) * 1024 * 128);
|
||||||
NULL_GUARD(device0mem);
|
NULL_GUARD(device0mem);
|
||||||
|
|
||||||
uint8_t* device1mem = malloc(sizeof(uint8_t) * 1024 * 1024);
|
uint8_t* device1mem = malloc(sizeof(uint8_t) * 1024 * 128);
|
||||||
NULL_GUARD(device1mem);
|
NULL_GUARD(device1mem);
|
||||||
|
|
||||||
uint8_t** devicesMem = malloc(sizeof(uint8_t*) * deviceCount);
|
uint8_t** devicesMem = malloc(sizeof(uint8_t*) * deviceCount);
|
||||||
@@ -327,18 +352,18 @@ int main(int argc, char** argv)
|
|||||||
devicesMem[0] = device0mem;
|
devicesMem[0] = device0mem;
|
||||||
devicesMem[1] = device1mem;
|
devicesMem[1] = device1mem;
|
||||||
|
|
||||||
uint64_t* device0readAddrs = malloc(sizeof(uint64_t) * 1024);
|
uint64_t* device0readAddrs = malloc(sizeof(uint64_t) * 128);
|
||||||
NULL_GUARD(device0readAddrs);
|
NULL_GUARD(device0readAddrs);
|
||||||
size_t device0readAddrsLen = 0;
|
size_t device0readAddrsLen = 0;
|
||||||
uint64_t* device0writeAddrs = malloc(sizeof(uint64_t) * 1024);
|
uint64_t* device0writeAddrs = malloc(sizeof(uint64_t) * 128);
|
||||||
NULL_GUARD(device0writeAddrs);
|
NULL_GUARD(device0writeAddrs);
|
||||||
size_t device0writeAddrsLen = 0;
|
size_t device0writeAddrsLen = 0;
|
||||||
|
|
||||||
|
|
||||||
uint64_t* device1readAddrs = malloc(sizeof(uint64_t) * 1024);
|
uint64_t* device1readAddrs = malloc(sizeof(uint64_t) * 128);
|
||||||
NULL_GUARD(device1readAddrs);
|
NULL_GUARD(device1readAddrs);
|
||||||
size_t device1readAddrsLen = 0;
|
size_t device1readAddrsLen = 0;
|
||||||
uint64_t* device1writeAddrs = malloc(sizeof(uint64_t) * 1024);
|
uint64_t* device1writeAddrs = malloc(sizeof(uint64_t) * 128);
|
||||||
NULL_GUARD(device1writeAddrs);
|
NULL_GUARD(device1writeAddrs);
|
||||||
size_t device1writeAddrsLen = 0;
|
size_t device1writeAddrsLen = 0;
|
||||||
|
|
||||||
@@ -358,7 +383,7 @@ int main(int argc, char** argv)
|
|||||||
for(size_t j = 0; j < bufs[i].allocatedSize; j++)
|
for(size_t j = 0; j < bufs[i].allocatedSize; j++)
|
||||||
{
|
{
|
||||||
messages[j].msgLen = 0xFFFF;
|
messages[j].msgLen = 0xFFFF;
|
||||||
messages[j].client = NULL;
|
messages[j].clientIdx = 0xFFFF;
|
||||||
messages[j].msg = NULL;
|
messages[j].msg = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,7 +420,6 @@ int main(int argc, char** argv)
|
|||||||
regQ,
|
regQ,
|
||||||
(uint8_t*)&access_token,
|
(uint8_t*)&access_token,
|
||||||
&emulContext,
|
&emulContext,
|
||||||
0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pthread_t outTid;
|
pthread_t outTid;
|
||||||
@@ -405,13 +429,12 @@ int main(int argc, char** argv)
|
|||||||
pthread_create(&outTid, &outAttr, outgoingMain, &outBufs);
|
pthread_create(&outTid, &outAttr, outgoingMain, &outBufs);
|
||||||
pthread_detach(outTid);
|
pthread_detach(outTid);
|
||||||
|
|
||||||
const uint64_t pingTimeoutMs = 1000;
|
|
||||||
|
|
||||||
ws_socket(&(struct ws_server){
|
ws_socket(&(struct ws_server){
|
||||||
.host = "localhost",
|
.host = "localhost",
|
||||||
.port = 8181,
|
.port = 8181,
|
||||||
.thread_loop = 1,
|
.thread_loop = 1,
|
||||||
.timeout_ms = pingTimeoutMs,
|
.timeout_ms = 1000,
|
||||||
.context = &ctx,
|
.context = &ctx,
|
||||||
.evs.onopen = &onWsOpen,
|
.evs.onopen = &onWsOpen,
|
||||||
.evs.onclose = &onWsClose,
|
.evs.onclose = &onWsClose,
|
||||||
@@ -420,17 +443,8 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
ptQueueElem* regQueueTail = regQ->tail;
|
ptQueueElem* regQueueTail = regQ->tail;
|
||||||
|
|
||||||
uint64_t lastPingAt = 0;
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(((uint64_t)time(NULL) - lastPingAt) * 1000 > pingTimeoutMs)
|
|
||||||
{
|
|
||||||
ws_ping(0, 3);
|
|
||||||
lastPingAt = (uint64_t)time(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientRegistrationEvent* payload = regQueueTail->payload;
|
ClientRegistrationEvent* payload = regQueueTail->payload;
|
||||||
if(payload != NULL)
|
if(payload != NULL)
|
||||||
{
|
{
|
||||||
@@ -454,7 +468,13 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
newWriteIdx = 0;
|
newWriteIdx = 0;
|
||||||
}
|
}
|
||||||
|
// printf("Switching write idx %d->%d\n", oldWriteIdx, newWriteIdx);
|
||||||
|
|
||||||
|
|
||||||
|
// if(readReqIdx == newWriteIdx)
|
||||||
|
// {
|
||||||
|
// printf("Flood control breach, waiting until outgoing buffers empty!\n");
|
||||||
|
// }
|
||||||
while(readReqIdx == newWriteIdx)
|
while(readReqIdx == newWriteIdx)
|
||||||
{
|
{
|
||||||
my_sleep(1000);
|
my_sleep(1000);
|
||||||
@@ -467,6 +487,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if(emulState == EMUL_STATE_EXEC)
|
if(emulState == EMUL_STATE_EXEC)
|
||||||
{
|
{
|
||||||
|
printf("Running...\n");
|
||||||
device0readAddrsLen = 0;
|
device0readAddrsLen = 0;
|
||||||
device0writeAddrsLen = 0;
|
device0writeAddrsLen = 0;
|
||||||
|
|
||||||
@@ -499,3 +520,619 @@ int main(int argc, char** argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// int main(int argc, char** argv)
|
||||||
|
// {
|
||||||
|
// char errbuf[1024];
|
||||||
|
|
||||||
|
// pthread_t tid; /* идентификатор потока */
|
||||||
|
// pthread_attr_t attr; /* отрибуты потока */
|
||||||
|
|
||||||
|
|
||||||
|
// ptQueue* qOut = ptQueueCreate(errbuf);
|
||||||
|
// ptQueue* qIn = ptQueueCreate(errbuf);
|
||||||
|
|
||||||
|
// ptQueue** ptArgs = malloc(sizeof(ptQueue*) * 2);
|
||||||
|
// if(ptArgs == NULL)
|
||||||
|
// {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// ptArgs[0] = qOut;
|
||||||
|
// ptArgs[1] = qIn;
|
||||||
|
|
||||||
|
// pthread_attr_init(&attr);
|
||||||
|
// pthread_create(&tid, &attr, threadMain, ptArgs);
|
||||||
|
|
||||||
|
|
||||||
|
// for(int i = 1; i < 4096; i++)
|
||||||
|
// {
|
||||||
|
// int* pass = malloc(sizeof(int));
|
||||||
|
// if(pass == NULL)
|
||||||
|
// {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// *pass = i;
|
||||||
|
|
||||||
|
// ptQueuePush(qOut, pass, errbuf);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int* ii = malloc(sizeof(int));
|
||||||
|
// if(ii == NULL)
|
||||||
|
// {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// *ii = 0;
|
||||||
|
|
||||||
|
// ptQueuePush(qOut, ii, errbuf);
|
||||||
|
|
||||||
|
// ptQueueElem* tailIn = qIn->tail;
|
||||||
|
|
||||||
|
// while (1)
|
||||||
|
// {
|
||||||
|
// void* payload = atomic_load(&(tailIn->payload));
|
||||||
|
// if(payload == NULL)
|
||||||
|
// {
|
||||||
|
// my_sleep(100);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// int* code = payload;
|
||||||
|
|
||||||
|
// printf("<Done reading %d\n", *code);
|
||||||
|
|
||||||
|
|
||||||
|
// int* pass = malloc(sizeof(int));
|
||||||
|
// if(pass != NULL)
|
||||||
|
// {
|
||||||
|
// *pass = *code;
|
||||||
|
// ptQueuePush(qOut, pass, errbuf);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(*code == 0)
|
||||||
|
// {
|
||||||
|
// free(payload);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// free(payload);
|
||||||
|
// ptQueueElem* newTail = atomic_load(&(tailIn->nextEl));
|
||||||
|
// if (newTail == NULL)
|
||||||
|
// {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// free(tailIn);
|
||||||
|
// tailIn = newTail;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pthread_join(tid, NULL);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// void *threadMain(void *param)
|
||||||
|
// {
|
||||||
|
// char errubf[1024];
|
||||||
|
// ptQueue** params = param;
|
||||||
|
// ptQueue* qIn = params[0];
|
||||||
|
// ptQueue* qOut = params[1];
|
||||||
|
// ptQueueElem* tailIn = atomic_load(&(qIn->head));
|
||||||
|
|
||||||
|
// while (1)
|
||||||
|
// {
|
||||||
|
// void* payload = atomic_load(&(tailIn->payload));
|
||||||
|
// if(payload == NULL)
|
||||||
|
// {
|
||||||
|
// my_sleep(100);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// int* code = payload;
|
||||||
|
|
||||||
|
// printf(">Done reading %d\n", *code);
|
||||||
|
|
||||||
|
|
||||||
|
// int* pass = malloc(sizeof(int));
|
||||||
|
// if(pass != NULL)
|
||||||
|
// {
|
||||||
|
// *pass = *code;
|
||||||
|
// ptQueuePush(qOut, pass, errubf);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(*code == 0)
|
||||||
|
// {
|
||||||
|
// free(payload);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// free(payload);
|
||||||
|
// ptQueueElem* newTail = atomic_load(&(tailIn->nextEl));
|
||||||
|
// if (newTail == NULL)
|
||||||
|
// {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// free(tailIn);
|
||||||
|
// tailIn = newTail;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for(int i = 4096; i >= 0; i--)
|
||||||
|
// {
|
||||||
|
// int* pass = malloc(sizeof(int));
|
||||||
|
// if(pass == NULL)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// *pass = i;
|
||||||
|
// ptQueuePush(qOut, pass, errubf);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pthread_exit(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int _main(int argc, char** argv)
|
||||||
|
// {
|
||||||
|
// char errbuf[4096] = {0};
|
||||||
|
// compose_dev_conf_t* devConf = openComposeDeviceConfig("/home/nikto_b/Documents/baum/hmmmm/glob.toml", errbuf);
|
||||||
|
// if(devConf == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Err: %s\n", errbuf);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// device_handle_t** devices = openComposeDevice(devConf, errbuf);
|
||||||
|
// if(devices == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Err: %s\n", errbuf);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint8_t failed = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// if(devices[0] != NULL)
|
||||||
|
// {
|
||||||
|
// uint64_t readSpecsCount = 0;
|
||||||
|
// uint64_t writeSpecsCount = 0x20;
|
||||||
|
|
||||||
|
// smart_read_spec_t* readSpecs = malloc(sizeof(smart_read_spec_t) * readSpecsCount);
|
||||||
|
// smart_write_spec_t* writeSpecs = malloc(sizeof(smart_write_spec_t) * writeSpecsCount);
|
||||||
|
|
||||||
|
// if (writeSpecs == NULL && writeSpecsCount != 0)
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// if (readSpecs == NULL && readSpecsCount != 0)
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < writeSpecsCount; i++)
|
||||||
|
// {
|
||||||
|
// writeSpecs[i].addr = 0;
|
||||||
|
// writeSpecs[i].segno = 2;
|
||||||
|
// writeSpecs[i].ident = 0;
|
||||||
|
// writeSpecs[i].localAddr = i;
|
||||||
|
// writeSpecs[i].addrType = SMART_ADDR_TYPE_SEGMENTED;
|
||||||
|
// writeSpecs[i].handler = dummyWriteHandler;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// devices[0]->lib->fillSmartReadSpecs(devices[0]->specs, readSpecs, readSpecsCount);
|
||||||
|
// devices[0]->lib->fillSmartWriteSpecs(devices[0]->specs, writeSpecs, writeSpecsCount);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// size_t devIdx = 0;
|
||||||
|
// while(devices[devIdx] != NULL)
|
||||||
|
// {
|
||||||
|
// device_handle_t* dev = devices[devIdx];
|
||||||
|
// dev->ctx = dev->lib->init(dev->specs, errbuf);
|
||||||
|
|
||||||
|
// if(dev->ctx == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Unable to init device %lu: %s\n", devIdx, errbuf);
|
||||||
|
// memset(errbuf, 0, strlen(errbuf));
|
||||||
|
// failed = 1;
|
||||||
|
// }
|
||||||
|
// devIdx++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(failed)
|
||||||
|
// {
|
||||||
|
// for(size_t i = 0; i < devIdx; i++)
|
||||||
|
// {
|
||||||
|
// closeBaseDevice(devices[i]);
|
||||||
|
// }
|
||||||
|
// free(devices);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// size_t projectIdx = 0;
|
||||||
|
// // while(devConf->projections[projectIdx] != NULL)
|
||||||
|
// // {
|
||||||
|
// // projection_conf_t* projection = devConf->projections[projectIdx];
|
||||||
|
|
||||||
|
// // size_t foundBaseDevId = (size_t)~0;
|
||||||
|
|
||||||
|
// // for(size_t i = 0; i < devIdx; i++)
|
||||||
|
// // {
|
||||||
|
// // conf_dev_t* cnf = devConf->baseConfigs[i];
|
||||||
|
// // if(compareComposeId(cnf->id, projection->baseAt))
|
||||||
|
// // {
|
||||||
|
// // foundBaseDevId = i;
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if(foundBaseDevId == (size_t)~0)
|
||||||
|
// // {
|
||||||
|
// // printf("Unable to find projection base: ");
|
||||||
|
// // for(size_t i = 0; projection->baseAt[i] != NULL; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("->%s", projection->baseAt[i]);
|
||||||
|
// // }
|
||||||
|
// // printf("\n");
|
||||||
|
// // return 1;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // size_t foundTargetDevId = (size_t)~0;
|
||||||
|
|
||||||
|
// // for(size_t i = 0; i < devIdx; i++)
|
||||||
|
// // {
|
||||||
|
// // conf_dev_t* cnf = devConf->baseConfigs[i];
|
||||||
|
// // if(compareComposeId(cnf->id, projection->target + 1))
|
||||||
|
// // {
|
||||||
|
// // foundTargetDevId = i;
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if(foundTargetDevId == (size_t)~0)
|
||||||
|
// // {
|
||||||
|
// // printf("Unable to find projection target: ");
|
||||||
|
// // for(size_t i = 0; projection->target[i] != NULL; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("->%s", projection->target[i]);
|
||||||
|
// // }
|
||||||
|
// // printf("\n");
|
||||||
|
// // return 1;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // uint16_t baseDevMemSpecCount = 0;
|
||||||
|
// // while(devConf->baseConfigs[foundBaseDevId]->memConf->memSegConfs[baseDevMemSpecCount] != NULL){baseDevMemSpecCount++;}
|
||||||
|
|
||||||
|
// // uint16_t foundBaseSegno = (uint16_t)~0;
|
||||||
|
|
||||||
|
// // for(uint16_t i = 0; i < baseDevMemSpecCount; i++)
|
||||||
|
// // {
|
||||||
|
// // if(strcmp(devices[foundBaseDevId]->ctx->deviceMem->memsegNames[i], projection->baseSeg) == 0)
|
||||||
|
// // {
|
||||||
|
// // foundBaseSegno = i;
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if(foundBaseSegno == (uint16_t)~0)
|
||||||
|
// // {
|
||||||
|
// // printf("Unable to find projection segment %s for base: ", projection->baseSeg);
|
||||||
|
// // for(size_t i = 0; projection->baseAt[i] != NULL; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("->%s", projection->baseAt[i]);
|
||||||
|
// // }
|
||||||
|
// // printf("\n");
|
||||||
|
// // return 1;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // uint16_t targetDevMemSpecCount = 0;
|
||||||
|
// // while(devConf->baseConfigs[foundTargetDevId]->memConf->memSegConfs[targetDevMemSpecCount] != NULL){targetDevMemSpecCount++;}
|
||||||
|
|
||||||
|
// // uint16_t foundTargetSegno = (uint16_t)~0;
|
||||||
|
|
||||||
|
// // for(uint16_t i = 0; i < targetDevMemSpecCount; i++)
|
||||||
|
// // {
|
||||||
|
// // if(strcmp(devices[foundTargetDevId]->ctx->deviceMem->memsegNames[i], projection->target[0]) == 0)
|
||||||
|
// // {
|
||||||
|
// // foundTargetSegno = i;
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // if(foundTargetSegno == (uint16_t)~0)
|
||||||
|
// // {
|
||||||
|
// // printf("Unable to find projection segment for target: ");
|
||||||
|
// // for(size_t i = 0; projection->target[i] != NULL; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("->%s", projection->target[i]);
|
||||||
|
// // }
|
||||||
|
// // printf("\n");
|
||||||
|
// // return 1;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
// // void* foundBaseAt = devices[foundBaseDevId]->ctx->deviceMem->cells[foundBaseSegno];
|
||||||
|
|
||||||
|
// // foundBaseAt += projection->projectionShift;
|
||||||
|
|
||||||
|
// // devices[foundTargetDevId]->ctx->deviceMem->cells[foundTargetSegno] = foundBaseAt;
|
||||||
|
|
||||||
|
|
||||||
|
// // projectIdx++;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// FILE *fp = fopen ("/home/nikto_b/Documents/baum/avr_selftests/test.bin", "rb");
|
||||||
|
// if (!fp) {
|
||||||
|
// fprintf (stderr, "error: file open failed.\n");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #define BUFSZ 1
|
||||||
|
|
||||||
|
// uint8_t buf[BUFSZ] = {0};
|
||||||
|
// size_t bytes = 0, i, readsz = sizeof(buf);
|
||||||
|
|
||||||
|
// size_t addr = 0;
|
||||||
|
// while ((bytes = fread(buf, sizeof(*buf), readsz, fp)) == readsz)
|
||||||
|
// {
|
||||||
|
// for (i = 0; i < readsz; i++)
|
||||||
|
// {
|
||||||
|
// ((uint8_t*)(devices[0]->ctx->deviceMem->rawCells))[addr] = buf[i];
|
||||||
|
// addr += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fclose(fp);
|
||||||
|
|
||||||
|
|
||||||
|
// // uint64_t ticks_limiter = 16 * 1000 * 1000 * 100;
|
||||||
|
// // uint64_t ticks_limiter = 40;
|
||||||
|
// uint64_t cycles_limiter = 18;
|
||||||
|
// uint64_t ticks = 0;
|
||||||
|
// uint64_t cycles = 0;
|
||||||
|
|
||||||
|
// // instruction_simul_handlers_t* instr_handl = (instruction_simul_handlers_t*)dev->lib->extendedHandlers;
|
||||||
|
|
||||||
|
// // uint16_t* pcounter = (uint16_t*)instr_handl->extractPcounterPtr(dev->ctx);
|
||||||
|
|
||||||
|
|
||||||
|
// struct timeval start;
|
||||||
|
// gettimeofday(&start, NULL);
|
||||||
|
|
||||||
|
// // uint16_t prevOp = 0;
|
||||||
|
// // uint16_t opStrikeCount = 0;
|
||||||
|
|
||||||
|
// printf("Init sequence done\n");
|
||||||
|
|
||||||
|
// while (cycles < cycles_limiter)
|
||||||
|
// {
|
||||||
|
// for(size_t i = 0; i < 1; i++)
|
||||||
|
// {
|
||||||
|
// device_handle_t* dev = devices[i];
|
||||||
|
// dev->ctx->deviceMem->memreadLen = 0;
|
||||||
|
// dev->ctx->deviceMem->memwriteLen = 0;
|
||||||
|
|
||||||
|
// // uint16_t op = ((uint16_t*)(devInfo->deviceMem->cells[0]))[*(pcounter)];
|
||||||
|
// // if (op != prevOp)
|
||||||
|
// // {
|
||||||
|
// // opStrikeCount = 0;
|
||||||
|
// // }
|
||||||
|
// // else
|
||||||
|
// // {
|
||||||
|
// // opStrikeCount++;
|
||||||
|
// // if(opStrikeCount > 0xFFF)
|
||||||
|
// // {
|
||||||
|
// // printf("Found endless loop\n");
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // prevOp = op;
|
||||||
|
// // printf("Executing at 0x%04X: 0x%04X\n", (*(pcounter)), op);
|
||||||
|
|
||||||
|
// ticks += dev->lib->makeDeviceTick(dev->ctx);
|
||||||
|
// // ticks += makeDeviceTick(devInfo);
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cycles += 1;
|
||||||
|
|
||||||
|
|
||||||
|
// // for (size_t i = 0; i < devInfo->deviceMem->memwriteLen; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("Got write [0x%04zuX] at 0x%04lX\n", i, devInfo->deviceMem->memwriteCellAddrs[i]);
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// struct timeval end;
|
||||||
|
|
||||||
|
// gettimeofday(&end, NULL);
|
||||||
|
|
||||||
|
// long seconds = end.tv_sec - start.tv_sec;
|
||||||
|
// long microseconds = end.tv_usec - start.tv_usec;
|
||||||
|
|
||||||
|
// long long total_microseconds = seconds * 1000000 + microseconds;
|
||||||
|
// // double rate = 0;
|
||||||
|
// // if (total_microseconds > 0)
|
||||||
|
// // {
|
||||||
|
// // rate = ((double)total_microseconds) / ((double)cycles);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // fflush(stdout);
|
||||||
|
// // printf("Rate: %f us/cycle (%f clock/us)\n", rate, ((double)ticks) / ((double)total_microseconds));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("Execution consumed %lu ticks, %lu iterations and %llu us\n", ticks, cycles, total_microseconds);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int main(int argc, char** argv)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// char errbuf[4096];+
|
||||||
|
|
||||||
|
// device_handle_t* dev = openBaseDevice("/home/nikto_b/Documents/baum/hmmmm/devices/avr_generic/AVRrc.toml", errbuf);
|
||||||
|
// if (dev == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Unable to open device: %s\n", errbuf);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint64_t readSpecsCount = 0;
|
||||||
|
// uint64_t writeSpecsCount = 0x20;
|
||||||
|
|
||||||
|
// smart_read_spec_t* readSpecs = malloc(sizeof(smart_read_spec_t) * readSpecsCount);
|
||||||
|
// smart_write_spec_t* writeSpecs = malloc(sizeof(smart_write_spec_t) * writeSpecsCount);
|
||||||
|
|
||||||
|
// if (writeSpecs == NULL && writeSpecsCount != 0)
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
// if (readSpecs == NULL && readSpecsCount != 0)
|
||||||
|
// {
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < writeSpecsCount; i++)
|
||||||
|
// {
|
||||||
|
// writeSpecs[i].addr = 0;
|
||||||
|
// writeSpecs[i].segno = 2;
|
||||||
|
// writeSpecs[i].localAddr = i;
|
||||||
|
// writeSpecs[i].addrType = SMART_ADDR_TYPE_SEGMENTED;
|
||||||
|
// writeSpecs[i].handler = dummyWriteHandler;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// dev->lib->fillSmartReadSpecs(dev->specs, readSpecs, readSpecsCount);
|
||||||
|
// dev->lib->fillSmartWriteSpecs(dev->specs, writeSpecs, writeSpecsCount);
|
||||||
|
|
||||||
|
|
||||||
|
// dev->ctx = dev->lib->init(dev->specs, errbuf);
|
||||||
|
|
||||||
|
// if (dev->ctx == NULL)
|
||||||
|
// {
|
||||||
|
// printf("Unable to init device: %s\n", errbuf);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// FILE *fp = fopen ("/home/nikto_b/Documents/baum/avr_selftests/test.bin", "rb");
|
||||||
|
// if (!fp) {
|
||||||
|
// fprintf (stderr, "error: file open failed.\n");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #define BUFSZ 1
|
||||||
|
|
||||||
|
// uint8_t buf[BUFSZ] = {0};
|
||||||
|
// size_t bytes = 0, i, readsz = sizeof(buf);
|
||||||
|
|
||||||
|
// size_t addr = 0;
|
||||||
|
// while ((bytes = fread(buf, sizeof(*buf), readsz, fp)) == readsz)
|
||||||
|
// {
|
||||||
|
// for (i = 0; i < readsz; i++)
|
||||||
|
// {
|
||||||
|
// ((uint8_t*)(dev->ctx->deviceMem->rawCells))[addr] = buf[i];
|
||||||
|
// addr += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fclose(fp);
|
||||||
|
|
||||||
|
// printf("Done writing %zu bytes from dump file\n", addr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// uint64_t ticks_limiter = 16 * 1000 * 1000 * 100;
|
||||||
|
// // uint64_t ticks_limiter = 64;
|
||||||
|
// uint64_t ticks = 0;
|
||||||
|
// uint64_t cycles = 0;
|
||||||
|
|
||||||
|
// instruction_simul_handlers_t* instr_handl = (instruction_simul_handlers_t*)dev->lib->extendedHandlers;
|
||||||
|
|
||||||
|
// uint16_t* pcounter = (uint16_t*)instr_handl->extractPcounterPtr(dev->ctx);
|
||||||
|
|
||||||
|
|
||||||
|
// struct timeval start;
|
||||||
|
// gettimeofday(&start, NULL);
|
||||||
|
|
||||||
|
// // uint16_t prevOp = 0;
|
||||||
|
// // uint16_t opStrikeCount = 0;
|
||||||
|
|
||||||
|
// while (ticks < ticks_limiter)
|
||||||
|
// {
|
||||||
|
// dev->ctx->deviceMem->memreadLen = 0;
|
||||||
|
// dev->ctx->deviceMem->memwriteLen = 0;
|
||||||
|
|
||||||
|
// // uint16_t op = ((uint16_t*)(devInfo->deviceMem->cells[0]))[*(pcounter)];
|
||||||
|
// // if (op != prevOp)
|
||||||
|
// // {
|
||||||
|
// // opStrikeCount = 0;
|
||||||
|
// // }
|
||||||
|
// // else
|
||||||
|
// // {
|
||||||
|
// // opStrikeCount++;
|
||||||
|
// // if(opStrikeCount > 0xFFF)
|
||||||
|
// // {
|
||||||
|
// // printf("Found endless loop\n");
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // prevOp = op;
|
||||||
|
// // printf("Executing at 0x%04X: 0x%04X\n", (*(pcounter)), op);
|
||||||
|
|
||||||
|
// ticks += dev->lib->makeDeviceTick(dev->ctx);
|
||||||
|
// // ticks += makeDeviceTick(devInfo);
|
||||||
|
|
||||||
|
|
||||||
|
// cycles += 1;
|
||||||
|
|
||||||
|
|
||||||
|
// // for (size_t i = 0; i < devInfo->deviceMem->memwriteLen; i++)
|
||||||
|
// // {
|
||||||
|
// // printf("Got write [0x%04zuX] at 0x%04lX\n", i, devInfo->deviceMem->memwriteCellAddrs[i]);
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// struct timeval end;
|
||||||
|
|
||||||
|
// gettimeofday(&end, NULL);
|
||||||
|
|
||||||
|
// long seconds = end.tv_sec - start.tv_sec;
|
||||||
|
// long microseconds = end.tv_usec - start.tv_usec;
|
||||||
|
|
||||||
|
// long long total_microseconds = seconds * 1000000 + microseconds;
|
||||||
|
// // double rate = 0;
|
||||||
|
// // if (total_microseconds > 0)
|
||||||
|
// // {
|
||||||
|
// // rate = ((double)total_microseconds) / ((double)cycles);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // fflush(stdout);
|
||||||
|
// // printf("Rate: %f us/cycle (%f clock/us)\n", rate, ((double)ticks) / ((double)total_microseconds));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("Execution consumed %lu ticks, %lu cycles and %llu us\n", ticks, cycles, total_microseconds);
|
||||||
|
|
||||||
|
// printf("general purpose registers:\n");
|
||||||
|
// // printMemory(devInfo->deviceMem->cells[1], 32);
|
||||||
|
|
||||||
|
|
||||||
|
// // printf("SREG: 0x%016X\n", ((io_reg_cell_t*)devInfo->deviceMem->cells[2])[0x3F]);
|
||||||
|
|
||||||
|
// // char* buf = foo();
|
||||||
|
// // if (buf == NULL) {
|
||||||
|
// // return 1;
|
||||||
|
// // }
|
||||||
|
// // for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
// // printf("%c", buf[i]);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
// // dlclose(handle);
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|||||||
1
src/main.h
Normal file
1
src/main.h
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#pragma once
|
||||||
@@ -17,7 +17,7 @@ void broadcastClients(EmulContext* emulContext, uint8_t* msg, size_t msgLen)
|
|||||||
memcpy(newMsg, msg, msgLen);
|
memcpy(newMsg, msg, msgLen);
|
||||||
|
|
||||||
ClientContext* ctx = clientsHead->payload;
|
ClientContext* ctx = clientsHead->payload;
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, newMsg, msgLen);
|
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, newMsg, msgLen);
|
||||||
clientsHead = clientsHead->nextEntry;
|
clientsHead = clientsHead->nextEntry;
|
||||||
}
|
}
|
||||||
free(msg);
|
free(msg);
|
||||||
@@ -27,7 +27,7 @@ void broadcastClients(EmulContext* emulContext, uint8_t* msg, size_t msgLen)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ClientContext* client, uint8_t* msg, size_t msgLen)
|
void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ws_cli_conn_t clientIdx, uint8_t* msg, size_t msgLen)
|
||||||
{
|
{
|
||||||
SizedPtr* p = &outBufs->bufs[outBufs->currWritingIdx];
|
SizedPtr* p = &outBufs->bufs[outBufs->currWritingIdx];
|
||||||
if(p->size + 1 >= p->allocatedSize)
|
if(p->size + 1 >= p->allocatedSize)
|
||||||
@@ -41,6 +41,6 @@ void dispatchOutgoingMessage(OutgoingBuffers* outBufs, ClientContext* client, ui
|
|||||||
OutgoingMessage* outmsg = &((OutgoingMessage*)p->ptr)[p->size];
|
OutgoingMessage* outmsg = &((OutgoingMessage*)p->ptr)[p->size];
|
||||||
outmsg->msg = msg;
|
outmsg->msg = msg;
|
||||||
outmsg->msgLen = msgLen;
|
outmsg->msgLen = msgLen;
|
||||||
outmsg->client = client;
|
outmsg->clientIdx = clientIdx;
|
||||||
p->size++;
|
p->size++;
|
||||||
}
|
}
|
||||||
@@ -8,34 +8,14 @@
|
|||||||
#include "proto/handlers/stream.h"
|
#include "proto/handlers/stream.h"
|
||||||
#include "proto/handlers/control.h"
|
#include "proto/handlers/control.h"
|
||||||
#include "proto/handlers/mem.h"
|
#include "proto/handlers/mem.h"
|
||||||
#include "state.h"
|
|
||||||
|
|
||||||
|
|
||||||
void handleCloseClient(EmulContext* emulContext, LinkedListEntry* clientEntry)
|
void handleCloseClient(EmulContext* emulContext, ClientContext* ctx)
|
||||||
{
|
{
|
||||||
ClientContext* ctx = clientEntry->payload;
|
if(ctx->streamRegIterator > 0)
|
||||||
|
|
||||||
if(ctx->orphanedAt == 0)
|
|
||||||
{
|
{
|
||||||
ctx->orphanedAt = (uint64_t)time(NULL);
|
unregisterClientStreams(emulContext, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(ctx->streamRegIterator > 0)
|
|
||||||
// {
|
|
||||||
// unregisterClientStreams(emulContext, ctx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if(ctx->streamRegIterator == 0)
|
|
||||||
// {
|
|
||||||
// removeLinkedListEntry(emulContext->clientsHead, clientEntry);
|
|
||||||
// ctx->clientId = 0;
|
|
||||||
// free(ctx->fallbackOutcomeQ->ptr);
|
|
||||||
// free(ctx->fallbackOutcomeQ);
|
|
||||||
// ptQueueFree(ctx->incomeQ);
|
|
||||||
// free(ctx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +23,7 @@ void handleRegEvent(EmulContext* emulContext, ClientRegistrationEvent* ev)
|
|||||||
{
|
{
|
||||||
if(ev->regType == REG_EVTYPE_CONNECT)
|
if(ev->regType == REG_EVTYPE_CONNECT)
|
||||||
{
|
{
|
||||||
printf("open client %lu\n", ev->ctx->seatId);
|
printf("open client %lu\n", ev->ctx->clientId);
|
||||||
LinkedListEntry* newClientsLinkedListHead = malloc(sizeof(LinkedListEntry));
|
LinkedListEntry* newClientsLinkedListHead = malloc(sizeof(LinkedListEntry));
|
||||||
NULL_GUARD(newClientsLinkedListHead);
|
NULL_GUARD(newClientsLinkedListHead);
|
||||||
|
|
||||||
@@ -64,8 +44,9 @@ void handleRegEvent(EmulContext* emulContext, ClientRegistrationEvent* ev)
|
|||||||
{
|
{
|
||||||
if(clientEntry->payload == ev->ctx)
|
if(clientEntry->payload == ev->ctx)
|
||||||
{
|
{
|
||||||
printf("close client %lu\n", ev->ctx->seatId);
|
printf("close client %lu\n", ev->ctx->clientId);
|
||||||
handleCloseClient(emulContext, clientEntry);
|
handleCloseClient(emulContext, ev->ctx);
|
||||||
|
removeLinkedListEntry(emulContext->clientsHead, clientEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
clientEntry = clientEntry->nextEntry;
|
clientEntry = clientEntry->nextEntry;
|
||||||
@@ -73,7 +54,7 @@ void handleRegEvent(EmulContext* emulContext, ClientRegistrationEvent* ev)
|
|||||||
}
|
}
|
||||||
else if (ev->regType == REG_EVTYPE_AUTH)
|
else if (ev->regType == REG_EVTYPE_AUTH)
|
||||||
{
|
{
|
||||||
printf("auth client %lu\n", ev->ctx->seatId);
|
printf("auth client %lu\n", ev->ctx->clientId);
|
||||||
ev->ctx->isAuthed = 1;
|
ev->ctx->isAuthed = 1;
|
||||||
handleOnClientAuthDone(ev->ctx, emulContext);
|
handleOnClientAuthDone(ev->ctx, emulContext);
|
||||||
}
|
}
|
||||||
@@ -88,16 +69,19 @@ void handleIncomingMessage(BaseMessage* msg, ClientContext* ctx, EmulContext* em
|
|||||||
{
|
{
|
||||||
case PACKET_TYPE_CTRL:
|
case PACKET_TYPE_CTRL:
|
||||||
{
|
{
|
||||||
handleIncomingControlMessage(msg, ctx, emulContext);
|
printf("CTRL packet\n");
|
||||||
|
handleIncomingControlMessage(msg, emulContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_STREAM:
|
case PACKET_TYPE_STREAM:
|
||||||
{
|
{
|
||||||
|
printf("STREAM packet\n");
|
||||||
handleIncomingStreamMessage(msg, ctx, emulContext);
|
handleIncomingStreamMessage(msg, ctx, emulContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PACKET_TYPE_MEM:
|
case PACKET_TYPE_MEM:
|
||||||
{
|
{
|
||||||
|
printf("MEM packet\n");
|
||||||
handleIncomingMemMessage(msg, ctx, emulContext);
|
handleIncomingMemMessage(msg, ctx, emulContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -115,34 +99,11 @@ void handleAllClients(EmulContext* emulContext)
|
|||||||
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
||||||
|
|
||||||
size_t handleLimit = 128;
|
size_t handleLimit = 128;
|
||||||
uint8_t hasAliveClients = 0;
|
|
||||||
|
|
||||||
while(clientEntry != NULL && handleLimit > 0)
|
while(clientEntry != NULL && handleLimit > 0)
|
||||||
{
|
{
|
||||||
LinkedListEntry* currEntry = clientEntry;
|
|
||||||
handleLimit--;
|
handleLimit--;
|
||||||
ClientContext* ctx = clientEntry->payload;
|
ClientContext* ctx = clientEntry->payload;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(ctx->orphanedDeadTimeout != 0 && ctx->orphanedAt != 0 && ctx->isAuthed)
|
|
||||||
{
|
|
||||||
// printf("Found orphaned client\n");
|
|
||||||
if((uint64_t)time(NULL) - ctx->orphanedAt > ctx->orphanedDeadTimeout || ctx->streamRegIterator == 0)
|
|
||||||
{
|
|
||||||
printf("Orphaned client dead timeout exceeded\n");
|
|
||||||
if(ctx->streamRegIterator > 0)
|
|
||||||
{
|
|
||||||
unregisterClientStreams(emulContext, ctx);
|
|
||||||
}
|
|
||||||
clientEntry = clientEntry->nextEntry;
|
|
||||||
removeLinkedListEntry(emulContext->clientsHead, currEntry);
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, NULL, 0);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ctx->isAuthed)
|
if(!ctx->isAuthed)
|
||||||
{
|
{
|
||||||
clientEntry = disconnectDueTimeout(emulContext, clientEntry);
|
clientEntry = disconnectDueTimeout(emulContext, clientEntry);
|
||||||
@@ -157,10 +118,6 @@ void handleAllClients(EmulContext* emulContext)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(ctx->orphanedAt == 0)
|
|
||||||
{
|
|
||||||
hasAliveClients = 1;
|
|
||||||
}
|
|
||||||
void* payload = ctx->incomeQ->head->payload;
|
void* payload = ctx->incomeQ->head->payload;
|
||||||
if(payload != NULL)
|
if(payload != NULL)
|
||||||
{
|
{
|
||||||
@@ -177,20 +134,6 @@ void handleAllClients(EmulContext* emulContext)
|
|||||||
clientEntry = clientEntry->nextEntry;
|
clientEntry = clientEntry->nextEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasAliveClients == 0)
|
|
||||||
{
|
|
||||||
uint8_t newEmulState = switchNewEmulState(*emulContext->emulState, EMUL_STATE_OP_PAUSE);
|
|
||||||
if(newEmulState != *emulContext->emulState)
|
|
||||||
{
|
|
||||||
printf("No alive clients, pausing execution\n");
|
|
||||||
*emulContext->emulState = newEmulState;
|
|
||||||
|
|
||||||
size_t len = 0;
|
|
||||||
uint8_t* notify = createControlNotifyMessage((uint64_t)~0, *emulContext->clockCounter, newEmulState, &len);
|
|
||||||
broadcastClients(emulContext, notify, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -128,16 +128,13 @@ void handleOnClientAuthDone(ClientContext* ctx, EmulContext* emulContext)
|
|||||||
uint8_t* framedata = malloc(sizeof(uint8_t) * 8);
|
uint8_t* framedata = malloc(sizeof(uint8_t) * 8);
|
||||||
NULL_GUARD(framedata);
|
NULL_GUARD(framedata);
|
||||||
|
|
||||||
encodeUintToBytes(ctx->seatId, framedata);
|
encodeUintToBytes(ctx->clientId, framedata);
|
||||||
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, framedata, 8);
|
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, framedata, 8);
|
||||||
|
|
||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint8_t* msg = createControlNotifyMessage((uint64_t)~0, *emulContext->clockCounter, *emulContext->emulState, &len);
|
uint8_t* msg = createControlNotifyMessage((uint64_t)~0, *emulContext->clockCounter, *emulContext->emulState, &len);
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, msg, len);
|
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, msg, len);
|
||||||
|
|
||||||
|
|
||||||
uint8_t* outMsg = createClientSetup((uint64_t)~0, ctx, &len);
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, len);
|
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,12 @@
|
|||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
|
||||||
// #include <alloca.h>
|
|
||||||
|
|
||||||
|
|
||||||
void handleIncomingExecControl(BaseMessage* msg, EmulContext* emulContext)
|
|
||||||
|
void handleIncomingControlMessage(BaseMessage* msg, EmulContext* emulContext)
|
||||||
|
{
|
||||||
|
if(msg->payloadHeader == CTRL_TYPE_EXEC)
|
||||||
{
|
{
|
||||||
printf("ctrl exec\n");
|
printf("ctrl exec\n");
|
||||||
uint8_t stateOp = ((const uint8_t*)(msg->payload))[0];
|
uint8_t stateOp = ((const uint8_t*)(msg->payload))[0];
|
||||||
@@ -24,176 +26,8 @@ void handleIncomingExecControl(BaseMessage* msg, EmulContext* emulContext)
|
|||||||
broadcastClients(emulContext, notify, len);
|
broadcastClients(emulContext, notify, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
|
||||||
void handleIncomingEditConnectionSettingsControl(BaseMessage* msg, ClientContext* ctx, EmulContext* emulContext)
|
|
||||||
{
|
{
|
||||||
uint64_t fallbackQLen = decodeBytesToU64(msg->payload);
|
printf("invalid payload header: %u\n", msg->payloadHeader);
|
||||||
uint64_t orphanedDeadTimeout = decodeBytesToU64(msg->payload + 8);
|
|
||||||
|
|
||||||
ctx->orphanedDeadTimeout = orphanedDeadTimeout;
|
|
||||||
uint8_t* newFallbackQPtr = realloc(ctx->fallbackOutcomeQ->ptr, sizeof(OutgoingMessage) * fallbackQLen);
|
|
||||||
NULL_GUARD(newFallbackQPtr);
|
|
||||||
ctx->fallbackOutcomeQ->ptr = newFallbackQPtr;
|
|
||||||
ctx->fallbackOutcomeQ->allocatedSize = fallbackQLen;
|
|
||||||
|
|
||||||
size_t len = 0;
|
|
||||||
uint8_t* outMsg = createClientSetup(msg->nonce, ctx, &len);
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t fillOrphanedClientReportItem(uint8_t* outmsg, ClientContext* ctx)
|
|
||||||
{
|
|
||||||
printf("filling orphaned %lu with %lu packets\n", ctx->seatId, ctx->fallbackOutcomeQ->size - ctx->fallbackOutcomeQPadding);
|
|
||||||
encodeUintToBytes(ctx->seatId, outmsg);
|
|
||||||
encodeUintToBytes(ctx->orphanedAt, outmsg + 8);
|
|
||||||
encodeUintToBytes((uint64_t)(ctx->fallbackOutcomeQ->size - ctx->fallbackOutcomeQPadding), outmsg + 8 + 8);
|
|
||||||
return 8 * 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleIncomingListOrphaned(BaseMessage* msg, ClientContext* ctx, EmulContext* emulContext)
|
|
||||||
{
|
|
||||||
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
|
||||||
size_t orphanedCount = 0;
|
|
||||||
size_t orphanedPackets = 0;
|
|
||||||
|
|
||||||
while(clientEntry != NULL)
|
|
||||||
{
|
|
||||||
ClientContext* orphanedCtx = clientEntry->payload;
|
|
||||||
if(orphanedCtx->orphanedAt != 0)
|
|
||||||
{
|
|
||||||
orphanedCount++;
|
|
||||||
orphanedPackets += orphanedCtx->fallbackOutcomeQ->size - ctx->fallbackOutcomeQPadding;
|
|
||||||
}
|
|
||||||
clientEntry = clientEntry->nextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("found %lu orphaned clients with %lu packets\n", orphanedCount, orphanedPackets);
|
|
||||||
|
|
||||||
const size_t orphanedListReportItemSize = 8 * 3;
|
|
||||||
const size_t msgLen = ((orphanedListReportItemSize * orphanedCount) + 9 + 8);
|
|
||||||
uint8_t* outMsg = malloc(sizeof(uint8_t) * msgLen);
|
|
||||||
NULL_GUARD(outMsg);
|
|
||||||
fillHead(msg->nonce, PACKET_TYPE_CTRL, CTRL_TYPE_LIST_ORPHANED, outMsg);
|
|
||||||
|
|
||||||
|
|
||||||
clientEntry = *emulContext->clientsHead;
|
|
||||||
size_t filledCount = 0;
|
|
||||||
uint8_t* outMsgCursor = outMsg + 9;
|
|
||||||
encodeUintToBytes((uint64_t)orphanedCount, outMsgCursor);
|
|
||||||
outMsgCursor += 8;
|
|
||||||
|
|
||||||
while(clientEntry != NULL && filledCount < orphanedCount)
|
|
||||||
{
|
|
||||||
ClientContext* orphanedCtx = clientEntry->payload;
|
|
||||||
if(orphanedCtx->orphanedAt != 0)
|
|
||||||
{
|
|
||||||
size_t filled = fillOrphanedClientReportItem(outMsgCursor, orphanedCtx);
|
|
||||||
outMsgCursor += filled;
|
|
||||||
filledCount++;
|
|
||||||
}
|
|
||||||
clientEntry = clientEntry->nextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, msgLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleIncomingLoadFailed(const BaseMessage* msg, ClientContext* ctx, const EmulContext* emulContext)
|
|
||||||
{
|
|
||||||
const uint8_t readMode = ((const uint8_t*)msg->payload)[0];
|
|
||||||
const uint64_t seatId = decodeBytesToU64(((const uint8_t*)msg->payload) + 1);
|
|
||||||
|
|
||||||
|
|
||||||
LinkedListEntry* clientEntry = *emulContext->clientsHead;
|
|
||||||
ClientContext* orphanedCtx = NULL;
|
|
||||||
|
|
||||||
while(clientEntry != NULL)
|
|
||||||
{
|
|
||||||
orphanedCtx = clientEntry->payload;
|
|
||||||
if(orphanedCtx->orphanedAt != 0)
|
|
||||||
{
|
|
||||||
if(orphanedCtx->seatId == seatId)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clientEntry = clientEntry->nextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(clientEntry == NULL || orphanedCtx == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t payloadSize = 0;
|
|
||||||
OutgoingMessage* failedQueue = (OutgoingMessage*)orphanedCtx->fallbackOutcomeQ->ptr;
|
|
||||||
for(size_t i = orphanedCtx->fallbackOutcomeQPadding; i < orphanedCtx->fallbackOutcomeQ->size; i++)
|
|
||||||
{
|
|
||||||
OutgoingMessage* failedMessage = &failedQueue[i];
|
|
||||||
payloadSize += 8;
|
|
||||||
payloadSize += failedMessage->msgLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t outLen = 9 + payloadSize;
|
|
||||||
|
|
||||||
printf("preparing failed messages report: %lu messages, %lu payload size, %lu message size\n",
|
|
||||||
orphanedCtx->fallbackOutcomeQ->size - orphanedCtx->fallbackOutcomeQPadding,
|
|
||||||
payloadSize,
|
|
||||||
outLen);
|
|
||||||
|
|
||||||
uint8_t* outMsg = malloc(sizeof(uint8_t) * outLen);
|
|
||||||
fillHead(msg->nonce, PACKET_TYPE_CTRL, CTRL_TYPE_LOAD_FAILED, outMsg);
|
|
||||||
uint8_t* outMsgCursor = outMsg + 9;
|
|
||||||
|
|
||||||
for(size_t i = orphanedCtx->fallbackOutcomeQPadding; i < orphanedCtx->fallbackOutcomeQ->size; i++)
|
|
||||||
{
|
|
||||||
OutgoingMessage* failedMessage = &failedQueue[i];
|
|
||||||
encodeUintToBytes(failedMessage->msgLen, outMsgCursor);
|
|
||||||
outMsgCursor += 8;
|
|
||||||
for(size_t j = 0; j < failedMessage->msgLen; j++)
|
|
||||||
{
|
|
||||||
outMsgCursor[j] = failedMessage->msg[j];
|
|
||||||
}
|
|
||||||
outMsgCursor += failedMessage->msgLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, outLen);
|
|
||||||
if(readMode == 1)
|
|
||||||
{
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, NULL, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handleIncomingControlMessage(BaseMessage* msg, ClientContext* ctx, EmulContext* emulContext)
|
|
||||||
{
|
|
||||||
switch (msg->payloadHeader)
|
|
||||||
{
|
|
||||||
case CTRL_TYPE_EXEC:
|
|
||||||
{
|
|
||||||
handleIncomingExecControl(msg, emulContext);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CTRL_TYPE_LIST_ORPHANED:
|
|
||||||
{
|
|
||||||
handleIncomingListOrphaned(msg, ctx, emulContext);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CTRL_TYPE_LOAD_FAILED:
|
|
||||||
{
|
|
||||||
handleIncomingLoadFailed(msg, ctx, emulContext);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CTRL_TYPE_SETUP_CONNECTION:
|
|
||||||
{
|
|
||||||
handleIncomingEditConnectionSettingsControl(msg, ctx, emulContext);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ void handleIncomingMemReadReq(BaseMessage* msg, ClientContext* ctx, EmulContext*
|
|||||||
|
|
||||||
size_t outLen = 0;
|
size_t outLen = 0;
|
||||||
uint8_t* outMsg = createMemReadResponseMessage(msg->nonce, *emulContext->clockCounter, readPtr, readLen, &outLen);
|
uint8_t* outMsg = createMemReadResponseMessage(msg->nonce, *emulContext->clockCounter, readPtr, readLen, &outLen);
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, outLen);
|
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, outMsg, outLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -64,10 +64,6 @@ void handleIncomingMemWrite(BaseMessage* msg, ClientContext* ctx, EmulContext* e
|
|||||||
uint8_t* writePtr = emulContext->devicesMem[devId] + globalAddr;
|
uint8_t* writePtr = emulContext->devicesMem[devId] + globalAddr;
|
||||||
|
|
||||||
memcpy(writePtr, msg->payload + 24, msg->payloadLen - 24);
|
memcpy(writePtr, msg->payload + 24, msg->payloadLen - 24);
|
||||||
|
|
||||||
size_t outLen = 0;
|
|
||||||
uint8_t* outMsg = createMemReadResponseMessage(msg->nonce, *emulContext->clockCounter, writePtr, msg->payloadLen - 24, &outLen);
|
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, outMsg, outLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void handleStreamRegMessage(BaseMessage* msg, ClientContext* ctx, EmulContext* e
|
|||||||
DeviceSegStreamReg* deviceRegs = emulContext->deviceStreamRegs[devId];
|
DeviceSegStreamReg* deviceRegs = emulContext->deviceStreamRegs[devId];
|
||||||
if(deviceRegs->regCount + 1 >= deviceRegs->allocatedSize)
|
if(deviceRegs->regCount + 1 >= deviceRegs->allocatedSize)
|
||||||
{
|
{
|
||||||
size_t newAllocatedSize = deviceRegs->allocatedSize * 2;
|
size_t newAllocatedSize = deviceRegs->allocatedSize;
|
||||||
if(newAllocatedSize <= deviceRegs->regCount + 1)
|
if(newAllocatedSize <= deviceRegs->regCount + 1)
|
||||||
{
|
{
|
||||||
newAllocatedSize = deviceRegs->regCount + 1;
|
newAllocatedSize = deviceRegs->regCount + 1;
|
||||||
@@ -103,7 +103,7 @@ void handleStreamRegMessage(BaseMessage* msg, ClientContext* ctx, EmulContext* e
|
|||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint8_t* notifMsg = createDoneRegMessage(msg->nonce, X, devId, segId, startAddr, segLen, reg->regId, &len);
|
uint8_t* notifMsg = createDoneRegMessage(msg->nonce, X, devId, segId, startAddr, segLen, reg->regId, &len);
|
||||||
dispatchOutgoingMessage(emulContext->outBufs, ctx, notifMsg, len);
|
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, notifMsg, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,40 +14,29 @@ void onWsOpen(ws_cli_conn_t client)
|
|||||||
ptQueue* incomeQueue = ptQueueCreate(errbuf);
|
ptQueue* incomeQueue = ptQueueCreate(errbuf);
|
||||||
NULL_GUARD(incomeQueue, "Unable to create income queue: %s\n", errbuf);
|
NULL_GUARD(incomeQueue, "Unable to create income queue: %s\n", errbuf);
|
||||||
|
|
||||||
// ptQueue* outcomeQueue = ptQueueCreate(errbuf);
|
ptQueue* outcomeQueue = ptQueueCreate(errbuf);
|
||||||
|
|
||||||
// NULL_GUARD(outcomeQueue, "Unable to create outcome queue: %s\n", errbuf);
|
NULL_GUARD(outcomeQueue, "Unable to create outcome queue: %s\n", errbuf);
|
||||||
|
|
||||||
ClientContext* cctx = malloc(sizeof(ClientContext));
|
ClientContext* cctx = malloc(sizeof(ClientContext));
|
||||||
if(cctx == NULL)
|
if(cctx == NULL)
|
||||||
{
|
{
|
||||||
ptQueueFree(incomeQueue);
|
ptQueueFree(incomeQueue);
|
||||||
// ptQueueFree(outcomeQueue);
|
ptQueueFree(outcomeQueue);
|
||||||
panic("Unable to allocate client context\n");
|
panic("Unable to allocate client context\n");
|
||||||
}
|
}
|
||||||
cctx->clientId = client;
|
cctx->clientId = client;
|
||||||
cctx->isAuthed = 0;
|
cctx->isAuthed = 0;
|
||||||
cctx->streamRegIterator = 0;
|
cctx->streamRegIterator = 0;
|
||||||
cctx->incomeQ = incomeQueue;
|
cctx->incomeQ = incomeQueue;
|
||||||
// cctx->outcomeQ = outcomeQueue;
|
cctx->outcomeQ = outcomeQueue;
|
||||||
cctx->connectedAt = (uint64_t)time(NULL);
|
cctx->connectedAt = (uint64_t)time(NULL);
|
||||||
cctx->orphanedAt = 0;
|
|
||||||
cctx->orphanedDeadTimeout = 60;
|
|
||||||
cctx->fallbackOutcomeQPadding = 0;
|
|
||||||
cctx->fallbackOutcomeQ = malloc(sizeof(SizedPtr));
|
|
||||||
NULL_GUARD(cctx->fallbackOutcomeQ);
|
|
||||||
cctx->fallbackOutcomeQ->ptr = (void*) calloc(1024, sizeof(OutgoingMessage));
|
|
||||||
NULL_GUARD(cctx->fallbackOutcomeQ->ptr);
|
|
||||||
cctx->fallbackOutcomeQ->allocatedSize = 1024;
|
|
||||||
cctx->fallbackOutcomeQ->size = 0;
|
|
||||||
|
|
||||||
ClientRegistrationEvent* ev = malloc(sizeof(ClientContext));
|
ClientRegistrationEvent* ev = malloc(sizeof(ClientContext));
|
||||||
if(ev == NULL)
|
if(ev == NULL)
|
||||||
{
|
{
|
||||||
ptQueueFree(incomeQueue);
|
ptQueueFree(incomeQueue);
|
||||||
// ptQueueFree(outcomeQueue);
|
ptQueueFree(outcomeQueue);
|
||||||
free(cctx->fallbackOutcomeQ->ptr);
|
|
||||||
free(cctx->fallbackOutcomeQ);
|
|
||||||
free(cctx);
|
free(cctx);
|
||||||
|
|
||||||
panic("Unable to allocate register event");
|
panic("Unable to allocate register event");
|
||||||
@@ -61,16 +50,11 @@ void onWsOpen(ws_cli_conn_t client)
|
|||||||
|
|
||||||
with_lock(&ctx->registerMutex)
|
with_lock(&ctx->registerMutex)
|
||||||
{
|
{
|
||||||
cctx->seatId = ctx->seatCounter;
|
|
||||||
ctx->seatCounter++;
|
|
||||||
|
|
||||||
int exitCode = ptQueuePush(ctx->regQueue, ev, errbuf);
|
int exitCode = ptQueuePush(ctx->regQueue, ev, errbuf);
|
||||||
if(exitCode)
|
if(exitCode)
|
||||||
{
|
{
|
||||||
ptQueueFree(incomeQueue);
|
ptQueueFree(incomeQueue);
|
||||||
// ptQueueFree(outcomeQueue);
|
ptQueueFree(outcomeQueue);
|
||||||
free(cctx->fallbackOutcomeQ->ptr);
|
|
||||||
free(cctx->fallbackOutcomeQ);
|
|
||||||
free(cctx);
|
free(cctx);
|
||||||
|
|
||||||
panic("Unable to push to reg queue: %s\n", errbuf);
|
panic("Unable to push to reg queue: %s\n", errbuf);
|
||||||
@@ -97,14 +81,14 @@ void onWsClose(ws_cli_conn_t client)
|
|||||||
if(cctx == NULL)
|
if(cctx == NULL)
|
||||||
{
|
{
|
||||||
cctx = NULL;
|
cctx = NULL;
|
||||||
printf("Unable to get client context for client %lu\n", client);
|
printf("Unable to get client context\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ServerContext* ctx = ws_get_server_context(client);
|
ServerContext* ctx = ws_get_server_context(client);
|
||||||
if(ctx == NULL)
|
if(ctx == NULL)
|
||||||
{
|
{
|
||||||
printf("Unable to get server context for client %lu\n", client);
|
printf("Unable to get server context\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,20 +31,16 @@ BaseMessage* parseMessage(const uint8_t* bytes, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fillHead(uint64_t nonce, uint8_t packetType, uint8_t payloadHeader, uint8_t* outmsg)
|
|
||||||
{
|
|
||||||
encodeUintToBytes(nonce, outmsg);
|
|
||||||
outmsg[8] = (uint8_t)((packetType & 0b1111) << 4);
|
|
||||||
outmsg[8] |= payloadHeader & 0b1111;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* createControlNotifyMessage(uint64_t nonce, uint64_t clockCounter, uint8_t newEmulState, size_t* lenOut)
|
uint8_t* createControlNotifyMessage(uint64_t nonce, uint64_t clockCounter, uint8_t newEmulState, size_t* lenOut)
|
||||||
{
|
{
|
||||||
*lenOut = 9 + 10;
|
*lenOut = 9 + 10;
|
||||||
uint8_t* outmsg = malloc(sizeof(uint8_t) * (*lenOut));
|
uint8_t* outmsg = malloc(sizeof(uint8_t) * (*lenOut));
|
||||||
NULL_GUARD(outmsg, "Unable to allocate message");
|
NULL_GUARD(outmsg, "Unable to allocate message");
|
||||||
|
|
||||||
fillHead(nonce, PACKET_TYPE_CTRL, CTRL_TYPE_NOTIF_STATE, outmsg);
|
encodeUintToBytes(nonce, outmsg);
|
||||||
|
|
||||||
|
outmsg[8] = PACKET_TYPE_CTRL << 4;
|
||||||
|
outmsg[8] |= CTRL_TYPE_NOTIF_STATE;
|
||||||
|
|
||||||
outmsg[9] = NOTIF_TYPE_EXEC;
|
outmsg[9] = NOTIF_TYPE_EXEC;
|
||||||
encodeUintToBytes(clockCounter, outmsg + 10);
|
encodeUintToBytes(clockCounter, outmsg + 10);
|
||||||
@@ -59,9 +55,8 @@ uint8_t* createDoneRegMessage(uint64_t nonce, uint8_t X, uint64_t devId, uint64_
|
|||||||
uint8_t* outmsg = malloc(sizeof(uint8_t) * (*lenOut));
|
uint8_t* outmsg = malloc(sizeof(uint8_t) * (*lenOut));
|
||||||
NULL_GUARD(outmsg);
|
NULL_GUARD(outmsg);
|
||||||
|
|
||||||
|
encodeUintToBytes(nonce, outmsg);
|
||||||
fillHead(nonce, PACKET_TYPE_STREAM, (uint8_t)(X << 3) | STREAM_TYPE_REG_CONFIRM, outmsg);
|
outmsg[8] = (uint8_t)((PACKET_TYPE_STREAM << 4) | (X << 3) | STREAM_TYPE_REG_CONFIRM);
|
||||||
|
|
||||||
encodeUintToBytes(devId, outmsg + 9);
|
encodeUintToBytes(devId, outmsg + 9);
|
||||||
encodeUintToBytes(segId, outmsg + 9 + 8);
|
encodeUintToBytes(segId, outmsg + 9 + 8);
|
||||||
encodeUintToBytes(startAddr, outmsg + 9 + 8 + 8);
|
encodeUintToBytes(startAddr, outmsg + 9 + 8 + 8);
|
||||||
@@ -82,26 +77,9 @@ uint8_t* createStreamSegmentPush(uint8_t mode, uint32_t regId, uint64_t clockCou
|
|||||||
encodeUintToBytes(nonce, outmsg);
|
encodeUintToBytes(nonce, outmsg);
|
||||||
outmsg[8] = (uint8_t)((PACKET_TYPE_STREAM << 4) | (mode << 3) | STREAM_TYPE_SEND);
|
outmsg[8] = (uint8_t)((PACKET_TYPE_STREAM << 4) | (mode << 3) | STREAM_TYPE_SEND);
|
||||||
|
|
||||||
fillHead(nonce, PACKET_TYPE_STREAM, (uint8_t)((mode << 3) | STREAM_TYPE_SEND), outmsg);
|
|
||||||
|
|
||||||
encodeUintToBytes(regId, outmsg + 9);
|
encodeUintToBytes(regId, outmsg + 9);
|
||||||
encodeUintToBytes(clockCounter, outmsg + 9 + 4);
|
encodeUintToBytes(clockCounter, outmsg + 9 + 4);
|
||||||
memcpy(outmsg + 9 + 4 + 8, payload, payloadLen);
|
memcpy(outmsg + 9 + 4 + 8, payload, payloadLen);
|
||||||
|
|
||||||
return outmsg;
|
return outmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t* createClientSetup(uint64_t nonce, ClientContext* ctx, size_t* lenOut)
|
|
||||||
{
|
|
||||||
*lenOut = 9 + 8 + 8;
|
|
||||||
uint8_t* outmsg = malloc(sizeof(uint8_t) * (*lenOut));
|
|
||||||
NULL_GUARD(outmsg);
|
|
||||||
|
|
||||||
fillHead(nonce, PACKET_TYPE_CTRL, CTRL_TYPE_SETUP_CONNECTION, outmsg);
|
|
||||||
uint8_t* payload = outmsg + 9;
|
|
||||||
encodeUintToBytes((uint64_t)ctx->fallbackOutcomeQ->allocatedSize, payload);
|
|
||||||
encodeUintToBytes((uint64_t)ctx->orphanedDeadTimeout, payload + 8);
|
|
||||||
|
|
||||||
return outmsg;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user