<commit_before>#ifndef CAN_EMULATOR

#include "usbutil.h"
#include "canread.h"
#include "serialutil.h"
#include "signals.h"
#include "log.h"
#include "cJSON.h"
#include "listener.h"
#include <stdint.h>

extern SerialDevice SERIAL_DEVICE;
extern UsbDevice USB_DEVICE;
extern Listener listener;

/* Forward declarations */

void receiveCan(CanBus*);
void initializeAllCan();
bool receiveWriteRequest(uint8_t*);

void setup() {
    initializeLogging();
#ifndef NO_UART
    initializeSerial(&SERIAL_DEVICE);
#endif
    initializeUsb(&USB_DEVICE);
    initializeAllCan();
}

void loop() {
    for(int i = 0; i < getCanBusCount(); i++) {
        receiveCan(&getCanBuses()[i]);
    }
    processListenerQueues(&listener);
    readFromHost(&USB_DEVICE, &receiveWriteRequest);
#ifndef NO_UART
    readFromSerial(&SERIAL_DEVICE, &receiveWriteRequest);
#endif
    for(int i = 0; i < getCanBusCount(); i++) {
        processCanWriteQueue(&getCanBuses()[i]);
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        initializeCan(&(getCanBuses()[i]));
    }
}

void receiveRawWriteRequest(cJSON* idObject, cJSON* root) {
    uint32_t id = idObject->valueint;
    cJSON* dataObject = cJSON_GetObjectItem(root, "data");
    if(dataObject == NULL) {
        debug("Raw write request missing data\r\n", id);
        return;
    }

    char* dataString = dataObject->valuestring;
    char* end;
    unsigned long long data = __builtin_bswap64(strtoull(dataString, &end, 16));
    CanMessage message = {id, data};
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, message);
}

void receiveBinaryWriteRequest(uint8_t* message) {
    int index = 0;
    const int BINARY_CAN_WRITE_PACKET_LENGTH = 15;

    while(message[index] != '!') {
        if (index + BINARY_CAN_WRITE_PACKET_LENGTH >= 64) {
            debug("!");
        }

        if(message[index] != '{' || message[index+5] != '|'
                || message[index+14] != '}') {
            debug("Received a corrupted CAN message.\r\n");
            for(int i = 0; i < 16; i++) {
                debug("%02x ", message[index+i] );
            }
            debug("\r\n");
        }

        CanMessage outgoing = {0, 0};
        memcpy((uint8_t*)&outgoing.id, &message[index+1], 4);
        for(int i = 0; i < 8; i++) {
            ((uint8_t*)&(outgoing.data))[i] = message[index+i+6];
        }
        QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, outgoing);
    }
}

void receiveTranslatedWriteRequest(cJSON* nameObject, cJSON* root) {
    char* name = nameObject->valuestring;
    cJSON* value = cJSON_GetObjectItem(root, "value");
    if(value == NULL) {
        debug("Write request for %s missing value\r\n", name);
        return;
    }

    CanSignal* signal = lookupSignal(name, getSignals(),
            getSignalCount(), true);
    CanCommand* command = lookupCommand(name, getCommands(),
            getCommandCount());
    if(signal != NULL) {
        sendCanSignal(signal, value, getSignals(), getSignalCount());
    } else if(command != NULL) {
        command->handler(name, value, getSignals(), getSignalCount());
    } else {
        debug("Writing not allowed for signal with name %s\r\n", name);
    }
}

bool receiveJsonWriteRequest(uint8_t* message) {
    cJSON *root = cJSON_Parse((char*)message);
    bool foundMessage = false;
    if(root != NULL) {
        foundMessage = true;
        cJSON* nameObject = cJSON_GetObjectItem(root, "name");
        if(nameObject == NULL) {
            cJSON* idObject = cJSON_GetObjectItem(root, "id");
            if(idObject == NULL) {
                debug("Write request is malformed, "
                        "missing name or id: %s\r\n", message);
            } else {
                receiveRawWriteRequest(idObject, root);
            }
        } else {
            receiveTranslatedWriteRequest(nameObject, root);
        }
        cJSON_Delete(root);
    } else {
        debug("Unable to parse JSON from \"%s\" -- if it's valid, "
                "may be out of memory\r\n", message);
    }
    return foundMessage;
}

bool receiveWriteRequest(uint8_t* message) {
#ifdef TRANSMITTER
    receiveBinaryWriteRequest(message);
    return true;
#else
    return receiveJsonWriteRequest(message);
#endif
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the serial monitor.
 */
void receiveCan(CanBus* bus) {
    // TODO what happens if we process until the queue is empty?
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        decodeCanMessage(message.id, message.data);
    }
}

void reset() {
    initializeAllCan();
}

#endif // CAN_EMULATOR
<commit_msg>Some bug fixes, and a comment explaining the expected data format in the CAN message parser.<commit_after>#ifndef CAN_EMULATOR

#include "usbutil.h"
#include "canread.h"
#include "serialutil.h"
#include "signals.h"
#include "log.h"
#include "cJSON.h"
#include "listener.h"
#include <stdint.h>

extern SerialDevice SERIAL_DEVICE;
extern UsbDevice USB_DEVICE;
extern Listener listener;

/* Forward declarations */

void receiveCan(CanBus*);
void initializeAllCan();
bool receiveWriteRequest(uint8_t*);

void setup() {
    initializeLogging();
#ifndef NO_UART
    initializeSerial(&SERIAL_DEVICE);
#endif
    initializeUsb(&USB_DEVICE);
    initializeAllCan();
}

void loop() {
    for(int i = 0; i < getCanBusCount(); i++) {
        receiveCan(&getCanBuses()[i]);
    }
    processListenerQueues(&listener);
    readFromHost(&USB_DEVICE, &receiveWriteRequest);
#ifndef NO_UART
    readFromSerial(&SERIAL_DEVICE, &receiveWriteRequest);
#endif
    for(int i = 0; i < getCanBusCount(); i++) {
        processCanWriteQueue(&getCanBuses()[i]);
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        initializeCan(&(getCanBuses()[i]));
    }
}

void receiveRawWriteRequest(cJSON* idObject, cJSON* root) {
    uint32_t id = idObject->valueint;
    cJSON* dataObject = cJSON_GetObjectItem(root, "data");
    if(dataObject == NULL) {
        debug("Raw write request missing data\r\n", id);
        return;
    }

    char* dataString = dataObject->valuestring;
    char* end;
    unsigned long long data = __builtin_bswap64(strtoull(dataString, &end, 16));
    CanMessage message = {id, data};
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, message);
}

void receiveBinaryWriteRequest(uint8_t* message) {

  //Expecting a leading '{' followed by a 4 byte message ID, 
  // followed by a seperator '|', followed by 8 bytes of data,
  // then a trailing '}'
    int index = 0;
    const int BINARY_CAN_WRITE_PACKET_LENGTH = 15;
    debug(".");
    while((message[index] != '!')  && (index + BINARY_CAN_WRITE_PACKET_LENGTH < 64)) {
        
	if(message[index] != '{' || message[index+5] != '|'
                || message[index+14] != '}') {
            debug("Received a corrupted CAN message.\r\n");
            for(int i = 0; i < 16; i++) {
                debug("%02x ", message[index+i] );
            }
            debug("\r\n");
	    continue;
        }

        CanMessage outgoing = {0, 0};
        memcpy((uint8_t*)&outgoing.id, &message[index+1], 4);
        for(int i = 0; i < 8; i++) {
            ((uint8_t*)&(outgoing.data))[i] = message[index+i+6];
        }
        QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, outgoing);
	index += BINARY_CAN_WRITE_PACKET_LENGTH;
    }
}

void receiveTranslatedWriteRequest(cJSON* nameObject, cJSON* root) {
    char* name = nameObject->valuestring;
    cJSON* value = cJSON_GetObjectItem(root, "value");
    if(value == NULL) {
        debug("Write request for %s missing value\r\n", name);
        return;
    }

    CanSignal* signal = lookupSignal(name, getSignals(),
            getSignalCount(), true);
    CanCommand* command = lookupCommand(name, getCommands(),
            getCommandCount());
    if(signal != NULL) {
        sendCanSignal(signal, value, getSignals(), getSignalCount());
    } else if(command != NULL) {
        command->handler(name, value, getSignals(), getSignalCount());
    } else {
        debug("Writing not allowed for signal with name %s\r\n", name);
    }
}

bool receiveJsonWriteRequest(uint8_t* message) {
    cJSON *root = cJSON_Parse((char*)message);
    bool foundMessage = false;
    if(root != NULL) {
        foundMessage = true;
        cJSON* nameObject = cJSON_GetObjectItem(root, "name");
        if(nameObject == NULL) {
            cJSON* idObject = cJSON_GetObjectItem(root, "id");
            if(idObject == NULL) {
                debug("Write request is malformed, "
                        "missing name or id: %s\r\n", message);
            } else {
                receiveRawWriteRequest(idObject, root);
            }
        } else {
            receiveTranslatedWriteRequest(nameObject, root);
        }
        cJSON_Delete(root);
    } else {
        debug("Unable to parse JSON from \"%s\" -- if it's valid, "
                "may be out of memory\r\n", message);
    }
    return foundMessage;
}

bool receiveWriteRequest(uint8_t* message) {
#ifdef TRANSMITTER
    receiveBinaryWriteRequest(message);
    return true;
#else
    return receiveJsonWriteRequest(message);
#endif
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the serial monitor.
 */
void receiveCan(CanBus* bus) {
    // TODO what happens if we process until the queue is empty?
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        decodeCanMessage(message.id, message.data);
    }
}

void reset() {
    initializeAllCan();
}

#endif // CAN_EMULATOR

{'fraction_non_alphanumeric': 0.13691756272401434, 'fraction_numerical': 0.007782898105478751, 'mean_word_length': 2.933145388642771, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2187115', 'n_tokens_mistral': 3167, 'n_tokens_neox': 3064, 'n_words': 732}