diff --git a/dev_handler/dev_handler.c b/dev_handler/dev_handler.c old mode 100755 new mode 100644 index 862ca3e9..d3afbbf6 --- a/dev_handler/dev_handler.c +++ b/dev_handler/dev_handler.c @@ -3,12 +3,12 @@ * acts as the interface between the devices and shared memory */ -#include // for POSIX terminal control definitions in serialport_open() +#include // for POSIX terminal control definitions in serialport_open() -#include "message.h" -#include "../shm_wrapper/shm_wrapper.h" -#include "../runtime_util/runtime_util.h" #include "../logger/logger.h" +#include "../runtime_util/runtime_util.h" +#include "../shm_wrapper/shm_wrapper.h" +#include "message.h" // ********************************* CONFIG ********************************* // @@ -25,16 +25,16 @@ * when the device disconnects or times out */ typedef struct { - pthread_t sender; // Thread to build and send outgoing messages - pthread_t receiver; // Thread to receive and process all incoming messages - pthread_t relayer; // Thread to get ACKNOWLEDGEMENT and monitor disconnect/timeout - uint8_t port_num; // Where device is connected to "/" - int file_descriptor; // Obtained from opening port. Used to close port. - int shm_dev_idx; // The unique index assigned to the device by shm_wrapper for shared memory operations on device_connect() - dev_id_t dev_id; // set by relayer once ACKNOWLEDGEMENT is received - uint64_t last_received_msg_time; // set by receiver: Timestamp of the most recent message from the device - pthread_mutex_t relay_lock; // Mutex on relay->last_received_msg_time - pthread_cond_t start_cond; // Conditional variable for relayer to broadcast to sender and receiver to start work + pthread_t sender; // Thread to build and send outgoing messages + pthread_t receiver; // Thread to receive and process all incoming messages + pthread_t relayer; // Thread to get ACKNOWLEDGEMENT and monitor disconnect/timeout + uint8_t port_num; // Where device is connected to "/" + int file_descriptor; // Obtained from opening port. Used to close port. + int shm_dev_idx; // The unique index assigned to the device by shm_wrapper for shared memory operations on device_connect() + dev_id_t dev_id; // set by relayer once ACKNOWLEDGEMENT is received + uint64_t last_received_msg_time; // set by receiver: Timestamp of the most recent message from the device + pthread_mutex_t relay_lock; // Mutex on relay->last_received_msg_time + pthread_cond_t start_cond; // Conditional variable for relayer to broadcast to sender and receiver to start work } relay_t; // ************************** FUNCTION DECLARATIONS ************************* // @@ -45,36 +45,36 @@ void stop(); void poll_connected_devices(); // Polling Utility -int get_new_devices(uint32_t *bitmap); +int get_new_devices(uint32_t* bitmap); // Threads for communicating with devices void communicate(uint8_t port_num); -void *relayer(void *relay_cast); -void relay_clean_up(relay_t *relay); -void *sender(void *relay_cast); -void *receiver(void *relay_cast); +void* relayer(void* relay_cast); +void relay_clean_up(relay_t* relay); +void* sender(void* relay_cast); +void* receiver(void* relay_cast); // Device communication -int send_message(relay_t *relay, message_t *msg); -int receive_message(relay_t *relay, message_t *msg); -int verify_lowcar(relay_t *relay); +int send_message(relay_t* relay, message_t* msg); +int receive_message(relay_t* relay, message_t* msg); +int verify_lowcar(relay_t* relay); // Serial port or socket opening and closing -int connect_socket(const char *socket_name); -int serialport_open(const char *port_name); +int connect_socket(const char* socket_name); +int serialport_open(const char* port_name); int serialport_close(int fd); // Utility -void cleanup_handler(void *args); +void cleanup_handler(void* args); // **************************** GLOBAL VARIABLES **************************** // // The file name prefix of where to find devices, preceeding the port number -char *port_prefix = "/dev/ttyACM"; +char* port_prefix = "/dev/ttyACM"; // Bitmap indicating whether port "*" is being monitored by dev handler, where * is the *-th bit // Bits are turned on in get_new_devices() and turned off on disconnect/timeout in relay_clean_up() uint32_t used_ports = 0; -pthread_mutex_t used_ports_lock; // poll_connected_devices() and relay_clean_up() shouldn't access used_ports at the same time +pthread_mutex_t used_ports_lock; // poll_connected_devices() and relay_clean_up() shouldn't access used_ports at the same time // ***************************** MAIN FUNCTIONS ***************************** // @@ -126,7 +126,7 @@ void poll_connected_devices() { } } connected_devs = 0; - // Save CPU usage by checking for new devices only every so often (defined in runtime_util.h) + // Save CPU usage by checking for new devices only every so often (defined in runtime_util.h) usleep(POLL_INTERVAL); } } @@ -140,7 +140,7 @@ void poll_connected_devices() { * Returns: * the number of devices that were found */ -int get_new_devices(uint32_t *bitmap) { +int get_new_devices(uint32_t* bitmap) { char port_name[14]; uint8_t num_devices_found = 0; // Check every port @@ -175,19 +175,19 @@ int get_new_devices(uint32_t *bitmap) { * port_num: The port number of the new device to connect to */ void communicate(uint8_t port_num) { - relay_t *relay = malloc(sizeof(relay_t)); + relay_t* relay = malloc(sizeof(relay_t)); relay->port_num = port_num; - char port_name[15]; // Template size + 2 indices for port_number + char port_name[15]; // Template size + 2 indices for port_number sprintf(port_name, "%s%d", port_prefix, relay->port_num); - if (strcmp(port_prefix, "/tmp/ttyACM") == 0) { // Bind to socket + if (strcmp(port_prefix, "/tmp/ttyACM") == 0) { // Bind to socket relay->file_descriptor = connect_socket(port_name); if (relay->file_descriptor == -1) { // log_printf(ERROR, "communicate: Couldn't connect to socket %s\n", port_name); relay_clean_up(relay); return; } - } else { // Open serial port + } else { // Open serial port relay->file_descriptor = serialport_open(port_name); if (relay->file_descriptor == -1) { log_printf(ERROR, "communicate: Couldn't open port %s\n", port_name); @@ -226,8 +226,8 @@ void communicate(uint8_t port_num) { * Arguments: * relay_cast: uncasted relay_t struct containing device info */ -void *relayer(void *relay_cast) { - relay_t *relay = relay_cast; +void* relayer(void* relay_cast) { + relay_t* relay = relay_cast; int ret; // Verify that the device is a lowcar device @@ -282,10 +282,10 @@ void *relayer(void *relay_cast) { * Arguments: * relay: Struct containing device/thread info used to clean up */ -void relay_clean_up(relay_t *relay) { +void relay_clean_up(relay_t* relay) { // If couldn't connect to device in the first place, just mark as unused if (relay->file_descriptor == -1) { - used_ports &= ~(1 << relay->port_num); // Set bit to 0 to indicate unused + used_ports &= ~(1 << relay->port_num); // Set bit to 0 to indicate unused free(relay); sleep(TIMEOUT / 1000); return; @@ -316,7 +316,7 @@ void relay_clean_up(relay_t *relay) { if ((ret = pthread_mutex_lock(&used_ports_lock))) { log_printf(ERROR, "relay_clean_up: used_ports_lock mutex lock failed with code %d", ret); } - used_ports &= ~(1 << relay->port_num); // Set bit to 0 to indicate unused + used_ports &= ~(1 << relay->port_num); // Set bit to 0 to indicate unused pthread_mutex_unlock(&used_ports_lock); pthread_mutex_destroy(&relay->relay_lock); pthread_cond_destroy(&relay->start_cond); @@ -333,12 +333,12 @@ void relay_clean_up(relay_t *relay) { * Arguments: * relay_cast: Uncasted relay_t struct containing device info */ -void *sender(void *relay_cast) { - relay_t *relay = relay_cast; +void* sender(void* relay_cast) { + relay_t* relay = relay_cast; // Wait until relayer gets an ACKNOWLEDGEMENT pthread_mutex_lock(&relay->relay_lock); - pthread_cleanup_push(&cleanup_handler, (void *)relay); + pthread_cleanup_push(&cleanup_handler, (void*) relay); pthread_cond_wait(&relay->start_cond, &relay->relay_lock); pthread_cleanup_pop(1); @@ -347,15 +347,15 @@ void *sender(void *relay_cast) { // Start doing work uint32_t pmap[MAX_DEVICES + 1]; - param_val_t *params = malloc(MAX_PARAMS * sizeof(param_val_t)); // Array of params to be filled on device_read() + param_val_t* params = malloc(MAX_PARAMS * sizeof(param_val_t)); // Array of params to be filled on device_read() uint32_t sub_map[MAX_DEVICES + 1]; - message_t *msg; // Message to build - int ret; // Hold the value from send_message() + message_t* msg; // Message to build + int ret; // Hold the value from send_message() uint64_t last_sent_ping_time = millis(); while (1) { // Write to device if needed via a DEVICE_WRITE message get_cmd_map(pmap); - if (pmap[0] & (1 << relay->shm_dev_idx)) { // If bit i in pmap[0] != 0, there are values to write to device i + if (pmap[0] & (1 << relay->shm_dev_idx)) { // If bit i in pmap[0] != 0, there are values to write to device i // Read the new parameter values to write from shared memory as DEV_HANDLER from the COMMAND stream device_read(relay->shm_dev_idx, DEV_HANDLER, COMMAND, pmap[1 + relay->shm_dev_idx], params); // Serialize and bulk transfer a DeviceWrite packet with PARAMS to the device @@ -381,7 +381,7 @@ void *sender(void *relay_cast) { // Send another SUBSCRIPTION_REQUEST if requested get_sub_requests(sub_map, DEV_HANDLER); - if (sub_map[0] & (1 << relay->shm_dev_idx)) { // If bit i in sub_map[0] != 0, there is a new SUBSCRIPTION_REQUEST to be sent to device i + if (sub_map[0] & (1 << relay->shm_dev_idx)) { // If bit i in sub_map[0] != 0, there is a new SUBSCRIPTION_REQUEST to be sent to device i msg = make_subscription_request(relay->dev_id.type, sub_map[1 + relay->shm_dev_idx], SUB_INTERVAL); ret = send_message(relay, msg); if (ret != 0) { @@ -391,7 +391,7 @@ void *sender(void *relay_cast) { } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_testcancel(); // Cancellation point + pthread_testcancel(); // Cancellation point pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); usleep(1000); } @@ -404,12 +404,12 @@ void *sender(void *relay_cast) { * Arguments: * relay_cast: uncasted relay_t struct containing device info */ -void *receiver(void *relay_cast) { - relay_t *relay = relay_cast; +void* receiver(void* relay_cast) { + relay_t* relay = relay_cast; // Wait until relayer gets an ACKNOWLEDGEMENT pthread_mutex_lock(&relay->relay_lock); - pthread_cleanup_push(&cleanup_handler, (void *)relay); + pthread_cleanup_push(&cleanup_handler, (void*) relay); pthread_cond_wait(&relay->start_cond, &relay->relay_lock); pthread_cleanup_pop(1); @@ -418,9 +418,9 @@ void *receiver(void *relay_cast) { // Start doing work! // An empty message to parse the received data into - message_t *msg = make_empty(MAX_PAYLOAD_SIZE); + message_t* msg = make_empty(MAX_PAYLOAD_SIZE); // An array of empty parameter values to be populated from DeviceData message payloads and written to shared memory - param_val_t *vals = malloc(MAX_PARAMS * sizeof(param_val_t)); + param_val_t* vals = malloc(MAX_PARAMS * sizeof(param_val_t)); while (1) { // Try to read a message if (receive_message(relay, msg) != 0) { @@ -435,13 +435,13 @@ void *receiver(void *relay_cast) { // Handle message if (msg->message_id == DEVICE_DATA) { // If received DEVICE_DATA, write to shared memory - parse_device_data(relay->dev_id.type, msg, vals); // Get param values from payload - device_write(relay->shm_dev_idx, DEV_HANDLER, DATA, *((uint32_t *)msg->payload), vals); + parse_device_data(relay->dev_id.type, msg, vals); // Get param values from payload + device_write(relay->shm_dev_idx, DEV_HANDLER, DATA, *((uint32_t*) msg->payload), vals); } else if (msg->message_id == LOG) { // If received LOG, send it to the logger log_printf(DEBUG, "[%s (0x%016llX)]: %s", get_device_name(relay->dev_id.type), relay->dev_id.uid, msg->payload); } - } else { // Invalid message type + } else { // Invalid message type log_printf(WARN, "Dropped bad message (type %d) from %s (0x%016llX)", msg->message_id, get_device_name(relay->dev_id.type), relay->dev_id.uid); } // Now that the message is taken care of, clear the message @@ -450,7 +450,7 @@ void *receiver(void *relay_cast) { msg->max_payload_length = MAX_PAYLOAD_SIZE; memset(msg->payload, 0, MAX_PAYLOAD_SIZE); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_testcancel(); // Cancellation point + pthread_testcancel(); // Cancellation point pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); } return NULL; @@ -468,9 +468,9 @@ void *receiver(void *relay_cast) { * 0 if successful * -1 if couldn't write all the bytes */ -int send_message(relay_t *relay, message_t *msg) { +int send_message(relay_t* relay, message_t* msg) { int len = calc_max_cobs_msg_length(msg); - uint8_t *data = malloc(len); + uint8_t* data = malloc(len); len = message_to_bytes(msg, data, len); int transferred = writen(relay->file_descriptor, data, len); if (transferred != len) { @@ -493,8 +493,8 @@ int send_message(relay_t *relay, message_t *msg) { * 2 on incorrect checksum * 3 on timeout */ -int receive_message(relay_t *relay, message_t *msg) { - uint8_t last_byte_read = 0; // Variable to temporarily hold a read byte +int receive_message(relay_t* relay, message_t* msg) { + uint8_t last_byte_read = 0; // Variable to temporarily hold a read byte int num_bytes_read = 0; if (relay->dev_id.uid == -1) { @@ -514,17 +514,16 @@ int receive_message(relay_t *relay, message_t *msg) { log_printf(WARN, "Attempting to read delimiter but got 0x%02X from %s%d\n", last_byte_read, port_prefix, relay->port_num); return 1; } - } else { // Receiving from a verified lowcar device + } else { // Receiving from a verified lowcar device // Keep reading a byte until we get the delimiter byte while (1) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - num_bytes_read = readn(relay->file_descriptor, &last_byte_read, 1); // Waiting for first byte can block + num_bytes_read = readn(relay->file_descriptor, &last_byte_read, 1); // Waiting for first byte can block if (num_bytes_read == 0) { // received EOF so sleep to make device disconnected sleep(TIMEOUT / 1000 + 1); return 1; - } - else if (num_bytes_read == -1) { + } else if (num_bytes_read == -1) { log_printf(ERROR, "receive_message: error reading from file: %s", strerror(errno)); return 1; } @@ -543,18 +542,18 @@ int receive_message(relay_t *relay, message_t *msg) { num_bytes_read = readn(relay->file_descriptor, &cobs_len, 1); if (num_bytes_read != 1) { return 1; - } else if (cobs_len > (MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + MAX_PAYLOAD_SIZE + CHECKSUM_SIZE + 1)) { // + 1 for cobs encoding overhead + } else if (cobs_len > (MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + MAX_PAYLOAD_SIZE + CHECKSUM_SIZE + 1)) { // + 1 for cobs encoding overhead // Got some weird message that is unusually long (longer than a valid message with the longest payload) log_printf(WARN, "Received a cobs length that is too large"); return 1; - } else if (cobs_len < (MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + CHECKSUM_SIZE + 1)) { // + 1 for cobs encoding overhead + } else if (cobs_len < (MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + CHECKSUM_SIZE + 1)) { // + 1 for cobs encoding overhead // Got some weird message that is unusually short (shorter than a PING with no payload) log_printf(WARN, "Received a cobs length that is too small"); return 1; } // Allocate buffer to read message into - uint8_t *data = malloc(DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_len); + uint8_t* data = malloc(DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_len); data[0] = 0x00; data[1] = cobs_len; @@ -587,9 +586,9 @@ int receive_message(relay_t *relay, message_t *msg) { * 1 if Ping message couldn't be sent * 2 if ACKNOWLEDGEMENT wasn't received */ -int verify_lowcar(relay_t *relay) { +int verify_lowcar(relay_t* relay) { // Send a Ping - message_t *ping = make_ping(); + message_t* ping = make_ping(); int ret = send_message(relay, ping); destroy_message(ping); if (ret != 0) { @@ -597,7 +596,7 @@ int verify_lowcar(relay_t *relay) { } // Try to read an ACKNOWLEDGEMENT, which we expect from a lowcar device that receives a PING - message_t *ack = make_empty(MAX_PAYLOAD_SIZE); + message_t* ack = make_empty(MAX_PAYLOAD_SIZE); ret = receive_message(relay, ack); if (ret != 0) { log_printf(DEBUG, "Didn't receive ACK"); @@ -616,11 +615,11 @@ int verify_lowcar(relay_t *relay) { * In serialport_open(), we set read() to timeout specifically for waiting for ACK */ if (strcmp(port_prefix, "/dev/ttyACM") == 0) { struct termios toptions; - if (tcgetattr(relay->file_descriptor, &toptions) < 0) { // Get current options + if (tcgetattr(relay->file_descriptor, &toptions) < 0) { // Get current options log_printf(ERROR, "verify_lowcar: Couldn't get term attributes for %s (0x%016llX)", get_device_name(relay->dev_id.type), relay->dev_id.uid); return -1; } - toptions.c_cc[VMIN] = 1; // read() must read at least a byte before returning + toptions.c_cc[VMIN] = 1; // read() must read at least a byte before returning // Save changes to TOPTIONS immediately using flag TCSANOW tcsetattr(relay->file_descriptor, TCSANOW, &toptions); if (tcsetattr(relay->file_descriptor, TCSAFLUSH, &toptions) < 0) { @@ -632,7 +631,7 @@ int verify_lowcar(relay_t *relay) { // Parse ACKNOWLEDGEMENT payload into relay->dev_id_t memcpy(&relay->dev_id.type, &ack->payload[0], 1); memcpy(&relay->dev_id.year, &ack->payload[1], 1); - memcpy(&relay->dev_id.uid , &ack->payload[2], 8); + memcpy(&relay->dev_id.uid, &ack->payload[2], 8); log_printf(INFO, "Connected %s (0x%016llX) from year %d!", get_device_name(relay->dev_id.type), relay->dev_id.uid, relay->dev_id.year); relay->last_received_msg_time = millis(); destroy_message(ack); @@ -649,7 +648,7 @@ int verify_lowcar(relay_t *relay) { * A valid file_descriptor, or * -1 on error */ -int connect_socket(const char *socket_name) { +int connect_socket(const char* socket_name) { // Make a local socket for sending/receiving raw byte streams int fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { @@ -661,7 +660,7 @@ int connect_socket(const char *socket_name) { struct sockaddr_un dev_socket_addr = {0}; dev_socket_addr.sun_family = AF_UNIX; strcpy(dev_socket_addr.sun_path, socket_name); - if (connect(fd, (struct sockaddr *) &dev_socket_addr, sizeof(dev_socket_addr)) != 0) { + if (connect(fd, (struct sockaddr*) &dev_socket_addr, sizeof(dev_socket_addr)) != 0) { log_printf(ERROR, "connect_socket: Couldn't connect socket %s--%s", dev_socket_addr.sun_path, strerror(errno)); remove(socket_name); return -1; @@ -671,7 +670,7 @@ int connect_socket(const char *socket_name) { struct timeval tv; tv.tv_sec = TIMEOUT / 1000; tv.tv_usec = 0; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)); + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof(tv)); return fd; } @@ -687,10 +686,10 @@ int connect_socket(const char *socket_name) { * A valid file_descriptor, or * -1 on error */ -int serialport_open(const char *port_name) { +int serialport_open(const char* port_name) { // Open the serialport for reading and writing int fd = open(port_name, O_RDWR); - if (fd == -1) { + if (fd == -1) { log_printf(ERROR, "serialport_open: Unable to open port %s", port_name); return -1; } @@ -708,18 +707,18 @@ int serialport_open(const char *port_name) { // Update serialport options: https://linux.die.net/man/3/cfsetspeed // Set serialport config to 8-N-1, which is default for Arduino Serial.begin() - toptions.c_cflag &= ~CSIZE; // Reset character size - toptions.c_cflag |= CS8; // Set character size to 8 - toptions.c_cflag &= ~PARENB; // Disable parity generation on output and parity checking for input (N) - toptions.c_cflag &= ~CSTOPB; // Set only one stop bit (1) + toptions.c_cflag &= ~CSIZE; // Reset character size + toptions.c_cflag |= CS8; // Set character size to 8 + toptions.c_cflag &= ~PARENB; // Disable parity generation on output and parity checking for input (N) + toptions.c_cflag &= ~CSTOPB; // Set only one stop bit (1) // Disables special processing of input and output bytes. See https://linux.die.net/man/3/cfsetspeed cfmakeraw(&toptions); // Set options for read(fd, buffer, num_bytes_to_read) // see: http://unixwiz.net/techtips/termios-vmin-vtime.html - toptions.c_cc[VMIN] = 0; // Until receiving ACK, do not block indefinitely (use timeout) - toptions.c_cc[VTIME] = TIMEOUT / 100; // Number of deciseconds to timeout + toptions.c_cc[VMIN] = 0; // Until receiving ACK, do not block indefinitely (use timeout) + toptions.c_cc[VTIME] = TIMEOUT / 100; // Number of deciseconds to timeout // Save changes to TOPTIONS. (Flag TCSANOW saves immediately) tcsetattr(fd, TCSANOW, &toptions); @@ -751,14 +750,14 @@ int serialport_close(int fd) { * Arguments: * args: Uncasted relay_t containing mutex requiring unlocking */ -void cleanup_handler (void *args) { - relay_t *relay = (relay_t *)args; +void cleanup_handler(void* args) { + relay_t* relay = (relay_t*) args; pthread_mutex_unlock(&relay->relay_lock); } // ********************************** MAIN ********************************** // -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { // If SIGINT (Ctrl+C) is received, call stop() to clean up signal(SIGINT, stop); init(); diff --git a/dev_handler/message.c b/dev_handler/message.c old mode 100755 new mode 100644 index ce1540ef..32e584af --- a/dev_handler/message.c +++ b/dev_handler/message.c @@ -2,7 +2,7 @@ // ******************************** Utility ********************************* // -void print_bytes(uint8_t *data, size_t len) { +void print_bytes(uint8_t* data, size_t len) { printf("0x"); for (int i = 0; i < len; i++) { printf("%02X ", data[i]); @@ -23,7 +23,7 @@ void print_bytes(uint8_t *data, size_t len) { */ static size_t device_write_payload_size(uint8_t device_type, uint32_t param_bitmap) { size_t result = BITMAP_SIZE; - device_t *dev = get_device(device_type); + device_t* dev = get_device(device_type); // Loop through each of the device's parameters and add the size of the parameter for (int i = 0; ((param_bitmap >> i) > 0) && (i < MAX_PARAMS); i++) { // Include parameter i if the i-th bit is on @@ -55,7 +55,7 @@ static size_t device_write_payload_size(uint8_t device_type, uint32_t param_bitm * 0 if successful * -1 if max_payload_length is too small */ -static int append_payload(message_t *msg, uint8_t *data, size_t len) { +static int append_payload(message_t* msg, uint8_t* data, size_t len) { memcpy(&(msg->payload[msg->payload_length]), data, len); msg->payload_length += len; return (msg->payload_length > msg->max_payload_length) ? -1 : 0; @@ -69,7 +69,7 @@ static int append_payload(message_t *msg, uint8_t *data, size_t len) { * Returns: * The checksum of DATA */ -static uint8_t checksum(uint8_t *data, size_t len) { +static uint8_t checksum(uint8_t* data, size_t len) { uint8_t chk = data[0]; for (int i = 1; i < len; i++) { chk ^= data[i]; @@ -80,13 +80,14 @@ static uint8_t checksum(uint8_t *data, size_t len) { /** * A macro to help with cobs_encode */ -#define finish_block() {\ - block[0] = (uint8_t) block_len; \ - block = dst; \ - dst++; \ - dst_len++; \ - block_len = 1; \ -}; +#define finish_block() \ + { \ + block[0] = (uint8_t) block_len; \ + block = dst; \ + dst++; \ + dst_len++; \ + block_len = 1; \ + }; /** * Cobs encodes a byte array into a buffer @@ -97,9 +98,9 @@ static uint8_t checksum(uint8_t *data, size_t len) { * Returns: * The size of the encoded data, DST */ -static ssize_t cobs_encode(uint8_t *dst, const uint8_t *src, size_t src_len) { - const uint8_t *end = src + src_len; - uint8_t *block = dst; // Advancing pointer to start of each block +static ssize_t cobs_encode(uint8_t* dst, const uint8_t* src, size_t src_len) { + const uint8_t* end = src + src_len; + uint8_t* block = dst; // Advancing pointer to start of each block dst++; size_t block_len = 1; ssize_t dst_len = 0; @@ -142,9 +143,9 @@ static ssize_t cobs_encode(uint8_t *dst, const uint8_t *src, size_t src_len) { * Returns: * The size of the decoded data, DST */ -static ssize_t cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len) { +static ssize_t cobs_decode(uint8_t* dst, const uint8_t* src, size_t src_len) { // Pointer to end of source array - const uint8_t *end = src + src_len; + const uint8_t* end = src + src_len; // Size counter of decoded array to return ssize_t out_len = 0; @@ -156,7 +157,7 @@ static ssize_t cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len) { dst++; src++; out_len++; - if (src > end) { // Bad packet + if (src > end) { // Bad packet return 0; } } @@ -171,8 +172,8 @@ static ssize_t cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len) { // ************************* MESSAGE CONSTRUCTORS *************************** // -message_t *make_empty(ssize_t payload_size) { - message_t *msg = malloc(sizeof(message_t)); +message_t* make_empty(ssize_t payload_size) { + message_t* msg = malloc(sizeof(message_t)); msg->message_id = NOP; msg->payload = malloc(payload_size); msg->payload_length = 0; @@ -180,8 +181,8 @@ message_t *make_empty(ssize_t payload_size) { return msg; } -message_t *make_ping() { - message_t *ping = malloc(sizeof(message_t)); +message_t* make_ping() { + message_t* ping = malloc(sizeof(message_t)); ping->message_id = PING; ping->payload = NULL; ping->payload_length = 0; @@ -189,17 +190,17 @@ message_t *make_ping() { return ping; } -message_t *make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t interval) { - device_t *dev = get_device(dev_type); +message_t* make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t interval) { + device_t* dev = get_device(dev_type); // Don't read from non-existent params - pmap &= ((uint32_t) -1) >> (MAX_PARAMS - dev->num_params); // Set non-existent params to 0 + pmap &= ((uint32_t) -1) >> (MAX_PARAMS - dev->num_params); // Set non-existent params to 0 // Set non-read-able params to 0 for (int i = 0; i < MAX_PARAMS; i++) { if (dev->params[i].read == 0) { - pmap &= ~(1 << i); // Set bit i to 0 + pmap &= ~(1 << i); // Set bit i to 0 } } - message_t *sub_request = malloc(sizeof(message_t)); + message_t* sub_request = malloc(sizeof(message_t)); sub_request->message_id = SUBSCRIPTION_REQUEST; sub_request->payload = malloc(BITMAP_SIZE + INTERVAL_SIZE); sub_request->payload_length = 0; @@ -211,18 +212,18 @@ message_t *make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t i return (status == 0) ? sub_request : NULL; } -message_t *make_device_write(uint8_t dev_type, uint32_t pmap, param_val_t param_values[]) { - device_t *dev = get_device(dev_type); +message_t* make_device_write(uint8_t dev_type, uint32_t pmap, param_val_t param_values[]) { + device_t* dev = get_device(dev_type); // Don't write to non-existent params - pmap &= ((uint32_t) -1) >> (MAX_PARAMS - dev->num_params); // Set non-existent params to 0 + pmap &= ((uint32_t) -1) >> (MAX_PARAMS - dev->num_params); // Set non-existent params to 0 // Set non-writeable params to 0 for (int i = 0; ((pmap >> i) > 0) && (i < MAX_PARAMS); i++) { if (dev->params[i].write == 0) { - pmap &= ~(1 << i); // Set bit i to 0 + pmap &= ~(1 << i); // Set bit i to 0 } } // Build the message - message_t *dev_write = malloc(sizeof(message_t)); + message_t* dev_write = malloc(sizeof(message_t)); dev_write->message_id = DEVICE_WRITE; dev_write->payload_length = 0; dev_write->max_payload_length = device_write_payload_size(dev_type, pmap); @@ -250,14 +251,14 @@ message_t *make_device_write(uint8_t dev_type, uint32_t pmap, param_val_t param_ return (status == 0) ? dev_write : NULL; } -void destroy_message(message_t *message) { +void destroy_message(message_t* message) { free(message->payload); free(message); } // ********************* SERIALIZE AND PARSE MESSAGES *********************** // -size_t calc_max_cobs_msg_length(message_t *msg){ +size_t calc_max_cobs_msg_length(message_t* msg) { size_t required_packet_length = MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + msg->payload_length + CHECKSUM_SIZE; // Cobs encoding a length N message adds overhead of at most ceil(N/254) size_t cobs_length = required_packet_length + (required_packet_length / 254) + 1; @@ -267,13 +268,13 @@ size_t calc_max_cobs_msg_length(message_t *msg){ return DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_length; } -ssize_t message_to_bytes(message_t *msg, uint8_t cobs_encoded[], size_t len) { +ssize_t message_to_bytes(message_t* msg, uint8_t cobs_encoded[], size_t len) { size_t required_length = calc_max_cobs_msg_length(msg); if (len < required_length) { return -1; } // Build an intermediate byte array to hold the serialized message to be encoded - uint8_t *data = malloc(MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + msg->payload_length + CHECKSUM_SIZE); + uint8_t* data = malloc(MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + msg->payload_length + CHECKSUM_SIZE); data[0] = msg->message_id; data[1] = msg->payload_length; for (int i = 0; i < msg->payload_length; i++) { @@ -289,9 +290,9 @@ ssize_t message_to_bytes(message_t *msg, uint8_t cobs_encoded[], size_t len) { return DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_len; } -int parse_message(uint8_t data[], message_t *msg_to_fill) { +int parse_message(uint8_t data[], message_t* msg_to_fill) { uint8_t cobs_len = data[1]; - uint8_t *decoded = malloc(cobs_len); // Actual number of bytes populated will be a couple less due to overhead + uint8_t* decoded = malloc(cobs_len); // Actual number of bytes populated will be a couple less due to overhead int ret = cobs_decode(decoded, &data[2], cobs_len); if (ret < (MESSAGE_ID_SIZE + PAYLOAD_LENGTH_SIZE + CHECKSUM_SIZE)) { // Smaller than valid message @@ -319,13 +320,13 @@ int parse_message(uint8_t data[], message_t *msg_to_fill) { return (expected_checksum != received_checksum) ? 1 : 0; } -void parse_device_data(uint8_t dev_type, message_t *dev_data, param_val_t vals[]) { - device_t *dev = get_device(dev_type); +void parse_device_data(uint8_t dev_type, message_t* dev_data, param_val_t vals[]) { + device_t* dev = get_device(dev_type); // Bitmap is stored in the first 32 bits of the payload uint32_t bitmap = *((uint32_t*) dev_data->payload); /* Iterate through device's parameters. If bit is off, continue * If bit is on, determine how much to read from the payload then put it in VALS in the appropriate field */ - uint8_t *payload_ptr = &(dev_data->payload[BITMAP_SIZE]); // Start the pointer at the beginning of the values (skip the bitmap) + uint8_t* payload_ptr = &(dev_data->payload[BITMAP_SIZE]); // Start the pointer at the beginning of the values (skip the bitmap) for (int i = 0; ((bitmap >> i) > 0) && (i < MAX_PARAMS); i++) { // If bit is on, parameter is included in the payload if ((1 << i) & bitmap) { diff --git a/dev_handler/message.h b/dev_handler/message.h old mode 100755 new mode 100644 index 87f593e5..59d1bffb --- a/dev_handler/message.h +++ b/dev_handler/message.h @@ -10,8 +10,8 @@ #ifndef MESSAGE_H #define MESSAGE_H -#include "../runtime_util/runtime_util.h" #include "../logger/logger.h" +#include "../runtime_util/runtime_util.h" /* The maximum number of milliseconds to wait between each PING from a device * Waiting for this long will exit all threads for that device (doing cleanup as necessary) */ @@ -29,7 +29,7 @@ // The size in bytes of the section specifying the length of the payload in the message #define PAYLOAD_LENGTH_SIZE 1 // The size in bytes of the param bitmap in SUBSCRIPTION_REQUEST, DEVICE_WRITE and DEVICE_DATA payloads -#define BITMAP_SIZE (MAX_PARAMS/8) +#define BITMAP_SIZE (MAX_PARAMS / 8) // The size in bytes of the section specifying the interval for SUBSCRIPTION_REQUEST #define INTERVAL_SIZE 2 // The size in bytes of the section specifying the device id for ACKNOWLEDGEMENT @@ -37,25 +37,25 @@ // The size in bytes of the section specifying the checksum of the message id, the payload length, and the payload itself #define CHECKSUM_SIZE 1 // The length of the largest payload in bytes, which may be reached for DEVICE_WRITE and DEVICE_DATA message types. -#define MAX_PAYLOAD_SIZE (BITMAP_SIZE+(MAX_PARAMS*sizeof(float))) // Bitmap + Each param (may be floats) +#define MAX_PAYLOAD_SIZE (BITMAP_SIZE + (MAX_PARAMS * sizeof(float))) // Bitmap + Each param (may be floats) // The types of messages typedef enum { - NOP = 0x00, // Dummy message - PING = 0x01, // To lowcar - ACKNOWLEDGEMENT = 0x02, // To dev handler - SUBSCRIPTION_REQUEST = 0x03, // To lowcar - DEVICE_WRITE = 0x04, // To lowcar - DEVICE_DATA = 0x05, // To dev handler - LOG = 0x06 // To dev handler + NOP = 0x00, // Dummy message + PING = 0x01, // To lowcar + ACKNOWLEDGEMENT = 0x02, // To dev handler + SUBSCRIPTION_REQUEST = 0x03, // To lowcar + DEVICE_WRITE = 0x04, // To lowcar + DEVICE_DATA = 0x05, // To dev handler + LOG = 0x06 // To dev handler } message_id_t; // A struct defining a message to be sent over serial typedef struct { message_id_t message_id; - uint8_t* payload; // Array of bytes - size_t payload_length; // The current number of bytes in payload - size_t max_payload_length; // The maximum length of the payload for the specific message_id + uint8_t* payload; // Array of bytes + size_t payload_length; // The current number of bytes in payload + size_t max_payload_length; // The maximum length of the payload for the specific message_id } message_t; // ******************************** Utility ********************************* // @@ -66,7 +66,7 @@ typedef struct { * data: Byte array to be printed * len: The length of the data array */ -void print_bytes(uint8_t *data, size_t len); +void print_bytes(uint8_t* data, size_t len); // ************************* MESSAGE CONSTRUCTORS *************************** // // Messages built from these constructors MUST be decalloated with destroy_message() @@ -79,7 +79,7 @@ void print_bytes(uint8_t *data, size_t len); * Returns: * A message of type NOP, payload_length 0, and max_payload_length PAYLOAD_SIZE */ -message_t *make_empty(ssize_t payload_size); +message_t* make_empty(ssize_t payload_size); /** * Builds a PING message @@ -88,7 +88,7 @@ message_t *make_empty(ssize_t payload_size); * payload_length 0 * max_payload_length 0 */ -message_t *make_ping(); +message_t* make_ping(); /** * Builds a SUBSCRIPTION_REQUEST @@ -102,7 +102,7 @@ message_t *make_ping(); * payload_length: sizeof(pmap) + sizeof(interval) * max_payload_length: same as above */ -message_t *make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t interval); +message_t* make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t interval); /** * Builds a DEVICE_WRITE @@ -117,14 +117,14 @@ message_t *make_subscription_request(uint8_t dev_type, uint32_t pmap, uint16_t i * payload_length: sizeof(pmap) + sizeof(all the values in PARAM_VALUES) * max_payload_length: same as above */ -message_t *make_device_write(uint8_t dev_type, uint32_t pmap, param_val_t param_values[]); +message_t* make_device_write(uint8_t dev_type, uint32_t pmap, param_val_t param_values[]); /** * Frees the memory allocated for the message struct and its payload. * Arguments: * message: The message to have its memory deallocated. */ -void destroy_message(message_t *message); +void destroy_message(message_t* message); // ********************* SERIALIZE AND PARSE MESSAGES *********************** // @@ -136,7 +136,7 @@ void destroy_message(message_t *message); * Returns: * The size of a byte array that should be allocated to serialize the message into */ -size_t calc_max_cobs_msg_length(message_t *msg); +size_t calc_max_cobs_msg_length(message_t* msg); /** * Serializes then cobs encodes a message into a byte array @@ -148,7 +148,7 @@ size_t calc_max_cobs_msg_length(message_t *msg); * The size of COBS_ENCODED that was actually populated * -1 if len is too small (less than calc_max_cobs_msg_length) */ -ssize_t message_to_bytes(message_t *msg, uint8_t cobs_encoded[], size_t len); +ssize_t message_to_bytes(message_t* msg, uint8_t cobs_encoded[], size_t len); /** * Cobs decodes a byte array and populates the fields of input message @@ -163,7 +163,7 @@ ssize_t message_to_bytes(message_t *msg, uint8_t cobs_encoded[], size_t len); * 2 if max_payload_length is too small * 3 if invalid message (decoded message has invalid length) */ -int parse_message(uint8_t data[], message_t *empty_msg); +int parse_message(uint8_t data[], message_t* empty_msg); /** * Reads the parameter values from a DEVICE_DATA message into param_val_t[] @@ -174,6 +174,6 @@ int parse_message(uint8_t data[], message_t *empty_msg); * NOTE: The length of vals MUST be at LEAST the number of params sent in the DEVICE_DATA message * Allocate MAX_PARAMS param_val_t structs to guarantee this */ -void parse_device_data(uint8_t dev_type, message_t *dev_data, param_val_t vals[]); +void parse_device_data(uint8_t dev_type, message_t* dev_data, param_val_t vals[]); #endif diff --git a/docs/style_guide.c b/docs/style_guide.c index 973c240b..0a3abb46 100644 --- a/docs/style_guide.c +++ b/docs/style_guide.c @@ -22,7 +22,8 @@ float baz; // in a dummy struct } foo_t; -5) Generally, comments inside of block comments (/* and */ /*) should be complete sentences and have proper capitalization. Inline comments, not so much. +5) Generally, comments inside of block comments (/* and */ +/*) should be complete sentences and have proper capitalization. Inline comments, not so much. 6) Delimiters should look like the ones that you see in this doc, with the length consistent through any one file (By "delimiters", we mean the things like the // ********** GENERAL ************ // you see in this file) @@ -55,15 +56,15 @@ // ********************************************* HEADER FILES *************************************** // -#ifndef SOMETHING_H // always include these two lines (replace SOMETHING with a descriptive name) at the top of your header files -#define SOMETHING_H // this prevents code from being included twice +#ifndef SOMETHING_H // always include these two lines (replace SOMETHING with a descriptive name) at the top of your header files +#define SOMETHING_H // this prevents code from being included twice -#include // always include standard headers first (stdio, string, stlib, etc.), separated by a newline from the #ifndef and #define -#include // for printf, fprintf, fopen <-- include a message like this to indicate what you'll be using from that header +#include // always include standard headers first (stdio, string, stlib, etc.), separated by a newline from the #ifndef and #define +#include // for printf, fprintf, fopen <-- include a message like this to indicate what you'll be using from that header -#include "c-runtime.h" // separate standard headers with C-runtime headers with a newline +#include "c-runtime.h" // separate standard headers with C-runtime headers with a newline -#endif // put this at the end of all header files +#endif // put this at the end of all header files // ******************************************** SOURCE CODE ***************************************** // @@ -106,7 +107,7 @@ while (foo < 1) { // comments for else's should go after the open brace if (foo == 0) { // foo is 0 -} else { // opening brace goes on same line +} else { // opening brace goes on same line // foo is not 0 } diff --git a/executor/executor.c b/executor/executor.c old mode 100755 new mode 100644 index 357d696c..b9f36c69 --- a/executor/executor.c +++ b/executor/executor.c @@ -1,36 +1,36 @@ #define PY_SSIZE_T_CLEAN +#include //for networking +#include //for POSIX threads #include // For Python's C API +#include // Used to handle SIGTERM, SIGINT, SIGKILL +#include //for standard int types #include //for i/o #include //for standard utility functions (exit, sleep) #include //for sem_t and other standard system types -#include //for wait functions #include //for unix sockets -#include //for networking -#include //for standard int types -#include //for sleep -#include //for POSIX threads -#include // Used to handle SIGTERM, SIGINT, SIGKILL +#include //for wait functions #include // for getting time -#include "../runtime_util/runtime_util.h" //for runtime constants (TODO: consider removing relative pathname in include) -#include "../shm_wrapper/shm_wrapper.h" // Shared memory wrapper to get/send device data +#include //for sleep #include "../logger/logger.h" // for runtime logger #include "../net_handler/net_util.h" // For Text protobuf message and buffer utilities +#include "../runtime_util/runtime_util.h" //for runtime constants (TODO: consider removing relative pathname in include) +#include "../shm_wrapper/shm_wrapper.h" // Shared memory wrapper to get/send device data // Global variables to all functions and threads const char* api_module = "studentapi"; char* module_name; PyObject *pModule, *pAPI, *pRobot, *pGamepad; -robot_desc_val_t mode = IDLE; // current robot mode -pid_t pid; // pid for mode process -int challenge_fd; // challenge socket +robot_desc_val_t mode = IDLE; // current robot mode +pid_t pid; // pid for mode process +int challenge_fd; // challenge socket // Timings for all modes -struct timespec setup_time = { 2, 0 }; // Max time allowed for setup functions -#define MIN_FREQ 10.0 // Minimum number of times per second the main loop should run -struct timespec main_interval = { 0, (long) ((1.0 / MIN_FREQ) * 1e9) }; -#define MAX_FREQ 10000.0 // Maximum number of times per second the Python function should run -uint64_t min_time = (1.0 / MAX_FREQ) * 1e9; // Minimum time in nanoseconds that the Python function should take -#define CHALLENGE_TIME 5 // Max allowed time for running all challenges in seconds +struct timespec setup_time = {2, 0}; // Max time allowed for setup functions +#define MIN_FREQ 10.0 // Minimum number of times per second the main loop should run +struct timespec main_interval = {0, (long) ((1.0 / MIN_FREQ) * 1e9)}; +#define MAX_FREQ 10000.0 // Maximum number of times per second the Python function should run +uint64_t min_time = (1.0 / MAX_FREQ) * 1e9; // Minimum time in nanoseconds that the Python function should take +#define CHALLENGE_TIME 5 // Max allowed time for running all challenges in seconds /** @@ -39,11 +39,9 @@ uint64_t min_time = (1.0 / MAX_FREQ) * 1e9; // Minimum time in nanoseconds that static char* get_mode_str(robot_desc_val_t mode) { if (mode == AUTO) { return "autonomous"; - } - else if (mode == TELEOP) { + } else if (mode == TELEOP) { return "teleop"; - } - else if (mode == IDLE) { + } else if (mode == IDLE) { return "idle"; } log_printf(ERROR, "Run mode %d is invalid", mode); @@ -60,17 +58,17 @@ static void reset_params() { get_catalog(&catalog); get_device_identifiers(dev_ids); for (int i = 0; i < MAX_DEVICES; i++) { - if (catalog & (1 << i)) { // If device at index i exists + if (catalog & (1 << i)) { // If device at index i exists device_t* device = get_device(dev_ids[i].type); - if(device == NULL) { + if (device == NULL) { log_printf(ERROR, "reset_params: device at index %d with type %d is invalid\n", i, dev_ids[i].type); continue; } uint32_t reset_params = 0; - param_val_t zero_params[MAX_PARAMS] = {0}; // By default we reset to 0 - for(int j = 0; j < device->num_params; j++) { + param_val_t zero_params[MAX_PARAMS] = {0}; // By default we reset to 0 + for (int j = 0; j < device->num_params; j++) { // Only reset parameters that are writeable - if (device->params[j].write) { + if (device->params[j].write) { reset_params |= (1 << j); } } @@ -92,7 +90,7 @@ static void executor_init(char* student_code) { PyEval_InitThreads(); // Need this so that the Python interpreter sees the Python files in this directory PyRun_SimpleString("import sys;sys.path.insert(0, '.')"); - + // imports the student code module_name = student_code; pModule = PyImport_ImportModule(module_name); @@ -106,8 +104,8 @@ static void executor_init(char* student_code) { if (mode == CHALLENGE) { return; } - - //imports the Cython student API + + //imports the Cython student API pAPI = PyImport_ImportModule(api_module); if (pAPI == NULL) { PyErr_Print(); @@ -115,7 +113,7 @@ static void executor_init(char* student_code) { exit(1); } - //checks to make sure there is a Robot class, then instantiates it + //checks to make sure there is a Robot class, then instantiates it PyObject* robot_class = PyObject_GetAttrString(pAPI, "Robot"); if (robot_class == NULL) { PyErr_Print(); @@ -129,8 +127,8 @@ static void executor_init(char* student_code) { exit(1); } Py_DECREF(robot_class); - - //checks to make sure there is a Gamepad class, then instantiates it + + //checks to make sure there is a Gamepad class, then instantiates it PyObject* gamepad_class = PyObject_GetAttrString(pAPI, "Gamepad"); if (gamepad_class == NULL) { PyErr_Print(); @@ -144,7 +142,7 @@ static void executor_init(char* student_code) { exit(1); } Py_DECREF(gamepad_class); - + // Insert student API into the student code int err = PyObject_SetAttrString(pModule, "Robot", pRobot); err |= PyObject_SetAttrString(pModule, "Gamepad", pGamepad); @@ -152,8 +150,8 @@ static void executor_init(char* student_code) { PyErr_Print(); log_printf(ERROR, "Could not insert API into student code."); exit(1); - } - + } + // Send the device subscription requests to dev_handler PyObject* ret = PyObject_CallMethod(pAPI, "make_device_subs", "s", student_code); if (ret == NULL) { @@ -188,7 +186,7 @@ static void executor_init(char* student_code) { */ static uint8_t run_py_function(const char* func_name, struct timespec* timeout, int loop, PyObject* args, PyObject** py_ret) { uint8_t ret = 0; - + //retrieve the Python function from the student code PyObject* pFunc = PyObject_GetAttrString(pModule, func_name); PyObject* pValue = NULL; @@ -201,41 +199,38 @@ static uint8_t run_py_function(const char* func_name, struct timespec* timeout, do { clock_gettime(CLOCK_MONOTONIC, &start); - pValue = PyObject_CallObject(pFunc, args); // make call to Python function + pValue = PyObject_CallObject(pFunc, args); // make call to Python function clock_gettime(CLOCK_MONOTONIC, &end); - //if the time the Python function took was greater than max_time, warn that it's taking too long + //if the time the Python function took was greater than max_time, warn that it's taking too long time = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec); if (timeout != NULL && time > max_time) { log_printf(WARN, "Function %s is taking longer than %lu milliseconds, indicating a loop in the code.", func_name, (long) (max_time / 1e6)); } //if the time the Python function took was less than min_time, sleep to slow down execution if (time < min_time) { - usleep((min_time - time) / 1000); // Need to convert nanoseconds to microseconds + usleep((min_time - time) / 1000); // Need to convert nanoseconds to microseconds } // Set return value if (py_ret != NULL) { - Py_XDECREF(*py_ret); // Decrement previous reference, if it exists + Py_XDECREF(*py_ret); // Decrement previous reference, if it exists *py_ret = pValue; - } - else { + } else { Py_XDECREF(pValue); } - //catch execution error + //catch execution error if (pValue == NULL) { if (!PyErr_ExceptionMatches(PyExc_TimeoutError)) { PyErr_Print(); log_printf(ERROR, "Python function %s call failed", func_name); ret = 2; - } - else { - ret = 3; // Timed out by parent process + } else { + ret = 3; // Timed out by parent process } break; - } - else if (mode != CHALLENGE) { + } else if (mode != CHALLENGE) { // Need to check if error occurred in action thread PyObject* event = PyObject_GetAttrString(pRobot, "error_event"); if (event == NULL) { @@ -249,22 +244,19 @@ static uint8_t run_py_function(const char* func_name, struct timespec* timeout, PyErr_Print(); log_printf(DEBUG, "Could not get if error is set from error_event"); exit(2); - } - else { - ret = 3; // Timed out by parent process + } else { + ret = 3; // Timed out by parent process } break; - } - else if (PyObject_IsTrue(event_set) == 1) { + } else if (PyObject_IsTrue(event_set) == 1) { log_printf(ERROR, "Stopping %s due to error in action", func_name); ret = 1; break; } - } - } while(loop); + } + } while (loop); Py_DECREF(pFunc); - } - else { + } else { if (PyErr_Occurred()) { PyErr_Print(); } @@ -285,20 +277,19 @@ static uint8_t run_py_function(const char* func_name, struct timespec* timeout, * args: string of the mode to start running */ static void run_mode(robot_desc_val_t mode) { - //Set up the arguments to the threads that will run the setup and main threads + //Set up the arguments to the threads that will run the setup and main threads char* mode_str = get_mode_str(mode); char setup_str[20], main_str[20]; sprintf(setup_str, "%s_setup", mode_str); sprintf(main_str, "%s_main", mode_str); - + int err = run_py_function(setup_str, &setup_time, 0, NULL, NULL); // Run setup function once if (err == 0) { err = run_py_function(main_str, &main_interval, 1, NULL, NULL); // Run main function on loop - } - else { + } else { log_printf(WARN, "Won't run %s due to error %d in %s", main_str, err, setup_str); } - return; + return; } @@ -338,7 +329,7 @@ static void run_challenges() { log_printf(ERROR, "run_challenges: failed to unpack challenge input protobuf"); return; } - if(num_challenges != inputs->n_payload) { + if (num_challenges != inputs->n_payload) { log_printf(ERROR, "run_challenges: number of challenge names %d is not equal to number of inputs %d", num_challenges, inputs->n_payload); return; } @@ -375,7 +366,7 @@ static void run_challenges() { } // Run the challenge PyObject* ret = NULL; - if (run_py_function(func_name, NULL, 0, arg, &ret) == 3) { // Check if challenge got timed out + if (run_py_function(func_name, NULL, 0, arg, &ret) == 3) { // Check if challenge got timed out for (int j = i; j < num_challenges; j++) { // Set rest of challenge outputs to notify the TCP client outputs.payload[i] = "Timed out"; @@ -396,7 +387,7 @@ static void run_challenges() { const char* c_ret = PyUnicode_AsUTF8AndSize(ret_string, &ret_len); Py_DECREF(ret_string); outputs.payload[i] = malloc(ret_len + 1); - strcpy(outputs.payload[i], c_ret); // Need to copy since pointer data is reset each iteration + strcpy(outputs.payload[i], c_ret); // Need to copy since pointer data is reset each iteration } text__free_unpacked(inputs, NULL); @@ -409,8 +400,7 @@ static void run_challenges() { int send_len = sendto(challenge_fd, send_buf, len_buf, 0, (struct sockaddr*) &address, addrlen); if (send_len <= 0) { log_printf(ERROR, "run_challenges: socket send to challenge_fd failed: %s", strerror(errno)); - } - else if (send_len != len_buf) { + } else if (send_len != len_buf) { log_printf(WARN, "run_challenges: only %d of %d bytes sent to challenge_fd", send_len, len_buf); } @@ -455,7 +445,7 @@ static void python_exit_handler(int signum) { static void kill_subprocess() { if (kill(pid, SIGTERM) != 0) { log_printf(ERROR, "Kill signal not sent: %s", strerror(errno)); - } + } int status; if (waitpid(pid, &status, 0) == -1) { log_printf(ERROR, "Wait failed for pid %d: %s", pid, strerror(errno)); @@ -482,27 +472,24 @@ static pid_t start_mode_subprocess(char* student_code, char* challenge_code) { if (pid < 0) { log_printf(ERROR, "Failed to create child subprocess for mode %d: %s", mode, strerror(errno)); return -1; - } - else if (pid == 0) { + } else if (pid == 0) { // Now in child process - signal(SIGINT, SIG_IGN); // Disable Ctrl+C for child process + signal(SIGINT, SIG_IGN); // Disable Ctrl+C for child process if (mode == CHALLENGE) { executor_init(challenge_code); signal(SIGTERM, exit); - signal(SIGALRM, python_exit_handler); // Sets interrupt for any long-running challenge - alarm(CHALLENGE_TIME); // Set timeout for challenges + signal(SIGALRM, python_exit_handler); // Sets interrupt for any long-running challenge + alarm(CHALLENGE_TIME); // Set timeout for challenges run_challenges(); - robot_desc_write(RUN_MODE, IDLE); // Will tell parent to call kill_subprocess - } - else { + robot_desc_write(RUN_MODE, IDLE); // Will tell parent to call kill_subprocess + } else { executor_init(student_code); signal(SIGTERM, python_exit_handler); run_mode(mode); } exit(0); - return pid; // Never reach this statement due to exit, needed to fix compiler warning - } - else { + return pid; // Never reach this statement due to exit, needed to fix compiler warning + } else { // Now in parent process return pid; } @@ -541,27 +528,27 @@ int main(int argc, char* argv[]) { if (argc > 1) { student_code = argv[1]; } - char* challenge_code = student_code; // = "challenges"; change default to "challenges" once Dawn separates challenges into a new Python file + char* challenge_code = student_code; // = "challenges"; change default to "challenges" once Dawn separates challenges into a new Python file if (argc > 2) { challenge_code = argv[2]; } - - remove(CHALLENGE_SOCKET); // Always remove any old challenge socket - struct sockaddr_un my_addr = {AF_UNIX, CHALLENGE_SOCKET}; //for holding IP addresses (IPv4) - //create the socket - if ((challenge_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + + remove(CHALLENGE_SOCKET); // Always remove any old challenge socket + struct sockaddr_un my_addr = {AF_UNIX, CHALLENGE_SOCKET}; //for holding IP addresses (IPv4) + //create the socket + if ((challenge_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { log_printf(FATAL, "could not create challenge socket: %s", strerror(errno)); - return 1; - } - if (bind(challenge_fd, (struct sockaddr*) &my_addr, sizeof(struct sockaddr_un)) < 0) { + return 1; + } + if (bind(challenge_fd, (struct sockaddr*) &my_addr, sizeof(struct sockaddr_un)) < 0) { log_printf(FATAL, "challenge socket bind failed: %s", strerror(errno)); - return 1; - } + return 1; + } log_printf(INFO, "Executor initialized"); robot_desc_val_t new_mode = IDLE; // Main loop that checks for new run mode in shared memory from the network handler - while(1) { + while (1) { new_mode = robot_desc_read(RUN_MODE); // If we receive a new mode, cancel the previous mode and start the new one if (new_mode != mode) { @@ -576,6 +563,6 @@ int main(int argc, char* argv[]) { } } } - usleep(100000); //throttle this thread to ~10 Hz + usleep(100000); //throttle this thread to ~10 Hz } } diff --git a/logger/logger.c b/logger/logger.c index 3c32f881..9483fc09 100644 --- a/logger/logger.c +++ b/logger/logger.c @@ -5,38 +5,37 @@ #define LOG_FILE (1 << 1) #define LOG_NETWORK (1 << 2) -#define NUM_CONFIGS 7 // number of configuration parameters in the config file -#define MAX_CONFIG_LINE_LEN 256 // maximum length of a configuration file line, in chars +#define NUM_CONFIGS 7 // number of configuration parameters in the config file +#define MAX_CONFIG_LINE_LEN 256 // maximum length of a configuration file line, in chars -#define PROCESS_STR_SIZE 32 // size in bytes of the process string +#define PROCESS_STR_SIZE 32 // size in bytes of the process string // *********************************** LOGER-SPECIFIC GLOBAL VARS **************************************** // // general variables -uint8_t OUTPUTS = 0; // bitmask that stores where the log outputs should go -char process_str[PROCESS_STR_SIZE]; // string for holding the process name, used in printing -char *log_level_strs[] = { // strings for holding names of log levels, used in printing +uint8_t OUTPUTS = 0; // bitmask that stores where the log outputs should go +char process_str[PROCESS_STR_SIZE]; // string for holding the process name, used in printing +char* log_level_strs[] = { // strings for holding names of log levels, used in printing "DEBUG", "INFO", "WARN", "PYTHON", "ERROR", - "FATAL" -}; + "FATAL"}; // for holding the requested log levels for the three output locations (all default to DEBUG) log_level_t stdout_level = DEBUG, file_level = DEBUG, network_level = DEBUG; // used for LOG_FILE only -FILE *log_file = NULL; // file descriptor of the log file -char log_file_path[MAX_CONFIG_LINE_LEN]; // file path to the log file +FILE* log_file = NULL; // file descriptor of the log file +char log_file_path[MAX_CONFIG_LINE_LEN]; // file path to the log file // used for LOG_NETWORK only -mode_t fifo_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; // -rw-rw-rw permission for FIFO -int fifo_up = 0; // flag that represents if FIFO is up and running -int fifo_fd = -1; // file descriptor for FIFO +mode_t fifo_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; // -rw-rw-rw permission for FIFO +int fifo_up = 0; // flag that represents if FIFO is up and running +int fifo_fd = -1; // file descriptor for FIFO -pthread_mutex_t log_mutex; // for ensuring one log gets emitted before processing the next +pthread_mutex_t log_mutex; // for ensuring one log gets emitted before processing the next // ************************************ HELPER FUNCTIONS ****************************************** // @@ -46,15 +45,21 @@ pthread_mutex_t log_mutex; // for ensuring one log gets emitted before processin * level: one of the global variables stdout_level, file_level, or network_level to set * important: string read in from the config file that contains one of the five levels as a string */ -static void set_log_level(log_level_t *level, char *important) { - important[strlen(important)] = '\0'; // overwrite the newline at the end +static void set_log_level(log_level_t* level, char* important) { + important[strlen(important)] = '\0'; // overwrite the newline at the end // set level to the contents of important - if (strcmp(important, "DEBUG") == 0) { *level = DEBUG; } - else if (strcmp(important, "INFO") == 0) { *level = INFO; } - else if (strcmp(important, "WARN") == 0) { *level = WARN; } - else if (strcmp(important, "ERROR") == 0) { *level = ERROR; } - else if (strcmp(important, "FATAL") == 0) { *level = FATAL; } + if (strcmp(important, "DEBUG") == 0) { + *level = DEBUG; + } else if (strcmp(important, "INFO") == 0) { + *level = INFO; + } else if (strcmp(important, "WARN") == 0) { + *level = WARN; + } else if (strcmp(important, "ERROR") == 0) { + *level = ERROR; + } else if (strcmp(important, "FATAL") == 0) { + *level = FATAL; + } } /** @@ -64,7 +69,7 @@ static void set_log_level(log_level_t *level, char *important) { */ static void open_fifo() { if ((fifo_fd = open(LOG_FIFO, O_WRONLY | O_NONBLOCK)) == -1) { - if (errno != ENXIO) { // don't show error if open failed because net_handler has not opened pipe for reading yet + if (errno != ENXIO) { // don't show error if open failed because net_handler has not opened pipe for reading yet printf("ERROR: logger open FIFO failed: %s", strerror(errno)); } } else { @@ -81,22 +86,22 @@ static void read_config_file() { char nextline[MAX_CONFIG_LINE_LEN]; char not_important[128], important[128]; // for holding information read from the file char important_char; - FILE *conf_fd; + FILE* conf_fd; // this logic gets the path of the logger config file char file_buf[128] = {0}; - sprintf(file_buf, "%s", __FILE__); // __FILE__ is the path of this file on the system - char *last = strrchr(file_buf, '/'); // use strrchr to get location of last '/' in path - strcpy(last + 1, CONFIG_FILE); // append CONFIG_FILE to that path to get the path to logger file + sprintf(file_buf, "%s", __FILE__); // __FILE__ is the path of this file on the system + char* last = strrchr(file_buf, '/'); // use strrchr to get location of last '/' in path + strcpy(last + 1, CONFIG_FILE); // append CONFIG_FILE to that path to get the path to logger file if ((conf_fd = fopen(file_buf, "r")) == NULL) { // open the config file for reading printf("ERROR: logger could not open config file %s: %s", file_buf, strerror(errno)); exit(1); } - + for (int i = 0; i < NUM_CONFIGS; i++) { // read until the next line read is not a comment or a blank line - while (1) { + while (1) { if (fgets(nextline, MAX_CONFIG_LINE_LEN, conf_fd) == NULL) { if (feof(conf_fd)) { printf("ERROR: end of config file reached before all logger configurations read"); @@ -115,7 +120,7 @@ static void read_config_file() { } break; } - + // get the configuration parameter in nextline sequentially switch (i) { case 0: @@ -154,15 +159,21 @@ static void read_config_file() { break; default: printf("ERROR: unknown configuration line: %s\n", nextline); - } + } } - + // set the log level of an output location that isn't being used to FATAL // this is to ensure that log_printf() actually returns early when no logs // will be output due to the log level check at the beginning of the function - if (!(OUTPUTS & LOG_STDOUT)) { stdout_level = FATAL; } - if (!(OUTPUTS & LOG_FILE)) { file_level = FATAL; } - if (!(OUTPUTS & LOG_NETWORK)) { network_level = FATAL; } + if (!(OUTPUTS & LOG_STDOUT)) { + stdout_level = FATAL; + } + if (!(OUTPUTS & LOG_FILE)) { + file_level = FATAL; + } + if (!(OUTPUTS & LOG_NETWORK)) { + network_level = FATAL; + } // close the file descriptor for config file fclose(conf_fd); @@ -178,14 +189,14 @@ static void logger_exit() { printf("ERROR: log file close failed: %s", strerror(errno)); } } - + // if outputting to network, close file descriptor if ((OUTPUTS & LOG_NETWORK) && (fifo_up == 1)) { if (close(fifo_fd) != 0) { printf("ERROR: logger close FIFO failed: %s", strerror(errno)); } } - + // destroy the log_mutex pthread_mutex_destroy(&log_mutex); } @@ -207,11 +218,11 @@ void logger_init(process_t process) { // read in desired logger configurations read_config_file(); - + // if we want to log to log file, open it for appending if (OUTPUTS & LOG_FILE) { wordexp_t words; - wordexp(log_file_path, &words, 0); // Perform bash expansion to convert ~/ to the $HOME directory + wordexp(log_file_path, &words, 0); // Perform bash expansion to convert ~/ to the $HOME directory if (words.we_wordc == 0) { printf("ERROR: log file name %s has invalid format", log_file_path); exit(1); @@ -225,7 +236,7 @@ void logger_init(process_t process) { exit(1); } close(temp_fd); - + // open with fopen to use stdio functions instead if ((log_file = fopen(log_file_path, "a")) == NULL) { // open the config file for reading printf("ERROR: logger could not open log file %s: %s\n", log_file_path, strerror(errno)); @@ -236,7 +247,7 @@ void logger_init(process_t process) { // if we want to log to network, create the FIFO pipe if it doesn't exist, and open it for writing if (OUTPUTS & LOG_NETWORK) { if (mkfifo(LOG_FIFO, fifo_mode) == -1) { - if (errno != EEXIST) { // don't show error if mkfifo failed because it already exists + if (errno != EEXIST) { // don't show error if mkfifo failed because it already exists printf("ERROR: logger create FIFO failed: %s", strerror(errno)); } } @@ -245,24 +256,30 @@ void logger_init(process_t process) { } // set the correct process_str for given process - if (process == DEV_HANDLER) { sprintf(process_str, "DEV_HANDLER"); } - else if (process == EXECUTOR) { sprintf(process_str, "EXECUTOR"); } - else if (process == NET_HANDLER) { sprintf(process_str, "NET_HANDLER"); } - else if (process == SHM) { sprintf(process_str, "SHM"); } - else if (process == TEST) { sprintf(process_str, "TEST"); } - - pthread_mutex_init(&log_mutex, NULL); // initialize the log_mutex - atexit(logger_exit); // add cleanup handler + if (process == DEV_HANDLER) { + sprintf(process_str, "DEV_HANDLER"); + } else if (process == EXECUTOR) { + sprintf(process_str, "EXECUTOR"); + } else if (process == NET_HANDLER) { + sprintf(process_str, "NET_HANDLER"); + } else if (process == SHM) { + sprintf(process_str, "SHM"); + } else if (process == TEST) { + sprintf(process_str, "TEST"); + } + + pthread_mutex_init(&log_mutex, NULL); // initialize the log_mutex + atexit(logger_exit); // add cleanup handler } -void log_printf(log_level_t level, char *format, ...) { +void log_printf(log_level_t level, char* format, ...) { // first, don't do anything with this message if less than all set levels if (level < network_level && level < file_level && level < stdout_level) { return; } - + static time_t now; // for holding system time - static char *time_str; // for string representation of system time + static char* time_str; // for string representation of system time static char final_msg[MAX_LOG_LEN]; // final message to be logged to requested locations static int len; // holding lengths of various strings static char msg[MAX_LOG_LEN - 100]; // holds the expanded format string (100 to make room for log header) @@ -289,7 +306,7 @@ void log_printf(log_level_t level, char *format, ...) { *(time_str + len - 1) = '\0'; } len = strlen(msg); - + // this logic ensures that log messages are separated by exactly one newline (as long as user doesn't put >1 newline) if (*(msg + len - 1) == '\n') { sprintf(final_msg, "%s @ %s\t(%s) %s", log_level_strs[level], process_str, time_str, msg); @@ -297,7 +314,7 @@ void log_printf(log_level_t level, char *format, ...) { sprintf(final_msg, "%s @ %s\t(%s) %s\n", log_level_strs[level], process_str, time_str, msg); } } - + // send final_msg to the desired output locations if ((OUTPUTS & LOG_STDOUT) && (level >= stdout_level)) { printf("%s", final_msg); @@ -322,7 +339,7 @@ void log_printf(log_level_t level, char *format, ...) { } } } - + // release the mutex pthread_mutex_unlock(&log_mutex); } \ No newline at end of file diff --git a/logger/logger.h b/logger/logger.h old mode 100755 new mode 100644 index 50a7a8e7..7a5cc932 --- a/logger/logger.h +++ b/logger/logger.h @@ -1,18 +1,23 @@ - + #ifndef LOGGER_H #define LOGGER_H -#include // to deal with variable-length argument lists arguments -#include // for wordexp +#include // to deal with variable-length argument lists arguments +#include // for wordexp #include "../runtime_util/runtime_util.h" -#define CONFIG_FILE "logger.config" // path to logger config file -#define LOG_FIFO "/tmp/log-fifo" // location of the log FIFO pipe in filesystem +#define CONFIG_FILE "logger.config" // path to logger config file +#define LOG_FIFO "/tmp/log-fifo" // location of the log FIFO pipe in filesystem // enumerate logger levels from least to most critical -typedef enum log_level { DEBUG, INFO, WARN, PYTHON, ERROR, FATAL } log_level_t; +typedef enum log_level { DEBUG, + INFO, + WARN, + PYTHON, + ERROR, + FATAL } log_level_t; // ************************************ PUBLIC LOGGER FUNCTIONS ****************************************** // diff --git a/lowcar/Device_template.cpp b/lowcar/Device_template.cpp index aae31dc8..abb2db6a 100644 --- a/lowcar/Device_template.cpp +++ b/lowcar/Device_template.cpp @@ -1,19 +1,19 @@ // flash script will append a #include above this line to include the necessary library for the requested device -#include #include #include #include +#include // THIS FILE IS USED BY THE FLASH SCRIPT TO BUILD THE ACTUAL DEVICE.INO FILE (which will be located in Device/Device.ino) -Device *device; //declare the device +Device* device; //declare the device void setup() { - device = new DEVICE(); //flash script will replace DEVICE with requested Device type - device->set_uid(UID_INSERTED); //flash script will replace UID_INSERTED with randomly generated 64-bit value + device = new DEVICE(); //flash script will replace DEVICE with requested Device type + device->set_uid(UID_INSERTED); //flash script will replace UID_INSERTED with randomly generated 64-bit value } void loop() { - device->loop(); -} + device->loop(); +} diff --git a/lowcar/devices/BatteryBuzzer/BatteryBuzzer.cpp b/lowcar/devices/BatteryBuzzer/BatteryBuzzer.cpp index 3f39bc60..c58b6835 100644 --- a/lowcar/devices/BatteryBuzzer/BatteryBuzzer.cpp +++ b/lowcar/devices/BatteryBuzzer/BatteryBuzzer.cpp @@ -3,115 +3,112 @@ // default constructor simply specifies DeviceID and and year to generic constructor // initalizes helper class objects and pre-existing variables -BatteryBuzzer::BatteryBuzzer () : - Device (DeviceType:: BATTERY_BUZZER, 1), - disp(SevenSeg(A, B, C, D, E, G, H)) -{ - v_cell1 = 0; // param - v_cell2 = 0; // param 4 - v_cell3 = 0; // param 5 - v_batt = 0; // param 6 - dv_cell2 = 0; // param 7 - dv_cell3 = 0; // param 8 - vref_guess = 0; // param 9 - - triple_calibration = TRUE; - - this->buzzer = 10; - this->last_check_time = 0; //for loop counter - - this->digitPins[0] = DISP_PIN_1; - this->digitPins[1] = DISP_PIN_2; - this->digitPins[2] = DISP_PIN_3; - this->digitPins[3] = DISP_PIN_4; - - this->last_LED_time = 0; //Time the last LED switched - this->sequence = 0; //used to switch states for the display. Remember that the hangle_8_segment cannot be blocking. - - this->segment_8_run = NORMAL_VOLT_READ; //0 for the normal voltage readout. 1 for "Clear Calibration". 2 for "New Calibration" +BatteryBuzzer::BatteryBuzzer() : Device(DeviceType::BATTERY_BUZZER, 1), + disp(SevenSeg(A, B, C, D, E, G, H)) { + v_cell1 = 0; // param + v_cell2 = 0; // param 4 + v_cell3 = 0; // param 5 + v_batt = 0; // param 6 + dv_cell2 = 0; // param 7 + dv_cell3 = 0; // param 8 + vref_guess = 0; // param 9 + + triple_calibration = TRUE; + + this->buzzer = 10; + this->last_check_time = 0; //for loop counter + + this->digitPins[0] = DISP_PIN_1; + this->digitPins[1] = DISP_PIN_2; + this->digitPins[2] = DISP_PIN_3; + this->digitPins[3] = DISP_PIN_4; + + this->last_LED_time = 0; //Time the last LED switched + this->sequence = 0; //used to switch states for the display. Remember that the hangle_8_segment cannot be blocking. + + this->segment_8_run = NORMAL_VOLT_READ; //0 for the normal voltage readout. 1 for "Clear Calibration". 2 for "New Calibration" } -size_t BatteryBuzzer::device_read (uint8_t param, uint8_t *data_buf) { - switch (param) { - // Boolean params - case IS_UNSAFE: - data_buf[0] = is_unsafe(); - return sizeof(uint8_t); - case CALIBRATED: - data_buf[0] = is_calibrated(); - return sizeof(uint8_t); - - // Float params - float *float_buf = (float*) data_buf; - case V_CELL1: - float_buf[0] = v_cell1; - break; - case V_CELL2: - float_buf[0] = v_cell2; - break; - case V_CELL3: - float_buf[0] = v_cell3; - break; - case V_BATT: - float_buf[0] = v_batt; - break; - case DV_CELL2: - float_buf[0] = dv_cell2; - break; - case DV_CELL3: - float_buf[0] = dv_cell3; - break; - } - return sizeof(float); +size_t BatteryBuzzer::device_read(uint8_t param, uint8_t* data_buf) { + switch (param) { + // Boolean params + case IS_UNSAFE: + data_buf[0] = is_unsafe(); + return sizeof(uint8_t); + case CALIBRATED: + data_buf[0] = is_calibrated(); + return sizeof(uint8_t); + + // Float params + float* float_buf = (float*) data_buf; + case V_CELL1: + float_buf[0] = v_cell1; + break; + case V_CELL2: + float_buf[0] = v_cell2; + break; + case V_CELL3: + float_buf[0] = v_cell3; + break; + case V_BATT: + float_buf[0] = v_batt; + break; + case DV_CELL2: + float_buf[0] = dv_cell2; + break; + case DV_CELL3: + float_buf[0] = dv_cell3; + break; + } + return sizeof(float); } -void BatteryBuzzer::device_enable () { - pinMode(buzzer, OUTPUT); +void BatteryBuzzer::device_enable() { + pinMode(buzzer, OUTPUT); - vref_guess = ADC_REF_NOM; //initial guesses, based on datasheet - calib[0] = ADC_REF_NOM; - calib[1] = ADC_REF_NOM; - calib[2] = ADC_REF_NOM; + vref_guess = ADC_REF_NOM; //initial guesses, based on datasheet + calib[0] = ADC_REF_NOM; + calib[1] = ADC_REF_NOM; + calib[2] = ADC_REF_NOM; - setup_display(); - disp.clearDisp(); - test_display(); //For production to check that the LED display is working - setup_sensing(); + setup_display(); + disp.clearDisp(); + test_display(); //For production to check that the LED display is working + setup_sensing(); } void BatteryBuzzer::device_actions() { - setup_display(); - disp.clearDisp(); - - handle_8_segment(); - SEQ_NUM mode = handle_calibration(); - setup_sensing(); - - if ((millis() - last_check_time) > 250) { - measure_cells(); - last_check_time = millis(); - handle_safety(); - } - disp.clearDisp(); + setup_display(); + disp.clearDisp(); + + handle_8_segment(); + SEQ_NUM mode = handle_calibration(); + setup_sensing(); + + if ((millis() - last_check_time) > 250) { + measure_cells(); + last_check_time = millis(); + handle_safety(); + } + disp.clearDisp(); } uint8_t BatteryBuzzer::is_calibrated() { - //triple calibration arrays are all default values - if (triple_calibration && (calib[0] == ADC_REF_NOM) \ - && (calib[1] == ADC_REF_NOM) && (calib[2] == ADC_REF_NOM)) { - return FALSE; - } - //calibration value is set to default - if (!triple_calibration && (get_calibration() == -1.0)) { - return FALSE; - } - //device is calibrated: no default values - return TRUE; + //triple calibration arrays are all default values + if (triple_calibration && (calib[0] == ADC_REF_NOM) && (calib[1] == ADC_REF_NOM) && (calib[2] == ADC_REF_NOM)) { + return FALSE; + } + //calibration value is set to default + if (!triple_calibration && (get_calibration() == -1.0)) { + return FALSE; + } + //device is calibrated: no default values + return TRUE; } void BatteryBuzzer::setup_display() { - disp.setDigitPins(numOfDigits, digitPins); - disp.setDPPin(DECIMAL_POINT); //set the Decimal Point pin to #1 + disp.setDigitPins(numOfDigits, digitPins); + disp.setDPPin(DECIMAL_POINT); //set the Decimal Point pin to #1 } /** @@ -120,12 +117,12 @@ void BatteryBuzzer::setup_display() { * The library is capable of handling : and ', but the wires are not hooked up to it. */ void BatteryBuzzer::test_display() { - for (int i = 0; i<250; i++) { - //this function call takes a surprising amount of time, - //probably because of how many characters are in it. - disp.write("8.8.8.8."); - } - disp.clearDisp(); + for (int i = 0; i < 250; i++) { + //this function call takes a surprising amount of time, + //probably because of how many characters are in it. + disp.write("8.8.8.8."); + } + disp.clearDisp(); } /** @@ -133,196 +130,196 @@ void BatteryBuzzer::test_display() { * MUST be called in the loop() without any if's */ void BatteryBuzzer::handle_8_segment() { - if(segment_8_run == NORMAL_VOLT_READ) { - //Shows text / numbers of all voltages & then individual cells. - //Changed every Second - switch(sequence) { - case 0: - disp.write("ALL"); - break; - case 1: - disp.write(v_batt, 2); - break; - case 2: - disp.write("CEL.1"); - break; - case 3: - disp.write(v_cell1, 2); - break; - case 4: - disp.write("CEL.2"); - break; - case 5: - disp.write(dv_cell2, 2); - break; - case 6: - disp.write("CEL.3"); - break; - case 7: - disp.write(dv_cell3, 2); - break; - } - - if (millis() > (last_LED_time + 1000)) { //every second - sequence = sequence + 1; - if(sequence == 8) { - sequence = 0; - } - last_LED_time = millis(); - } - } else if (segment_8_run == CLEAR_CALIB) { - if (sequence == 0) { - disp.write("CAL"); - } else if (sequence == 1) { - disp.write("CLR"); - } - - if (millis() > (last_LED_time + 750)) { //every 3/4 second - sequence = sequence + 1; - if (sequence == 2) { - //return to default Programming... showing battery voltages. - start_8_seg_sequence(NORMAL_VOLT_READ); - } - last_LED_time = millis(); - } - } else if (segment_8_run == NEW_CALIB) { - if (triple_calibration) { - switch (sequence) { - case 0: - disp.write("CAL"); - break; - case 1: - disp.write("DONE"); - break; - case 2: - disp.write("CAL.1"); - break; - case 3: - disp.write(calib[0], 3); - break; - case 4: - disp.write("CAL.2"); - break; - case 5: - disp.write(calib[1], 3); - break; - case 6: - disp.write("CAL.3"); - break; - case 7: - disp.write(calib[2], 3); - break; - } - - if (millis() > (last_LED_time + 750)) { //every 3/4 second - sequence++; - if (sequence == 8) { - start_8_seg_sequence(NORMAL_VOLT_READ); //return to default Programming... showing battery voltages. - } - last_LED_time = millis(); - } - } else { - switch (sequence) { - case 0: - disp.write("CAL"); - break; - case 1: - disp.write("DONE"); - break; - case 2: - disp.write("CAL"); - break; - case 3: - disp.write(vref_guess, 3); - break; - } - - if (millis() > (last_LED_time + 750)) { //every 3/4 second - sequence++; - if (sequence == 4) { - start_8_seg_sequence(NORMAL_VOLT_READ); //return to default Programming... showing battery voltages. - } - last_LED_time = millis(); - } - } - } + if (segment_8_run == NORMAL_VOLT_READ) { + //Shows text / numbers of all voltages & then individual cells. + //Changed every Second + switch (sequence) { + case 0: + disp.write("ALL"); + break; + case 1: + disp.write(v_batt, 2); + break; + case 2: + disp.write("CEL.1"); + break; + case 3: + disp.write(v_cell1, 2); + break; + case 4: + disp.write("CEL.2"); + break; + case 5: + disp.write(dv_cell2, 2); + break; + case 6: + disp.write("CEL.3"); + break; + case 7: + disp.write(dv_cell3, 2); + break; + } + + if (millis() > (last_LED_time + 1000)) { //every second + sequence = sequence + 1; + if (sequence == 8) { + sequence = 0; + } + last_LED_time = millis(); + } + } else if (segment_8_run == CLEAR_CALIB) { + if (sequence == 0) { + disp.write("CAL"); + } else if (sequence == 1) { + disp.write("CLR"); + } + + if (millis() > (last_LED_time + 750)) { //every 3/4 second + sequence = sequence + 1; + if (sequence == 2) { + //return to default Programming... showing battery voltages. + start_8_seg_sequence(NORMAL_VOLT_READ); + } + last_LED_time = millis(); + } + } else if (segment_8_run == NEW_CALIB) { + if (triple_calibration) { + switch (sequence) { + case 0: + disp.write("CAL"); + break; + case 1: + disp.write("DONE"); + break; + case 2: + disp.write("CAL.1"); + break; + case 3: + disp.write(calib[0], 3); + break; + case 4: + disp.write("CAL.2"); + break; + case 5: + disp.write(calib[1], 3); + break; + case 6: + disp.write("CAL.3"); + break; + case 7: + disp.write(calib[2], 3); + break; + } + + if (millis() > (last_LED_time + 750)) { //every 3/4 second + sequence++; + if (sequence == 8) { + start_8_seg_sequence(NORMAL_VOLT_READ); //return to default Programming... showing battery voltages. + } + last_LED_time = millis(); + } + } else { + switch (sequence) { + case 0: + disp.write("CAL"); + break; + case 1: + disp.write("DONE"); + break; + case 2: + disp.write("CAL"); + break; + case 3: + disp.write(vref_guess, 3); + break; + } + + if (millis() > (last_LED_time + 750)) { //every 3/4 second + sequence++; + if (sequence == 4) { + start_8_seg_sequence(NORMAL_VOLT_READ); //return to default Programming... showing battery voltages. + } + last_LED_time = millis(); + } + } + } } void BatteryBuzzer::start_8_seg_sequence(SEQ_NUM sequence_num) { - segment_8_run = sequence_num; //rel the display to run the right sequence - sequence = 0; //and reset the step in the sequence to zero. - last_LED_time = millis(); + segment_8_run = sequence_num; //rel the display to run the right sequence + sequence = 0; //and reset the step in the sequence to zero. + last_LED_time = millis(); } void BatteryBuzzer::setup_sensing() { - pinMode(ENABLE, OUTPUT); - pinMode(CALIB_BUTTON, INPUT); - - //for stable (if unknown) internal voltage. - analogReference(INTERNAL); - - //let's turn enable on, so we can measure the battery voltage. - digitalWrite(ENABLE, HIGH); - - if (triple_calibration) { - update_triple_calibration(); //and then update the calibration values I use based on what I now know - } else { - float val = get_calibration(); - if (val > 0) { //by convention, val is -1 if there's no calibration. - vref_guess = val; - } - } + pinMode(ENABLE, OUTPUT); + pinMode(CALIB_BUTTON, INPUT); + + //for stable (if unknown) internal voltage. + analogReference(INTERNAL); + + //let's turn enable on, so we can measure the battery voltage. + digitalWrite(ENABLE, HIGH); + + if (triple_calibration) { + update_triple_calibration(); //and then update the calibration values I use based on what I now know + } else { + float val = get_calibration(); + if (val > 0) { //by convention, val is -1 if there's no calibration. + vref_guess = val; + } + } } //measures the battery cells. Should call at least twice a second, but preferrably 5x a second. No use faster. -void BatteryBuzzer::measure_cells() { - int r_cell1 = analogRead(CELL1); - int r_cell2 = analogRead(CELL2); - int r_cell3 = analogRead(CELL3); +void BatteryBuzzer::measure_cells() { + int r_cell1 = analogRead(CELL1); + int r_cell2 = analogRead(CELL2); + int r_cell3 = analogRead(CELL3); - v_cell1 = float(r_cell1) * (R2 + R5) / R5 * calib[0] / ADC_COUNTS; - v_cell2 = float(r_cell2) * (R3 + R6) / R6 * calib[1] / ADC_COUNTS; - v_cell3 = float(r_cell3) * (R4 + R7) / R7 * calib[2] / ADC_COUNTS; + v_cell1 = float(r_cell1) * (R2 + R5) / R5 * calib[0] / ADC_COUNTS; + v_cell2 = float(r_cell2) * (R3 + R6) / R6 * calib[1] / ADC_COUNTS; + v_cell3 = float(r_cell3) * (R4 + R7) / R7 * calib[2] / ADC_COUNTS; - dv_cell2 = v_cell2 - v_cell1; - dv_cell3 = v_cell3 - v_cell2; + dv_cell2 = v_cell2 - v_cell1; + dv_cell3 = v_cell3 - v_cell2; - v_batt = v_cell3; + v_batt = v_cell3; } //called very frequently by loop. uint8_t BatteryBuzzer::handle_calibration() { - if (digitalRead(CALIB_BUTTON)) { //I pressed the button, start calibrating. - float calib_0 = calib[0]; - float calib_1 = calib[1]; - float calib_2 = calib[2]; - - //i'm in triple calibration mode, but the calibration array is exactly the same as the datasheet values... which means i haven't been calibrated. - if (triple_calibration && calib_0 == ADC_REF_NOM && calib_1 == ADC_REF_NOM & calib_2 == ADC_REF_NOM) { - float vref_new = calibrate(); - calib_0 = calib[0]; - calib_1 = calib[1]; - calib_2 = calib[2]; - write_triple_eeprom(calib_0, calib_1, calib_2); - return NEW_CALIB; - } else if (!triple_calibration && get_calibration() == -1.0) { //i'm not in triple calibration mode, and i haven't been calibrated. - float vref_new = calibrate(); - write_single_eeprom(vref_new); - return NEW_CALIB; - } else { //I have already been calibrated with something. reset it. - //wait untill the button press goes away. - //This is to maintain commonality with how calibrate() works. - delay(1); - //reset all my calibration values as well, so my calibration values that i'm using are in lockstep with the EEPROM. - vref_guess = ADC_REF_NOM; - calib[0] = ADC_REF_NOM; - calib[1] = ADC_REF_NOM; - calib[2] = ADC_REF_NOM; - - clear_eeprom(); - return CLEAR_CALIB; - } - } + if (digitalRead(CALIB_BUTTON)) { //I pressed the button, start calibrating. + float calib_0 = calib[0]; + float calib_1 = calib[1]; + float calib_2 = calib[2]; + + //i'm in triple calibration mode, but the calibration array is exactly the same as the datasheet values... which means i haven't been calibrated. + if (triple_calibration && calib_0 == ADC_REF_NOM && calib_1 == ADC_REF_NOM & calib_2 == ADC_REF_NOM) { + float vref_new = calibrate(); + calib_0 = calib[0]; + calib_1 = calib[1]; + calib_2 = calib[2]; + write_triple_eeprom(calib_0, calib_1, calib_2); + return NEW_CALIB; + } else if (!triple_calibration && get_calibration() == -1.0) { //i'm not in triple calibration mode, and i haven't been calibrated. + float vref_new = calibrate(); + write_single_eeprom(vref_new); + return NEW_CALIB; + } else { //I have already been calibrated with something. reset it. + //wait untill the button press goes away. + //This is to maintain commonality with how calibrate() works. + delay(1); + //reset all my calibration values as well, so my calibration values that i'm using are in lockstep with the EEPROM. + vref_guess = ADC_REF_NOM; + calib[0] = ADC_REF_NOM; + calib[1] = ADC_REF_NOM; + calib[2] = ADC_REF_NOM; + + clear_eeprom(); + return CLEAR_CALIB; + } + } } /** @@ -331,170 +328,170 @@ uint8_t BatteryBuzzer::handle_calibration() { * it then calculates its best guess for vref. */ float BatteryBuzzer::calibrate() { - //wait untill the button press goes away. - //This is jank debouncing. - //Have to calibrate AFTER the button is pressed, not while. Yes, it's wierd. PCB issue. - while (digitalRead(CALIB_BUTTON)) { - delay(1); - } - delay(100); - - //ok. let's assume (for now) that every line has 5V put at it. - //I want to calculate the best-fit for the 1 vref. - - //expected voltages, after the resistive dividers. - float expected_vc1 = EXT_CALIB_VOLT * R5 / (R2 + R5); - float expected_vc2 = EXT_CALIB_VOLT * R6 / (R3 + R6); - float expected_vc3 = EXT_CALIB_VOLT * R7 / (R4 + R7); - - int r_cell1 = analogRead(CELL1); - int r_cell2 = analogRead(CELL2); - int r_cell3 = analogRead(CELL3); - - //as per whiteboard math. - float vref1 = ADC_COUNTS / (float(r_cell1)) * R5 / (R2 + R5) * EXT_CALIB_VOLT; - float vref2 = ADC_COUNTS / (float(r_cell2)) * R6 / (R3 + R6) * EXT_CALIB_VOLT; - float vref3 = ADC_COUNTS / (float(r_cell3)) * R7 / (R4 + R7) * EXT_CALIB_VOLT; - - //calibration array values are updated. These are only used if triple calibration is in use. - calib[0] = vref1; - calib[1] = vref2; - calib[2] = vref3; - //avg all vrefs together to get best guess value - vref_guess = (vref1 + vref2 + vref3) / 3.0f; - return vref_guess; + //wait untill the button press goes away. + //This is jank debouncing. + //Have to calibrate AFTER the button is pressed, not while. Yes, it's wierd. PCB issue. + while (digitalRead(CALIB_BUTTON)) { + delay(1); + } + delay(100); + + //ok. let's assume (for now) that every line has 5V put at it. + //I want to calculate the best-fit for the 1 vref. + + //expected voltages, after the resistive dividers. + float expected_vc1 = EXT_CALIB_VOLT * R5 / (R2 + R5); + float expected_vc2 = EXT_CALIB_VOLT * R6 / (R3 + R6); + float expected_vc3 = EXT_CALIB_VOLT * R7 / (R4 + R7); + + int r_cell1 = analogRead(CELL1); + int r_cell2 = analogRead(CELL2); + int r_cell3 = analogRead(CELL3); + + //as per whiteboard math. + float vref1 = ADC_COUNTS / (float(r_cell1)) * R5 / (R2 + R5) * EXT_CALIB_VOLT; + float vref2 = ADC_COUNTS / (float(r_cell2)) * R6 / (R3 + R6) * EXT_CALIB_VOLT; + float vref3 = ADC_COUNTS / (float(r_cell3)) * R7 / (R4 + R7) * EXT_CALIB_VOLT; + + //calibration array values are updated. These are only used if triple calibration is in use. + calib[0] = vref1; + calib[1] = vref2; + calib[2] = vref3; + //avg all vrefs together to get best guess value + vref_guess = (vref1 + vref2 + vref3) / 3.0f; + return vref_guess; } //returns if i'm safe or not based on the most recent reading. //Currently does only over and under voltage protection. No time averaging. So will need to be fancier later. uint8_t BatteryBuzzer::compute_safety() { - uint8_t unsafe; - // Case 0: Cell voltages are below minimum values. - if ((v_cell1 < min_cell ) || (dv_cell2 < min_cell) || (dv_cell3 < min_cell)) { - unsafe = TRUE; - under_volt = TRUE; - } - // Case 1: Cell voltages are above maximum values. - else if ((v_cell1 > max_cell ) || (dv_cell2 > max_cell) || (dv_cell3 > max_cell)) { - unsafe = TRUE; - } - // Case 2: Imbalanced cell voltages. - else if ((abs(v_cell1 - dv_cell2) > d_cell) || (abs(dv_cell2 - dv_cell3) > d_cell) || (abs(dv_cell3 - v_cell1) > d_cell)) { - imbalance = TRUE; - unsafe = TRUE; - } - // Case 3: Previously undervolted, now exceeding exit threshold. This has the effect of - // rejecting momentary dips under the undervolt threshold but continuing to be unsafe if hovering close. - else if (under_volt && (v_cell1 > end_undervolt) && (dv_cell2 > end_undervolt) && (dv_cell3 > end_undervolt) ) { - unsafe = FALSE; - under_volt = FALSE; - } - // Case 4: Imbalanced, previously undervolted, and now exceeding exit thresholds. - else if (imbalance && (abs(v_cell1 - dv_cell2) < end_d_cell) && (abs(dv_cell2 - dv_cell3) < end_d_cell) && (abs(dv_cell3 - v_cell1) < end_d_cell) ) { - unsafe = FALSE; - imbalance = FALSE; - } - // Case 5: All is well. - else { - unsafe = FALSE; - } - return unsafe; + uint8_t unsafe; + // Case 0: Cell voltages are below minimum values. + if ((v_cell1 < min_cell) || (dv_cell2 < min_cell) || (dv_cell3 < min_cell)) { + unsafe = TRUE; + under_volt = TRUE; + } + // Case 1: Cell voltages are above maximum values. + else if ((v_cell1 > max_cell) || (dv_cell2 > max_cell) || (dv_cell3 > max_cell)) { + unsafe = TRUE; + } + // Case 2: Imbalanced cell voltages. + else if ((abs(v_cell1 - dv_cell2) > d_cell) || (abs(dv_cell2 - dv_cell3) > d_cell) || (abs(dv_cell3 - v_cell1) > d_cell)) { + imbalance = TRUE; + unsafe = TRUE; + } + // Case 3: Previously undervolted, now exceeding exit threshold. This has the effect of + // rejecting momentary dips under the undervolt threshold but continuing to be unsafe if hovering close. + else if (under_volt && (v_cell1 > end_undervolt) && (dv_cell2 > end_undervolt) && (dv_cell3 > end_undervolt)) { + unsafe = FALSE; + under_volt = FALSE; + } + // Case 4: Imbalanced, previously undervolted, and now exceeding exit thresholds. + else if (imbalance && (abs(v_cell1 - dv_cell2) < end_d_cell) && (abs(dv_cell2 - dv_cell3) < end_d_cell) && (abs(dv_cell3 - v_cell1) < end_d_cell)) { + unsafe = FALSE; + imbalance = FALSE; + } + // Case 5: All is well. + else { + unsafe = FALSE; + } + return unsafe; } -void BatteryBuzzer::buzz (uint8_t should_buzz) { - if (should_buzz) { - tone(buzzer, NOTE_A5); - } else { - noTone(buzzer); - } +void BatteryBuzzer::buzz(uint8_t should_buzz) { + if (should_buzz) { + tone(buzzer, NOTE_A5); + } else { + noTone(buzzer); + } } void BatteryBuzzer::handle_safety() { - unsafe_status = compute_safety(); //Currently, just does basic sensing. Should get updated. - buzz(unsafe_status); + unsafe_status = compute_safety(); //Currently, just does basic sensing. Should get updated. + buzz(unsafe_status); } uint8_t BatteryBuzzer::is_unsafe() { - return unsafe_status; + return unsafe_status; } float BatteryBuzzer::get_calibration() { - if (EEPROM.read(0)=='C' && EEPROM.read(1)=='A' && EEPROM.read(2)=='L' && EEPROM.read(3)==':') { - //instantiate a float. - float f = 0.0f; - EEPROM.get(4,f); //calibration value is stored in location 4 - return f; - } else { - return -1.0; - } + if (EEPROM.read(0) == 'C' && EEPROM.read(1) == 'A' && EEPROM.read(2) == 'L' && EEPROM.read(3) == ':') { + //instantiate a float. + float f = 0.0f; + EEPROM.get(4, f); //calibration value is stored in location 4 + return f; + } else { + return -1.0; + } } //updates the global "calib" array based on EEPROM. //Calib will contain datasheet values (2.56) if there's no calibration. //If there is, the appopriate elements will be updated. void BatteryBuzzer::update_triple_calibration() { - int next_addr = 0; - for (int i = 1; i<=3; i++) { - char first = EEPROM.read(next_addr); - char second = EEPROM.read(next_addr + 1); - char third = EEPROM.read(next_addr + 2); - char fourth = EEPROM.read(next_addr + 3); - char fifth = EEPROM.read(next_addr + 4); - - // Only takes in a valid calibration - no chance of using partial triple calibration left over in single mode. - if (first == 'C' && second == 'A' && third == 'L' && fourth == char(i+'0') && fifth == ':') { - float f = 0.0f; //instantiate a float. - EEPROM.get(next_addr + 5,f); //calibration value is stored in location 4 - calib[i - 1] = f; // put value into the calibration array - next_addr = next_addr + 5 + sizeof(float); - } else { - return; - } - } + int next_addr = 0; + for (int i = 1; i <= 3; i++) { + char first = EEPROM.read(next_addr); + char second = EEPROM.read(next_addr + 1); + char third = EEPROM.read(next_addr + 2); + char fourth = EEPROM.read(next_addr + 3); + char fifth = EEPROM.read(next_addr + 4); + + // Only takes in a valid calibration - no chance of using partial triple calibration left over in single mode. + if (first == 'C' && second == 'A' && third == 'L' && fourth == char(i + '0') && fifth == ':') { + float f = 0.0f; //instantiate a float. + EEPROM.get(next_addr + 5, f); //calibration value is stored in location 4 + calib[i - 1] = f; // put value into the calibration array + next_addr = next_addr + 5 + sizeof(float); + } else { + return; + } + } } void BatteryBuzzer::write_single_eeprom(float val) { - //Write one-value calibration to eeprom in the following format. - //This code may not be used in three-calibration mode, which will be standard. - EEPROM.write(0, 'C'); - EEPROM.write(1, 'A'); - EEPROM.write(2, 'L'); - EEPROM.write(3, ':'); - - //Needs arduino 1.6.12 or later. - EEPROM.put(4, val); + //Write one-value calibration to eeprom in the following format. + //This code may not be used in three-calibration mode, which will be standard. + EEPROM.write(0, 'C'); + EEPROM.write(1, 'A'); + EEPROM.write(2, 'L'); + EEPROM.write(3, ':'); + + //Needs arduino 1.6.12 or later. + EEPROM.put(4, val); } void BatteryBuzzer::write_triple_eeprom(float val1, float val2, float val3) { - // Write one-value calibration to eeprom in the following format: - // "CAL1:CAL2:CAL3 - - int next_addr = 0; - for (int i = 1; i <= 3; i++) { - EEPROM.write(next_addr, 'C'); - next_addr++; - EEPROM.write(next_addr, 'A'); - next_addr++; - EEPROM.write(next_addr, 'L'); - next_addr++; - EEPROM.write(next_addr, char(i+'0')); - next_addr++; - EEPROM.write(next_addr,':'); - next_addr++; - if(i == 1) { - EEPROM.put(next_addr,val1); - } else if(i == 2) { - EEPROM.put(next_addr,val2); - } else if(i == 3) { - EEPROM.put(next_addr,val3); - } - next_addr = next_addr + sizeof(float); - } + // Write one-value calibration to eeprom in the following format: + // "CAL1:CAL2:CAL3 + + int next_addr = 0; + for (int i = 1; i <= 3; i++) { + EEPROM.write(next_addr, 'C'); + next_addr++; + EEPROM.write(next_addr, 'A'); + next_addr++; + EEPROM.write(next_addr, 'L'); + next_addr++; + EEPROM.write(next_addr, char(i + '0')); + next_addr++; + EEPROM.write(next_addr, ':'); + next_addr++; + if (i == 1) { + EEPROM.put(next_addr, val1); + } else if (i == 2) { + EEPROM.put(next_addr, val2); + } else if (i == 3) { + EEPROM.put(next_addr, val3); + } + next_addr = next_addr + sizeof(float); + } } void BatteryBuzzer::clear_eeprom() { - // Writes 0 into all positions of the eeprom. - for (int i = 0 ; i < EEPROM.length() ; i++) { - EEPROM.write(i, 0); - } + // Writes 0 into all positions of the eeprom. + for (int i = 0; i < EEPROM.length(); i++) { + EEPROM.write(i, 0); + } } diff --git a/lowcar/devices/BatteryBuzzer/BatteryBuzzer.h b/lowcar/devices/BatteryBuzzer/BatteryBuzzer.h index cdecebbf..4ffa0dfd 100644 --- a/lowcar/devices/BatteryBuzzer/BatteryBuzzer.h +++ b/lowcar/devices/BatteryBuzzer/BatteryBuzzer.h @@ -1,107 +1,104 @@ #ifndef BATTERY_BUZZER_H #define BATTERY_BUZZER_H -#include "Device.h" -#include "pitches.h" -#include "pdb_defs.h" +#include #include -#include #include -#include +#include +#include "Device.h" +#include "pdb_defs.h" +#include "pitches.h" const int numOfDigits = 4; -class BatteryBuzzer : public Device -{ -public: - uint8_t triple_calibration; - int buzzer; - - BatteryBuzzer (); - - //overriden functions from Device class; see descriptions in Device.h - virtual size_t device_read (uint8_t param, uint8_t *data_buf); - virtual void device_enable (); - virtual void device_actions (); +class BatteryBuzzer : public Device { + public: + uint8_t triple_calibration; + int buzzer; -private: + BatteryBuzzer(); - /* EEPROM component */ + //overriden functions from Device class; see descriptions in Device.h + virtual size_t device_read(uint8_t param, uint8_t* data_buf); + virtual void device_enable(); + virtual void device_actions(); - float get_calibration(); - void update_triple_calibration(); - void write_single_eeprom(float val); - void write_triple_eeprom(float val1, float val2, float val3); - void clear_eeprom(); + private: + /* EEPROM component */ - /* Safety component */ + float get_calibration(); + void update_triple_calibration(); + void write_single_eeprom(float val); + void write_triple_eeprom(float val1, float val2, float val3); + void clear_eeprom(); - void handle_safety(); - uint8_t is_unsafe(); - void buzz(uint8_t should_buzz); + /* Safety component */ - uint8_t unsafe_status; + void handle_safety(); + uint8_t is_unsafe(); + void buzz(uint8_t should_buzz); - const float min_cell = 3.3; - const float end_undervolt = 3.6; // Exceed this value to remove my undervolt condition. - uint8_t under_volt; + uint8_t unsafe_status; - const float max_cell = 4.4; + const float min_cell = 3.3; + const float end_undervolt = 3.6; // Exceed this value to remove my undervolt condition. + uint8_t under_volt; - const float d_cell = 0.3; // Max voltage difference between cells. - const float end_d_cell = 0.1; //imbalance must be less than this before i'm happy again. - uint8_t imbalance; + const float max_cell = 4.4; - uint8_t compute_safety(); + const float d_cell = 0.3; // Max voltage difference between cells. + const float end_d_cell = 0.1; //imbalance must be less than this before i'm happy again. + uint8_t imbalance; - /* VoltageSense component */ + uint8_t compute_safety(); - void setup_sensing(); - void measure_cells(); - uint8_t handle_calibration(); - float calibrate(); + /* VoltageSense component */ - /* VoltageTracker component */ + void setup_sensing(); + void measure_cells(); + uint8_t handle_calibration(); + float calibrate(); - float get_voltage (PARAMS param); - void set_voltage (PARAMS param, float value); + /* VoltageTracker component */ - float get_calib (uint8_t index); - void set_calib (uint8_t index, float value); + float get_voltage(PARAMS param); + void set_voltage(PARAMS param, float value); - uint8_t get_triple_calibration(); - void set_triple_calibration(uint8_t triple_cal); + float get_calib(uint8_t index); + void set_calib(uint8_t index, float value); - float v_cell1; // param 3 - float v_cell2; // param 4 - float v_cell3; // param 5 - float v_batt; // param 6 - float dv_cell2; // param 7 - float dv_cell3; // param 8 - float vref_guess; // param 9 + uint8_t get_triple_calibration(); + void set_triple_calibration(uint8_t triple_cal); - float calib[3] = {0.0, 0.0, 0.0}; + float v_cell1; // param 3 + float v_cell2; // param 4 + float v_cell3; // param 5 + float v_batt; // param 6 + float dv_cell2; // param 7 + float dv_cell3; // param 8 + float vref_guess; // param 9 - /* disp_8 component */ + float calib[3] = {0.0, 0.0, 0.0}; - unsigned long last_check_time; + /* disp_8 component */ - SevenSeg disp; + unsigned long last_check_time; - int digitPins[numOfDigits]; - unsigned long last_LED_time; //Time the last LED switched - int sequence; //used to switch states for the display. Remember that the handle_8_segment cannot be blocking. - SEQ_NUM segment_8_run; //0 for the normal voltage readout. 1 for "Clear Calibration". 2 for "New Calibration" + SevenSeg disp; - void start_8_seg_sequence(SEQ_NUM sequence_num); - void handle_8_segment(); - void test_display(); - void setup_display(); + int digitPins[numOfDigits]; + unsigned long last_LED_time; //Time the last LED switched + int sequence; //used to switch states for the display. Remember that the handle_8_segment cannot be blocking. + SEQ_NUM segment_8_run; //0 for the normal voltage readout. 1 for "Clear Calibration". 2 for "New Calibration" - /* BatteryBuzzer component */ + void start_8_seg_sequence(SEQ_NUM sequence_num); + void handle_8_segment(); + void test_display(); + void setup_display(); - uint8_t is_calibrated (); + /* BatteryBuzzer component */ + uint8_t is_calibrated(); }; #endif diff --git a/lowcar/devices/BatteryBuzzer/pdb_defs.h b/lowcar/devices/BatteryBuzzer/pdb_defs.h index 58a1cf96..0c2390a4 100644 --- a/lowcar/devices/BatteryBuzzer/pdb_defs.h +++ b/lowcar/devices/BatteryBuzzer/pdb_defs.h @@ -38,22 +38,22 @@ // Enumerated values for BatteryBuzzer and VoltageTracker typedef enum { - IS_UNSAFE, - CALIBRATED, - V_CELL1, - V_CELL2, - V_CELL3, - V_BATT, - DV_CELL2, - DV_CELL3, - VREF_GUESS + IS_UNSAFE, + CALIBRATED, + V_CELL1, + V_CELL2, + V_CELL3, + V_BATT, + DV_CELL2, + DV_CELL3, + VREF_GUESS } PARAMS; // Enumerated values for disp_8 typedef enum { - NORMAL_VOLT_READ, - CLEAR_CALIB, - NEW_CALIB + NORMAL_VOLT_READ, + CLEAR_CALIB, + NEW_CALIB } SEQ_NUM; #endif diff --git a/lowcar/devices/BatteryBuzzer/pitches.h b/lowcar/devices/BatteryBuzzer/pitches.h index 9f16b4d6..f3037d5e 100644 --- a/lowcar/devices/BatteryBuzzer/pitches.h +++ b/lowcar/devices/BatteryBuzzer/pitches.h @@ -2,92 +2,92 @@ * Public Constants *************************************************/ -#define NOTE_B0 31 -#define NOTE_C1 33 +#define NOTE_B0 31 +#define NOTE_C1 33 #define NOTE_CS1 35 -#define NOTE_D1 37 +#define NOTE_D1 37 #define NOTE_DS1 39 -#define NOTE_E1 41 -#define NOTE_F1 44 +#define NOTE_E1 41 +#define NOTE_F1 44 #define NOTE_FS1 46 -#define NOTE_G1 49 +#define NOTE_G1 49 #define NOTE_GS1 52 -#define NOTE_A1 55 +#define NOTE_A1 55 #define NOTE_AS1 58 -#define NOTE_B1 62 -#define NOTE_C2 65 +#define NOTE_B1 62 +#define NOTE_C2 65 #define NOTE_CS2 69 -#define NOTE_D2 73 +#define NOTE_D2 73 #define NOTE_DS2 78 -#define NOTE_E2 82 -#define NOTE_F2 87 +#define NOTE_E2 82 +#define NOTE_F2 87 #define NOTE_FS2 93 -#define NOTE_G2 98 +#define NOTE_G2 98 #define NOTE_GS2 104 -#define NOTE_A2 110 +#define NOTE_A2 110 #define NOTE_AS2 117 -#define NOTE_B2 123 -#define NOTE_C3 131 +#define NOTE_B2 123 +#define NOTE_C3 131 #define NOTE_CS3 139 -#define NOTE_D3 147 +#define NOTE_D3 147 #define NOTE_DS3 156 -#define NOTE_E3 165 -#define NOTE_F3 175 +#define NOTE_E3 165 +#define NOTE_F3 175 #define NOTE_FS3 185 -#define NOTE_G3 196 +#define NOTE_G3 196 #define NOTE_GS3 208 -#define NOTE_A3 220 +#define NOTE_A3 220 #define NOTE_AS3 233 -#define NOTE_B3 247 -#define NOTE_C4 262 +#define NOTE_B3 247 +#define NOTE_C4 262 #define NOTE_CS4 277 -#define NOTE_D4 294 +#define NOTE_D4 294 #define NOTE_DS4 311 -#define NOTE_E4 330 -#define NOTE_F4 349 +#define NOTE_E4 330 +#define NOTE_F4 349 #define NOTE_FS4 370 -#define NOTE_G4 392 +#define NOTE_G4 392 #define NOTE_GS4 415 -#define NOTE_A4 440 +#define NOTE_A4 440 #define NOTE_AS4 466 -#define NOTE_B4 494 -#define NOTE_C5 523 +#define NOTE_B4 494 +#define NOTE_C5 523 #define NOTE_CS5 554 -#define NOTE_D5 587 +#define NOTE_D5 587 #define NOTE_DS5 622 -#define NOTE_E5 659 -#define NOTE_F5 698 +#define NOTE_E5 659 +#define NOTE_F5 698 #define NOTE_FS5 740 -#define NOTE_G5 784 +#define NOTE_G5 784 #define NOTE_GS5 831 -#define NOTE_A5 880 +#define NOTE_A5 880 #define NOTE_AS5 932 -#define NOTE_B5 988 -#define NOTE_C6 1047 +#define NOTE_B5 988 +#define NOTE_C6 1047 #define NOTE_CS6 1109 -#define NOTE_D6 1175 +#define NOTE_D6 1175 #define NOTE_DS6 1245 -#define NOTE_E6 1319 -#define NOTE_F6 1397 +#define NOTE_E6 1319 +#define NOTE_F6 1397 #define NOTE_FS6 1480 -#define NOTE_G6 1568 +#define NOTE_G6 1568 #define NOTE_GS6 1661 -#define NOTE_A6 1760 +#define NOTE_A6 1760 #define NOTE_AS6 1865 -#define NOTE_B6 1976 -#define NOTE_C7 2093 +#define NOTE_B6 1976 +#define NOTE_C7 2093 #define NOTE_CS7 2217 -#define NOTE_D7 2349 +#define NOTE_D7 2349 #define NOTE_DS7 2489 -#define NOTE_E7 2637 -#define NOTE_F7 2794 +#define NOTE_E7 2637 +#define NOTE_F7 2794 #define NOTE_FS7 2960 -#define NOTE_G7 3136 +#define NOTE_G7 3136 #define NOTE_GS7 3322 -#define NOTE_A7 3520 +#define NOTE_A7 3520 #define NOTE_AS7 3729 -#define NOTE_B7 3951 -#define NOTE_C8 4186 +#define NOTE_B7 3951 +#define NOTE_C8 4186 #define NOTE_CS8 4435 -#define NOTE_D8 4699 +#define NOTE_D8 4699 #define NOTE_DS8 4978 diff --git a/lowcar/devices/Device/Device.cpp b/lowcar/devices/Device/Device.cpp index 8772c3a1..91e73430 100644 --- a/lowcar/devices/Device/Device.cpp +++ b/lowcar/devices/Device/Device.cpp @@ -1,37 +1,37 @@ #include "Device.h" -const float Device::MAX_SUB_INTERVAL_MS = 500.0; // maximum tolerable subscription delay, in ms -const float Device::MIN_SUB_INTERVAL_MS = 40.0; // minimum tolerable subscription delay, in ms +const float Device::MAX_SUB_INTERVAL_MS = 500.0; // maximum tolerable subscription delay, in ms +const float Device::MIN_SUB_INTERVAL_MS = 40.0; // minimum tolerable subscription delay, in ms // Device constructor Device::Device(DeviceType dev_id, uint8_t dev_year, uint32_t timeout) { this->dev_id.type = dev_id; this->dev_id.year = dev_year; - this->dev_id.uid = 0; // sets a temporary value + this->dev_id.uid = 0; // sets a temporary value - this->params = 0; // Initialize to no subscribed parameters (empty DEVICE_DATA) - this->sub_interval = 0; // 0 acts as flag indicating no subscription - this->timeout = timeout; // timeout in ms how long we tolerate not receiving a PING from dev handler + this->params = 0; // Initialize to no subscribed parameters (empty DEVICE_DATA) + this->sub_interval = 0; // 0 acts as flag indicating no subscription + this->timeout = timeout; // timeout in ms how long we tolerate not receiving a PING from dev handler this->enabled = FALSE; this->msngr = new Messenger(); this->led = new StatusLED(); - device_enable(); // call device's enable function + device_enable(); // call device's enable function this->last_sent_data_time = this->last_received_ping_time = this->curr_time = millis(); } -void Device::set_uid (uint64_t uid) { +void Device::set_uid(uint64_t uid) { this->dev_id.uid = uid; } -void Device::loop () { +void Device::loop() { Status sts; this->curr_time = millis(); - sts = this->msngr->read_message(&(this->curr_msg)); // try to read a new message + sts = this->msngr->read_message(&(this->curr_msg)); // try to read a new message - if (sts == Status::SUCCESS) { // we have a message! + if (sts == Status::SUCCESS) { // we have a message! switch (this->curr_msg.message_id) { case MessageID::PING: this->last_received_ping_time = this->curr_time; @@ -44,8 +44,8 @@ void Device::loop () { break; case MessageID::SUBSCRIPTION_REQUEST: - this->params = *((uint32_t *) this->curr_msg.payload); // Update subscribed params - this->sub_interval = *((uint16_t *) (this->curr_msg.payload + PARAM_BITMAP_BYTES)); // Update the interval at which we send DEVICE_DATA + this->params = *((uint32_t*) this->curr_msg.payload); // Update subscribed params + this->sub_interval = *((uint16_t*) (this->curr_msg.payload + PARAM_BITMAP_BYTES)); // Update the interval at which we send DEVICE_DATA // Make sure sub_interval is within bounds this->sub_interval = min(this->sub_interval, MAX_SUB_INTERVAL_MS); this->sub_interval = max(this->sub_interval, MIN_SUB_INTERVAL_MS); @@ -65,7 +65,7 @@ void Device::loop () { } // If it's been too long since we received a PING, disable the device - if ((this->timeout > 0) && (this->curr_time - this->last_received_ping_time >= this->timeout)) { + if ((this->timeout > 0) && (this->curr_time - this->last_received_ping_time >= this->timeout)) { device_disable(); this->enabled = FALSE; } @@ -96,29 +96,29 @@ void Device::loop () { // ******************** DEFAULT DEVICE-SPECIFIC METHODS ********************* // -size_t Device::device_read (uint8_t param, uint8_t *data_buf) { - return 0; // by default, we read 0 bytes into buffer +size_t Device::device_read(uint8_t param, uint8_t* data_buf) { + return 0; // by default, we read 0 bytes into buffer } -size_t Device::device_write (uint8_t param, uint8_t *data_buf) { - return 0; // by default, we wrote 0 bytes successfully to device +size_t Device::device_write(uint8_t param, uint8_t* data_buf) { + return 0; // by default, we wrote 0 bytes successfully to device } -void Device::device_enable () { - return; // by default, enabling the device does nothing +void Device::device_enable() { + return; // by default, enabling the device does nothing } -void Device::device_disable () { - return; // by default, disabling the device does nothing +void Device::device_disable() { + return; // by default, disabling the device does nothing } -void Device::device_actions () { - return; // by default, device does nothing on every loop +void Device::device_actions() { + return; // by default, device does nothing on every loop } // ***************************** HELPER METHODS ***************************** // -void Device::device_read_params (message_t *msg) { +void Device::device_read_params(message_t* msg) { // Clear the message before building device data msg->message_id = MessageID::DEVICE_DATA; msg->payload_length = 0; @@ -126,7 +126,7 @@ void Device::device_read_params (message_t *msg) { // Read all subscribed params // Set beginning of payload to subscribed param bitmap - uint32_t* payload_ptr_uint32 = (uint32_t *) msg->payload; + uint32_t* payload_ptr_uint32 = (uint32_t*) msg->payload; *payload_ptr_uint32 = this->params; // Loop over param_bitmap and attempt to read data for subscribed bits @@ -138,7 +138,7 @@ void Device::device_read_params (message_t *msg) { } } -void Device::device_write_params (message_t *msg) { +void Device::device_write_params(message_t* msg) { if (msg->message_id != MessageID::DEVICE_WRITE) { return; } @@ -147,7 +147,7 @@ void Device::device_write_params (message_t *msg) { uint32_t param_bitmap = *((uint32_t*) msg->payload); // Loop over param_bitmap and attempt to write data for requested bits - uint8_t *payload_ptr = msg->payload + PARAM_BITMAP_BYTES; + uint8_t* payload_ptr = msg->payload + PARAM_BITMAP_BYTES; for (uint32_t param_num = 0; (param_bitmap >> param_num) > 0; param_num++) { if (param_bitmap & (1 << param_num)) { payload_ptr += device_write((uint8_t) param_num, payload_ptr); diff --git a/lowcar/devices/Device/Device.h b/lowcar/devices/Device/Device.h index 685a9edd..da3139ce 100644 --- a/lowcar/devices/Device/Device.h +++ b/lowcar/devices/Device/Device.h @@ -6,13 +6,12 @@ #ifndef DEVICE_H #define DEVICE_H -#include "defs.h" #include "Messenger.h" #include "StatusLED.h" +#include "defs.h" class Device { - -public: + public: // ********************** UNIVERSAL DEVICE METHODS ********************** // /** @@ -57,7 +56,7 @@ class Device { * the size of the parameter read into the buffer, or * 0 on failure */ - virtual size_t device_read(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); /** * Writes the value of a parameter from a buffer into the device @@ -69,7 +68,7 @@ class Device { * the size of the parameter that was written, or * 0 on failure. */ - virtual size_t device_write(uint8_t param, uint8_t *data_buf); + virtual size_t device_write(uint8_t param, uint8_t* data_buf); /** * Performs necessary setup for the device to operate. @@ -93,37 +92,37 @@ class Device { */ virtual void device_actions(); -protected: - Messenger *msngr; // Encodes/decodes and send/receive messages over serial + protected: + Messenger* msngr; // Encodes/decodes and send/receive messages over serial uint8_t enabled; -private: + private: const static float MAX_SUB_INTERVAL_MS; // Maximum tolerable subscription delay, in ms const static float MIN_SUB_INTERVAL_MS; // Minimum tolerable subscription delay, in ms - StatusLED *led; // The LED on the Arduino - dev_id_t dev_id; // dev_id of this device determined when flashing - uint32_t params; // Bitmap of parameters subscribed to by dev handler - uint16_t sub_interval; // Time between sending new DEVICE_DATA messages - uint32_t timeout; // Maximum time (ms) we'll wait between PING messages from dev handler - uint64_t last_sent_data_time; // Timestamp of last time we sent DEVICE_DATA due to Subscription - uint64_t last_received_ping_time; // Timestamp of last time we received a PING - uint64_t curr_time; // The current time - message_t curr_msg; // current message being processed + StatusLED* led; // The LED on the Arduino + dev_id_t dev_id; // dev_id of this device determined when flashing + uint32_t params; // Bitmap of parameters subscribed to by dev handler + uint16_t sub_interval; // Time between sending new DEVICE_DATA messages + uint32_t timeout; // Maximum time (ms) we'll wait between PING messages from dev handler + uint64_t last_sent_data_time; // Timestamp of last time we sent DEVICE_DATA due to Subscription + uint64_t last_received_ping_time; // Timestamp of last time we received a PING + uint64_t curr_time; // The current time + message_t curr_msg; // current message being processed /** * Builds a DEVICE_DATA message by reading all subscribed parameters. * Arguments: * msg: An empty message to be populated with parameter values ready for sending. */ - void device_read_params(message_t *msg); + void device_read_params(message_t* msg); /** * Writes to device parameters given a DEVICE_WRITE message. * Arguments: * msg: A DEVICE_WRITE message containing parameters to write to the device. */ - void device_write_params(message_t *msg); + void device_write_params(message_t* msg); }; #endif diff --git a/lowcar/devices/Device/Messenger.cpp b/lowcar/devices/Device/Messenger.cpp index 1c93cd5f..c63beb79 100644 --- a/lowcar/devices/Device/Messenger.cpp +++ b/lowcar/devices/Device/Messenger.cpp @@ -3,34 +3,34 @@ // ************************ MESSENGER CLASS CONSTANTS *********************** // // Final encoded data sizes -const int Messenger::DELIMITER_BYTES = 1; // Bytes of the delimiter -const int Messenger::COBS_LEN_BYTES = 1; // Bytes indicating the size of the cobs encoded message +const int Messenger::DELIMITER_BYTES = 1; // Bytes of the delimiter +const int Messenger::COBS_LEN_BYTES = 1; // Bytes indicating the size of the cobs encoded message // Message sizes -const int Messenger::MESSAGEID_BYTES = 1; // Bytes in message ID field of packet -const int Messenger::PAYLOAD_SIZE_BYTES = 1; // Bytes in payload size field of packet -const int Messenger::CHECKSUM_BYTES = 1; // Bytes in checksum field of packet +const int Messenger::MESSAGEID_BYTES = 1; // Bytes in message ID field of packet +const int Messenger::PAYLOAD_SIZE_BYTES = 1; // Bytes in payload size field of packet +const int Messenger::CHECKSUM_BYTES = 1; // Bytes in checksum field of packet // Sizes for ACKNOWLEDGEMENT message -const int Messenger::DEV_ID_TYPE_BYTES = 2; // Bytes in device type field of dev id -const int Messenger::DEV_ID_YEAR_BYTES = 1; // Bytes in year field of dev id -const int Messenger::DEV_ID_UID_BYTES = 8; // Bytes in uid field of dev id +const int Messenger::DEV_ID_TYPE_BYTES = 2; // Bytes in device type field of dev id +const int Messenger::DEV_ID_YEAR_BYTES = 1; // Bytes in year field of dev id +const int Messenger::DEV_ID_UID_BYTES = 8; // Bytes in uid field of dev id // ************************* MESSENGER CLASS METHODS ************************ // Messenger::Messenger() { - Serial.begin(115200); // open Serial (USB) connection + Serial.begin(115200); // open Serial (USB) connection // A queue initialized with room for 10 strings each of size MAX_PAYLOAD_SIZE this->log_queue_max_size = 10; - this->log_queue = (char **) malloc(sizeof(char *) * this->log_queue_max_size); + this->log_queue = (char**) malloc(sizeof(char*) * this->log_queue_max_size); for (int i = 0; i < this->log_queue_max_size; i++) { - this->log_queue[i] = (char *) malloc(sizeof(char) * MAX_PAYLOAD_SIZE); + this->log_queue[i] = (char*) malloc(sizeof(char) * MAX_PAYLOAD_SIZE); } this->num_logs = 0; } -Status Messenger::send_message(MessageID msg_id, message_t *msg, dev_id_t *dev_id) { +Status Messenger::send_message(MessageID msg_id, message_t* msg, dev_id_t* dev_id) { // Fill MessageID field msg->message_id = msg_id; @@ -40,9 +40,9 @@ Status Messenger::send_message(MessageID msg_id, message_t *msg, dev_id_t *dev_i */ if (msg_id == MessageID::ACKNOWLEDGEMENT) { int status = 0; - status += append_payload(msg, (uint8_t *) &dev_id->type, Messenger::DEV_ID_TYPE_BYTES); - status += append_payload(msg, (uint8_t *) &dev_id->year, Messenger::DEV_ID_YEAR_BYTES); - status += append_payload(msg, (uint8_t *) &dev_id->uid, Messenger::DEV_ID_UID_BYTES); + status += append_payload(msg, (uint8_t*) &dev_id->type, Messenger::DEV_ID_TYPE_BYTES); + status += append_payload(msg, (uint8_t*) &dev_id->year, Messenger::DEV_ID_YEAR_BYTES); + status += append_payload(msg, (uint8_t*) &dev_id->uid, Messenger::DEV_ID_UID_BYTES); if (status != 0) { return Status::PROCESS_ERROR; @@ -53,11 +53,11 @@ Status Messenger::send_message(MessageID msg_id, message_t *msg, dev_id_t *dev_i size_t msg_len = Messenger::MESSAGEID_BYTES + Messenger::PAYLOAD_SIZE_BYTES + msg->payload_length + Messenger::CHECKSUM_BYTES; uint8_t data[msg_len]; message_to_byte(data, msg); - data[msg_len - Messenger::CHECKSUM_BYTES] = checksum(data, msg_len - Messenger::CHECKSUM_BYTES); // put the checksum into data + data[msg_len - Messenger::CHECKSUM_BYTES] = checksum(data, msg_len - Messenger::CHECKSUM_BYTES); // put the checksum into data // Cobs encode the byte array - uint8_t cobs_buf[Messenger::DELIMITER_BYTES + Messenger::COBS_LEN_BYTES + msg_len + 1]; // Cobs encoding adds at most 1 byte overhead - cobs_buf[0] = 0x00; // Start with the delimiter + uint8_t cobs_buf[Messenger::DELIMITER_BYTES + Messenger::COBS_LEN_BYTES + msg_len + 1]; // Cobs encoding adds at most 1 byte overhead + cobs_buf[0] = 0x00; // Start with the delimiter size_t cobs_len = cobs_encode(&cobs_buf[2], data, msg_len); cobs_buf[1] = (byte) cobs_len; @@ -72,7 +72,7 @@ Status Messenger::send_message(MessageID msg_id, message_t *msg, dev_id_t *dev_i return (written == Messenger::DELIMITER_BYTES + Messenger::COBS_LEN_BYTES + cobs_len) ? Status::SUCCESS : Status::PROCESS_ERROR; } -Status Messenger::read_message (message_t *msg) { +Status Messenger::read_message(message_t* msg) { // Check if there's something to read if (!Serial.available()) { return Status::NO_DATA; @@ -82,15 +82,15 @@ Status Messenger::read_message (message_t *msg) { int last_byte_read = -1; while (Serial.available()) { last_byte_read = Serial.read(); - if (last_byte_read == 0) { // Byte 0x00 is the delimiter + if (last_byte_read == 0) { // Byte 0x00 is the delimiter break; } } - if (last_byte_read != 0) { // no start of packet found + if (last_byte_read != 0) { // no start of packet found return Status::MALFORMED_DATA; } - if (Serial.available() == 0 || Serial.peek() == 0) { // no packet length found + if (Serial.available() == 0 || Serial.peek() == 0) { // no packet length found return Status::MALFORMED_DATA; } @@ -99,13 +99,13 @@ Status Messenger::read_message (message_t *msg) { // Read the rest of the message into buffer uint8_t cobs_buf[cobs_len]; - size_t read_len = Serial.readBytesUntil(0x00, (char *)cobs_buf, cobs_len); // Read cobs_len bytes or until the next delimiter (whichever is first) + size_t read_len = Serial.readBytesUntil(0x00, (char*) cobs_buf, cobs_len); // Read cobs_len bytes or until the next delimiter (whichever is first) if (cobs_len != read_len) { return Status::PROCESS_ERROR; } // Decode the cobs-encoded message into a buffer - uint8_t data[cobs_len]; // The decoded message will be smaller than COBS_LEN + uint8_t data[cobs_len]; // The decoded message will be smaller than COBS_LEN cobs_decode(data, cobs_buf, cobs_len); uint8_t message_id = data[0]; @@ -128,9 +128,9 @@ Status Messenger::read_message (message_t *msg) { void Messenger::lowcar_printf(char* format, ...) { // Double the queue size if it's full if (this->num_logs == this->log_queue_max_size) { - this->log_queue = (char**) realloc(this->log_queue, sizeof(char *) * 2 * this->log_queue_max_size); + this->log_queue = (char**) realloc(this->log_queue, sizeof(char*) * 2 * this->log_queue_max_size); for (int i = this->log_queue_max_size; i < 2 * this->log_queue_max_size; i++) { - this->log_queue[i] = (char *) malloc(sizeof(char) * MAX_PAYLOAD_SIZE); + this->log_queue[i] = (char*) malloc(sizeof(char) * MAX_PAYLOAD_SIZE); } this->log_queue_max_size *= 2; } @@ -143,9 +143,9 @@ void Messenger::lowcar_printf(char* format, ...) { this->num_logs++; } -void Messenger::lowcar_print_float(char *name, float val) { - int whole_val = (int) val; // Part of val to the left of the decimal point - int thousandths = (int) ((val - whole_val) * 1000); // The 3 digits to the right of the decimal point +void Messenger::lowcar_print_float(char* name, float val) { + int whole_val = (int) val; // Part of val to the left of the decimal point + int thousandths = (int) ((val - whole_val) * 1000); // The 3 digits to the right of the decimal point this->lowcar_printf("%s: %d.%03d", name, whole_val, thousandths); } @@ -158,7 +158,7 @@ void Messenger::lowcar_flush() { message_t log; // For each log, send a new message for (int i = 0; i < this->num_logs; i++) { - log.payload_length = strlen(this->log_queue[i]) + 1; // Null terminator character + log.payload_length = strlen(this->log_queue[i]) + 1; // Null terminator character // Copy string into payload memcpy((char*) log.payload, this->log_queue[i], (size_t) log.payload_length); @@ -170,7 +170,7 @@ void Messenger::lowcar_flush() { // ***************************** HELPER METHODS ***************************** // -int Messenger::append_payload(message_t *msg, uint8_t *data, uint8_t length) { +int Messenger::append_payload(message_t* msg, uint8_t* data, uint8_t length) { if (msg->payload_length + length > MAX_PAYLOAD_SIZE) { return -1; } @@ -179,13 +179,13 @@ int Messenger::append_payload(message_t *msg, uint8_t *data, uint8_t length) { return 0; } -void Messenger::message_to_byte(uint8_t *data, message_t *msg) { +void Messenger::message_to_byte(uint8_t* data, message_t* msg) { data[0] = (uint8_t) msg->message_id; data[1] = msg->payload_length; memcpy(&data[2], msg->payload, msg->payload_length); } -uint8_t Messenger::checksum (uint8_t *data, int length) { +uint8_t Messenger::checksum(uint8_t* data, int length) { uint8_t chk = data[0]; for (int i = 1; i < length; i++) { chk ^= data[i]; @@ -195,16 +195,17 @@ uint8_t Messenger::checksum (uint8_t *data, int length) { // ***************************** COBS ENCODING ****************************** // -#define finish_block() { \ - *block_len_loc = block_len; \ - block_len_loc = dst++; \ - out_len++; \ - block_len = 0x01; \ -} +#define finish_block() \ + { \ + *block_len_loc = block_len; \ + block_len_loc = dst++; \ + out_len++; \ + block_len = 0x01; \ + } -size_t Messenger::cobs_encode(uint8_t *dst, const uint8_t *src, size_t src_len) { - const uint8_t *end = src + src_len; - uint8_t *block_len_loc = dst++; +size_t Messenger::cobs_encode(uint8_t* dst, const uint8_t* src, size_t src_len) { + const uint8_t* end = src + src_len; + uint8_t* block_len_loc = dst++; uint8_t block_len = 0x01; size_t out_len = 0; @@ -225,8 +226,8 @@ size_t Messenger::cobs_encode(uint8_t *dst, const uint8_t *src, size_t src_len) return out_len; } -size_t Messenger::cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len) { - const uint8_t *end = src + src_len; +size_t Messenger::cobs_decode(uint8_t* dst, const uint8_t* src, size_t src_len) { + const uint8_t* end = src + src_len; size_t out_len = 0; while (src < end) { @@ -234,7 +235,7 @@ size_t Messenger::cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len) for (uint8_t i = 1; i < code; i++) { *dst++ = *src++; out_len++; - if (src > end) { // Bad packet + if (src > end) { // Bad packet return 0; } } diff --git a/lowcar/devices/Device/Messenger.h b/lowcar/devices/Device/Messenger.h index 364cd0fd..2b50c99e 100644 --- a/lowcar/devices/Device/Messenger.h +++ b/lowcar/devices/Device/Messenger.h @@ -5,11 +5,11 @@ #ifndef MESSENGER_H #define MESSENGER_H +#include // va_start, va_list, va_arg, va_end #include "defs.h" -#include // va_start, va_list, va_arg, va_end class Messenger { -public: + public: /* constructor; opens Serial connection */ Messenger(); @@ -23,7 +23,7 @@ class Messenger { * Returns: * a Status enum to report on success/failure */ - Status send_message(MessageID msg_id, message_t *msg, dev_id_t *dev_id = NULL); + Status send_message(MessageID msg_id, message_t* msg, dev_id_t* dev_id = NULL); /** * Reads in data from serial port and puts results into msg @@ -32,7 +32,7 @@ class Messenger { * Returns: * a Status enum to report on success/failure */ - Status read_message(message_t *msg); + Status read_message(message_t* msg); // ****************************** LOGGING ******************************* // @@ -53,7 +53,7 @@ class Messenger { * name: A string describing the value of the float (ex: the variable name) * val: The float to be printed alongside NAME */ - void lowcar_print_float(char *name, float val); + void lowcar_print_float(char* name, float val); /** * Sends all currently queued logs to dev handler @@ -61,23 +61,23 @@ class Messenger { */ void lowcar_flush(); -private: + private: // protocol constants - const static int DELIMITER_BYTES; // The size of a packet delimiter - const static int COBS_LEN_BYTES; // The size the cobs length in a packet + const static int DELIMITER_BYTES; // The size of a packet delimiter + const static int COBS_LEN_BYTES; // The size the cobs length in a packet - const static int MESSAGEID_BYTES; // bytes in message ID field of packet - const static int PAYLOAD_SIZE_BYTES; // bytes in payload size field of packet - const static int CHECKSUM_BYTES; // bytes in checksum field of packet + const static int MESSAGEID_BYTES; // bytes in message ID field of packet + const static int PAYLOAD_SIZE_BYTES; // bytes in payload size field of packet + const static int CHECKSUM_BYTES; // bytes in checksum field of packet const static int DEV_ID_TYPE_BYTES; // bytes in device type field of dev_id const static int DEV_ID_YEAR_BYTES; // bytes in year field of dev_id const static int DEV_ID_UID_BYTES; // bytes in uid field of dev_id // private variables - uint8_t log_queue_max_size; // The size of the log queue in bytes - char **log_queue; // The log queue - uint8_t num_logs; // The number of logs in the log queue + uint8_t log_queue_max_size; // The size of the log queue in bytes + char** log_queue; // The log queue + uint8_t num_logs; // The number of logs in the log queue // *************************** HELPER METHODS *************************** // @@ -92,7 +92,7 @@ class Messenger { * 0 on success, or * -1 if LENGTH is too large (DATA can't fit in the allocated payload) */ - int append_payload(message_t *msg, uint8_t *data, uint8_t length); + int append_payload(message_t* msg, uint8_t* data, uint8_t length); /** * Serializes a message into a byte packet to be sent over serial. @@ -100,7 +100,7 @@ class Messenger { * data: The buffer to write the serialized message into * msg: A populated message to be serialized. */ - void message_to_byte(uint8_t *data, message_t *msg); + void message_to_byte(uint8_t* data, message_t* msg); /** * Computes the checksum of a data buffer. @@ -111,7 +111,7 @@ class Messenger { * Returns: * the checksum */ - uint8_t checksum(uint8_t *data, int length); + uint8_t checksum(uint8_t* data, int length); // **************************** COBS ENCODING *************************** // @@ -124,7 +124,7 @@ class Messenger { * Returns: * The size of the encoded data, DST */ - size_t cobs_encode(uint8_t *dst, const uint8_t *src, size_t src_len); + size_t cobs_encode(uint8_t* dst, const uint8_t* src, size_t src_len); /** * Cobs decodes a byte array into a buffer @@ -135,7 +135,7 @@ class Messenger { * Returns: * The size of the decoded data, DST */ - size_t cobs_decode(uint8_t *dst, const uint8_t *src, size_t src_len); + size_t cobs_decode(uint8_t* dst, const uint8_t* src, size_t src_len); }; #endif diff --git a/lowcar/devices/Device/StatusLED.cpp b/lowcar/devices/Device/StatusLED.cpp index fae0823f..7524dbff 100644 --- a/lowcar/devices/Device/StatusLED.cpp +++ b/lowcar/devices/Device/StatusLED.cpp @@ -1,8 +1,8 @@ #include "StatusLED.h" -#define QUICK_TIME 300 // Feel free to change this +#define QUICK_TIME 300 // Feel free to change this // Morse code ratios -#define SLOW_TIME (QUICK_TIME*3) +#define SLOW_TIME (QUICK_TIME * 3) #define PAUSE_TIME QUICK_TIME StatusLED::StatusLED() { diff --git a/lowcar/devices/Device/StatusLED.h b/lowcar/devices/Device/StatusLED.h index 2d4f561c..f03a02f2 100644 --- a/lowcar/devices/Device/StatusLED.h +++ b/lowcar/devices/Device/StatusLED.h @@ -8,7 +8,7 @@ #include "defs.h" class StatusLED { -public: + public: // sets up the status LED and configures the pin StatusLED(); @@ -21,9 +21,9 @@ class StatusLED { // Blink slowly NUM times void slow_blink(int num); -private: - const static int LED_PIN = 17; // pin to control the LED - bool led_enabled; // keeps track of whether LED is on or off + private: + const static int LED_PIN = 17; // pin to control the LED + bool led_enabled; // keeps track of whether LED is on or off // Blinks NUM times, waiting MS ms between the toggles, and SPACE ms between each blink void blink(int num, int ms, int space); diff --git a/lowcar/devices/Device/defs.h b/lowcar/devices/Device/defs.h index b3b68c2d..460b7088 100644 --- a/lowcar/devices/Device/defs.h +++ b/lowcar/devices/Device/defs.h @@ -1,17 +1,17 @@ #ifndef DEFS_H #define DEFS_H -#include "Arduino.h" #include +#include "Arduino.h" // The maximum number of parameters for a lowcar device #define MAX_PARAMS 32 // The size of the param bitmap used in various messages (8 bits in a byte) -#define PARAM_BITMAP_BYTES (MAX_PARAMS / 8) +#define PARAM_BITMAP_BYTES (MAX_PARAMS / 8) // Maximum size of a message payload // achieved with a DEVICE_WRITE/DEVICE_DATA of MAX_PARAMS of all floats -#define MAX_PAYLOAD_SIZE (PARAM_BITMAP_BYTES + (MAX_PARAMS * sizeof(float))) +#define MAX_PAYLOAD_SIZE (PARAM_BITMAP_BYTES + (MAX_PARAMS * sizeof(float))) // Use these with uint8_t instead of `bool` with `true` and `false` // This makes device_read() and device_write() cleaner when parsing on C @@ -38,24 +38,24 @@ enum class Digital : uint8_t { /* The types of messages */ enum class MessageID : uint8_t { - NOP = 0x00, // Dummy message - PING = 0x01, // To lowcar - ACKNOWLEDGEMENT = 0x02, // To dev handler - SUBSCRIPTION_REQUEST = 0x03, // To lowcar - DEVICE_WRITE = 0x04, // To lowcar - DEVICE_DATA = 0x05, // To dev handler - LOG = 0x06 // To dev handler + NOP = 0x00, // Dummy message + PING = 0x01, // To lowcar + ACKNOWLEDGEMENT = 0x02, // To dev handler + SUBSCRIPTION_REQUEST = 0x03, // To lowcar + DEVICE_WRITE = 0x04, // To lowcar + DEVICE_DATA = 0x05, // To dev handler + LOG = 0x06 // To dev handler }; // identification for device types enum class DeviceType : uint16_t { - DUMMY_DEVICE = 0x00, - LIMIT_SWITCH = 0x01, - LINE_FOLLOWER = 0x02, - BATTERY_BUZZER = 0x03, - SERVO_CONTROL = 0x04, - POLAR_BEAR = 0x05, - KOALA_BEAR = 0x06 + DUMMY_DEVICE = 0x00, + LIMIT_SWITCH = 0x01, + LINE_FOLLOWER = 0x02, + BATTERY_BUZZER = 0x03, + SERVO_CONTROL = 0x04, + POLAR_BEAR = 0x05, + KOALA_BEAR = 0x06 // DISTANCE_SENSOR = 0x07 Uncomment when implemented }; diff --git a/lowcar/devices/DummyDevice/DummyDevice.cpp b/lowcar/devices/DummyDevice/DummyDevice.cpp index a4d10243..1dcea026 100644 --- a/lowcar/devices/DummyDevice/DummyDevice.cpp +++ b/lowcar/devices/DummyDevice/DummyDevice.cpp @@ -44,12 +44,11 @@ DummyDevice::DummyDevice() : Device(DeviceType::DUMMY_DEVICE, 13) { this->dusk = 0; } -size_t DummyDevice::device_read(uint8_t param, uint8_t *data_buf) { - float *float_buf = (float *) data_buf; - int32_t *int_buf = (int32_t *) data_buf; +size_t DummyDevice::device_read(uint8_t param, uint8_t* data_buf) { + float* float_buf = (float*) data_buf; + int32_t* int_buf = (int32_t*) data_buf; switch (param) { - case RUNTIME: int_buf[0] = this->runtime; return sizeof(this->runtime); @@ -111,9 +110,8 @@ size_t DummyDevice::device_read(uint8_t param, uint8_t *data_buf) { return 0; } -size_t DummyDevice::device_write(uint8_t param, uint8_t *data_buf) { +size_t DummyDevice::device_write(uint8_t param, uint8_t* data_buf) { switch (param) { - case RUNTIME: break; @@ -133,11 +131,11 @@ size_t DummyDevice::device_write(uint8_t param, uint8_t *data_buf) { break; case SENS: - this->sens = ((int32_t *) data_buf)[0]; + this->sens = ((int32_t*) data_buf)[0]; return sizeof(this->sens); case PDB: - this->pdb = ((float *) data_buf)[0]; + this->pdb = ((float*) data_buf)[0]; return sizeof(this->pdb); case MECH: @@ -145,11 +143,11 @@ size_t DummyDevice::device_write(uint8_t param, uint8_t *data_buf) { return sizeof(this->mech); case CPR: - this->cpr = ((int32_t *) data_buf)[0]; + this->cpr = ((int32_t*) data_buf)[0]; return sizeof(this->cpr); case EDU: - this->edu = ((float *) data_buf)[0]; + this->edu = ((float*) data_buf)[0]; return sizeof(this->edu); case EXEC: @@ -157,11 +155,11 @@ size_t DummyDevice::device_write(uint8_t param, uint8_t *data_buf) { return sizeof(this->exec); case PIEF: - this->pief = ((int32_t *) data_buf)[0]; + this->pief = ((int32_t*) data_buf)[0]; return sizeof(this->pief); case FUNTIME: - this->funtime = ((float *) data_buf)[0]; + this->funtime = ((float*) data_buf)[0]; return sizeof(this->funtime); case SHEEP: @@ -169,7 +167,7 @@ size_t DummyDevice::device_write(uint8_t param, uint8_t *data_buf) { return sizeof(this->sheep); case DUSK: - this->dusk = ((int32_t *) data_buf)[0]; + this->dusk = ((int32_t*) data_buf)[0]; return sizeof(this->dusk); } return 0; @@ -190,7 +188,6 @@ void DummyDevice::device_actions() { // Simulate read-only params changing if (curr - last_update_time > 500) { - this->runtime += 2; this->shepherd += 1.9; this->dawn = !this->dawn; diff --git a/lowcar/devices/DummyDevice/DummyDevice.h b/lowcar/devices/DummyDevice/DummyDevice.h index b9a78f2f..05b0dba3 100644 --- a/lowcar/devices/DummyDevice/DummyDevice.h +++ b/lowcar/devices/DummyDevice/DummyDevice.h @@ -12,40 +12,40 @@ */ class DummyDevice : public Device { -public: + public: // construct a Dummy device DummyDevice(); - virtual size_t device_read(uint8_t param, uint8_t *data_buf); - virtual size_t device_write(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); + virtual size_t device_write(uint8_t param, uint8_t* data_buf); virtual void device_enable(); virtual void device_disable(); // Changes several of the readable params for testing virtual void device_actions(); -private: - int32_t runtime; //param 0 + private: + int32_t runtime; //param 0 float shepherd; uint8_t dawn; - int32_t devops; //param 3 + int32_t devops; //param 3 float atlas; uint8_t infra; - int32_t sens; //param 6 + int32_t sens; //param 6 float pdb; uint8_t mech; - int32_t cpr; //param 9 + int32_t cpr; //param 9 float edu; uint8_t exec; - int32_t pief; //param 12 + int32_t pief; //param 12 float funtime; uint8_t sheep; - int32_t dusk; //param 15 + int32_t dusk; //param 15 }; #endif diff --git a/lowcar/devices/KoalaBear/KoalaBear.cpp b/lowcar/devices/KoalaBear/KoalaBear.cpp index 9d547da0..42558612 100644 --- a/lowcar/devices/KoalaBear/KoalaBear.cpp +++ b/lowcar/devices/KoalaBear/KoalaBear.cpp @@ -2,28 +2,28 @@ //********************************* constants and variables used for setting up the controller ********************// //TODO: ask electrical for what they mean -#define CTRL_REG 0b000 -#define TORQUE_REG 0b001 +#define CTRL_REG 0b000 +#define TORQUE_REG 0b001 // Control Register options // Dead time -#define DTIME_410_ns 0b00 -#define DTIME_460_ns 0b01 -#define DTIME_670_ns 0b10 -#define DTIME_880_ns 0b11 +#define DTIME_410_ns 0b00 +#define DTIME_460_ns 0b01 +#define DTIME_670_ns 0b10 +#define DTIME_880_ns 0b11 // Current sense gain -#define ISGAIN_5 0b00 -#define ISGAIN_10 0b01 -#define ISGAIN_20 0b10 -#define ISGAIN_40 0b11 +#define ISGAIN_5 0b00 +#define ISGAIN_10 0b01 +#define ISGAIN_20 0b10 +#define ISGAIN_40 0b11 // Enable or disable motors -#define ENABLE 0b1 -#define DISABLE 0b0 +#define ENABLE 0b1 +#define DISABLE 0b0 // Set VREF scaling out of 256 -#define TORQUE 0x70 +#define TORQUE 0x70 uint16_t ctrl_read_data; uint16_t torque_read_data; @@ -33,23 +33,23 @@ volatile int32_t enc_a, enc_b; //********************************** labels for useful indices **********************************// typedef enum { // params for the first motor - DUTY_CYCLE_A = 0, // Student's desired speed between -1 and 1, inclusive - DEADBAND_A = 1, // between 0 and 1, magnitude of duty cycle input under which the motor will not move - CURRENT_A = 2, - PID_ENABLED_A = 3, // True if using PID control; False if using manual drive mode - PID_KP_A = 4, // these three are the PID coefficients - PID_KI_A = 5, - PID_KD_A = 6, - ENC_A = 7, // encoder position, in ticks + DUTY_CYCLE_A = 0, // Student's desired speed between -1 and 1, inclusive + DEADBAND_A = 1, // between 0 and 1, magnitude of duty cycle input under which the motor will not move + CURRENT_A = 2, + PID_ENABLED_A = 3, // True if using PID control; False if using manual drive mode + PID_KP_A = 4, // these three are the PID coefficients + PID_KI_A = 5, + PID_KD_A = 6, + ENC_A = 7, // encoder position, in ticks //same params for the second motor - DUTY_CYCLE_B = 8, - DEADBAND_B = 9, - CURRENT_B = 10, + DUTY_CYCLE_B = 8, + DEADBAND_B = 9, + CURRENT_B = 10, PID_ENABLED_B = 11, - PID_KP_B = 12, - PID_KI_B = 13, - PID_KD_B = 14, - ENC_B = 15 + PID_KP_B = 12, + PID_KI_B = 13, + PID_KD_B = 14, + ENC_B = 15 } param; typedef enum { @@ -86,23 +86,23 @@ KoalaBear::KoalaBear() : Device(DeviceType::KOALA_BEAR, 13) { // initialize encoders enc_a = enc_b = 0.0; - attachInterrupt(digitalPinToInterrupt(AENC1), handle_enc_a_tick, RISING); // set interrupt service routines for encoder pins + attachInterrupt(digitalPinToInterrupt(AENC1), handle_enc_a_tick, RISING); // set interrupt service routines for encoder pins attachInterrupt(digitalPinToInterrupt(BENC1), handle_enc_b_tick, RISING); // initialize PID controllers this->pid_a = new PID(); this->pid_b = new PID(); - this->pid_enabled_a = this->pid_enabled_b = FALSE; // TODO: change to true when PID written + this->pid_enabled_a = this->pid_enabled_b = FALSE; // TODO: change to true when PID written this->led = new LEDKoala(); this->prev_led_time = millis(); this->curr_led_mtr = MTRA; } -size_t KoalaBear::device_read(uint8_t param, uint8_t *data_buf) { - float *float_buf = (float *) data_buf; - bool *bool_buf = (bool *) data_buf; - int32_t *int_buf = (int32_t *) data_buf; +size_t KoalaBear::device_read(uint8_t param, uint8_t* data_buf) { + float* float_buf = (float*) data_buf; + bool* bool_buf = (bool*) data_buf; + int32_t* int_buf = (int32_t*) data_buf; switch (param) { case DUTY_CYCLE_A: @@ -159,14 +159,14 @@ size_t KoalaBear::device_read(uint8_t param, uint8_t *data_buf) { return 0; } -size_t KoalaBear::device_write(uint8_t param, uint8_t *data_buf) { +size_t KoalaBear::device_write(uint8_t param, uint8_t* data_buf) { switch (param) { case DUTY_CYCLE_A: - this->pid_enabled_a = FALSE; // TODO: remove later once PID added in - this->target_speed_a = ((float *)data_buf)[0]; + this->pid_enabled_a = FALSE; // TODO: remove later once PID added in + this->target_speed_a = ((float*) data_buf)[0]; return sizeof(float); case DEADBAND_A: - this->deadband_a = ((float *)data_buf)[0]; + this->deadband_a = ((float*) data_buf)[0]; return sizeof(float); case CURRENT_A: break; @@ -174,26 +174,26 @@ size_t KoalaBear::device_write(uint8_t param, uint8_t *data_buf) { this->pid_enabled_a = data_buf[0]; return sizeof(uint8_t); case PID_KP_A: - this->pid_a->set_coefficients(((double *)data_buf)[0], this->pid_a->get_ki(), this->pid_a->get_kd()); + this->pid_a->set_coefficients(((double*) data_buf)[0], this->pid_a->get_ki(), this->pid_a->get_kd()); return sizeof(float); case PID_KI_A: - this->pid_a->set_coefficients(this->pid_a->get_kp(), ((double *)data_buf)[0], this->pid_a->get_kd()); + this->pid_a->set_coefficients(this->pid_a->get_kp(), ((double*) data_buf)[0], this->pid_a->get_kd()); return sizeof(float); case PID_KD_A: - this->pid_a->set_coefficients(this->pid_a->get_kp(), this->pid_a->get_ki(), ((double *)data_buf)[0]); + this->pid_a->set_coefficients(this->pid_a->get_kp(), this->pid_a->get_ki(), ((double*) data_buf)[0]); return sizeof(float); case ENC_A: - enc_a = ((int32_t *)data_buf)[0]; + enc_a = ((int32_t*) data_buf)[0]; this->pid_a->set_position((float) enc_a); return sizeof(int32_t); // Params for Motor B case DUTY_CYCLE_B: - this->pid_enabled_b = FALSE; //remove later for PID functionality - this->target_speed_b = ((float *)data_buf)[0]; + this->pid_enabled_b = FALSE; //remove later for PID functionality + this->target_speed_b = ((float*) data_buf)[0]; return sizeof(float); case DEADBAND_B: - this->deadband_b = ((float *)data_buf)[0]; + this->deadband_b = ((float*) data_buf)[0]; return sizeof(float); case CURRENT_B: break; @@ -201,16 +201,16 @@ size_t KoalaBear::device_write(uint8_t param, uint8_t *data_buf) { this->pid_enabled_b = data_buf[0]; return sizeof(uint8_t); case PID_KP_B: - this->pid_b->set_coefficients(((double *)data_buf)[0], this->pid_b->get_ki(), this->pid_b->get_kd()); + this->pid_b->set_coefficients(((double*) data_buf)[0], this->pid_b->get_ki(), this->pid_b->get_kd()); return sizeof(float); case PID_KI_B: - this->pid_b->set_coefficients(this->pid_b->get_kp(), ((double *)data_buf)[0], this->pid_b->get_kd()); + this->pid_b->set_coefficients(this->pid_b->get_kp(), ((double*) data_buf)[0], this->pid_b->get_kd()); return sizeof(float); case PID_KD_B: - this->pid_b->set_coefficients(this->pid_b->get_kp(), this->pid_b->get_ki(), ((double *)data_buf)[0]); + this->pid_b->set_coefficients(this->pid_b->get_kp(), this->pid_b->get_ki(), ((double*) data_buf)[0]); return sizeof(float); case ENC_B: - enc_b = ((int32_t *)data_buf)[0]; + enc_b = ((int32_t*) data_buf)[0]; this->pid_b->set_position((float) enc_b); return sizeof(int32_t); default: @@ -220,7 +220,7 @@ size_t KoalaBear::device_write(uint8_t param, uint8_t *data_buf) { } void KoalaBear::device_enable() { - electrical_setup(); // ask electrical about this function (it's hardware setup for the motor controller) + electrical_setup(); // ask electrical about this function (it's hardware setup for the motor controller) // set up encoders pinMode(AENC1, INPUT); @@ -228,7 +228,7 @@ void KoalaBear::device_enable() { pinMode(BENC1, INPUT); pinMode(BENC2, INPUT); - this->pid_enabled_a = FALSE; // TODO: change to true once implemented + this->pid_enabled_a = FALSE; // TODO: change to true once implemented this->pid_enabled_b = FALSE; this->led->setup_LEDs(); @@ -287,14 +287,14 @@ void KoalaBear::device_actions() { digitalWrite(RESET, LOW); // send target duty cycle to drive function - drive(target_A * -1.0, MTRA); // by default, MTRA drives the wrong way + drive(target_A * -1.0, MTRA); // by default, MTRA drives the wrong way drive(target_B, MTRB); } //************************* KOALABEAR HELPER FUNCTIONS *************************// -void KoalaBear::drive (float target, uint8_t mtr) { - int pin1 = (mtr == MTRA) ? AIN1 : BIN1; // select the correct pins based on the motor +void KoalaBear::drive(float target, uint8_t mtr) { + int pin1 = (mtr == MTRA) ? AIN1 : BIN1; // select the correct pins based on the motor int pin2 = (mtr == MTRA) ? AIN2 : BIN2; float direction = (target > 0.0) ? 1.0 : -1.0; @@ -308,11 +308,11 @@ void KoalaBear::drive (float target, uint8_t mtr) { // Determine how much to move the pins down from 255 // Sanity check: If |target| == 1, move max speed --> pwm_difference == 255 // If |target| == 0, stop moving --> pwm_difference == 0 - int pwm_difference = (int)(target * direction * 255.0); // A number between 0 and 255 inclusive (255 is stop; 0 is max speed); + int pwm_difference = (int) (target * direction * 255.0); // A number between 0 and 255 inclusive (255 is stop; 0 is max speed); - if (direction > 0) { // Moving forwards + if (direction > 0) { // Moving forwards currpwm1 -= pwm_difference; - } else if (direction < 0) { // Moving backwards + } else if (direction < 0) { // Moving backwards currpwm2 -= pwm_difference; } diff --git a/lowcar/devices/KoalaBear/KoalaBear.h b/lowcar/devices/KoalaBear/KoalaBear.h index 585cc4fc..8f73879b 100644 --- a/lowcar/devices/KoalaBear/KoalaBear.h +++ b/lowcar/devices/KoalaBear/KoalaBear.h @@ -4,20 +4,20 @@ #include #include "Device.h" -#include "PID.h" #include "LEDKoala.h" -#include "pindefs_koala.h" +#include "PID.h" #include "defs.h" +#include "pindefs_koala.h" class KoalaBear : public Device { -public: + public: /** * Constructor. Initializes motors, encoders, and PID controllers */ - KoalaBear (); + KoalaBear(); - virtual size_t device_read(uint8_t param, uint8_t *data_buf); - virtual size_t device_write(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); + virtual size_t device_write(uint8_t param, uint8_t* data_buf); /** * Does electrical setup, setup pins, encoders, and LEDs @@ -34,13 +34,13 @@ class KoalaBear : public Device { */ virtual void device_actions(); -private: - float target_speed_a, target_speed_b; // target speeds of motors - float deadband_a, deadband_b; // deadbands of motors - uint8_t pid_enabled_a, pid_enabled_b; // whether or not motors are enabled - volatile uint32_t enc_a, enc_b; // encoder values of motors - PID *pid_a, *pid_b; // PID controllers for motors - LEDKoala *led; // for controlling the KoalaBear LED + private: + float target_speed_a, target_speed_b; // target speeds of motors + float deadband_a, deadband_b; // deadbands of motors + uint8_t pid_enabled_a, pid_enabled_b; // whether or not motors are enabled + volatile uint32_t enc_a, enc_b; // encoder values of motors + PID *pid_a, *pid_b; // PID controllers for motors + LEDKoala* led; // for controlling the KoalaBear LED unsigned long prev_led_time; int curr_led_mtr; diff --git a/lowcar/devices/KoalaBear/LEDKoala.cpp b/lowcar/devices/KoalaBear/LEDKoala.cpp index 2821a1f7..dfd118a2 100644 --- a/lowcar/devices/KoalaBear/LEDKoala.cpp +++ b/lowcar/devices/KoalaBear/LEDKoala.cpp @@ -2,9 +2,9 @@ #include "Arduino.h" #include "pindefs_koala.h" -#define LED_RED A3 -#define LED_YELLOW A4 -#define LED_GREEN A5 +#define LED_RED A3 +#define LED_YELLOW A4 +#define LED_GREEN A5 // LED constructor LEDKoala::LEDKoala() { @@ -23,7 +23,7 @@ void LEDKoala::ctrl_LEDs(float vel, float deadband, bool enabled) { ctrl_green(vel, deadband, enabled); } -void LEDKoala::ctrl_red (float vel, float deadband, bool enabled) { +void LEDKoala::ctrl_red(float vel, float deadband, bool enabled) { //turn red LED on if motor is stopped if ((vel > deadband * -1.0 && vel < deadband) && enabled) { this->red_state = true; @@ -38,7 +38,7 @@ void LEDKoala::ctrl_red (float vel, float deadband, bool enabled) { } } -void LEDKoala::ctrl_yellow (float vel, float deadband, bool enabled) { +void LEDKoala::ctrl_yellow(float vel, float deadband, bool enabled) { //turn yellow LED on if motor is going backwards if ((vel < deadband * -1.0) && enabled) { this->yellow_state = true; @@ -53,7 +53,7 @@ void LEDKoala::ctrl_yellow (float vel, float deadband, bool enabled) { } } -void LEDKoala::ctrl_green (float vel, float deadband, bool enabled) { +void LEDKoala::ctrl_green(float vel, float deadband, bool enabled) { //turn green LED on if motor moving forward if (vel > deadband && enabled) { this->green_state = true; @@ -69,15 +69,15 @@ void LEDKoala::ctrl_green (float vel, float deadband, bool enabled) { } void LEDKoala::test_LEDs() { - digitalWrite(LED_GREEN,HIGH); - digitalWrite(LED_RED,HIGH); - digitalWrite(LED_YELLOW,HIGH); + digitalWrite(LED_GREEN, HIGH); + digitalWrite(LED_RED, HIGH); + digitalWrite(LED_YELLOW, HIGH); delay(1000); - digitalWrite(LED_GREEN,LOW); - digitalWrite(LED_RED,LOW); - digitalWrite(LED_YELLOW,LOW); + digitalWrite(LED_GREEN, LOW); + digitalWrite(LED_RED, LOW); + digitalWrite(LED_YELLOW, LOW); } void LEDKoala::setup_LEDs() { diff --git a/lowcar/devices/KoalaBear/LEDKoala.h b/lowcar/devices/KoalaBear/LEDKoala.h index 5ccf8537..474cc44c 100644 --- a/lowcar/devices/KoalaBear/LEDKoala.h +++ b/lowcar/devices/KoalaBear/LEDKoala.h @@ -5,7 +5,7 @@ // class for controlling the LED's on the KoalaBear class LEDKoala { -public: + public: // Sets LEDs to output and disabled LEDKoala(); @@ -29,7 +29,7 @@ class LEDKoala { */ void setup_LEDs(); -private: + private: bool red_state; bool yellow_state; bool green_state; diff --git a/lowcar/devices/KoalaBear/PID.cpp b/lowcar/devices/KoalaBear/PID.cpp index 5ac578c9..724ad591 100644 --- a/lowcar/devices/KoalaBear/PID.cpp +++ b/lowcar/devices/KoalaBear/PID.cpp @@ -9,11 +9,11 @@ PID::PID() { } float PID::compute(float curr_pos) { - unsigned long curr_time = micros(); // get the current time - float interval_secs = ((float)(curr_time - this->prev_time)) / 1000000.0; // compute time passed between loops, in seconds - float desired_pos = this->prev_desired_pos + (duty_cycle_to_tps(this->target_speed) * interval_secs); // compute the desired position at this time - float error = desired_pos - curr_pos; // compute the error as the set point (desired position) - process variable (current position) - this->integral += error * interval_secs; // compute the new value of this->integral using right-rectangle approximation + unsigned long curr_time = micros(); // get the current time + float interval_secs = ((float) (curr_time - this->prev_time)) / 1000000.0; // compute time passed between loops, in seconds + float desired_pos = this->prev_desired_pos + (duty_cycle_to_tps(this->target_speed) * interval_secs); // compute the desired position at this time + float error = desired_pos - curr_pos; // compute the error as the set point (desired position) - process variable (current position) + this->integral += error * interval_secs; // compute the new value of this->integral using right-rectangle approximation // output = kp * error + ki * integral of error * kd * "derivative" of error float output = (this->kp * error) + (this->ki * this->integral) + (this->kd * ((error - this->prev_error) / interval_secs)); @@ -40,7 +40,7 @@ void PID::set_target_speed(float target_speed) { // used when student sets encoder to a certain value void PID::set_position(float curr_pos) { this->prev_pos = curr_pos; - this->prev_error = 0.0; // resets the error too + this->prev_error = 0.0; // resets the error too } // three getter functions for the three coefficients @@ -51,5 +51,5 @@ float PID::get_kd() { return this->kd; } // *********************** HELPER FUNCTIONS *********************** // float PID::duty_cycle_to_tps(float duty_cycle) { - return 300.0 * duty_cycle; // TODO: determine this function. will probably be of the form y = kx (if not can go do a regression on a calculator after some tests) + return 300.0 * duty_cycle; // TODO: determine this function. will probably be of the form y = kx (if not can go do a regression on a calculator after some tests) } diff --git a/lowcar/devices/KoalaBear/PID.h b/lowcar/devices/KoalaBear/PID.h index 8657c7ce..346a31f1 100644 --- a/lowcar/devices/KoalaBear/PID.h +++ b/lowcar/devices/KoalaBear/PID.h @@ -5,7 +5,7 @@ // Handles the PID controller on one motor class PID { -public: + public: PID(); /** @@ -26,8 +26,8 @@ class PID { float get_ki(); float get_kd(); -private: - float kp, ki, kd; + private: + float kp, ki, kd; float prev_error, prev_pos, prev_desired_pos; float target_speed; float integral; diff --git a/lowcar/devices/KoalaBear/pindefs_koala.h b/lowcar/devices/KoalaBear/pindefs_koala.h index 1e4a6f17..76e25f54 100644 --- a/lowcar/devices/KoalaBear/pindefs_koala.h +++ b/lowcar/devices/KoalaBear/pindefs_koala.h @@ -1,21 +1,21 @@ -#define SLEEP 13 // set during setup, should always be high -#define RESET 10 // set during setup, should always be low +#define SLEEP 13 // set during setup, should always be high +#define RESET 10 // set during setup, should always be low -#define AIN1 5 // first motor, PWM1 -#define AIN2 9 // first motor, PWM2 -#define BIN1 6 // second motor, PWM1 -#define BIN2 3 // second motor, PWM2 +#define AIN1 5 // first motor, PWM1 +#define AIN2 9 // first motor, PWM2 +#define BIN1 6 // second motor, PWM1 +#define BIN2 3 // second motor, PWM2 -#define LED_RED A3 -#define LED_YELLOW A4 -#define LED_GREEN A5 +#define LED_RED A3 +#define LED_YELLOW A4 +#define LED_GREEN A5 -#define HEARTBEAT A2 // flashes on heartbeats +#define HEARTBEAT A2 // flashes on heartbeats -#define SCS 11 // opens communication to motor controller chip during setup +#define SCS 11 // opens communication to motor controller chip during setup -#define AENC1 1 // motor 1, first encoder pin, this is the interrupt pin -#define AENC2 A0 // motor 1, second encoder pin +#define AENC1 1 // motor 1, first encoder pin, this is the interrupt pin +#define AENC2 A0 // motor 1, second encoder pin -#define BENC1 2 // motor 2, first encoder pin, this is the interrupt pin -#define BENC2 0 // motor 2, second encoder pin (can also be an interrupt pin) +#define BENC1 2 // motor 2, first encoder pin, this is the interrupt pin +#define BENC2 0 // motor 2, second encoder pin (can also be an interrupt pin) diff --git a/lowcar/devices/LimitSwitch/LimitSwitch.cpp b/lowcar/devices/LimitSwitch/LimitSwitch.cpp index 871400b5..72898e87 100644 --- a/lowcar/devices/LimitSwitch/LimitSwitch.cpp +++ b/lowcar/devices/LimitSwitch/LimitSwitch.cpp @@ -5,15 +5,14 @@ const int LimitSwitch::NUM_SWITCHES = 3; const uint8_t LimitSwitch::pins[] = { (const uint8_t) Analog::IO0, (const uint8_t) Analog::IO1, - (const uint8_t) Analog::IO2 -}; + (const uint8_t) Analog::IO2}; // default constructor simply specifies DeviceID and year to generic constructor LimitSwitch::LimitSwitch() : Device(DeviceType::LIMIT_SWITCH, 0) { ; } -size_t LimitSwitch::device_read(uint8_t param, uint8_t *data_buf) { +size_t LimitSwitch::device_read(uint8_t param, uint8_t* data_buf) { // put pin value into data_buf and return the state of the switch data_buf[0] = (digitalRead(this->pins[param]) == LOW); return sizeof(uint8_t); diff --git a/lowcar/devices/LimitSwitch/LimitSwitch.h b/lowcar/devices/LimitSwitch/LimitSwitch.h index 5f3542f9..4a40bddc 100644 --- a/lowcar/devices/LimitSwitch/LimitSwitch.h +++ b/lowcar/devices/LimitSwitch/LimitSwitch.h @@ -5,15 +5,15 @@ #include "defs.h" class LimitSwitch : public Device { -public: + public: // Simply calls generic Device constructor with device type and year LimitSwitch(); // overridden functions from Device class; see descriptions in Device.h - virtual size_t device_read(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); virtual void device_enable(); -private: + private: // number of switches (one switch per pin) on a limit switch const static int NUM_SWITCHES; // pins that the limit switch reads data from (defined in defs.h) diff --git a/lowcar/devices/LineFollower/LineFollower.cpp b/lowcar/devices/LineFollower/LineFollower.cpp index 7c8e7193..dbedff09 100644 --- a/lowcar/devices/LineFollower/LineFollower.cpp +++ b/lowcar/devices/LineFollower/LineFollower.cpp @@ -4,17 +4,16 @@ const uint8_t LineFollower::pins[] = { (const uint8_t) Analog::IO0, (const uint8_t) Analog::IO1, - (const uint8_t) Analog::IO2 -}; -const int LineFollower::NUM_PINS = 3; // number of pins used for I/O for LineFollower + (const uint8_t) Analog::IO2}; +const int LineFollower::NUM_PINS = 3; // number of pins used for I/O for LineFollower -LineFollower::LineFollower () : Device (DeviceType::LINE_FOLLOWER, 1) { +LineFollower::LineFollower() : Device(DeviceType::LINE_FOLLOWER, 1) { ; } -size_t LineFollower::device_read(uint8_t param, uint8_t *data_buf) { +size_t LineFollower::device_read(uint8_t param, uint8_t* data_buf) { // use data_ptr_float to shove 10-bit sensor reading into the data_buf - float *data_ptr_float = (float *)data_buf; + float* data_ptr_float = (float*) data_buf; *data_ptr_float = 1.0 - ((float) analogRead(this->pins[param])) / 1023.0; return sizeof(float); } diff --git a/lowcar/devices/LineFollower/LineFollower.h b/lowcar/devices/LineFollower/LineFollower.h index 7fa75967..4308658b 100644 --- a/lowcar/devices/LineFollower/LineFollower.h +++ b/lowcar/devices/LineFollower/LineFollower.h @@ -5,15 +5,15 @@ #include "defs.h" class LineFollower : public Device { -public: + public: // Simply calls generic Device constructor with device type and year - LineFollower (); + LineFollower(); // overridden functions from Device class; see descriptions in Device.h - virtual size_t device_read(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); virtual void device_enable(); -private: + private: // number of pins used for I/O for LineFollower const static int NUM_PINS; // pins that the line follower reads data from (defined in defs.h) diff --git a/lowcar/devices/PolarBear/LED.cpp b/lowcar/devices/PolarBear/LED.cpp index ad0d4f67..114b83f4 100644 --- a/lowcar/devices/PolarBear/LED.cpp +++ b/lowcar/devices/PolarBear/LED.cpp @@ -1,9 +1,9 @@ #include "LED.h" // pins that control the red, yellow, and green LEDs -#define LED_RED 2 -#define LED_YELLOW 3 -#define LED_GREEN 4 +#define LED_RED 2 +#define LED_YELLOW 3 +#define LED_GREEN 4 // decides when the red LED is on static void ctrl_RED(float duty_cycle, float deadband) { @@ -46,13 +46,13 @@ void setup_LEDs() { pinMode(LED_RED, OUTPUT); pinMode(LED_YELLOW, OUTPUT); - digitalWrite(LED_GREEN,HIGH); - digitalWrite(LED_RED,HIGH); - digitalWrite(LED_YELLOW,HIGH); + digitalWrite(LED_GREEN, HIGH); + digitalWrite(LED_RED, HIGH); + digitalWrite(LED_YELLOW, HIGH); delay(1000); - digitalWrite(LED_GREEN,LOW); - digitalWrite(LED_RED,LOW); - digitalWrite(LED_YELLOW,LOW); + digitalWrite(LED_GREEN, LOW); + digitalWrite(LED_RED, LOW); + digitalWrite(LED_YELLOW, LOW); } diff --git a/lowcar/devices/PolarBear/PolarBear.cpp b/lowcar/devices/PolarBear/PolarBear.cpp index 12fcc644..7a4eaa18 100644 --- a/lowcar/devices/PolarBear/PolarBear.cpp +++ b/lowcar/devices/PolarBear/PolarBear.cpp @@ -14,8 +14,8 @@ PolarBear::PolarBear() : Device(DeviceType::POLAR_BEAR, 2) { this->dpwm_dt = 255 / 200000; } -size_t PolarBear::device_read(uint8_t param, uint8_t *data_buf) { - float* float_buf = (float *) data_buf; +size_t PolarBear::device_read(uint8_t param, uint8_t* data_buf) { + float* float_buf = (float*) data_buf; switch (param) { case DUTY_CYCLE: @@ -33,8 +33,8 @@ size_t PolarBear::device_read(uint8_t param, uint8_t *data_buf) { return 0; } -size_t PolarBear::device_write(uint8_t param, uint8_t *data_buf) { - float *float_buf = (float *) data_buf; +size_t PolarBear::device_write(uint8_t param, uint8_t* data_buf) { + float* float_buf = (float*) data_buf; switch (param) { case DUTY_CYCLE: // Change duty_cycle only if abs(input) is greater than deadband @@ -59,7 +59,7 @@ void PolarBear::device_enable() { // Start LEDs setup_LEDs(); - pinMode(FEEDBACK,INPUT); + pinMode(FEEDBACK, INPUT); pinMode(PWM1, OUTPUT); pinMode(PWM2, OUTPUT); } @@ -75,7 +75,7 @@ void PolarBear::device_actions() { } void PolarBear::drive(float target) { - float direction = (target > 0.0) ? 1.0 : -1.0; // if target == 0.0, direction will be -1 ("backwards") + float direction = (target > 0.0) ? 1.0 : -1.0; // if target == 0.0, direction will be -1 ("backwards") /* If moving forwards, set pwm1 to 255 (stop), then move pwm2 down * If moving backwards, set pwm2 to 255, then move pwm1 down * Make sure that at least one of the pins is set to 255 at all times. @@ -86,17 +86,17 @@ void PolarBear::drive(float target) { // Determine how much to move the pins down from 255 // Sanity check: If |target| == 1, move max speed --> pwm_difference == 255 // If |target| == 0, stop moving --> pwm_difference == 0 - int pwm_difference = (int)(target * direction * 255.0); // A number between 0 and 255 inclusive (255 is stop; 0 is max speed); + int pwm_difference = (int) (target * direction * 255.0); // A number between 0 and 255 inclusive (255 is stop; 0 is max speed); // We don't catch direction 0.0 because it will be either 1.0 or -1.0. // If stopped (target == 0.0) then 255 will be written to both drive pins - if (direction > 0.0) { // Moving forwards + if (direction > 0.0) { // Moving forwards currpwm1 -= pwm_difference; - } else if (direction < 0.0) { // Moving backwards + } else if (direction < 0.0) { // Moving backwards currpwm2 -= pwm_difference; } analogWrite(PWM1, currpwm1); analogWrite(PWM2, currpwm2); - delayMicroseconds(1 / this->dpwm_dt); // About 784 + delayMicroseconds(1 / this->dpwm_dt); // About 784 } diff --git a/lowcar/devices/PolarBear/PolarBear.h b/lowcar/devices/PolarBear/PolarBear.h index 5d44a8a1..eec31aab 100644 --- a/lowcar/devices/PolarBear/PolarBear.h +++ b/lowcar/devices/PolarBear/PolarBear.h @@ -2,19 +2,19 @@ #define POLARBEAR_H #include "Device.h" -#include "PID.h" #include "LED.h" +#include "PID.h" #include "defs.h" -#define FEEDBACK A3 // pin for getting motor current -#define PWM1 6 // pwm pin 1 -#define PWM2 9 // pwm pin 2 +#define FEEDBACK A3 // pin for getting motor current +#define PWM1 6 // pwm pin 1 +#define PWM2 9 // pwm pin 2 class PolarBear : public Device { -public: + public: PolarBear(); - virtual size_t device_read(uint8_t param, uint8_t *data_buf); - virtual size_t device_write(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); + virtual size_t device_write(uint8_t param, uint8_t* data_buf); /** * Setup LEDs, and set FEEDBACk to input and PWM1 & PWM2 to output @@ -31,7 +31,7 @@ class PolarBear : public Device { */ virtual void device_actions(); -private: + private: // The "velocity" to move the motor // (range -1, 1 inclusive, where 1 is max speed forward, -1 is max speed backwards) // 0 is stop diff --git a/lowcar/devices/RFID/RFID.cpp b/lowcar/devices/RFID/RFID.cpp index 5e7a4d9e..93ebb9a1 100644 --- a/lowcar/devices/RFID/RFID.cpp +++ b/lowcar/devices/RFID/RFID.cpp @@ -5,54 +5,54 @@ const int RFID::SS_PIN = 10; //default constructor simply specifies DeviceID and year to generic constructor and initializes variables //initializes the msfrc22 object in the initializer list -RFID::RFID () : Device (DeviceType::RFID, 1), tag_detector (RFID::SS_PIN, RFID::RST_PIN) { - this->id_upper = 0; - this->id_lower = 0; - this->tag_detect = 0; - this->delay = FALSE; +RFID::RFID() : Device(DeviceType::RFID, 1), tag_detector(RFID::SS_PIN, RFID::RST_PIN) { + this->id_upper = 0; + this->id_lower = 0; + this->tag_detect = 0; + this->delay = FALSE; } -size_t RFID::device_read (uint8_t param, uint8_t *data_buf) { - switch ((RFID_Param) param) { //switch the incoming parameter (cast to RFID_Param) - case RFID_Param::ID: - ((int32_t *)data_buf)[0] = this->id; - return sizeof(this->id); +size_t RFID::device_read(uint8_t param, uint8_t* data_buf) { + switch ((RFID_Param) param) { //switch the incoming parameter (cast to RFID_Param) + case RFID_Param::ID: + ((int32_t*) data_buf)[0] = this->id; + return sizeof(this->id); - case RFID_Param::TAG_DETECT: - data_buf[0] = this->tag_detect; - return sizeof(this->tag_detect); + case RFID_Param::TAG_DETECT: + data_buf[0] = this->tag_detect; + return sizeof(this->tag_detect); - default: - return 0; - } + default: + return 0; + } } -void RFID::device_enable () { - SPI.begin(); //begin SPI (what's this?) - this->tag_detector->PCD_Init(); //initialize the RFID object +void RFID::device_enable() { + SPI.begin(); //begin SPI (what's this?) + this->tag_detector->PCD_Init(); //initialize the RFID object } -void RFID::device_actions () { - /* If we either don't sense a card or can't read the UID, we invalidate the data +void RFID::device_actions() { + /* If we either don't sense a card or can't read the UID, we invalidate the data * The sensor is too slow, so we have to delay the read by one loop * The delay makes sure that id and tag_detect don't update for * one cycle of the loop after finding a tag */ - if (!this->tag_detector->PICC_IsNewCardPresent() || !this->tag_detector->PICC_ReadCardSerial()) { - if (this->delay) { - this->id = 0; //clear the id to invalidate it - this->tag_detect = 0; //no tag detected - } - this->delay = TRUE; - return; //after resetting all our values, we return - } - - //Otherwise, if there is a card that we can read the UID from, we grab the data - //and set tag_detect to 1 to signal that we have a new tag UID - uint32_t uid = (uint32_t)(this->tag_detector->uid.uidByte[2]) << 16 | - (uint32_t)(this->tag_detector->uid.uidByte[1]) << 8 | - (uint32_t)(this->tag_detector->uid.uidByte[0]); - this->id = uid; - this->tag_detect = 1; - this->delay = FALSE; //reset the delay + if (!this->tag_detector->PICC_IsNewCardPresent() || !this->tag_detector->PICC_ReadCardSerial()) { + if (this->delay) { + this->id = 0; //clear the id to invalidate it + this->tag_detect = 0; //no tag detected + } + this->delay = TRUE; + return; //after resetting all our values, we return + } + + //Otherwise, if there is a card that we can read the UID from, we grab the data + //and set tag_detect to 1 to signal that we have a new tag UID + uint32_t uid = (uint32_t)(this->tag_detector->uid.uidByte[2]) << 16 | + (uint32_t)(this->tag_detector->uid.uidByte[1]) << 8 | + (uint32_t)(this->tag_detector->uid.uidByte[0]); + this->id = uid; + this->tag_detect = 1; + this->delay = FALSE; //reset the delay } diff --git a/lowcar/devices/RFID/RFID.h b/lowcar/devices/RFID/RFID.h index 2e3cc26f..9b8ac83f 100644 --- a/lowcar/devices/RFID/RFID.h +++ b/lowcar/devices/RFID/RFID.h @@ -1,39 +1,39 @@ #ifndef RFID_H #define RFID_H +#include +#include #include "Device.h" #include "defs.h" -#include -#include //give params more readable names enum class RFID_Param : uint8_t { - ID = 0, - TAG_DETECT = 1 //is 1 if we have a tag; 0 otherwise + ID = 0, + TAG_DETECT = 1 //is 1 if we have a tag; 0 otherwise }; class RFID : public Device { -public: - //constructs an RFID; simply calls generic Device constructor with device type and year - //instatiates the mfrc522 private variable, and initializes the other private variables - RFID (); - - //overridden functions from Device class; see descriptions in Device.h - virtual size_t device_read (uint8_t param, uint8_t *data_buf); - virtual void device_enable (); - virtual void device_actions (); - -private: - //Pin definitions - const static int RST_PIN; - const static int SS_PIN; - - MFRC522 *tag_detector; //object used to operate the actual RFID tag detector - uint8_t delay; //for delaying the reading of the device - - // Outward facing (read-only) params - uint32_t id; - uint8_t tag_detect; //tag_detect parameter + public: + //constructs an RFID; simply calls generic Device constructor with device type and year + //instatiates the mfrc522 private variable, and initializes the other private variables + RFID(); + + //overridden functions from Device class; see descriptions in Device.h + virtual size_t device_read(uint8_t param, uint8_t* data_buf); + virtual void device_enable(); + virtual void device_actions(); + + private: + //Pin definitions + const static int RST_PIN; + const static int SS_PIN; + + MFRC522* tag_detector; //object used to operate the actual RFID tag detector + uint8_t delay; //for delaying the reading of the device + + // Outward facing (read-only) params + uint32_t id; + uint8_t tag_detect; //tag_detect parameter }; #endif diff --git a/lowcar/devices/ServoControl/ServoControl.cpp b/lowcar/devices/ServoControl/ServoControl.cpp index 6f1dfc7e..2ec99c4b 100644 --- a/lowcar/devices/ServoControl/ServoControl.cpp +++ b/lowcar/devices/ServoControl/ServoControl.cpp @@ -3,13 +3,13 @@ const int ServoControl::NUM_SERVOS = 2; const int ServoControl::SERVO_0 = 5; const int ServoControl::SERVO_1 = 6; -const int ServoControl::SERVO_CENTER = 1500; // center position on servo, in microseconds (?) -const int ServoControl::SERVO_RANGE = 1000; // range of movement of servo is SERVO_CENTER +/- SERVO_RANGE +const int ServoControl::SERVO_CENTER = 1500; // center position on servo, in microseconds (?) +const int ServoControl::SERVO_RANGE = 1000; // range of movement of servo is SERVO_CENTER +/- SERVO_RANGE const uint8_t ServoControl::pins[] = {SERVO_0, SERVO_1}; -Servo *servo0 = new Servo(); -Servo *servo1 = new Servo(); -Servo servos[2] = { *servo0, *servo1 }; +Servo* servo0 = new Servo(); +Servo* servo1 = new Servo(); +Servo servos[2] = {*servo0, *servo1}; ServoControl::ServoControl() : Device(DeviceType::SERVO_CONTROL, 1) { this->positions = new float[NUM_SERVOS]; @@ -19,14 +19,14 @@ ServoControl::ServoControl() : Device(DeviceType::SERVO_CONTROL, 1) { disable_all(); } -size_t ServoControl::device_read (uint8_t param, uint8_t *data_buf) { - float *float_buf = (float *) data_buf; +size_t ServoControl::device_read(uint8_t param, uint8_t* data_buf) { + float* float_buf = (float*) data_buf; float_buf[0] = this->positions[param]; return sizeof(float); } -size_t ServoControl::device_write (uint8_t param, uint8_t *data_buf) { - float value = ((float *) data_buf)[0]; +size_t ServoControl::device_write(uint8_t param, uint8_t* data_buf) { + float value = ((float*) data_buf)[0]; if (value < -1 || value > 1) { return 0; } diff --git a/lowcar/devices/ServoControl/ServoControl.h b/lowcar/devices/ServoControl/ServoControl.h index 599a43d4..9a3d8b96 100644 --- a/lowcar/devices/ServoControl/ServoControl.h +++ b/lowcar/devices/ServoControl/ServoControl.h @@ -1,12 +1,12 @@ #ifndef SERVO_CONTROL_H #define SERVO_CONTROL_H +#include #include "Device.h" #include "defs.h" -#include class ServoControl : public Device { -public: + public: /** * Initializes servos and disables them */ @@ -14,22 +14,22 @@ class ServoControl : public Device { // Overridden functions // Comments/descriptions can be found in source file and in Device.h - virtual size_t device_read(uint8_t param, uint8_t *data_buf); + virtual size_t device_read(uint8_t param, uint8_t* data_buf); /** * Updates provided servo position. * Updates pulse width associated with specified servo * Attaches servo at param to corresponding pin if not attached yet */ - virtual size_t device_write(uint8_t param, uint8_t *data_buf); - virtual void device_disable(); // calls helper disableAll() to detach all servos + virtual size_t device_write(uint8_t param, uint8_t* data_buf); + virtual void device_disable(); // calls helper disableAll() to detach all servos -private: + private: // class constants and variables const static int NUM_SERVOS, SERVO_0, SERVO_1, SERVO_CENTER, SERVO_RANGE; const static uint8_t pins[]; - float *positions; + float* positions; // detaches all servos void disable_all(); diff --git a/net_handler/net_handler.c b/net_handler/net_handler.c index c725e928..47cf69b1 100644 --- a/net_handler/net_handler.c +++ b/net_handler/net_handler.c @@ -11,41 +11,40 @@ * - 0: all steps completed successfully * - 1: listening socket setup failed */ -static int socket_setup (int *sockfd) -{ - struct sockaddr_in serv_addr = {0}; //initialize everything to 0 - - //create socket - if ((*sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - log_printf(ERROR, "socket_setup: failed to create listening socket: %s", strerror(errno)); - return 1; - } - - //set the socket option SO_REUSEPORT on so that if raspi terminates and restarts it can immediately reopen the same port - int optval = 1; - if ((setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(int))) != 0) { - log_printf(ERROR, "socket_setup: failed to set listening socket for reuse of port: %s", strerror(errno)); - } - - //set the elements of serv_addr - serv_addr.sin_family = AF_INET; //use IPv4 - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //use any IP interface on raspi - serv_addr.sin_port = htons(RASPI_PORT); //assign a port number - - //bind socket to well-known IP_addr:port - if ((bind(*sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))) != 0) { - log_printf(ERROR, "socket_setup: failed to bind listening socket to raspi port: %s", strerror(errno)); - close(*sockfd); - return 1; - } - - //set the socket to be in listening mode (since the robot is the server) - if ((listen(*sockfd, 2)) != 0) { - log_printf(ERROR, "socket_setup: failed to set listening socket to listen mode: %s", strerror(errno)); - close(*sockfd); - return 1; - } - return 0; +static int socket_setup(int* sockfd) { + struct sockaddr_in serv_addr = {0}; //initialize everything to 0 + + //create socket + if ((*sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + log_printf(ERROR, "socket_setup: failed to create listening socket: %s", strerror(errno)); + return 1; + } + + //set the socket option SO_REUSEPORT on so that if raspi terminates and restarts it can immediately reopen the same port + int optval = 1; + if ((setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(int))) != 0) { + log_printf(ERROR, "socket_setup: failed to set listening socket for reuse of port: %s", strerror(errno)); + } + + //set the elements of serv_addr + serv_addr.sin_family = AF_INET; //use IPv4 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //use any IP interface on raspi + serv_addr.sin_port = htons(RASPI_PORT); //assign a port number + + //bind socket to well-known IP_addr:port + if ((bind(*sockfd, (struct sockaddr*) &serv_addr, sizeof(struct sockaddr_in))) != 0) { + log_printf(ERROR, "socket_setup: failed to bind listening socket to raspi port: %s", strerror(errno)); + close(*sockfd); + return 1; + } + + //set the socket to be in listening mode (since the robot is the server) + if ((listen(*sockfd, 2)) != 0) { + log_printf(ERROR, "socket_setup: failed to set listening socket to listen mode: %s", strerror(errno)); + close(*sockfd); + return 1; + } + return 0; } @@ -54,73 +53,71 @@ static int socket_setup (int *sockfd) * Arguments: * - int sig_num: signal that caused this handler to execute (will always be SIGINT in this case) */ -static void sigint_handler (int sig_num) -{ - log_printf(INFO, "Stopping net_handler..."); - stop_udp_conn(); - if (robot_desc_read(SHEPHERD) == CONNECTED) { - stop_tcp_conn(SHEPHERD); - } - if (robot_desc_read(DAWN) == CONNECTED) { - stop_tcp_conn(DAWN); - } - //sockfd and connfd are automatically closed when process terminates - exit(0); +static void sigint_handler(int sig_num) { + log_printf(INFO, "Stopping net_handler..."); + stop_udp_conn(); + if (robot_desc_read(SHEPHERD) == CONNECTED) { + stop_tcp_conn(SHEPHERD); + } + if (robot_desc_read(DAWN) == CONNECTED) { + stop_tcp_conn(DAWN); + } + //sockfd and connfd are automatically closed when process terminates + exit(0); } // ******************************************* MAIN ROUTINE ******************************* // -int main () -{ - int sockfd = -1, connfd = -1; - struct sockaddr_in cli_addr; //requesting client's address - socklen_t cli_addr_len = sizeof(struct sockaddr_in); //length of requesting client's address in bytes - uint8_t client_id; //this is 0 if shepherd, 1 if dawn - - //setup - logger_init(NET_HANDLER); - signal(SIGINT, sigint_handler); - if (socket_setup(&sockfd) != 0) { - if (sockfd != -1) { - close(sockfd); - } - return 1; - } - shm_init(); - - log_printf(INFO, "Net handler initialized"); - - //start UDP connection with Dawn - start_udp_conn(); - - //run net_handler main control loop - while (1) { - //wait for a client to make a request to the robot, and accept it - if ((connfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_addr_len)) < 0) { - log_printf(ERROR, "main: listen socket failed to accept a connection: %s", strerror(errno)); - continue; - } - cli_addr_len = sizeof(struct sockaddr_in); - log_printf(DEBUG, "Received connection request from %s:%d", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)); - - //get the client ID (first byte on the socket from client) - if (read(connfd, &client_id, 1) == -1) { - log_printf(ERROR, "Couldn't get client type: %s", strerror(errno)); - continue; - } - - //if the incoming request is shepherd or dawn, start the appropriate threads - if (client_id == 0 && cli_addr.sin_family == AF_INET && robot_desc_read(SHEPHERD) == DISCONNECTED) { - log_printf(DEBUG, "Starting Shepherd connection"); - start_tcp_conn(SHEPHERD, connfd, 0); - } else if (client_id == 1 && cli_addr.sin_family == AF_INET && robot_desc_read(DAWN) == DISCONNECTED) { - log_printf(DEBUG, "Starting Dawn connection"); - start_tcp_conn(DAWN, connfd, 1); - } else { - log_printf(ERROR, "Client is neither Dawn nor Shepherd"); - close(connfd); - } - } - - return 0; +int main() { + int sockfd = -1, connfd = -1; + struct sockaddr_in cli_addr; //requesting client's address + socklen_t cli_addr_len = sizeof(struct sockaddr_in); //length of requesting client's address in bytes + uint8_t client_id; //this is 0 if shepherd, 1 if dawn + + //setup + logger_init(NET_HANDLER); + signal(SIGINT, sigint_handler); + if (socket_setup(&sockfd) != 0) { + if (sockfd != -1) { + close(sockfd); + } + return 1; + } + shm_init(); + + log_printf(INFO, "Net handler initialized"); + + //start UDP connection with Dawn + start_udp_conn(); + + //run net_handler main control loop + while (1) { + //wait for a client to make a request to the robot, and accept it + if ((connfd = accept(sockfd, (struct sockaddr*) &cli_addr, &cli_addr_len)) < 0) { + log_printf(ERROR, "main: listen socket failed to accept a connection: %s", strerror(errno)); + continue; + } + cli_addr_len = sizeof(struct sockaddr_in); + log_printf(DEBUG, "Received connection request from %s:%d", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)); + + //get the client ID (first byte on the socket from client) + if (read(connfd, &client_id, 1) == -1) { + log_printf(ERROR, "Couldn't get client type: %s", strerror(errno)); + continue; + } + + //if the incoming request is shepherd or dawn, start the appropriate threads + if (client_id == 0 && cli_addr.sin_family == AF_INET && robot_desc_read(SHEPHERD) == DISCONNECTED) { + log_printf(DEBUG, "Starting Shepherd connection"); + start_tcp_conn(SHEPHERD, connfd, 0); + } else if (client_id == 1 && cli_addr.sin_family == AF_INET && robot_desc_read(DAWN) == DISCONNECTED) { + log_printf(DEBUG, "Starting Dawn connection"); + start_tcp_conn(DAWN, connfd, 1); + } else { + log_printf(ERROR, "Client is neither Dawn nor Shepherd"); + close(connfd); + } + } + + return 0; } diff --git a/net_handler/net_util.c b/net_handler/net_util.c index 125b78e1..8e504990 100644 --- a/net_handler/net_util.c +++ b/net_handler/net_util.c @@ -13,14 +13,13 @@ * - pointer to uint8_t that was malloc'ed, with the first three bytes set appropriately and with exactly enough space * to fit the rest of the serialized message into */ -uint8_t* make_buf (net_msg_t msg_type, uint16_t len_pb) -{ - uint8_t* send_buf = malloc(len_pb + 3); - *send_buf = (uint8_t) msg_type; // Can cast since we know net_msg_t has < 10 options - uint16_t* ptr_16 = (uint16_t*) (send_buf + 1); - *ptr_16 = len_pb; - // log_printf(DEBUG, "prepped buffer, len %d, ptr16 %d, msg_type %d, send buf %d %d %d", len_pb, *ptr_16, msg_type, *send_buf, *(send_buf+1), *(send_buf+2)); - return send_buf; +uint8_t* make_buf(net_msg_t msg_type, uint16_t len_pb) { + uint8_t* send_buf = malloc(len_pb + 3); + *send_buf = (uint8_t) msg_type; // Can cast since we know net_msg_t has < 10 options + uint16_t* ptr_16 = (uint16_t*) (send_buf + 1); + *ptr_16 = len_pb; + // log_printf(DEBUG, "prepped buffer, len %d, ptr16 %d, msg_type %d, send buf %d %d %d", len_pb, *ptr_16, msg_type, *send_buf, *(send_buf+1), *(send_buf+2)); + return send_buf; } /* @@ -35,27 +34,26 @@ uint8_t* make_buf (net_msg_t msg_type, uint16_t len_pb) * - 0: EOF encountered when reading from fd * - -1: Error encountered when reading from fd */ -int parse_msg (int fd, net_msg_t *msg_type, uint16_t *len_pb, uint8_t** buf) -{ - int result; - uint8_t type; - //read one byte -> determine message type - if ((result = readn(fd, &type, 1)) <= 0) { - return result; - } - *msg_type = type; +int parse_msg(int fd, net_msg_t* msg_type, uint16_t* len_pb, uint8_t** buf) { + int result; + uint8_t type; + //read one byte -> determine message type + if ((result = readn(fd, &type, 1)) <= 0) { + return result; + } + *msg_type = type; - //read two bytes -> determine message length - if ((result = readn(fd, len_pb, 2)) <= 0) { - return result; - } + //read two bytes -> determine message length + if ((result = readn(fd, len_pb, 2)) <= 0) { + return result; + } - *buf = malloc(*len_pb); - //read len_pb bytes -> put into buffer - if ((result = readn(fd, *buf, *len_pb)) < 0) { - free(*buf); - return result; - } - // log_printf(DEBUG, "parse_msg: type %d len %d buf %d", *msg_type, *len_pb, *buf); - return 1; + *buf = malloc(*len_pb); + //read len_pb bytes -> put into buffer + if ((result = readn(fd, *buf, *len_pb)) < 0) { + free(*buf); + return result; + } + // log_printf(DEBUG, "parse_msg: type %d len %d buf %d", *msg_type, *len_pb, *buf); + return 1; } diff --git a/net_handler/net_util.h b/net_handler/net_util.h index 348a0cb0..fe472c45 100644 --- a/net_handler/net_util.h +++ b/net_handler/net_util.h @@ -1,42 +1,46 @@ #ifndef NET_UTIL #define NET_UTIL -#include -#include //for malloc, free, exit -#include //for strcpy, memset #include //for inet_addr, bind, listen, accept, socket types #include //for structures relating to IPv4 addresses -#include //for read, write, close #include //for threading -#include //for signal -#include //for unix sockets +#include //for signal +#include +#include //for malloc, free, exit +#include //for strcpy, memset +#include //for unix sockets +#include //for read, write, close //include other runtime files +#include "../logger/logger.h" #include "../runtime_util/runtime_util.h" #include "../shm_wrapper/shm_wrapper.h" -#include "../logger/logger.h" //include compiled protobuf headers #include "pbc_gen/device.pb-c.h" #include "pbc_gen/gamepad.pb-c.h" #include "pbc_gen/run_mode.pb-c.h" -#include "pbc_gen/text.pb-c.h" #include "pbc_gen/start_pos.pb-c.h" +#include "pbc_gen/text.pb-c.h" #define RASPI_ADDR "127.0.0.1" -#define RASPI_PORT 8101 //well-known port of TCP listening socket used by runtime on raspi +#define RASPI_PORT 8101 //well-known port of TCP listening socket used by runtime on raspi #define SHEPHERD_PORT 6101 #define DAWN_PORT 7101 #define RASPI_UDP_PORT 9000 -#define MAX_NUM_LOGS 16 //maximum number of logs that can be sent in one msg +#define MAX_NUM_LOGS 16 //maximum number of logs that can be sent in one msg #define BUFFER_OFFSET 3 //All the different possible messages the network handler works with. The order must be the same between net_handler and clients typedef enum net_msg { - RUN_MODE_MSG, START_POS_MSG, CHALLENGE_DATA_MSG, LOG_MSG, DEVICE_DATA_MSG + RUN_MODE_MSG, + START_POS_MSG, + CHALLENGE_DATA_MSG, + LOG_MSG, + DEVICE_DATA_MSG } net_msg_t; // ******************************************* USEFUL UTIL FUNCTIONS ******************************* // @@ -54,7 +58,7 @@ typedef enum net_msg { * - pointer to uint8_t that was malloc'ed, with the first three bytes set appropriately and with exactly enough space * to fit the rest of the serialized message into */ -uint8_t* make_buf (net_msg_t msg_type, uint16_t len_pb); +uint8_t* make_buf(net_msg_t msg_type, uint16_t len_pb); /* * Parses a message from the given file descriptor into its separate components and stores them in provided pointers @@ -67,6 +71,6 @@ uint8_t* make_buf (net_msg_t msg_type, uint16_t len_pb); * - 0: successful return * - -1: Error/EOF encountered when reading from fd */ -int parse_msg (int fd, net_msg_t *msg_type, uint16_t *len_pb, uint8_t** buf); +int parse_msg(int fd, net_msg_t* msg_type, uint16_t* len_pb, uint8_t** buf); #endif diff --git a/net_handler/pbc_gen/device.pb-c.c b/net_handler/pbc_gen/device.pb-c.c index 7b04f539..6f59adb9 100644 --- a/net_handler/pbc_gen/device.pb-c.c +++ b/net_handler/pbc_gen/device.pb-c.c @@ -7,330 +7,291 @@ #endif #include "device.pb-c.h" -void param__init - (Param *message) -{ - static const Param init_value = PARAM__INIT; - *message = init_value; +void param__init(Param* message) { + static const Param init_value = PARAM__INIT; + *message = init_value; } -size_t param__get_packed_size - (const Param *message) -{ - assert(message->base.descriptor == ¶m__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t param__get_packed_size(const Param* message) { + assert(message->base.descriptor == ¶m__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t param__pack - (const Param *message, - uint8_t *out) -{ - assert(message->base.descriptor == ¶m__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t param__pack(const Param* message, + uint8_t* out) { + assert(message->base.descriptor == ¶m__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t param__pack_to_buffer - (const Param *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == ¶m__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t param__pack_to_buffer(const Param* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == ¶m__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -Param * - param__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Param *) - protobuf_c_message_unpack (¶m__descriptor, - allocator, len, data); +Param* +param__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (Param*) + protobuf_c_message_unpack(¶m__descriptor, + allocator, len, data); } -void param__free_unpacked - (Param *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == ¶m__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void param__free_unpacked(Param* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == ¶m__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } -void device__init - (Device *message) -{ - static const Device init_value = DEVICE__INIT; - *message = init_value; +void device__init(Device* message) { + static const Device init_value = DEVICE__INIT; + *message = init_value; } -size_t device__get_packed_size - (const Device *message) -{ - assert(message->base.descriptor == &device__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t device__get_packed_size(const Device* message) { + assert(message->base.descriptor == &device__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t device__pack - (const Device *message, - uint8_t *out) -{ - assert(message->base.descriptor == &device__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t device__pack(const Device* message, + uint8_t* out) { + assert(message->base.descriptor == &device__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t device__pack_to_buffer - (const Device *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &device__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t device__pack_to_buffer(const Device* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &device__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -Device * - device__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Device *) - protobuf_c_message_unpack (&device__descriptor, - allocator, len, data); +Device* +device__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (Device*) + protobuf_c_message_unpack(&device__descriptor, + allocator, len, data); } -void device__free_unpacked - (Device *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &device__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void device__free_unpacked(Device* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &device__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } -void dev_data__init - (DevData *message) -{ - static const DevData init_value = DEV_DATA__INIT; - *message = init_value; +void dev_data__init(DevData* message) { + static const DevData init_value = DEV_DATA__INIT; + *message = init_value; } -size_t dev_data__get_packed_size - (const DevData *message) -{ - assert(message->base.descriptor == &dev_data__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t dev_data__get_packed_size(const DevData* message) { + assert(message->base.descriptor == &dev_data__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t dev_data__pack - (const DevData *message, - uint8_t *out) -{ - assert(message->base.descriptor == &dev_data__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t dev_data__pack(const DevData* message, + uint8_t* out) { + assert(message->base.descriptor == &dev_data__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t dev_data__pack_to_buffer - (const DevData *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &dev_data__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t dev_data__pack_to_buffer(const DevData* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &dev_data__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -DevData * - dev_data__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (DevData *) - protobuf_c_message_unpack (&dev_data__descriptor, - allocator, len, data); +DevData* +dev_data__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (DevData*) + protobuf_c_message_unpack(&dev_data__descriptor, + allocator, len, data); } -void dev_data__free_unpacked - (DevData *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &dev_data__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void dev_data__free_unpacked(DevData* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &dev_data__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } static const ProtobufCFieldDescriptor param__field_descriptors[4] = -{ - { - "name", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(Param, name), - NULL, - &protobuf_c_empty_string, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "fval", - 2, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_FLOAT, - offsetof(Param, val_case), - offsetof(Param, fval), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "ival", - 3, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_INT32, - offsetof(Param, val_case), - offsetof(Param, ival), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "bval", - 4, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_BOOL, - offsetof(Param, val_case), - offsetof(Param, bval), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "name", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Param, name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "fval", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_FLOAT, + offsetof(Param, val_case), + offsetof(Param, fval), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "ival", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + offsetof(Param, val_case), + offsetof(Param, ival), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "bval", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + offsetof(Param, val_case), + offsetof(Param, bval), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned param__field_indices_by_name[] = { - 3, /* field[3] = bval */ - 1, /* field[1] = fval */ - 2, /* field[2] = ival */ - 0, /* field[0] = name */ + 3, /* field[3] = bval */ + 1, /* field[1] = fval */ + 2, /* field[2] = ival */ + 0, /* field[0] = name */ }; static const ProtobufCIntRange param__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 4 } -}; + { + {1, 0}, + {0, 4}}; const ProtobufCMessageDescriptor param__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "Param", - "Param", - "Param", - "", - sizeof(Param), - 4, - param__field_descriptors, - param__field_indices_by_name, - 1, param__number_ranges, - (ProtobufCMessageInit) param__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "Param", + "Param", + "Param", + "", + sizeof(Param), + 4, + param__field_descriptors, + param__field_indices_by_name, + 1, param__number_ranges, + (ProtobufCMessageInit) param__init, + NULL, NULL, NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor device__field_descriptors[4] = -{ - { - "name", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(Device, name), - NULL, - &protobuf_c_empty_string, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "uid", - 2, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_UINT64, - 0, /* quantifier_offset */ - offsetof(Device, uid), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "type", - 3, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_UINT32, - 0, /* quantifier_offset */ - offsetof(Device, type), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "params", - 4, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(Device, n_params), - offsetof(Device, params), - ¶m__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "name", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Device, name), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "uid", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT64, + 0, /* quantifier_offset */ + offsetof(Device, uid), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "type", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, + 0, /* quantifier_offset */ + offsetof(Device, type), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "params", + 4, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Device, n_params), + offsetof(Device, params), + ¶m__descriptor, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned device__field_indices_by_name[] = { - 0, /* field[0] = name */ - 3, /* field[3] = params */ - 2, /* field[2] = type */ - 1, /* field[1] = uid */ + 0, /* field[0] = name */ + 3, /* field[3] = params */ + 2, /* field[2] = type */ + 1, /* field[1] = uid */ }; static const ProtobufCIntRange device__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 4 } -}; + { + {1, 0}, + {0, 4}}; const ProtobufCMessageDescriptor device__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "Device", - "Device", - "Device", - "", - sizeof(Device), - 4, - device__field_descriptors, - device__field_indices_by_name, - 1, device__number_ranges, - (ProtobufCMessageInit) device__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "Device", + "Device", + "Device", + "", + sizeof(Device), + 4, + device__field_descriptors, + device__field_indices_by_name, + 1, device__number_ranges, + (ProtobufCMessageInit) device__init, + NULL, NULL, NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor dev_data__field_descriptors[1] = -{ - { - "devices", - 1, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_MESSAGE, - offsetof(DevData, n_devices), - offsetof(DevData, devices), - &device__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "devices", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(DevData, n_devices), + offsetof(DevData, devices), + &device__descriptor, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned dev_data__field_indices_by_name[] = { - 0, /* field[0] = devices */ + 0, /* field[0] = devices */ }; static const ProtobufCIntRange dev_data__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; + { + {1, 0}, + {0, 1}}; const ProtobufCMessageDescriptor dev_data__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "DevData", - "DevData", - "DevData", - "", - sizeof(DevData), - 1, - dev_data__field_descriptors, - dev_data__field_indices_by_name, - 1, dev_data__number_ranges, - (ProtobufCMessageInit) dev_data__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "DevData", + "DevData", + "DevData", + "", + sizeof(DevData), + 1, + dev_data__field_descriptors, + dev_data__field_indices_by_name, + 1, dev_data__number_ranges, + (ProtobufCMessageInit) dev_data__init, + NULL, NULL, NULL /* reserved[123] */ }; diff --git a/net_handler/pbc_gen/device.pb-c.h b/net_handler/pbc_gen/device.pb-c.h index ec525c27..9b0bb277 100644 --- a/net_handler/pbc_gen/device.pb-c.h +++ b/net_handler/pbc_gen/device.pb-c.h @@ -9,9 +9,9 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -26,134 +26,115 @@ typedef struct _DevData DevData; /* --- messages --- */ typedef enum { - PARAM__VAL__NOT_SET = 0, - PARAM__VAL_FVAL = 2, - PARAM__VAL_IVAL = 3, - PARAM__VAL_BVAL = 4 - PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(PARAM__VAL) + PARAM__VAL__NOT_SET = 0, + PARAM__VAL_FVAL = 2, + PARAM__VAL_IVAL = 3, + PARAM__VAL_BVAL = 4 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(PARAM__VAL) } Param__ValCase; /* *message for describing a single device parameter */ -struct _Param -{ - ProtobufCMessage base; - char *name; - Param__ValCase val_case; - union { - float fval; - int32_t ival; - protobuf_c_boolean bval; - }; +struct _Param { + ProtobufCMessage base; + char* name; + Param__ValCase val_case; + union { + float fval; + int32_t ival; + protobuf_c_boolean bval; + }; }; -#define PARAM__INIT \ - { PROTOBUF_C_MESSAGE_INIT (¶m__descriptor) \ - , (char *)protobuf_c_empty_string, PARAM__VAL__NOT_SET, {0} } +#define PARAM__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(¶m__descriptor) \ + , (char*) protobuf_c_empty_string, PARAM__VAL__NOT_SET, { 0 } \ + } /* *message for describing a single device */ -struct _Device -{ - ProtobufCMessage base; - char *name; - uint64_t uid; - uint32_t type; - /* +struct _Device { + ProtobufCMessage base; + char* name; + uint64_t uid; + uint32_t type; + /* *each device has some number of params */ - size_t n_params; - Param **params; + size_t n_params; + Param** params; }; -#define DEVICE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&device__descriptor) \ - , (char *)protobuf_c_empty_string, 0, 0, 0,NULL } +#define DEVICE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&device__descriptor) \ + , (char*) protobuf_c_empty_string, 0, 0, 0, NULL \ + } -struct _DevData -{ - ProtobufCMessage base; - /* +struct _DevData { + ProtobufCMessage base; + /* *this single field has information about all requested params of devices */ - size_t n_devices; - Device **devices; + size_t n_devices; + Device** devices; }; -#define DEV_DATA__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&dev_data__descriptor) \ - , 0,NULL } +#define DEV_DATA__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&dev_data__descriptor) \ + , 0, NULL \ + } /* Param methods */ -void param__init - (Param *message); -size_t param__get_packed_size - (const Param *message); -size_t param__pack - (const Param *message, - uint8_t *out); -size_t param__pack_to_buffer - (const Param *message, - ProtobufCBuffer *buffer); -Param * - param__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void param__free_unpacked - (Param *message, - ProtobufCAllocator *allocator); +void param__init(Param* message); +size_t param__get_packed_size(const Param* message); +size_t param__pack(const Param* message, + uint8_t* out); +size_t param__pack_to_buffer(const Param* message, + ProtobufCBuffer* buffer); +Param* +param__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void param__free_unpacked(Param* message, + ProtobufCAllocator* allocator); /* Device methods */ -void device__init - (Device *message); -size_t device__get_packed_size - (const Device *message); -size_t device__pack - (const Device *message, - uint8_t *out); -size_t device__pack_to_buffer - (const Device *message, - ProtobufCBuffer *buffer); -Device * - device__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void device__free_unpacked - (Device *message, - ProtobufCAllocator *allocator); +void device__init(Device* message); +size_t device__get_packed_size(const Device* message); +size_t device__pack(const Device* message, + uint8_t* out); +size_t device__pack_to_buffer(const Device* message, + ProtobufCBuffer* buffer); +Device* +device__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void device__free_unpacked(Device* message, + ProtobufCAllocator* allocator); /* DevData methods */ -void dev_data__init - (DevData *message); -size_t dev_data__get_packed_size - (const DevData *message); -size_t dev_data__pack - (const DevData *message, - uint8_t *out); -size_t dev_data__pack_to_buffer - (const DevData *message, - ProtobufCBuffer *buffer); -DevData * - dev_data__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void dev_data__free_unpacked - (DevData *message, - ProtobufCAllocator *allocator); +void dev_data__init(DevData* message); +size_t dev_data__get_packed_size(const DevData* message); +size_t dev_data__pack(const DevData* message, + uint8_t* out); +size_t dev_data__pack_to_buffer(const DevData* message, + ProtobufCBuffer* buffer); +DevData* +dev_data__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void dev_data__free_unpacked(DevData* message, + ProtobufCAllocator* allocator); /* --- per-message closures --- */ -typedef void (*Param_Closure) - (const Param *message, - void *closure_data); -typedef void (*Device_Closure) - (const Device *message, - void *closure_data); -typedef void (*DevData_Closure) - (const DevData *message, - void *closure_data); +typedef void (*Param_Closure)(const Param* message, + void* closure_data); +typedef void (*Device_Closure)(const Device* message, + void* closure_data); +typedef void (*DevData_Closure)(const DevData* message, + void* closure_data); /* --- services --- */ @@ -167,4 +148,4 @@ extern const ProtobufCMessageDescriptor dev_data__descriptor; PROTOBUF_C__END_DECLS -#endif /* PROTOBUF_C_device_2eproto__INCLUDED */ +#endif /* PROTOBUF_C_device_2eproto__INCLUDED */ diff --git a/net_handler/pbc_gen/gamepad.pb-c.c b/net_handler/pbc_gen/gamepad.pb-c.c index f880fc81..d2792724 100644 --- a/net_handler/pbc_gen/gamepad.pb-c.c +++ b/net_handler/pbc_gen/gamepad.pb-c.c @@ -7,112 +7,99 @@ #endif #include "gamepad.pb-c.h" -void gp_state__init - (GpState *message) -{ - static const GpState init_value = GP_STATE__INIT; - *message = init_value; +void gp_state__init(GpState* message) { + static const GpState init_value = GP_STATE__INIT; + *message = init_value; } -size_t gp_state__get_packed_size - (const GpState *message) -{ - assert(message->base.descriptor == &gp_state__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t gp_state__get_packed_size(const GpState* message) { + assert(message->base.descriptor == &gp_state__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t gp_state__pack - (const GpState *message, - uint8_t *out) -{ - assert(message->base.descriptor == &gp_state__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t gp_state__pack(const GpState* message, + uint8_t* out) { + assert(message->base.descriptor == &gp_state__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t gp_state__pack_to_buffer - (const GpState *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &gp_state__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t gp_state__pack_to_buffer(const GpState* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &gp_state__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -GpState * - gp_state__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (GpState *) - protobuf_c_message_unpack (&gp_state__descriptor, - allocator, len, data); +GpState* +gp_state__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (GpState*) + protobuf_c_message_unpack(&gp_state__descriptor, + allocator, len, data); } -void gp_state__free_unpacked - (GpState *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &gp_state__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void gp_state__free_unpacked(GpState* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &gp_state__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } static const ProtobufCFieldDescriptor gp_state__field_descriptors[3] = -{ - { - "connected", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_BOOL, - 0, /* quantifier_offset */ - offsetof(GpState, connected), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "buttons", - 2, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_FIXED32, - 0, /* quantifier_offset */ - offsetof(GpState, buttons), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "axes", - 3, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_FLOAT, - offsetof(GpState, n_axes), - offsetof(GpState, axes), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "connected", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BOOL, + 0, /* quantifier_offset */ + offsetof(GpState, connected), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "buttons", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_FIXED32, + 0, /* quantifier_offset */ + offsetof(GpState, buttons), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "axes", + 3, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_FLOAT, + offsetof(GpState, n_axes), + offsetof(GpState, axes), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_PACKED, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned gp_state__field_indices_by_name[] = { - 2, /* field[2] = axes */ - 1, /* field[1] = buttons */ - 0, /* field[0] = connected */ + 2, /* field[2] = axes */ + 1, /* field[1] = buttons */ + 0, /* field[0] = connected */ }; static const ProtobufCIntRange gp_state__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 3 } -}; + { + {1, 0}, + {0, 3}}; const ProtobufCMessageDescriptor gp_state__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "GpState", - "GpState", - "GpState", - "", - sizeof(GpState), - 3, - gp_state__field_descriptors, - gp_state__field_indices_by_name, - 1, gp_state__number_ranges, - (ProtobufCMessageInit) gp_state__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "GpState", + "GpState", + "GpState", + "", + sizeof(GpState), + 3, + gp_state__field_descriptors, + gp_state__field_indices_by_name, + 1, gp_state__number_ranges, + (ProtobufCMessageInit) gp_state__init, + NULL, NULL, NULL /* reserved[123] */ }; diff --git a/net_handler/pbc_gen/gamepad.pb-c.h b/net_handler/pbc_gen/gamepad.pb-c.h index 8681185f..edb55e21 100644 --- a/net_handler/pbc_gen/gamepad.pb-c.h +++ b/net_handler/pbc_gen/gamepad.pb-c.h @@ -9,9 +9,9 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -23,43 +23,37 @@ typedef struct _GpState GpState; /* --- messages --- */ -struct _GpState -{ - ProtobufCMessage base; - protobuf_c_boolean connected; - uint32_t buttons; - size_t n_axes; - float *axes; +struct _GpState { + ProtobufCMessage base; + protobuf_c_boolean connected; + uint32_t buttons; + size_t n_axes; + float* axes; }; -#define GP_STATE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&gp_state__descriptor) \ - , 0, 0, 0,NULL } +#define GP_STATE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&gp_state__descriptor) \ + , 0, 0, 0, NULL \ + } /* GpState methods */ -void gp_state__init - (GpState *message); -size_t gp_state__get_packed_size - (const GpState *message); -size_t gp_state__pack - (const GpState *message, - uint8_t *out); -size_t gp_state__pack_to_buffer - (const GpState *message, - ProtobufCBuffer *buffer); -GpState * - gp_state__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void gp_state__free_unpacked - (GpState *message, - ProtobufCAllocator *allocator); +void gp_state__init(GpState* message); +size_t gp_state__get_packed_size(const GpState* message); +size_t gp_state__pack(const GpState* message, + uint8_t* out); +size_t gp_state__pack_to_buffer(const GpState* message, + ProtobufCBuffer* buffer); +GpState* +gp_state__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void gp_state__free_unpacked(GpState* message, + ProtobufCAllocator* allocator); /* --- per-message closures --- */ -typedef void (*GpState_Closure) - (const GpState *message, - void *closure_data); +typedef void (*GpState_Closure)(const GpState* message, + void* closure_data); /* --- services --- */ @@ -71,4 +65,4 @@ extern const ProtobufCMessageDescriptor gp_state__descriptor; PROTOBUF_C__END_DECLS -#endif /* PROTOBUF_C_gamepad_2eproto__INCLUDED */ +#endif /* PROTOBUF_C_gamepad_2eproto__INCLUDED */ diff --git a/net_handler/pbc_gen/run_mode.pb-c.c b/net_handler/pbc_gen/run_mode.pb-c.c index cbcccfd4..ec99d7ff 100644 --- a/net_handler/pbc_gen/run_mode.pb-c.c +++ b/net_handler/pbc_gen/run_mode.pb-c.c @@ -7,120 +7,106 @@ #endif #include "run_mode.pb-c.h" -void run_mode__init - (RunMode *message) -{ - static const RunMode init_value = RUN_MODE__INIT; - *message = init_value; +void run_mode__init(RunMode* message) { + static const RunMode init_value = RUN_MODE__INIT; + *message = init_value; } -size_t run_mode__get_packed_size - (const RunMode *message) -{ - assert(message->base.descriptor == &run_mode__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t run_mode__get_packed_size(const RunMode* message) { + assert(message->base.descriptor == &run_mode__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t run_mode__pack - (const RunMode *message, - uint8_t *out) -{ - assert(message->base.descriptor == &run_mode__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t run_mode__pack(const RunMode* message, + uint8_t* out) { + assert(message->base.descriptor == &run_mode__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t run_mode__pack_to_buffer - (const RunMode *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &run_mode__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t run_mode__pack_to_buffer(const RunMode* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &run_mode__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -RunMode * - run_mode__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (RunMode *) - protobuf_c_message_unpack (&run_mode__descriptor, - allocator, len, data); +RunMode* +run_mode__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (RunMode*) + protobuf_c_message_unpack(&run_mode__descriptor, + allocator, len, data); } -void run_mode__free_unpacked - (RunMode *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &run_mode__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void run_mode__free_unpacked(RunMode* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &run_mode__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } static const ProtobufCFieldDescriptor run_mode__field_descriptors[1] = -{ - { - "mode", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_ENUM, - 0, /* quantifier_offset */ - offsetof(RunMode, mode), - &mode__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "mode", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(RunMode, mode), + &mode__descriptor, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned run_mode__field_indices_by_name[] = { - 0, /* field[0] = mode */ + 0, /* field[0] = mode */ }; static const ProtobufCIntRange run_mode__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; + { + {1, 0}, + {0, 1}}; const ProtobufCMessageDescriptor run_mode__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "RunMode", - "RunMode", - "RunMode", - "", - sizeof(RunMode), - 1, - run_mode__field_descriptors, - run_mode__field_indices_by_name, - 1, run_mode__number_ranges, - (ProtobufCMessageInit) run_mode__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "RunMode", + "RunMode", + "RunMode", + "", + sizeof(RunMode), + 1, + run_mode__field_descriptors, + run_mode__field_indices_by_name, + 1, run_mode__number_ranges, + (ProtobufCMessageInit) run_mode__init, + NULL, NULL, NULL /* reserved[123] */ }; static const ProtobufCEnumValue mode__enum_values_by_number[5] = -{ - { "IDLE", "MODE__IDLE", 0 }, - { "AUTO", "MODE__AUTO", 1 }, - { "TELEOP", "MODE__TELEOP", 2 }, - { "ESTOP", "MODE__ESTOP", 3 }, - { "CHALLENGE", "MODE__CHALLENGE", 4 }, + { + {"IDLE", "MODE__IDLE", 0}, + {"AUTO", "MODE__AUTO", 1}, + {"TELEOP", "MODE__TELEOP", 2}, + {"ESTOP", "MODE__ESTOP", 3}, + {"CHALLENGE", "MODE__CHALLENGE", 4}, }; static const ProtobufCIntRange mode__value_ranges[] = { -{0, 0},{0, 5} -}; + {0, 0}, {0, 5}}; static const ProtobufCEnumValueIndex mode__enum_values_by_name[5] = -{ - { "AUTO", 1 }, - { "CHALLENGE", 4 }, - { "ESTOP", 3 }, - { "IDLE", 0 }, - { "TELEOP", 2 }, + { + {"AUTO", 1}, + {"CHALLENGE", 4}, + {"ESTOP", 3}, + {"IDLE", 0}, + {"TELEOP", 2}, }; const ProtobufCEnumDescriptor mode__descriptor = -{ - PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, - "Mode", - "Mode", - "Mode", - "", - 5, - mode__enum_values_by_number, - 5, - mode__enum_values_by_name, - 1, - mode__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ + { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "Mode", + "Mode", + "Mode", + "", + 5, + mode__enum_values_by_number, + 5, + mode__enum_values_by_name, + 1, + mode__value_ranges, + NULL, NULL, NULL, NULL /* reserved[1234] */ }; diff --git a/net_handler/pbc_gen/run_mode.pb-c.h b/net_handler/pbc_gen/run_mode.pb-c.h index f87a9a87..dc96d8cf 100644 --- a/net_handler/pbc_gen/run_mode.pb-c.h +++ b/net_handler/pbc_gen/run_mode.pb-c.h @@ -9,9 +9,9 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -21,60 +21,53 @@ typedef struct _RunMode RunMode; /* --- enums --- */ typedef enum _Mode { - MODE__IDLE = 0, - MODE__AUTO = 1, - MODE__TELEOP = 2, - MODE__ESTOP = 3, - MODE__CHALLENGE = 4 - PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(MODE) + MODE__IDLE = 0, + MODE__AUTO = 1, + MODE__TELEOP = 2, + MODE__ESTOP = 3, + MODE__CHALLENGE = 4 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(MODE) } Mode; /* --- messages --- */ -struct _RunMode -{ - ProtobufCMessage base; - Mode mode; +struct _RunMode { + ProtobufCMessage base; + Mode mode; }; -#define RUN_MODE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&run_mode__descriptor) \ - , MODE__IDLE } +#define RUN_MODE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&run_mode__descriptor) \ + , MODE__IDLE \ + } /* RunMode methods */ -void run_mode__init - (RunMode *message); -size_t run_mode__get_packed_size - (const RunMode *message); -size_t run_mode__pack - (const RunMode *message, - uint8_t *out); -size_t run_mode__pack_to_buffer - (const RunMode *message, - ProtobufCBuffer *buffer); -RunMode * - run_mode__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void run_mode__free_unpacked - (RunMode *message, - ProtobufCAllocator *allocator); +void run_mode__init(RunMode* message); +size_t run_mode__get_packed_size(const RunMode* message); +size_t run_mode__pack(const RunMode* message, + uint8_t* out); +size_t run_mode__pack_to_buffer(const RunMode* message, + ProtobufCBuffer* buffer); +RunMode* +run_mode__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void run_mode__free_unpacked(RunMode* message, + ProtobufCAllocator* allocator); /* --- per-message closures --- */ -typedef void (*RunMode_Closure) - (const RunMode *message, - void *closure_data); +typedef void (*RunMode_Closure)(const RunMode* message, + void* closure_data); /* --- services --- */ /* --- descriptors --- */ -extern const ProtobufCEnumDescriptor mode__descriptor; +extern const ProtobufCEnumDescriptor mode__descriptor; extern const ProtobufCMessageDescriptor run_mode__descriptor; PROTOBUF_C__END_DECLS -#endif /* PROTOBUF_C_run_5fmode_2eproto__INCLUDED */ +#endif /* PROTOBUF_C_run_5fmode_2eproto__INCLUDED */ diff --git a/net_handler/pbc_gen/start_pos.pb-c.c b/net_handler/pbc_gen/start_pos.pb-c.c index be35ecac..6575063c 100644 --- a/net_handler/pbc_gen/start_pos.pb-c.c +++ b/net_handler/pbc_gen/start_pos.pb-c.c @@ -7,114 +7,100 @@ #endif #include "start_pos.pb-c.h" -void start_pos__init - (StartPos *message) -{ - static const StartPos init_value = START_POS__INIT; - *message = init_value; +void start_pos__init(StartPos* message) { + static const StartPos init_value = START_POS__INIT; + *message = init_value; } -size_t start_pos__get_packed_size - (const StartPos *message) -{ - assert(message->base.descriptor == &start_pos__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t start_pos__get_packed_size(const StartPos* message) { + assert(message->base.descriptor == &start_pos__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t start_pos__pack - (const StartPos *message, - uint8_t *out) -{ - assert(message->base.descriptor == &start_pos__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t start_pos__pack(const StartPos* message, + uint8_t* out) { + assert(message->base.descriptor == &start_pos__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t start_pos__pack_to_buffer - (const StartPos *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &start_pos__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t start_pos__pack_to_buffer(const StartPos* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &start_pos__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -StartPos * - start_pos__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (StartPos *) - protobuf_c_message_unpack (&start_pos__descriptor, - allocator, len, data); +StartPos* +start_pos__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (StartPos*) + protobuf_c_message_unpack(&start_pos__descriptor, + allocator, len, data); } -void start_pos__free_unpacked - (StartPos *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &start_pos__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void start_pos__free_unpacked(StartPos* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &start_pos__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } static const ProtobufCFieldDescriptor start_pos__field_descriptors[1] = -{ - { - "pos", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_ENUM, - 0, /* quantifier_offset */ - offsetof(StartPos, pos), - &pos__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "pos", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(StartPos, pos), + &pos__descriptor, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned start_pos__field_indices_by_name[] = { - 0, /* field[0] = pos */ + 0, /* field[0] = pos */ }; static const ProtobufCIntRange start_pos__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; + { + {1, 0}, + {0, 1}}; const ProtobufCMessageDescriptor start_pos__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "StartPos", - "StartPos", - "StartPos", - "", - sizeof(StartPos), - 1, - start_pos__field_descriptors, - start_pos__field_indices_by_name, - 1, start_pos__number_ranges, - (ProtobufCMessageInit) start_pos__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "StartPos", + "StartPos", + "StartPos", + "", + sizeof(StartPos), + 1, + start_pos__field_descriptors, + start_pos__field_indices_by_name, + 1, start_pos__number_ranges, + (ProtobufCMessageInit) start_pos__init, + NULL, NULL, NULL /* reserved[123] */ }; static const ProtobufCEnumValue pos__enum_values_by_number[2] = -{ - { "LEFT", "POS__LEFT", 0 }, - { "RIGHT", "POS__RIGHT", 1 }, + { + {"LEFT", "POS__LEFT", 0}, + {"RIGHT", "POS__RIGHT", 1}, }; static const ProtobufCIntRange pos__value_ranges[] = { -{0, 0},{0, 2} -}; + {0, 0}, {0, 2}}; static const ProtobufCEnumValueIndex pos__enum_values_by_name[2] = -{ - { "LEFT", 0 }, - { "RIGHT", 1 }, + { + {"LEFT", 0}, + {"RIGHT", 1}, }; const ProtobufCEnumDescriptor pos__descriptor = -{ - PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, - "Pos", - "Pos", - "Pos", - "", - 2, - pos__enum_values_by_number, - 2, - pos__enum_values_by_name, - 1, - pos__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ + { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "Pos", + "Pos", + "Pos", + "", + 2, + pos__enum_values_by_number, + 2, + pos__enum_values_by_name, + 1, + pos__value_ranges, + NULL, NULL, NULL, NULL /* reserved[1234] */ }; diff --git a/net_handler/pbc_gen/start_pos.pb-c.h b/net_handler/pbc_gen/start_pos.pb-c.h index 5e48f0bb..9c894263 100644 --- a/net_handler/pbc_gen/start_pos.pb-c.h +++ b/net_handler/pbc_gen/start_pos.pb-c.h @@ -9,9 +9,9 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -21,57 +21,50 @@ typedef struct _StartPos StartPos; /* --- enums --- */ typedef enum _Pos { - POS__LEFT = 0, - POS__RIGHT = 1 - PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(POS) + POS__LEFT = 0, + POS__RIGHT = 1 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(POS) } Pos; /* --- messages --- */ -struct _StartPos -{ - ProtobufCMessage base; - Pos pos; +struct _StartPos { + ProtobufCMessage base; + Pos pos; }; -#define START_POS__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&start_pos__descriptor) \ - , POS__LEFT } +#define START_POS__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&start_pos__descriptor) \ + , POS__LEFT \ + } /* StartPos methods */ -void start_pos__init - (StartPos *message); -size_t start_pos__get_packed_size - (const StartPos *message); -size_t start_pos__pack - (const StartPos *message, - uint8_t *out); -size_t start_pos__pack_to_buffer - (const StartPos *message, - ProtobufCBuffer *buffer); -StartPos * - start_pos__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void start_pos__free_unpacked - (StartPos *message, - ProtobufCAllocator *allocator); +void start_pos__init(StartPos* message); +size_t start_pos__get_packed_size(const StartPos* message); +size_t start_pos__pack(const StartPos* message, + uint8_t* out); +size_t start_pos__pack_to_buffer(const StartPos* message, + ProtobufCBuffer* buffer); +StartPos* +start_pos__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void start_pos__free_unpacked(StartPos* message, + ProtobufCAllocator* allocator); /* --- per-message closures --- */ -typedef void (*StartPos_Closure) - (const StartPos *message, - void *closure_data); +typedef void (*StartPos_Closure)(const StartPos* message, + void* closure_data); /* --- services --- */ /* --- descriptors --- */ -extern const ProtobufCEnumDescriptor pos__descriptor; +extern const ProtobufCEnumDescriptor pos__descriptor; extern const ProtobufCMessageDescriptor start_pos__descriptor; PROTOBUF_C__END_DECLS -#endif /* PROTOBUF_C_start_5fpos_2eproto__INCLUDED */ +#endif /* PROTOBUF_C_start_5fpos_2eproto__INCLUDED */ diff --git a/net_handler/pbc_gen/text.pb-c.c b/net_handler/pbc_gen/text.pb-c.c index 703b4cd8..f3522632 100644 --- a/net_handler/pbc_gen/text.pb-c.c +++ b/net_handler/pbc_gen/text.pb-c.c @@ -7,86 +7,72 @@ #endif #include "text.pb-c.h" -void text__init - (Text *message) -{ - static const Text init_value = TEXT__INIT; - *message = init_value; +void text__init(Text* message) { + static const Text init_value = TEXT__INIT; + *message = init_value; } -size_t text__get_packed_size - (const Text *message) -{ - assert(message->base.descriptor == &text__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +size_t text__get_packed_size(const Text* message) { + assert(message->base.descriptor == &text__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage*) (message)); } -size_t text__pack - (const Text *message, - uint8_t *out) -{ - assert(message->base.descriptor == &text__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +size_t text__pack(const Text* message, + uint8_t* out) { + assert(message->base.descriptor == &text__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage*) message, out); } -size_t text__pack_to_buffer - (const Text *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &text__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +size_t text__pack_to_buffer(const Text* message, + ProtobufCBuffer* buffer) { + assert(message->base.descriptor == &text__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage*) message, buffer); } -Text * - text__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (Text *) - protobuf_c_message_unpack (&text__descriptor, - allocator, len, data); +Text* text__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data) { + return (Text*) + protobuf_c_message_unpack(&text__descriptor, + allocator, len, data); } -void text__free_unpacked - (Text *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &text__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +void text__free_unpacked(Text* message, + ProtobufCAllocator* allocator) { + if (!message) + return; + assert(message->base.descriptor == &text__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage*) message, allocator); } static const ProtobufCFieldDescriptor text__field_descriptors[1] = -{ - { - "payload", - 1, - PROTOBUF_C_LABEL_REPEATED, - PROTOBUF_C_TYPE_STRING, - offsetof(Text, n_payload), - offsetof(Text, payload), - NULL, - &protobuf_c_empty_string, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, + { + { + "payload", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Text, n_payload), + offsetof(Text, payload), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned text__field_indices_by_name[] = { - 0, /* field[0] = payload */ + 0, /* field[0] = payload */ }; static const ProtobufCIntRange text__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; + { + {1, 0}, + {0, 1}}; const ProtobufCMessageDescriptor text__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "Text", - "Text", - "Text", - "", - sizeof(Text), - 1, - text__field_descriptors, - text__field_indices_by_name, - 1, text__number_ranges, - (ProtobufCMessageInit) text__init, - NULL,NULL,NULL /* reserved[123] */ + { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "Text", + "Text", + "Text", + "", + sizeof(Text), + 1, + text__field_descriptors, + text__field_indices_by_name, + 1, text__number_ranges, + (ProtobufCMessageInit) text__init, + NULL, NULL, NULL /* reserved[123] */ }; diff --git a/net_handler/pbc_gen/text.pb-c.h b/net_handler/pbc_gen/text.pb-c.h index 45e75529..73c16e0f 100644 --- a/net_handler/pbc_gen/text.pb-c.h +++ b/net_handler/pbc_gen/text.pb-c.h @@ -9,9 +9,9 @@ PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif @@ -23,44 +23,37 @@ typedef struct _Text Text; /* --- messages --- */ -struct _Text -{ - ProtobufCMessage base; - /* +struct _Text { + ProtobufCMessage base; + /* *CHALLENGE_DATA: initial values or results of challenges */ - size_t n_payload; - char **payload; + size_t n_payload; + char** payload; }; -#define TEXT__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&text__descriptor) \ - , 0,NULL } +#define TEXT__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT(&text__descriptor) \ + , 0, NULL \ + } /* Text methods */ -void text__init - (Text *message); -size_t text__get_packed_size - (const Text *message); -size_t text__pack - (const Text *message, - uint8_t *out); -size_t text__pack_to_buffer - (const Text *message, - ProtobufCBuffer *buffer); -Text * - text__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void text__free_unpacked - (Text *message, - ProtobufCAllocator *allocator); +void text__init(Text* message); +size_t text__get_packed_size(const Text* message); +size_t text__pack(const Text* message, + uint8_t* out); +size_t text__pack_to_buffer(const Text* message, + ProtobufCBuffer* buffer); +Text* text__unpack(ProtobufCAllocator* allocator, + size_t len, + const uint8_t* data); +void text__free_unpacked(Text* message, + ProtobufCAllocator* allocator); /* --- per-message closures --- */ -typedef void (*Text_Closure) - (const Text *message, - void *closure_data); +typedef void (*Text_Closure)(const Text* message, + void* closure_data); /* --- services --- */ @@ -72,4 +65,4 @@ extern const ProtobufCMessageDescriptor text__descriptor; PROTOBUF_C__END_DECLS -#endif /* PROTOBUF_C_text_2eproto__INCLUDED */ +#endif /* PROTOBUF_C_text_2eproto__INCLUDED */ diff --git a/net_handler/protobuf_tests/devdata_in.c b/net_handler/protobuf_tests/devdata_in.c index e8fbf8bc..eb49610e 100644 --- a/net_handler/protobuf_tests/devdata_in.c +++ b/net_handler/protobuf_tests/devdata_in.c @@ -3,64 +3,59 @@ #include "../pbc_gen/device.pb-c.h" #define MAX_MSG_SIZE 1024 -static size_t read_buffer (unsigned max_length, uint8_t *out) -{ - size_t cur_len = 0; - size_t nread; - while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) - { - cur_len += nread; - if (cur_len == max_length) - { - fprintf(stderr, "max message length exceeded\n"); - exit(1); - } - } - return cur_len; +static size_t read_buffer(unsigned max_length, uint8_t* out) { + size_t cur_len = 0; + size_t nread; + while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) { + cur_len += nread; + if (cur_len == max_length) { + fprintf(stderr, "max message length exceeded\n"); + exit(1); + } + } + return cur_len; } -int main () -{ - DevData *dev_data; - - // Read packed message from standard-input. - uint8_t buf[MAX_MSG_SIZE]; - size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); - - // Unpack the message using protobuf-c. - dev_data = dev_data__unpack(NULL, msg_len, buf); - if (dev_data == NULL) - { - fprintf(stderr, "error unpacking incoming message\n"); - exit(1); - } - - // display the message's fields. - printf("Received:\n"); - for (int i = 0; i < dev_data->n_devices; i++) { - printf("Device No. %d: ", i); - printf("\ttype = %s, uid = %llu, itype = %d\n", dev_data->devices[i]->name, dev_data->devices[i]->uid, dev_data->devices[i]->type); - printf("\tParams:\n"); - for (int j = 0; j < dev_data->devices[i]->n_params; j++) { - printf("\t\tparam \"%s\" has type ", dev_data->devices[i]->params[j]->name); - switch (dev_data->devices[i]->params[j]->val_case) { - case (PARAM__VAL_FVAL): - printf("FLOAT with value %f\n", dev_data->devices[i]->params[j]->fval); - break; - case (PARAM__VAL_IVAL): - printf("INT with value %d\n", dev_data->devices[i]->params[j]->ival); - break; - case (PARAM__VAL_BVAL): - printf("BOOL with value %d\n", dev_data->devices[i]->params[j]->bval); - break; - default: - printf("UNKNOWN"); - break; - } - } - } +int main() { + DevData* dev_data; - // Free the unpacked message - dev_data__free_unpacked(dev_data, NULL); - return 0; + // Read packed message from standard-input. + uint8_t buf[MAX_MSG_SIZE]; + size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); + + // Unpack the message using protobuf-c. + dev_data = dev_data__unpack(NULL, msg_len, buf); + if (dev_data == NULL) { + fprintf(stderr, "error unpacking incoming message\n"); + exit(1); + } + + // display the message's fields. + printf("Received:\n"); + for (int i = 0; i < dev_data->n_devices; i++) { + printf("Device No. %d: ", i); + printf("\ttype = %s, uid = %llu, itype = %d\n", dev_data->devices[i]->name, dev_data->devices[i]->uid, dev_data->devices[i]->type); + printf("\tParams:\n"); + for (int j = 0; j < dev_data->devices[i]->n_params; j++) { + printf("\t\tparam \"%s\" has type ", dev_data->devices[i]->params[j]->name); + switch (dev_data->devices[i]->params[j]->val_case) { + case (PARAM__VAL_FVAL): + printf("FLOAT with value %f\n", dev_data->devices[i]->params[j]->fval); + break; + case (PARAM__VAL_IVAL): + printf("INT with value %d\n", dev_data->devices[i]->params[j]->ival); + break; + case (PARAM__VAL_BVAL): + printf("BOOL with value %d\n", dev_data->devices[i]->params[j]->bval); + break; + default: + printf("UNKNOWN"); + break; + } + } + } + + // Free the unpacked message + dev_data__free_unpacked(dev_data, NULL); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/devdata_out.c b/net_handler/protobuf_tests/devdata_out.c index 8f26ff37..59ad21e0 100644 --- a/net_handler/protobuf_tests/devdata_out.c +++ b/net_handler/protobuf_tests/devdata_out.c @@ -2,64 +2,63 @@ #include #include "../pbc_gen/device.pb-c.h" -int main () -{ - void *buf; // Buffer to store serialized data - unsigned len; // Length of serialized data - - //initialize all the messages and submessages (let's send two devices, the first with 1 param and the second with 2 params) - DevData dev_data = DEV_DATA__INIT; - Device dev1 = DEVICE__INIT; - Device dev2 = DEVICE__INIT; - Param d1p1 = PARAM__INIT; - Param d2p1 = PARAM__INIT; - Param d2p2 = PARAM__INIT; - - //set all the fields ..... - d1p1.name = "switch0"; - d1p1.val_case = PARAM__VAL_FVAL; - d1p1.fval = 0.3; - - d2p1.name = "sensor0"; - d2p1.val_case = PARAM__VAL_IVAL; - d2p1.ival = 42; - - d2p2.name = "bogus"; - d2p2.val_case = PARAM__VAL_BVAL; - d2p2.bval = 1; - - dev1.name = "LimitSwitch"; - dev1.uid = 984789478297; - dev1.type = 12; - dev1.n_params = 1; - dev1.params = (Param **) malloc(dev1.n_params * sizeof(Param *)); - dev1.params[0] = &d1p1; - - dev2.name = "LineFollower"; - dev2.uid = 47834674267; - dev2.type = 13; - dev2.n_params = 2; - dev2.params = (Param **) malloc(dev2.n_params * sizeof(Param *)); - dev2.params[0] = &d2p1; - dev2.params[1] = &d2p2; - - dev_data.n_devices = 2; - dev_data.devices = (Device **) malloc(dev_data.n_devices * sizeof(Device *)); - dev_data.devices[0] = &dev1; - dev_data.devices[1] = &dev2; - //done setting all fields! - - len = dev_data__get_packed_size(&dev_data); - - buf = malloc(len); - dev_data__pack(&dev_data, buf); - - fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message - fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping - - free(buf); // Free the allocated serialized buffer - free(dev1.params); - free(dev2.params); - free(dev_data.devices); - return 0; +int main() { + void* buf; // Buffer to store serialized data + unsigned len; // Length of serialized data + + //initialize all the messages and submessages (let's send two devices, the first with 1 param and the second with 2 params) + DevData dev_data = DEV_DATA__INIT; + Device dev1 = DEVICE__INIT; + Device dev2 = DEVICE__INIT; + Param d1p1 = PARAM__INIT; + Param d2p1 = PARAM__INIT; + Param d2p2 = PARAM__INIT; + + //set all the fields ..... + d1p1.name = "switch0"; + d1p1.val_case = PARAM__VAL_FVAL; + d1p1.fval = 0.3; + + d2p1.name = "sensor0"; + d2p1.val_case = PARAM__VAL_IVAL; + d2p1.ival = 42; + + d2p2.name = "bogus"; + d2p2.val_case = PARAM__VAL_BVAL; + d2p2.bval = 1; + + dev1.name = "LimitSwitch"; + dev1.uid = 984789478297; + dev1.type = 12; + dev1.n_params = 1; + dev1.params = (Param**) malloc(dev1.n_params * sizeof(Param*)); + dev1.params[0] = &d1p1; + + dev2.name = "LineFollower"; + dev2.uid = 47834674267; + dev2.type = 13; + dev2.n_params = 2; + dev2.params = (Param**) malloc(dev2.n_params * sizeof(Param*)); + dev2.params[0] = &d2p1; + dev2.params[1] = &d2p2; + + dev_data.n_devices = 2; + dev_data.devices = (Device**) malloc(dev_data.n_devices * sizeof(Device*)); + dev_data.devices[0] = &dev1; + dev_data.devices[1] = &dev2; + //done setting all fields! + + len = dev_data__get_packed_size(&dev_data); + + buf = malloc(len); + dev_data__pack(&dev_data, buf); + + fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message + fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping + + free(buf); // Free the allocated serialized buffer + free(dev1.params); + free(dev2.params); + free(dev_data.devices); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/gpstate_in.c b/net_handler/protobuf_tests/gpstate_in.c index d02914b4..7ce396fc 100644 --- a/net_handler/protobuf_tests/gpstate_in.c +++ b/net_handler/protobuf_tests/gpstate_in.c @@ -3,46 +3,41 @@ #include "../pbc_gen/gamepad.pb-c.h" #define MAX_MSG_SIZE 1024 -static size_t read_buffer (unsigned max_length, uint8_t *out) -{ - size_t cur_len = 0; - size_t nread; - while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) - { - cur_len += nread; - if (cur_len == max_length) - { - fprintf(stderr, "max message length exceeded\n"); - exit(1); - } - } - return cur_len; +static size_t read_buffer(unsigned max_length, uint8_t* out) { + size_t cur_len = 0; + size_t nread; + while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) { + cur_len += nread; + if (cur_len == max_length) { + fprintf(stderr, "max message length exceeded\n"); + exit(1); + } + } + return cur_len; } -int main () -{ - GpState *gp_state; - - // Read packed message from standard-input. - uint8_t buf[MAX_MSG_SIZE]; - size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); - - // Unpack the message using protobuf-c. - gp_state = gp_state__unpack(NULL, msg_len, buf); - if (gp_state == NULL) - { - fprintf(stderr, "error unpacking incoming message\n"); - exit(1); - } - - // display the message's fields. - printf("Is gamepad connected: %d. Received: buttons = %d\n\taxes:", gp_state->connected, gp_state->buttons); - for (int i = 0; i < gp_state->n_axes; i++) { - printf("\t%f", gp_state->axes[i]); - } - printf("\n"); +int main() { + GpState* gp_state; - // Free the unpacked message - gp_state__free_unpacked(gp_state, NULL); - return 0; + // Read packed message from standard-input. + uint8_t buf[MAX_MSG_SIZE]; + size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); + + // Unpack the message using protobuf-c. + gp_state = gp_state__unpack(NULL, msg_len, buf); + if (gp_state == NULL) { + fprintf(stderr, "error unpacking incoming message\n"); + exit(1); + } + + // display the message's fields. + printf("Is gamepad connected: %d. Received: buttons = %d\n\taxes:", gp_state->connected, gp_state->buttons); + for (int i = 0; i < gp_state->n_axes; i++) { + printf("\t%f", gp_state->axes[i]); + } + printf("\n"); + + // Free the unpacked message + gp_state__free_unpacked(gp_state, NULL); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/gpstate_out.c b/net_handler/protobuf_tests/gpstate_out.c index 615182d4..9014c0da 100644 --- a/net_handler/protobuf_tests/gpstate_out.c +++ b/net_handler/protobuf_tests/gpstate_out.c @@ -2,31 +2,30 @@ #include #include "../pbc_gen/gamepad.pb-c.h" -int main () -{ - GpState gp_state = GP_STATE__INIT; //iniitialize hooray - void *buf; // Buffer to store serialized data - unsigned len; // Length of serialized data - - //put some data - gp_state.connected = 1; - gp_state.buttons = 47894789; - gp_state.n_axes = 4; - gp_state.axes = malloc(gp_state.n_axes * sizeof(double)); - gp_state.axes[0] = -0.42; - gp_state.axes[1] = -0.97; - gp_state.axes[2] = 0.77; - gp_state.axes[3] = 0.04; - - - len = gp_state__get_packed_size(&gp_state); - - buf = malloc(len); - gp_state__pack(&gp_state,buf); - - fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message - fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping - - free(buf); // Free the allocated serialized buffer - return 0; +int main() { + GpState gp_state = GP_STATE__INIT; //iniitialize hooray + void* buf; // Buffer to store serialized data + unsigned len; // Length of serialized data + + //put some data + gp_state.connected = 1; + gp_state.buttons = 47894789; + gp_state.n_axes = 4; + gp_state.axes = malloc(gp_state.n_axes * sizeof(double)); + gp_state.axes[0] = -0.42; + gp_state.axes[1] = -0.97; + gp_state.axes[2] = 0.77; + gp_state.axes[3] = 0.04; + + + len = gp_state__get_packed_size(&gp_state); + + buf = malloc(len); + gp_state__pack(&gp_state, buf); + + fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message + fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping + + free(buf); // Free the allocated serialized buffer + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/log_in.c b/net_handler/protobuf_tests/log_in.c index 077ba787..f515e864 100644 --- a/net_handler/protobuf_tests/log_in.c +++ b/net_handler/protobuf_tests/log_in.c @@ -3,44 +3,39 @@ #include "../pbc_gen/text.pb-c.h" #define MAX_MSG_SIZE 1024 -static size_t read_buffer (unsigned max_length, uint8_t *out) -{ - size_t cur_len = 0; - size_t nread; - while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) - { - cur_len += nread; - if (cur_len == max_length) - { - fprintf(stderr, "max message length exceeded\n"); - exit(1); - } - } - return cur_len; +static size_t read_buffer(unsigned max_length, uint8_t* out) { + size_t cur_len = 0; + size_t nread; + while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) { + cur_len += nread; + if (cur_len == max_length) { + fprintf(stderr, "max message length exceeded\n"); + exit(1); + } + } + return cur_len; } -int main () -{ - Text *log_msg; - - // Read packed message from standard-input. - uint8_t buf[MAX_MSG_SIZE]; - size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); - - // Unpack the message using protobuf-c. - log_msg = text__unpack(NULL, msg_len, buf); - if (log_msg == NULL) - { - fprintf(stderr, "error unpacking incoming message\n"); - exit(1); - } - - // display the message's fields. - for (int i = 0; i < log_msg->n_payload; i++) { - printf("\t%s\n", log_msg->payload[i]); - } +int main() { + Text* log_msg; - // Free the unpacked message - text__free_unpacked(log_msg, NULL); - return 0; + // Read packed message from standard-input. + uint8_t buf[MAX_MSG_SIZE]; + size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); + + // Unpack the message using protobuf-c. + log_msg = text__unpack(NULL, msg_len, buf); + if (log_msg == NULL) { + fprintf(stderr, "error unpacking incoming message\n"); + exit(1); + } + + // display the message's fields. + for (int i = 0; i < log_msg->n_payload; i++) { + printf("\t%s\n", log_msg->payload[i]); + } + + // Free the unpacked message + text__free_unpacked(log_msg, NULL); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/log_out.c b/net_handler/protobuf_tests/log_out.c index 3b01cfb7..431fb5eb 100644 --- a/net_handler/protobuf_tests/log_out.c +++ b/net_handler/protobuf_tests/log_out.c @@ -5,34 +5,33 @@ #define MAX_STRLEN 100 -char* strs[4] = { "hello", "beautiful", "precious", "world" }; - -int main () -{ - Text log_msg = TEXT__INIT; //iniitialize hooray - void *buf; // Buffer to store serialized data - unsigned len; // Length of serialized data - - //put some data - log_msg.n_payload = 4; - log_msg.payload = (char **) malloc (sizeof(char *) * log_msg.n_payload); - for (int i = 0; i < log_msg.n_payload; i++) { - log_msg.payload[i] = (char *) malloc(sizeof(char) * strlen(strs[i])); - strcpy(log_msg.payload[i], (const char *) strs[i]); - } - - len = text__get_packed_size(&log_msg); - - buf = malloc(len); - text__pack(&log_msg, buf); - - fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message - fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping - - free(buf); // Free the allocated serialized buffer - for (int i = 0; i < log_msg.n_payload; i++) { - free(log_msg.payload[i]); - } - free(log_msg.payload); - return 0; +char* strs[4] = {"hello", "beautiful", "precious", "world"}; + +int main() { + Text log_msg = TEXT__INIT; //iniitialize hooray + void* buf; // Buffer to store serialized data + unsigned len; // Length of serialized data + + //put some data + log_msg.n_payload = 4; + log_msg.payload = (char**) malloc(sizeof(char*) * log_msg.n_payload); + for (int i = 0; i < log_msg.n_payload; i++) { + log_msg.payload[i] = (char*) malloc(sizeof(char) * strlen(strs[i])); + strcpy(log_msg.payload[i], (const char*) strs[i]); + } + + len = text__get_packed_size(&log_msg); + + buf = malloc(len); + text__pack(&log_msg, buf); + + fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message + fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping + + free(buf); // Free the allocated serialized buffer + for (int i = 0; i < log_msg.n_payload; i++) { + free(log_msg.payload[i]); + } + free(log_msg.payload); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/runmode_in.c b/net_handler/protobuf_tests/runmode_in.c index 77f19f4b..bb5cbc09 100644 --- a/net_handler/protobuf_tests/runmode_in.c +++ b/net_handler/protobuf_tests/runmode_in.c @@ -3,42 +3,37 @@ #include "../pbc_gen/run_mode.pb-c.h" #define MAX_MSG_SIZE 1024 -static size_t read_buffer (unsigned max_length, uint8_t *out) -{ - size_t cur_len = 0; - size_t nread; - while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) - { - cur_len += nread; - if (cur_len == max_length) - { - fprintf(stderr, "max message length exceeded\n"); - exit(1); - } - } - return cur_len; +static size_t read_buffer(unsigned max_length, uint8_t* out) { + size_t cur_len = 0; + size_t nread; + while ((nread = fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0) { + cur_len += nread; + if (cur_len == max_length) { + fprintf(stderr, "max message length exceeded\n"); + exit(1); + } + } + return cur_len; } -int main () -{ - RunMode *run_mode; - - // Read packed message from standard-input. - uint8_t buf[MAX_MSG_SIZE]; - size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); - - // Unpack the message using protobuf-c. - run_mode = run_mode__unpack(NULL, msg_len, buf); - if (run_mode == NULL) - { - fprintf(stderr, "error unpacking incoming message\n"); - exit(1); - } - - // display the message's fields. - printf("Received: mode = %u\n", run_mode->mode); //comes in as unsigned int +int main() { + RunMode* run_mode; - // Free the unpacked message - run_mode__free_unpacked(run_mode, NULL); - return 0; + // Read packed message from standard-input. + uint8_t buf[MAX_MSG_SIZE]; + size_t msg_len = read_buffer(MAX_MSG_SIZE, buf); + + // Unpack the message using protobuf-c. + run_mode = run_mode__unpack(NULL, msg_len, buf); + if (run_mode == NULL) { + fprintf(stderr, "error unpacking incoming message\n"); + exit(1); + } + + // display the message's fields. + printf("Received: mode = %u\n", run_mode->mode); //comes in as unsigned int + + // Free the unpacked message + run_mode__free_unpacked(run_mode, NULL); + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/runmode_out.c b/net_handler/protobuf_tests/runmode_out.c index 605b65a2..75f5aca0 100644 --- a/net_handler/protobuf_tests/runmode_out.c +++ b/net_handler/protobuf_tests/runmode_out.c @@ -2,23 +2,22 @@ #include #include "../pbc_gen/run_mode.pb-c.h" -int main () -{ - RunMode run_mode = RUN_MODE__INIT; //iniitialize hooray - void *buf; // Buffer to store serialized data - unsigned len; // Length of serialized data - - //put some data - run_mode.mode = MODE__AUTO; - - len = run_mode__get_packed_size(&run_mode); - - buf = malloc(len); - run_mode__pack(&run_mode, buf); - - fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message - fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping - - free(buf); // Free the allocated serialized buffer - return 0; +int main() { + RunMode run_mode = RUN_MODE__INIT; //iniitialize hooray + void* buf; // Buffer to store serialized data + unsigned len; // Length of serialized data + + //put some data + run_mode.mode = MODE__AUTO; + + len = run_mode__get_packed_size(&run_mode); + + buf = malloc(len); + run_mode__pack(&run_mode, buf); + + fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message + fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping + + free(buf); // Free the allocated serialized buffer + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/tcp_pb_client.c b/net_handler/protobuf_tests/tcp_pb_client.c index 3c649d79..5a23ede2 100644 --- a/net_handler/protobuf_tests/tcp_pb_client.c +++ b/net_handler/protobuf_tests/tcp_pb_client.c @@ -1,8 +1,8 @@ -#include //for i/o -#include //for exit -#include //for memset -#include //for inet_addr, bind, listen, accept, socket types -#include //for read, write, close +#include //for inet_addr, bind, listen, accept, socket types +#include //for i/o +#include //for exit +#include //for memset +#include //for read, write, close #include "../pbc_gen/text.pb-c.h" #define MAX_MSG_SIZE 1024 @@ -15,68 +15,67 @@ * in this file, that file descriptor is called sockfd */ -int main () -{ - uint8_t buf[MAX_MSG_SIZE]; - - //Open TCP connection - int sockfd; - struct sockaddr_in servaddr; - - // socket create and varification - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) { - printf("socket creation failed...\n"); - exit(0); - } else { - printf("Socket successfully created..\n"); - } - memset(&servaddr, '\0', sizeof(servaddr)); - - // assign IP, PORT - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - servaddr.sin_port = htons(PORT); - - // connect the client socket to server socket - if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { - printf("connection with the server failed...\n"); - exit(0); - } else { - printf("connected to the server..\n"); - } - - //send a connection message for example - ssize_t n = write(sockfd, "write", 6); - if (n < 0) { - perror("ERROR writing to socket"); - } - - //read the message - ssize_t msg_len = read(sockfd, buf, 100); - printf("received %zd bytes from server\n", msg_len); - - // close the socket - close(sockfd); - - //process the message - Text *log_msg; - - // Unpack the message using protobuf-c. - log_msg = text__unpack(NULL, (size_t) msg_len, buf); - if (log_msg == NULL) { - fprintf(stderr, "error unpacking incoming message\n"); - exit(1); - } - - // display the message's fields. - for (int i = 0; i < log_msg->n_payload; i++) { - printf("%s\n", log_msg->payload[i]); - } - // Free the unpacked message - text__free_unpacked(log_msg, NULL); - - sleep(1); - - return 0; +int main() { + uint8_t buf[MAX_MSG_SIZE]; + + //Open TCP connection + int sockfd; + struct sockaddr_in servaddr; + + // socket create and varification + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } else { + printf("Socket successfully created..\n"); + } + memset(&servaddr, '\0', sizeof(servaddr)); + + // assign IP, PORT + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + servaddr.sin_port = htons(PORT); + + // connect the client socket to server socket + if (connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) != 0) { + printf("connection with the server failed...\n"); + exit(0); + } else { + printf("connected to the server..\n"); + } + + //send a connection message for example + ssize_t n = write(sockfd, "write", 6); + if (n < 0) { + perror("ERROR writing to socket"); + } + + //read the message + ssize_t msg_len = read(sockfd, buf, 100); + printf("received %zd bytes from server\n", msg_len); + + // close the socket + close(sockfd); + + //process the message + Text* log_msg; + + // Unpack the message using protobuf-c. + log_msg = text__unpack(NULL, (size_t) msg_len, buf); + if (log_msg == NULL) { + fprintf(stderr, "error unpacking incoming message\n"); + exit(1); + } + + // display the message's fields. + for (int i = 0; i < log_msg->n_payload; i++) { + printf("%s\n", log_msg->payload[i]); + } + // Free the unpacked message + text__free_unpacked(log_msg, NULL); + + sleep(1); + + return 0; } \ No newline at end of file diff --git a/net_handler/protobuf_tests/tcp_pb_server.c b/net_handler/protobuf_tests/tcp_pb_server.c index 53f0fb1d..3d3ebe90 100644 --- a/net_handler/protobuf_tests/tcp_pb_server.c +++ b/net_handler/protobuf_tests/tcp_pb_server.c @@ -1,8 +1,8 @@ -#include //for i/o -#include //for malloc, free, exit -#include //for strcpy, memset -#include //for inet_addr, bind, listen, accept, socket types -#include //for read, write, close +#include //for inet_addr, bind, listen, accept, socket types +#include //for i/o +#include //for malloc, free, exit +#include //for strcpy, memset +#include //for read, write, close #include "../pbc_gen/text.pb-c.h" @@ -10,7 +10,7 @@ #define MAX_STRLEN 100 -char* strs[4] = { "hello", "beautiful", "precious", "world" }; +char* strs[4] = {"hello", "beautiful", "precious", "world"}; /* NOTES: * this is the server. @@ -19,91 +19,90 @@ char* strs[4] = { "hello", "beautiful", "precious", "world" }; * in this file, that file descriptor is called connfd */ -int main () -{ - Text log_msg = TEXT__INIT; //iniitialize hooray - uint8_t *log_msg_buf; // Buffer to store serialized data - char conn_msg_buf[100]; //buffer for connection message - unsigned len; // Length of serialized data - - //put some data - log_msg.n_payload = 4; - log_msg.payload = (char **) malloc (sizeof(char *) * log_msg.n_payload); - for (int i = 0; i < log_msg.n_payload; i++) { - log_msg.payload[i] = (char *) malloc(sizeof(char) * strlen(strs[i])); - strcpy(log_msg.payload[i], (const char *) strs[i]); - } - - //establish TCP sever-side - int sockfd, connfd; - struct sockaddr_in servaddr, cli; - - // socket create and verification - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) { - printf("socket creation failed...\n"); - exit(0); - } else { - printf("Socket successfully created..\n"); - } - memset(&servaddr, '\0', sizeof(servaddr)); - - // assign IP, PORT - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(PORT); - - // Binding newly created socket to given IP and verification - if ((bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) != 0) { - printf("socket bind failed...\n"); - perror("bind"); - exit(0); - } else { - printf("Socket successfully binded..\n"); - } - - // Now server is ready to listen and verification - if ((listen(sockfd, 5)) != 0) { - printf("Listen failed...\n"); - exit(0); - } else { - printf("Server listening..\n"); - } - len = sizeof(cli); - - // Accept the data packet from client and verification - connfd = accept(sockfd, (struct sockaddr *)&cli, &len); - if (connfd < 0) { - printf("server acccept failed...\n"); - exit(0); - } else { - printf("server acccept the client...\n"); - } - - //read a connection message for example - ssize_t n = read(connfd, conn_msg_buf, 255); - if (n < 0) { - perror("ERROR reading from socket"); - } - printf("Here is the message: %s\n", conn_msg_buf); - - //send the serialized data to the client - len = text__get_packed_size(&log_msg); - fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message - log_msg_buf = (uint8_t *) malloc(sizeof(uint8_t) * len); - text__pack(&log_msg, log_msg_buf); - ssize_t w_bytes = write(connfd, log_msg_buf, len); - printf("wrote %zd bytes to client\n", w_bytes); - if (w_bytes == -1) { - perror("failed in socket write"); - } - // After chatting close the socket - close(connfd); - close(sockfd); - - //fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping - - free(log_msg_buf); // Free the allocated serialized buffer - free(log_msg.payload); - return 0; +int main() { + Text log_msg = TEXT__INIT; //iniitialize hooray + uint8_t* log_msg_buf; // Buffer to store serialized data + char conn_msg_buf[100]; //buffer for connection message + unsigned len; // Length of serialized data + + //put some data + log_msg.n_payload = 4; + log_msg.payload = (char**) malloc(sizeof(char*) * log_msg.n_payload); + for (int i = 0; i < log_msg.n_payload; i++) { + log_msg.payload[i] = (char*) malloc(sizeof(char) * strlen(strs[i])); + strcpy(log_msg.payload[i], (const char*) strs[i]); + } + + //establish TCP sever-side + int sockfd, connfd; + struct sockaddr_in servaddr, cli; + + // socket create and verification + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } else { + printf("Socket successfully created..\n"); + } + memset(&servaddr, '\0', sizeof(servaddr)); + + // assign IP, PORT + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(PORT); + + // Binding newly created socket to given IP and verification + if ((bind(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr))) != 0) { + printf("socket bind failed...\n"); + perror("bind"); + exit(0); + } else { + printf("Socket successfully binded..\n"); + } + + // Now server is ready to listen and verification + if ((listen(sockfd, 5)) != 0) { + printf("Listen failed...\n"); + exit(0); + } else { + printf("Server listening..\n"); + } + len = sizeof(cli); + + // Accept the data packet from client and verification + connfd = accept(sockfd, (struct sockaddr*) &cli, &len); + if (connfd < 0) { + printf("server acccept failed...\n"); + exit(0); + } else { + printf("server acccept the client...\n"); + } + + //read a connection message for example + ssize_t n = read(connfd, conn_msg_buf, 255); + if (n < 0) { + perror("ERROR reading from socket"); + } + printf("Here is the message: %s\n", conn_msg_buf); + + //send the serialized data to the client + len = text__get_packed_size(&log_msg); + fprintf(stderr, "Writing %d serialized bytes\n", len); // See the length of message + log_msg_buf = (uint8_t*) malloc(sizeof(uint8_t) * len); + text__pack(&log_msg, log_msg_buf); + ssize_t w_bytes = write(connfd, log_msg_buf, len); + printf("wrote %zd bytes to client\n", w_bytes); + if (w_bytes == -1) { + perror("failed in socket write"); + } + // After chatting close the socket + close(connfd); + close(sockfd); + + //fwrite(buf, len, 1, stdout); // Write to stdout to allow direct command line piping + + free(log_msg_buf); // Free the allocated serialized buffer + free(log_msg.payload); + return 0; } \ No newline at end of file diff --git a/net_handler/protos/device.proto b/net_handler/protos/device.proto index 5b00518f..fb8b8f06 100644 --- a/net_handler/protos/device.proto +++ b/net_handler/protos/device.proto @@ -8,22 +8,22 @@ option optimize_for = LITE_RUNTIME; //message for describing a single device parameter message Param { - string name = 1; - oneof val { - float fval = 2; - int32 ival = 3; - bool bval = 4; - } + string name = 1; + oneof val { + float fval = 2; + int32 ival = 3; + bool bval = 4; + } } //message for describing a single device message Device { - string name = 1; - uint64 uid = 2; - uint32 type = 3; - repeated Param params = 4; //each device has some number of params + string name = 1; + uint64 uid = 2; + uint32 type = 3; + repeated Param params = 4; //each device has some number of params } message DevData { - repeated Device devices = 1; //this single field has information about all requested params of devices + repeated Device devices = 1; //this single field has information about all requested params of devices } diff --git a/net_handler/protos/gamepad.proto b/net_handler/protos/gamepad.proto index 6ed72650..93e363e1 100644 --- a/net_handler/protos/gamepad.proto +++ b/net_handler/protos/gamepad.proto @@ -7,7 +7,7 @@ syntax = "proto3"; option optimize_for = LITE_RUNTIME; message GpState { - bool connected = 1; - fixed32 buttons = 2; - repeated float axes = 3; + bool connected = 1; + fixed32 buttons = 2; + repeated float axes = 3; } diff --git a/net_handler/protos/run_mode.proto b/net_handler/protos/run_mode.proto index c0178fd4..54f3999b 100644 --- a/net_handler/protos/run_mode.proto +++ b/net_handler/protos/run_mode.proto @@ -7,13 +7,13 @@ syntax = "proto3"; option optimize_for = LITE_RUNTIME; enum Mode { - IDLE = 0; - AUTO = 1; - TELEOP = 2; - ESTOP = 3; - CHALLENGE = 4; + IDLE = 0; + AUTO = 1; + TELEOP = 2; + ESTOP = 3; + CHALLENGE = 4; } message RunMode { - Mode mode = 1; + Mode mode = 1; } diff --git a/net_handler/protos/start_pos.proto b/net_handler/protos/start_pos.proto index 8ef0bdc1..fc252370 100644 --- a/net_handler/protos/start_pos.proto +++ b/net_handler/protos/start_pos.proto @@ -4,11 +4,11 @@ syntax = "proto3"; option optimize_for = LITE_RUNTIME; -enum Pos { //we can add more start positions in the future - LEFT = 0; - RIGHT = 1; +enum Pos { //we can add more start positions in the future + LEFT = 0; + RIGHT = 1; } message StartPos { - Pos pos = 1; + Pos pos = 1; } \ No newline at end of file diff --git a/net_handler/protos/text.proto b/net_handler/protos/text.proto index ff6c7469..94d1efc7 100644 --- a/net_handler/protos/text.proto +++ b/net_handler/protos/text.proto @@ -7,6 +7,6 @@ syntax = "proto3"; option optimize_for = LITE_RUNTIME; message Text { - repeated string payload = 1; //CHALLENGE_DATA: initial values or results of challenges - //LOG: list of log lines + repeated string payload = 1; //CHALLENGE_DATA: initial values or results of challenges + //LOG: list of log lines } diff --git a/net_handler/tcp_conn.c b/net_handler/tcp_conn.c index 114946ff..8abc7dab 100644 --- a/net_handler/tcp_conn.c +++ b/net_handler/tcp_conn.c @@ -2,11 +2,11 @@ //used for creating and cleaning up TCP connection typedef struct { - int conn_fd; - int challenge_fd; - int send_logs; - FILE *log_file; - robot_desc_field_t client; + int conn_fd; + int challenge_fd; + int send_logs; + FILE* log_file; + robot_desc_field_t client; } tcp_conn_args_t; pthread_t dawn_tid, shepherd_tid; @@ -16,28 +16,27 @@ pthread_t dawn_tid, shepherd_tid; * Arguments: * - void *args: should be a pointer to tcp_conn_args_t populated with the listed descriptors and pointers */ -static void tcp_conn_cleanup (void *args) -{ - tcp_conn_args_t* tcp_args = (tcp_conn_args_t *) args; - robot_desc_write(RUN_MODE, IDLE); - - if (close(tcp_args->conn_fd) != 0) { - log_printf(ERROR, "Failed to close conn_fd: %s", strerror(errno)); - } - if (close(tcp_args->challenge_fd) != 0) { - log_printf(ERROR, "Failed to close challenge_fd: %s", strerror(errno)); - } - if (tcp_args->log_file != NULL) { - if (fclose(tcp_args->log_file) != 0) { - log_printf(ERROR, "Failed to close log_file: %s", strerror(errno)); - } - tcp_args->log_file = NULL; - } - robot_desc_write(tcp_args->client, DISCONNECTED); - if (tcp_args->client == DAWN) { - robot_desc_write(GAMEPAD, DISCONNECTED); // Disconnect gamepad if Dawn is no longer connected - } - free(args); +static void tcp_conn_cleanup(void* args) { + tcp_conn_args_t* tcp_args = (tcp_conn_args_t*) args; + robot_desc_write(RUN_MODE, IDLE); + + if (close(tcp_args->conn_fd) != 0) { + log_printf(ERROR, "Failed to close conn_fd: %s", strerror(errno)); + } + if (close(tcp_args->challenge_fd) != 0) { + log_printf(ERROR, "Failed to close challenge_fd: %s", strerror(errno)); + } + if (tcp_args->log_file != NULL) { + if (fclose(tcp_args->log_file) != 0) { + log_printf(ERROR, "Failed to close log_file: %s", strerror(errno)); + } + tcp_args->log_file = NULL; + } + robot_desc_write(tcp_args->client, DISCONNECTED); + if (tcp_args->client == DAWN) { + robot_desc_write(GAMEPAD, DISCONNECTED); // Disconnect gamepad if Dawn is no longer connected + } + free(args); } @@ -47,49 +46,48 @@ static void tcp_conn_cleanup (void *args) * Arguments: * - int conn_fd: socket connection's file descriptor on which to write to the TCP port */ -static void send_log_msg (int conn_fd, FILE *log_file) -{ - char nextline[MAX_LOG_LEN]; //next log line read from FIFO pipe - Text log_msg = TEXT__INIT; //initialize a new Text protobuf message - log_msg.n_payload = 0; - log_msg.payload = malloc(MAX_NUM_LOGS * sizeof(char *)); - - //read in log lines until there are no more to read, or we read MAX_NUM_LOGS lines - while (log_msg.n_payload < MAX_NUM_LOGS) { - if (fgets(nextline, MAX_LOG_LEN, log_file) != NULL) { - log_msg.payload[log_msg.n_payload] = malloc(strlen(nextline) + 1); - strcpy(log_msg.payload[log_msg.n_payload], nextline); - log_msg.n_payload++; - } else if (feof(log_file) != 0) { // All write ends of FIFO are closed, don't send any more logs - if (log_msg.n_payload != 0) { //if a few last logs to send, break to send those logs - break; - } else { //otherwise, return immediately - return; - } - } else if (errno == EAGAIN || errno == EWOULDBLOCK) { // No more to read on pipe (would block in a blocking read) - break; - } else { // Error occurred - log_printf(ERROR, "send_log_msg: Error reading from log fifo: %s", strerror(errno)); - return; - } - } - - //prepare the message for sending - uint16_t len_pb = text__get_packed_size(&log_msg); - uint8_t* send_buf = make_buf(LOG_MSG, len_pb); - text__pack(&log_msg, send_buf + BUFFER_OFFSET); //pack message into the rest of send_buf (starting at send_buf[3] onward) - - //send message on socket - if (writen(conn_fd, send_buf, len_pb + BUFFER_OFFSET) == -1) { - log_printf(ERROR, "send_log_msg: sending log message over socket failed: %s", strerror(errno)); - } - - //free all allocated memory - for (int i = 0; i < log_msg.n_payload; i++) { - free(log_msg.payload[i]); - } - free(log_msg.payload); - free(send_buf); +static void send_log_msg(int conn_fd, FILE* log_file) { + char nextline[MAX_LOG_LEN]; //next log line read from FIFO pipe + Text log_msg = TEXT__INIT; //initialize a new Text protobuf message + log_msg.n_payload = 0; + log_msg.payload = malloc(MAX_NUM_LOGS * sizeof(char*)); + + //read in log lines until there are no more to read, or we read MAX_NUM_LOGS lines + while (log_msg.n_payload < MAX_NUM_LOGS) { + if (fgets(nextline, MAX_LOG_LEN, log_file) != NULL) { + log_msg.payload[log_msg.n_payload] = malloc(strlen(nextline) + 1); + strcpy(log_msg.payload[log_msg.n_payload], nextline); + log_msg.n_payload++; + } else if (feof(log_file) != 0) { // All write ends of FIFO are closed, don't send any more logs + if (log_msg.n_payload != 0) { //if a few last logs to send, break to send those logs + break; + } else { //otherwise, return immediately + return; + } + } else if (errno == EAGAIN || errno == EWOULDBLOCK) { // No more to read on pipe (would block in a blocking read) + break; + } else { // Error occurred + log_printf(ERROR, "send_log_msg: Error reading from log fifo: %s", strerror(errno)); + return; + } + } + + //prepare the message for sending + uint16_t len_pb = text__get_packed_size(&log_msg); + uint8_t* send_buf = make_buf(LOG_MSG, len_pb); + text__pack(&log_msg, send_buf + BUFFER_OFFSET); //pack message into the rest of send_buf (starting at send_buf[3] onward) + + //send message on socket + if (writen(conn_fd, send_buf, len_pb + BUFFER_OFFSET) == -1) { + log_printf(ERROR, "send_log_msg: sending log message over socket failed: %s", strerror(errno)); + } + + //free all allocated memory + for (int i = 0; i < log_msg.n_payload; i++) { + free(log_msg.payload[i]); + } + free(log_msg.payload); + free(send_buf); } @@ -101,23 +99,23 @@ static void send_log_msg (int conn_fd, FILE *log_file) * - int challenge_fd: Unix socket connection's file descriptor from which to read challenge results from executor */ static void send_challenge_results(int conn_fd, int challenge_fd) { - // Get results from executor - int buf_size = 256; - char read_buf[buf_size]; - - int read_len = recvfrom(challenge_fd, read_buf, buf_size, 0, NULL, NULL); - if (read_len == buf_size) { - log_printf(WARN, "send_challenge_results: read length matches size of read buffer %d", read_len); - } - if (read_len < 0) { - log_printf(ERROR, "send_challenge_results: socket recv from challenge_fd failed: %s", strerror(errno)); - return; - } - - // Send results to client - if (writen(conn_fd, read_buf, read_len) == -1) { - log_printf(ERROR, "send_challenge_results: sending challenge data message failed: %s", strerror(errno)); - } + // Get results from executor + int buf_size = 256; + char read_buf[buf_size]; + + int read_len = recvfrom(challenge_fd, read_buf, buf_size, 0, NULL, NULL); + if (read_len == buf_size) { + log_printf(WARN, "send_challenge_results: read length matches size of read buffer %d", read_len); + } + if (read_len < 0) { + log_printf(ERROR, "send_challenge_results: socket recv from challenge_fd failed: %s", strerror(errno)); + return; + } + + // Send results to client + if (writen(conn_fd, read_buf, read_len) == -1) { + log_printf(ERROR, "send_challenge_results: sending challenge data message failed: %s", strerror(errno)); + } } @@ -131,120 +129,114 @@ static void send_challenge_results(int conn_fd, int challenge_fd) { * -1 if message could not be parsed because client disconnected and connection closed * -2 if message could not be unpacked or other error */ -static int recv_new_msg (int conn_fd, int challenge_fd) -{ - net_msg_t msg_type; //message type - uint16_t len_pb; //length of incoming serialized protobuf message - uint8_t* buf; //buffer to read raw data into - - int err = parse_msg(conn_fd, &msg_type, &len_pb, &buf); - if (err == 0) { // Means there is EOF while reading which means client disconnected - return -1; - } - else if (err == -1) { // Means there is some other error while reading - return -2; - } - - //unpack according to message - if (msg_type == CHALLENGE_DATA_MSG) { - //socket address structure for the UNIX socket to executor for challenge data - struct sockaddr_un exec_addr = {0}; - exec_addr.sun_family = AF_UNIX; - strcpy(exec_addr.sun_path, CHALLENGE_SOCKET); - - int send_len = sendto(challenge_fd, buf, len_pb, 0, (struct sockaddr*) &exec_addr, sizeof(struct sockaddr_un)); - if (send_len < 0) { - log_printf(ERROR, "recv_new_msg: socket send to challenge_fd failed: %s", strerror(errno)); - return -2; - } - if (send_len != len_pb) { - log_printf(WARN, "recv_new_msg: socket send len %d is not equal to intended protobuf length %d", send_len, len_pb); - } - - log_printf(DEBUG, "entering CHALLENGE mode. running coding challenges!"); - robot_desc_write(RUN_MODE, CHALLENGE); - } - else if (msg_type == RUN_MODE_MSG) { - RunMode* run_mode_msg = run_mode__unpack(NULL, len_pb, buf); - if (run_mode_msg == NULL) { - log_printf(ERROR, "recv_new_msg: Cannot unpack run_mode msg"); - return -2; - } - - //write the specified run mode to the RUN_MODE field of the robot description - switch (run_mode_msg->mode) { - case (MODE__IDLE): - log_printf(DEBUG, "entering IDLE mode"); - robot_desc_write(RUN_MODE, IDLE); - break; - case (MODE__AUTO): - log_printf(DEBUG, "entering AUTO mode"); - robot_desc_write(RUN_MODE, AUTO); - break; - case (MODE__TELEOP): - log_printf(DEBUG, "entering TELEOP mode"); - robot_desc_write(RUN_MODE, TELEOP); - break; - case (MODE__ESTOP): - log_printf(DEBUG, "ESTOP RECEIVED! entering IDLE mode"); - robot_desc_write(RUN_MODE, IDLE); - break; - default: - log_printf(ERROR, "recv_new_msg: requested robot to enter invalid robot mode %s", run_mode_msg->mode); - break; - } - run_mode__free_unpacked(run_mode_msg, NULL); - } - else if (msg_type == START_POS_MSG) { - StartPos* start_pos_msg = start_pos__unpack(NULL, len_pb, buf); - if (start_pos_msg == NULL) { - log_printf(ERROR, "recv_new_msg: Cannot unpack start_pos msg"); - return -2; - } - - //write the specified start pos to the STARTPOS field of the robot description - switch (start_pos_msg->pos) { - case (POS__LEFT): - log_printf(DEBUG, "robot is in LEFT start position"); - robot_desc_write(START_POS, LEFT); - break; - case (POS__RIGHT): - log_printf(DEBUG, "robot is in RIGHT start position"); - robot_desc_write(START_POS, RIGHT); - break; - default: - log_printf(ERROR, "recv_new_msg: trying to enter unknown start position %d", start_pos_msg->pos); - break; - } - start_pos__free_unpacked(start_pos_msg, NULL); - } - else if (msg_type == DEVICE_DATA_MSG) { - DevData* dev_data_msg = dev_data__unpack(NULL, len_pb, buf); - if (dev_data_msg == NULL) { - log_printf(ERROR, "recv_new_msg: Cannot unpack dev_data msg"); - return -2; - } - for (int i = 0; i < dev_data_msg->n_devices; i++) { - Device* req_device = dev_data_msg->devices[i]; - uint32_t requests = 0; - for (int j = 0; j < req_device->n_params; j++) { - if (req_device->params[i]->val_case == PARAM__VAL_BVAL) { - requests |= (req_device->params[j]->bval << j); - } - } - int err = place_sub_request(req_device->uid, NET_HANDLER, requests); - if (err == -1) { - log_printf(ERROR, "recv_new_msg: Invalid device subscription, device uid %llu is invalid", req_device->uid); - } - } - dev_data__free_unpacked(dev_data_msg, NULL); - } - else { - log_printf(ERROR, "recv_new_msg: unknown message type %d, tcp should only receive CHALLENGE_DATA (2), RUN_MODE (0), START_POS (1), or DEVICE_DATA (4)", msg_type); - return -2; - } - free(buf); - return 0; +static int recv_new_msg(int conn_fd, int challenge_fd) { + net_msg_t msg_type; //message type + uint16_t len_pb; //length of incoming serialized protobuf message + uint8_t* buf; //buffer to read raw data into + + int err = parse_msg(conn_fd, &msg_type, &len_pb, &buf); + if (err == 0) { // Means there is EOF while reading which means client disconnected + return -1; + } else if (err == -1) { // Means there is some other error while reading + return -2; + } + + //unpack according to message + if (msg_type == CHALLENGE_DATA_MSG) { + //socket address structure for the UNIX socket to executor for challenge data + struct sockaddr_un exec_addr = {0}; + exec_addr.sun_family = AF_UNIX; + strcpy(exec_addr.sun_path, CHALLENGE_SOCKET); + + int send_len = sendto(challenge_fd, buf, len_pb, 0, (struct sockaddr*) &exec_addr, sizeof(struct sockaddr_un)); + if (send_len < 0) { + log_printf(ERROR, "recv_new_msg: socket send to challenge_fd failed: %s", strerror(errno)); + return -2; + } + if (send_len != len_pb) { + log_printf(WARN, "recv_new_msg: socket send len %d is not equal to intended protobuf length %d", send_len, len_pb); + } + + log_printf(DEBUG, "entering CHALLENGE mode. running coding challenges!"); + robot_desc_write(RUN_MODE, CHALLENGE); + } else if (msg_type == RUN_MODE_MSG) { + RunMode* run_mode_msg = run_mode__unpack(NULL, len_pb, buf); + if (run_mode_msg == NULL) { + log_printf(ERROR, "recv_new_msg: Cannot unpack run_mode msg"); + return -2; + } + + //write the specified run mode to the RUN_MODE field of the robot description + switch (run_mode_msg->mode) { + case (MODE__IDLE): + log_printf(DEBUG, "entering IDLE mode"); + robot_desc_write(RUN_MODE, IDLE); + break; + case (MODE__AUTO): + log_printf(DEBUG, "entering AUTO mode"); + robot_desc_write(RUN_MODE, AUTO); + break; + case (MODE__TELEOP): + log_printf(DEBUG, "entering TELEOP mode"); + robot_desc_write(RUN_MODE, TELEOP); + break; + case (MODE__ESTOP): + log_printf(DEBUG, "ESTOP RECEIVED! entering IDLE mode"); + robot_desc_write(RUN_MODE, IDLE); + break; + default: + log_printf(ERROR, "recv_new_msg: requested robot to enter invalid robot mode %s", run_mode_msg->mode); + break; + } + run_mode__free_unpacked(run_mode_msg, NULL); + } else if (msg_type == START_POS_MSG) { + StartPos* start_pos_msg = start_pos__unpack(NULL, len_pb, buf); + if (start_pos_msg == NULL) { + log_printf(ERROR, "recv_new_msg: Cannot unpack start_pos msg"); + return -2; + } + + //write the specified start pos to the STARTPOS field of the robot description + switch (start_pos_msg->pos) { + case (POS__LEFT): + log_printf(DEBUG, "robot is in LEFT start position"); + robot_desc_write(START_POS, LEFT); + break; + case (POS__RIGHT): + log_printf(DEBUG, "robot is in RIGHT start position"); + robot_desc_write(START_POS, RIGHT); + break; + default: + log_printf(ERROR, "recv_new_msg: trying to enter unknown start position %d", start_pos_msg->pos); + break; + } + start_pos__free_unpacked(start_pos_msg, NULL); + } else if (msg_type == DEVICE_DATA_MSG) { + DevData* dev_data_msg = dev_data__unpack(NULL, len_pb, buf); + if (dev_data_msg == NULL) { + log_printf(ERROR, "recv_new_msg: Cannot unpack dev_data msg"); + return -2; + } + for (int i = 0; i < dev_data_msg->n_devices; i++) { + Device* req_device = dev_data_msg->devices[i]; + uint32_t requests = 0; + for (int j = 0; j < req_device->n_params; j++) { + if (req_device->params[i]->val_case == PARAM__VAL_BVAL) { + requests |= (req_device->params[j]->bval << j); + } + } + int err = place_sub_request(req_device->uid, NET_HANDLER, requests); + if (err == -1) { + log_printf(ERROR, "recv_new_msg: Invalid device subscription, device uid %llu is invalid", req_device->uid); + } + } + dev_data__free_unpacked(dev_data_msg, NULL); + } else { + log_printf(ERROR, "recv_new_msg: unknown message type %d, tcp should only receive CHALLENGE_DATA (2), RUN_MODE (0), START_POS (1), or DEVICE_DATA (4)", msg_type); + return -2; + } + free(buf); + return 0; } @@ -256,143 +248,138 @@ static int recv_new_msg (int conn_fd, int challenge_fd) * Return: * - NULL */ -static void* tcp_process (void* tcp_args) -{ - tcp_conn_args_t* args = (tcp_conn_args_t*) tcp_args; - pthread_cleanup_push(tcp_conn_cleanup, args); - - //variables used for waiting for something to do using select() - fd_set read_set; - int log_fd; - int maxfd = args->challenge_fd > args->conn_fd ? args->challenge_fd : args->conn_fd; - if (args->send_logs) { - log_fd = fileno(args->log_file); - maxfd = log_fd > maxfd ? log_fd : maxfd; - } - maxfd = maxfd + 1; - - //main control loop that is responsible for sending and receiving data - while (1) { - //set up the read_set argument to selct() - FD_ZERO(&read_set); - FD_SET(args->conn_fd, &read_set); - FD_SET(args->challenge_fd, &read_set); - if (args->send_logs) { - FD_SET(log_fd, &read_set); - } - - //prepare to accept cancellation requests over the select - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - - //wait for something to happen - if (select(maxfd, &read_set, NULL, NULL, NULL) < 0) { - log_printf(ERROR, "tcp_process: Failed to wait for select in control loop for client %d: %s", args->client, strerror(errno)); - } - - //deny all cancellation requests until the next loop - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - - //send a new log message if one is available and we want to send logs - if (args->send_logs && FD_ISSET(log_fd, &read_set)) { - send_log_msg(args->conn_fd, args->log_file); - } - - //send challenge results if executor sent them - if (FD_ISSET(args->challenge_fd, &read_set)) { - send_challenge_results(args->conn_fd, args->challenge_fd); - } - - //receive new message on socket if it is ready - if (FD_ISSET(args->conn_fd, &read_set)) { - if (recv_new_msg(args->conn_fd, args->challenge_fd) == -1) { - log_printf(DEBUG, "client %d has disconnected", args->client); - break; - } - } - } - - //call the cleanup function - pthread_cleanup_pop(1); - return NULL; +static void* tcp_process(void* tcp_args) { + tcp_conn_args_t* args = (tcp_conn_args_t*) tcp_args; + pthread_cleanup_push(tcp_conn_cleanup, args); + + //variables used for waiting for something to do using select() + fd_set read_set; + int log_fd; + int maxfd = args->challenge_fd > args->conn_fd ? args->challenge_fd : args->conn_fd; + if (args->send_logs) { + log_fd = fileno(args->log_file); + maxfd = log_fd > maxfd ? log_fd : maxfd; + } + maxfd = maxfd + 1; + + //main control loop that is responsible for sending and receiving data + while (1) { + //set up the read_set argument to selct() + FD_ZERO(&read_set); + FD_SET(args->conn_fd, &read_set); + FD_SET(args->challenge_fd, &read_set); + if (args->send_logs) { + FD_SET(log_fd, &read_set); + } + + //prepare to accept cancellation requests over the select + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + //wait for something to happen + if (select(maxfd, &read_set, NULL, NULL, NULL) < 0) { + log_printf(ERROR, "tcp_process: Failed to wait for select in control loop for client %d: %s", args->client, strerror(errno)); + } + + //deny all cancellation requests until the next loop + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + //send a new log message if one is available and we want to send logs + if (args->send_logs && FD_ISSET(log_fd, &read_set)) { + send_log_msg(args->conn_fd, args->log_file); + } + + //send challenge results if executor sent them + if (FD_ISSET(args->challenge_fd, &read_set)) { + send_challenge_results(args->conn_fd, args->challenge_fd); + } + + //receive new message on socket if it is ready + if (FD_ISSET(args->conn_fd, &read_set)) { + if (recv_new_msg(args->conn_fd, args->challenge_fd) == -1) { + log_printf(DEBUG, "client %d has disconnected", args->client); + break; + } + } + } + + //call the cleanup function + pthread_cleanup_pop(1); + return NULL; } /************************ PUBLIC FUNCTIONS *************************/ -void start_tcp_conn (robot_desc_field_t client, int conn_fd, int send_logs) -{ - pthread_t* tid; - if (client == DAWN) { - tid = &dawn_tid; - } - else if (client == SHEPHERD) { - tid = &shepherd_tid; - } - else { - log_printf(ERROR, "start_tcp_conn: Invalid TCP client %d, not DAWN(%d) or SHEPHERD(%d)", client, DAWN, SHEPHERD); - return; - } - - //initialize argument to new connection thread - tcp_conn_args_t* args = malloc(sizeof(tcp_conn_args_t)); - args->client = client; - args->conn_fd = conn_fd; - args->send_logs = send_logs; - args->log_file = NULL; - args->challenge_fd = -1; - - // open challenge socket to read and write - if ((args->challenge_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { - log_printf(ERROR, "start_tcp_conn: failed to create challenge socket: %s", strerror(errno)); - return; - } - struct sockaddr_un my_addr = {0}; - my_addr.sun_family = AF_UNIX; - if (bind(args->challenge_fd, (struct sockaddr *) &my_addr, sizeof(sa_family_t)) < 0) { - log_printf(FATAL, "start_tcp_conn: challenge socket bind failed: %s", strerror(errno)); - close(args->challenge_fd); - return; - } - - //Open FIFO pipe for logs - if (send_logs) { - int log_fd; - if ((log_fd = open(LOG_FIFO, O_RDONLY | O_NONBLOCK)) == -1) { - log_printf(ERROR, "start_tcp_conn: could not open log FIFO on %d: %s", args->client, strerror(errno)); - close(args->challenge_fd); - return; - } - if ((args->log_file = fdopen(log_fd, "r")) == NULL) { - log_printf(ERROR, "start_tcp_conn: could not open log file from fd: %s", strerror(errno)); - close(args->challenge_fd); - close(log_fd); - return; - } - } - - //create the main control thread for this client - if (pthread_create(tid, NULL, tcp_process, args) != 0) { - log_printf(ERROR, "start_tcp_conn: Failed to create main TCP thread for %d: %s", client, strerror(errno)); - return; - } - robot_desc_write(client, CONNECTED); +void start_tcp_conn(robot_desc_field_t client, int conn_fd, int send_logs) { + pthread_t* tid; + if (client == DAWN) { + tid = &dawn_tid; + } else if (client == SHEPHERD) { + tid = &shepherd_tid; + } else { + log_printf(ERROR, "start_tcp_conn: Invalid TCP client %d, not DAWN(%d) or SHEPHERD(%d)", client, DAWN, SHEPHERD); + return; + } + + //initialize argument to new connection thread + tcp_conn_args_t* args = malloc(sizeof(tcp_conn_args_t)); + args->client = client; + args->conn_fd = conn_fd; + args->send_logs = send_logs; + args->log_file = NULL; + args->challenge_fd = -1; + + // open challenge socket to read and write + if ((args->challenge_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { + log_printf(ERROR, "start_tcp_conn: failed to create challenge socket: %s", strerror(errno)); + return; + } + struct sockaddr_un my_addr = {0}; + my_addr.sun_family = AF_UNIX; + if (bind(args->challenge_fd, (struct sockaddr*) &my_addr, sizeof(sa_family_t)) < 0) { + log_printf(FATAL, "start_tcp_conn: challenge socket bind failed: %s", strerror(errno)); + close(args->challenge_fd); + return; + } + + //Open FIFO pipe for logs + if (send_logs) { + int log_fd; + if ((log_fd = open(LOG_FIFO, O_RDONLY | O_NONBLOCK)) == -1) { + log_printf(ERROR, "start_tcp_conn: could not open log FIFO on %d: %s", args->client, strerror(errno)); + close(args->challenge_fd); + return; + } + if ((args->log_file = fdopen(log_fd, "r")) == NULL) { + log_printf(ERROR, "start_tcp_conn: could not open log file from fd: %s", strerror(errno)); + close(args->challenge_fd); + close(log_fd); + return; + } + } + + //create the main control thread for this client + if (pthread_create(tid, NULL, tcp_process, args) != 0) { + log_printf(ERROR, "start_tcp_conn: Failed to create main TCP thread for %d: %s", client, strerror(errno)); + return; + } + robot_desc_write(client, CONNECTED); } -void stop_tcp_conn (robot_desc_field_t client) -{ - if (client != DAWN && client != SHEPHERD) { - log_printf(ERROR, "stop_tcp_conn: Invalid TCP client %d, not DAWN(%d) or SHEPHERD(%d)", client, DAWN, SHEPHERD); - return; - } - - pthread_t tid = (client == DAWN) ? dawn_tid : shepherd_tid; - - if (pthread_cancel(tid) != 0) { - log_printf(ERROR, "stop_tcp_conn: Failed to cancel TCP client thread for %d: %s", client, strerror(errno)); - } - if (pthread_join(tid, NULL) != 0) { - log_printf(ERROR, "stop_tcp_conn: Failed to join on TCP client thread for %d: %s", client, strerror(errno)); - } +void stop_tcp_conn(robot_desc_field_t client) { + if (client != DAWN && client != SHEPHERD) { + log_printf(ERROR, "stop_tcp_conn: Invalid TCP client %d, not DAWN(%d) or SHEPHERD(%d)", client, DAWN, SHEPHERD); + return; + } + + pthread_t tid = (client == DAWN) ? dawn_tid : shepherd_tid; + + if (pthread_cancel(tid) != 0) { + log_printf(ERROR, "stop_tcp_conn: Failed to cancel TCP client thread for %d: %s", client, strerror(errno)); + } + if (pthread_join(tid, NULL) != 0) { + log_printf(ERROR, "stop_tcp_conn: Failed to join on TCP client thread for %d: %s", client, strerror(errno)); + } } diff --git a/net_handler/tcp_conn.h b/net_handler/tcp_conn.h index 9a19e39e..17938657 100644 --- a/net_handler/tcp_conn.h +++ b/net_handler/tcp_conn.h @@ -12,7 +12,7 @@ * - connfd: connection socket descriptor on which there is the established connection with Dawn * - send_logs: whether to send logs over TCP to client. DAWN should receive logs and SHEPHERD should not */ -void start_tcp_conn (robot_desc_field_t client, int connfd, int send_logs); +void start_tcp_conn(robot_desc_field_t client, int connfd, int send_logs); /** * Stops the TCP connection control thread cleanly. May block briefly to allow @@ -21,6 +21,6 @@ void start_tcp_conn (robot_desc_field_t client, int connfd, int send_logs); * Args: * - client: which client to stop communicating with, either DAWN or SHEPHERD */ -void stop_tcp_conn (robot_desc_field_t client); +void stop_tcp_conn(robot_desc_field_t client); #endif \ No newline at end of file diff --git a/net_handler/udp_conn.c b/net_handler/udp_conn.c index b1fc4f2e..7d8b594c 100644 --- a/net_handler/udp_conn.c +++ b/net_handler/udp_conn.c @@ -1,259 +1,254 @@ #include "udp_conn.h" -pthread_t gp_thread, device_thread; // thread IDs for receiving gamepad data and sending device data -int socket_fd = -1; // the UDP socket's file descriptor -struct sockaddr_in dawn_addr = {0}; // the address of our client, which should be Dawn -socklen_t addr_len = sizeof(struct sockaddr_in); // length of the address +pthread_t gp_thread, device_thread; // thread IDs for receiving gamepad data and sending device data +int socket_fd = -1; // the UDP socket's file descriptor +struct sockaddr_in dawn_addr = {0}; // the address of our client, which should be Dawn +socklen_t addr_len = sizeof(struct sockaddr_in); // length of the address -uint64_t start_time; // the time that Runtime/net_handler was started, in milliseconds since the UNIX epoch +uint64_t start_time; // the time that Runtime/net_handler was started, in milliseconds since the UNIX epoch static void* send_device_data(void* args) { - int len; - uint8_t* buffer; - int err; - // Needed to wait for UDP client to talk to us - while(dawn_addr.sin_family == 0) { - sleep(1); - } - - uint32_t sub_map[MAX_DEVICES + 1]; - dev_id_t dev_ids[MAX_DEVICES]; - int valid_dev_idxs[MAX_DEVICES]; - uint32_t catalog; - - param_val_t custom_params[UCHAR_MAX]; - param_type_t custom_types[UCHAR_MAX]; - char custom_names[UCHAR_MAX][64]; - uint8_t num_params; - - while (1) { - DevData dev_data = DEV_DATA__INIT; - - //get information - get_catalog(&catalog); - get_sub_requests(sub_map, NET_HANDLER); - get_device_identifiers(dev_ids); - - //calculate num_devices, get valid device indices - int num_devices = 0; - for (int i = 0; i < MAX_DEVICES; i++) { - if (catalog & (1 << i)) { - valid_dev_idxs[num_devices] = i; - num_devices++; - } - } - dev_data.devices = malloc((num_devices + 1) * sizeof(Device *)); // + 1 is for custom data - - //populate dev_data.device[i] - int dev_idx = 0; - for (int i = 0; i < num_devices; i++) { - int idx = valid_dev_idxs[i]; - device_t* device_info = get_device(dev_ids[idx].type); - if (device_info == NULL) { - log_printf(ERROR, "send_device_data: Device %d in SHM with type %d is invalid", idx, dev_ids[idx].type); - continue; - } - - Device* device = malloc(sizeof(Device)); - device__init(device); - dev_data.devices[dev_idx] = device; - device->type = dev_ids[idx].type; - device->uid = dev_ids[idx].uid; - device->name = device_info->name; - - device->n_params = 0; - param_val_t param_data[MAX_PARAMS]; - device_read_uid(device->uid, NET_HANDLER, DATA, sub_map[idx + 1], param_data); - - device->params = malloc(device_info->num_params * sizeof(Param*)); - //populate device parameters - for (int j = 0; j < device_info->num_params; j++) { - if (sub_map[idx + 1] & (1 << j)) { - Param* param = malloc(sizeof(Param)); - param__init(param); - param->name = device_info->params[j].name; - switch (device_info->params[j].type) { - case INT: - param->val_case = PARAM__VAL_IVAL; - param->ival = param_data[j].p_i; - break; - case FLOAT: - param->val_case = PARAM__VAL_FVAL; - param->fval = param_data[j].p_f; - break; - case BOOL: - param->val_case = PARAM__VAL_BVAL; - param->bval = param_data[j].p_b; - break; - } - device->params[device->n_params] = param; - device->n_params++; - } - } - dev_idx++; - } - - // Add custom log data to protobuf - Device* custom = malloc(sizeof(Device)); - device__init(custom); - dev_data.devices[dev_idx] = custom; - log_data_read(&num_params, custom_names, custom_types, custom_params); - custom->n_params = num_params + 1; // + 1 is for the current time - custom->params = malloc(sizeof(Param*) * custom->n_params); - custom->name = "CustomData"; - custom->type = MAX_DEVICES; - custom->uid = 0; - for (int i = 0; i < custom->n_params; i++) { - Param* param = malloc(sizeof(Param)); - param__init(param); - custom->params[i] = param; - param->name = custom_names[i]; - switch (custom_types[i]) { - case INT: - param->val_case = PARAM__VAL_IVAL; - param->ival = custom_params[i].p_i; - break; - case FLOAT: - param->val_case = PARAM__VAL_FVAL; - param->fval = custom_params[i].p_f; - break; - case BOOL: - param->val_case = PARAM__VAL_BVAL; - param->bval = custom_params[i].p_b; - break; - } - } - Param* time = malloc(sizeof(Param)); - param__init(time); - custom->params[num_params] = time; - time->name = "time_ms"; - time->val_case = PARAM__VAL_IVAL; - time->ival = millis() - start_time; // Can only give difference in millisecond since robot start since it is int32, not int64 - - dev_data.n_devices = dev_idx + 1; // + 1 is for custom data - - len = dev_data__get_packed_size(&dev_data); - buffer = malloc(len); - dev_data__pack(&dev_data, buffer); - - //send data to Dawn - err = sendto(socket_fd, buffer, len, 0, (struct sockaddr*) &dawn_addr, addr_len); - if (err < 0) { - log_printf(ERROR, "send_device_data: UDP sendto failed: %s", strerror(errno)); - } - else if (err != len) { - log_printf(WARN, "send_device_data: Didn't send all data to Dawn UDP socket. send buffer length %d, actual sent %d", len, err); - } - - //free everything - for (int i = 0; i < dev_data.n_devices; i++) { - for (int j = 0; j < dev_data.devices[i]->n_params; j++) { - free(dev_data.devices[i]->params[j]); - } - free(dev_data.devices[i]->params); - free(dev_data.devices[i]); - } - free(dev_data.devices); - free(buffer); // Free buffer with device data protobuf - usleep(10000); // Send data at 100 Hz - } - return NULL; + int len; + uint8_t* buffer; + int err; + // Needed to wait for UDP client to talk to us + while (dawn_addr.sin_family == 0) { + sleep(1); + } + + uint32_t sub_map[MAX_DEVICES + 1]; + dev_id_t dev_ids[MAX_DEVICES]; + int valid_dev_idxs[MAX_DEVICES]; + uint32_t catalog; + + param_val_t custom_params[UCHAR_MAX]; + param_type_t custom_types[UCHAR_MAX]; + char custom_names[UCHAR_MAX][64]; + uint8_t num_params; + + while (1) { + DevData dev_data = DEV_DATA__INIT; + + //get information + get_catalog(&catalog); + get_sub_requests(sub_map, NET_HANDLER); + get_device_identifiers(dev_ids); + + //calculate num_devices, get valid device indices + int num_devices = 0; + for (int i = 0; i < MAX_DEVICES; i++) { + if (catalog & (1 << i)) { + valid_dev_idxs[num_devices] = i; + num_devices++; + } + } + dev_data.devices = malloc((num_devices + 1) * sizeof(Device*)); // + 1 is for custom data + + //populate dev_data.device[i] + int dev_idx = 0; + for (int i = 0; i < num_devices; i++) { + int idx = valid_dev_idxs[i]; + device_t* device_info = get_device(dev_ids[idx].type); + if (device_info == NULL) { + log_printf(ERROR, "send_device_data: Device %d in SHM with type %d is invalid", idx, dev_ids[idx].type); + continue; + } + + Device* device = malloc(sizeof(Device)); + device__init(device); + dev_data.devices[dev_idx] = device; + device->type = dev_ids[idx].type; + device->uid = dev_ids[idx].uid; + device->name = device_info->name; + + device->n_params = 0; + param_val_t param_data[MAX_PARAMS]; + device_read_uid(device->uid, NET_HANDLER, DATA, sub_map[idx + 1], param_data); + + device->params = malloc(device_info->num_params * sizeof(Param*)); + //populate device parameters + for (int j = 0; j < device_info->num_params; j++) { + if (sub_map[idx + 1] & (1 << j)) { + Param* param = malloc(sizeof(Param)); + param__init(param); + param->name = device_info->params[j].name; + switch (device_info->params[j].type) { + case INT: + param->val_case = PARAM__VAL_IVAL; + param->ival = param_data[j].p_i; + break; + case FLOAT: + param->val_case = PARAM__VAL_FVAL; + param->fval = param_data[j].p_f; + break; + case BOOL: + param->val_case = PARAM__VAL_BVAL; + param->bval = param_data[j].p_b; + break; + } + device->params[device->n_params] = param; + device->n_params++; + } + } + dev_idx++; + } + + // Add custom log data to protobuf + Device* custom = malloc(sizeof(Device)); + device__init(custom); + dev_data.devices[dev_idx] = custom; + log_data_read(&num_params, custom_names, custom_types, custom_params); + custom->n_params = num_params + 1; // + 1 is for the current time + custom->params = malloc(sizeof(Param*) * custom->n_params); + custom->name = "CustomData"; + custom->type = MAX_DEVICES; + custom->uid = 0; + for (int i = 0; i < custom->n_params; i++) { + Param* param = malloc(sizeof(Param)); + param__init(param); + custom->params[i] = param; + param->name = custom_names[i]; + switch (custom_types[i]) { + case INT: + param->val_case = PARAM__VAL_IVAL; + param->ival = custom_params[i].p_i; + break; + case FLOAT: + param->val_case = PARAM__VAL_FVAL; + param->fval = custom_params[i].p_f; + break; + case BOOL: + param->val_case = PARAM__VAL_BVAL; + param->bval = custom_params[i].p_b; + break; + } + } + Param* time = malloc(sizeof(Param)); + param__init(time); + custom->params[num_params] = time; + time->name = "time_ms"; + time->val_case = PARAM__VAL_IVAL; + time->ival = millis() - start_time; // Can only give difference in millisecond since robot start since it is int32, not int64 + + dev_data.n_devices = dev_idx + 1; // + 1 is for custom data + + len = dev_data__get_packed_size(&dev_data); + buffer = malloc(len); + dev_data__pack(&dev_data, buffer); + + //send data to Dawn + err = sendto(socket_fd, buffer, len, 0, (struct sockaddr*) &dawn_addr, addr_len); + if (err < 0) { + log_printf(ERROR, "send_device_data: UDP sendto failed: %s", strerror(errno)); + } else if (err != len) { + log_printf(WARN, "send_device_data: Didn't send all data to Dawn UDP socket. send buffer length %d, actual sent %d", len, err); + } + + //free everything + for (int i = 0; i < dev_data.n_devices; i++) { + for (int j = 0; j < dev_data.devices[i]->n_params; j++) { + free(dev_data.devices[i]->params[j]); + } + free(dev_data.devices[i]->params); + free(dev_data.devices[i]); + } + free(dev_data.devices); + free(buffer); // Free buffer with device data protobuf + usleep(10000); // Send data at 100 Hz + } + return NULL; } static void* update_gamepad_state(void* args) { - static int size = sizeof(GpState); - uint8_t buffer[size]; - int recvlen; - - while (1) { - recvlen = recvfrom(socket_fd, buffer, size, 0, (struct sockaddr*) &dawn_addr, &addr_len); - // log_printf(DEBUG, "Dawn IP is %s:%d", inet_ntoa(dawn_addr.sin_addr), ntohs(dawn_addr.sin_port)); - if (recvlen == size) { - log_printf(WARN, "update_gamepad_state: UDP Read length matches read buffer size %d", recvlen); - } - if (recvlen < 0) { - log_printf(ERROR, "update_gamepad_state: UDP recvfrom failed: %s", strerror(errno)); - continue; - } - GpState* gp_state = gp_state__unpack(NULL, recvlen, buffer); - if (gp_state == NULL) { - log_printf(ERROR, "update_gamepad_state: Failed to unpack GpState"); - continue; - } - if (gp_state->n_axes != 4) { - log_printf(ERROR, "update_gamepad_state: Number of joystick axes given is %d which is not 4. Cannot update gamepad state", gp_state->n_axes); - } - else { - // display the message's fields. - // log_printf(DEBUG, "Is gamepad connected: %d. Received: buttons = %d\n\taxes:", gp_state->connected, gp_state->buttons); - // for (int i = 0; i < gp_state->n_axes; i++) { - // log_printf(PYTHON, "\t%f", gp_state->axes[i]); - // } - // log_printf(PYTHON, "\n"); - - robot_desc_write(GAMEPAD, gp_state->connected ? CONNECTED : DISCONNECTED); - if (gp_state->connected) { - gamepad_write(gp_state->buttons, gp_state->axes); - } - } - gp_state__free_unpacked(gp_state, NULL); - memset(buffer, 0, size); - } - return NULL; + static int size = sizeof(GpState); + uint8_t buffer[size]; + int recvlen; + + while (1) { + recvlen = recvfrom(socket_fd, buffer, size, 0, (struct sockaddr*) &dawn_addr, &addr_len); + // log_printf(DEBUG, "Dawn IP is %s:%d", inet_ntoa(dawn_addr.sin_addr), ntohs(dawn_addr.sin_port)); + if (recvlen == size) { + log_printf(WARN, "update_gamepad_state: UDP Read length matches read buffer size %d", recvlen); + } + if (recvlen < 0) { + log_printf(ERROR, "update_gamepad_state: UDP recvfrom failed: %s", strerror(errno)); + continue; + } + GpState* gp_state = gp_state__unpack(NULL, recvlen, buffer); + if (gp_state == NULL) { + log_printf(ERROR, "update_gamepad_state: Failed to unpack GpState"); + continue; + } + if (gp_state->n_axes != 4) { + log_printf(ERROR, "update_gamepad_state: Number of joystick axes given is %d which is not 4. Cannot update gamepad state", gp_state->n_axes); + } else { + // display the message's fields. + // log_printf(DEBUG, "Is gamepad connected: %d. Received: buttons = %d\n\taxes:", gp_state->connected, gp_state->buttons); + // for (int i = 0; i < gp_state->n_axes; i++) { + // log_printf(PYTHON, "\t%f", gp_state->axes[i]); + // } + // log_printf(PYTHON, "\n"); + + robot_desc_write(GAMEPAD, gp_state->connected ? CONNECTED : DISCONNECTED); + if (gp_state->connected) { + gamepad_write(gp_state->buttons, gp_state->axes); + } + } + gp_state__free_unpacked(gp_state, NULL); + memset(buffer, 0, size); + } + return NULL; } /******************************** PUBLIC FUNCTIONS *************************************/ -void start_udp_conn () -{ - //create the socket - if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - log_printf(ERROR, "start_udp_conn: could not create udp socket: %s", strerror(errno)); - return; - } - - //bind the socket to any valid IP address on the raspi and specified port - struct sockaddr_in my_addr = {0}; //for holding IP addresses (IPv4) - my_addr.sin_family = AF_INET; - my_addr.sin_addr.s_addr = htonl(INADDR_ANY); - my_addr.sin_port = htons(RASPI_UDP_PORT); - if (bind(socket_fd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in)) < 0) { - log_printf(ERROR, "start_udp_conn: udp socket bind failed: %s", strerror(errno)); - return; - } - - start_time = millis(); - - //create threads - if (pthread_create(&gp_thread, NULL, update_gamepad_state, NULL) != 0) { - log_printf(ERROR, "start_udp_conn: failed to create update_gamepad_state thread: %s", strerror(errno)); - return; - } - if (pthread_create(&device_thread, NULL, send_device_data, NULL) != 0) { - log_printf(ERROR, "start_udp_conn: failed to create send_device_data thread: %s", strerror(errno)); - stop_udp_conn(); - } - +void start_udp_conn() { + //create the socket + if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + log_printf(ERROR, "start_udp_conn: could not create udp socket: %s", strerror(errno)); + return; + } + + //bind the socket to any valid IP address on the raspi and specified port + struct sockaddr_in my_addr = {0}; //for holding IP addresses (IPv4) + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl(INADDR_ANY); + my_addr.sin_port = htons(RASPI_UDP_PORT); + if (bind(socket_fd, (struct sockaddr*) &my_addr, sizeof(struct sockaddr_in)) < 0) { + log_printf(ERROR, "start_udp_conn: udp socket bind failed: %s", strerror(errno)); + return; + } + + start_time = millis(); + + //create threads + if (pthread_create(&gp_thread, NULL, update_gamepad_state, NULL) != 0) { + log_printf(ERROR, "start_udp_conn: failed to create update_gamepad_state thread: %s", strerror(errno)); + return; + } + if (pthread_create(&device_thread, NULL, send_device_data, NULL) != 0) { + log_printf(ERROR, "start_udp_conn: failed to create send_device_data thread: %s", strerror(errno)); + stop_udp_conn(); + } } -void stop_udp_conn () -{ - if (pthread_cancel(gp_thread) != 0) { - log_printf(ERROR, "stop_udp_conn: failed to cancel gp_thread: %s", strerror(errno)); - } - if (pthread_cancel(device_thread) != 0) { - log_printf(ERROR, "stop_udp_conn: failed to cancel device_thread: %s", strerror(errno)); - } - if (pthread_join(gp_thread, NULL) != 0) { - log_printf(ERROR, "stop_udp_conn: failed to join gp_thread: %s", strerror(errno)); - } - if (pthread_join(device_thread, NULL) != 0) { - log_printf(ERROR, "stop_udp_conn: failed to join device_thread: %s", strerror(errno)); - } - if(close(socket_fd) != 0) { - log_printf(ERROR, "stop_udp_conn: Couldn't close UDP socket properly: %s", strerror(errno)); - } +void stop_udp_conn() { + if (pthread_cancel(gp_thread) != 0) { + log_printf(ERROR, "stop_udp_conn: failed to cancel gp_thread: %s", strerror(errno)); + } + if (pthread_cancel(device_thread) != 0) { + log_printf(ERROR, "stop_udp_conn: failed to cancel device_thread: %s", strerror(errno)); + } + if (pthread_join(gp_thread, NULL) != 0) { + log_printf(ERROR, "stop_udp_conn: failed to join gp_thread: %s", strerror(errno)); + } + if (pthread_join(device_thread, NULL) != 0) { + log_printf(ERROR, "stop_udp_conn: failed to join device_thread: %s", strerror(errno)); + } + if (close(socket_fd) != 0) { + log_printf(ERROR, "stop_udp_conn: Couldn't close UDP socket properly: %s", strerror(errno)); + } } diff --git a/net_handler/udp_conn.h b/net_handler/udp_conn.h index ceaa818b..036fe6cb 100644 --- a/net_handler/udp_conn.h +++ b/net_handler/udp_conn.h @@ -10,7 +10,7 @@ void start_udp_conn(); /** * Stop the gamepad and device threads managing the UDP connection - */ + */ void stop_udp_conn(); #endif \ No newline at end of file diff --git a/runtime_util/runtime_util.c b/runtime_util/runtime_util.c index ba6de2cf..0a1d5940 100644 --- a/runtime_util/runtime_util.c +++ b/runtime_util/runtime_util.c @@ -8,110 +8,98 @@ device_t DummyDevice = { .num_params = 16, .params = { // Read-only - {.name = "RUNTIME" , .type = INT , .read = 1, .write = 0}, - {.name = "SHEPHERD" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "DAWN" , .type = BOOL , .read = 1, .write = 0}, - {.name = "DEVOPS" , .type = INT , .read = 1, .write = 0}, - {.name = "ATLAS" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "INFRA" , .type = BOOL , .read = 1, .write = 0}, + {.name = "RUNTIME", .type = INT, .read = 1, .write = 0}, + {.name = "SHEPHERD", .type = FLOAT, .read = 1, .write = 0}, + {.name = "DAWN", .type = BOOL, .read = 1, .write = 0}, + {.name = "DEVOPS", .type = INT, .read = 1, .write = 0}, + {.name = "ATLAS", .type = FLOAT, .read = 1, .write = 0}, + {.name = "INFRA", .type = BOOL, .read = 1, .write = 0}, // Write-only - {.name = "SENS" , .type = INT , .read = 0, .write = 1}, - {.name = "PDB" , .type = FLOAT , .read = 0, .write = 1}, - {.name = "MECH" , .type = BOOL , .read = 0, .write = 1}, - {.name = "CPR" , .type = INT , .read = 0, .write = 1}, - {.name = "EDU" , .type = FLOAT , .read = 0, .write = 1}, - {.name = "EXEC" , .type = BOOL , .read = 0, .write = 1}, + {.name = "SENS", .type = INT, .read = 0, .write = 1}, + {.name = "PDB", .type = FLOAT, .read = 0, .write = 1}, + {.name = "MECH", .type = BOOL, .read = 0, .write = 1}, + {.name = "CPR", .type = INT, .read = 0, .write = 1}, + {.name = "EDU", .type = FLOAT, .read = 0, .write = 1}, + {.name = "EXEC", .type = BOOL, .read = 0, .write = 1}, // Read-able and write-able - {.name = "PIEF" , .type = INT , .read = 1, .write = 1}, - {.name = "FUNTIME" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "SHEEP" , .type = BOOL , .read = 1, .write = 1}, - {.name = "DUSK" , .type = INT , .read = 1, .write = 1}, - } -}; + {.name = "PIEF", .type = INT, .read = 1, .write = 1}, + {.name = "FUNTIME", .type = FLOAT, .read = 1, .write = 1}, + {.name = "SHEEP", .type = BOOL, .read = 1, .write = 1}, + {.name = "DUSK", .type = INT, .read = 1, .write = 1}, + }}; device_t LimitSwitch = { .type = 1, .name = "LimitSwitch", .num_params = 3, .params = { - {.name = "switch0" , .type = BOOL , .read = 1 , .write = 0 }, - {.name = "switch1" , .type = BOOL , .read = 1 , .write = 0 }, - {.name = "switch2" , .type = BOOL , .read = 1 , .write = 0 } - } -}; + {.name = "switch0", .type = BOOL, .read = 1, .write = 0}, + {.name = "switch1", .type = BOOL, .read = 1, .write = 0}, + {.name = "switch2", .type = BOOL, .read = 1, .write = 0}}}; device_t LineFollower = { .type = 2, .name = "LineFollower", .num_params = 3, .params = { - {.name = "left" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "center" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "right" , .type = FLOAT , .read = 1 , .write = 0 } - } -}; + {.name = "left", .type = FLOAT, .read = 1, .write = 0}, + {.name = "center", .type = FLOAT, .read = 1, .write = 0}, + {.name = "right", .type = FLOAT, .read = 1, .write = 0}}}; device_t BatteryBuzzer = { .type = 3, .name = "BatteryBuzzer", .num_params = 8, .params = { - {.name = "is_unsafe" , .type = BOOL , .read = 1 , .write = 0 }, - {.name = "calibrated" , .type = BOOL , .read = 1 , .write = 0 }, - {.name = "v_cell1" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "v_cell2" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "v_cell3" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "v_batt" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "dv_cell2" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "dv_cell3" , .type = FLOAT , .read = 1 , .write = 0 } - } -}; + {.name = "is_unsafe", .type = BOOL, .read = 1, .write = 0}, + {.name = "calibrated", .type = BOOL, .read = 1, .write = 0}, + {.name = "v_cell1", .type = FLOAT, .read = 1, .write = 0}, + {.name = "v_cell2", .type = FLOAT, .read = 1, .write = 0}, + {.name = "v_cell3", .type = FLOAT, .read = 1, .write = 0}, + {.name = "v_batt", .type = FLOAT, .read = 1, .write = 0}, + {.name = "dv_cell2", .type = FLOAT, .read = 1, .write = 0}, + {.name = "dv_cell3", .type = FLOAT, .read = 1, .write = 0}}}; device_t ServoControl = { .type = 4, - .name= "ServoControl", + .name = "ServoControl", .num_params = 2, .params = { - {.name = "servo0" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "servo1" , .type = FLOAT , .read = 1 , .write = 1 } - } -}; + {.name = "servo0", .type = FLOAT, .read = 1, .write = 1}, + {.name = "servo1", .type = FLOAT, .read = 1, .write = 1}}}; device_t PolarBear = { .type = 5, .name = "PolarBear", .num_params = 3, .params = { - {.name = "duty_cycle" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "motor_current" , .type = FLOAT , .read = 1 , .write = 0 }, - {.name = "deadband" , .type = FLOAT , .read = 1 , .write = 1 } - } -}; + {.name = "duty_cycle", .type = FLOAT, .read = 1, .write = 1}, + {.name = "motor_current", .type = FLOAT, .read = 1, .write = 0}, + {.name = "deadband", .type = FLOAT, .read = 1, .write = 1}}}; device_t KoalaBear = { .type = 6, .name = "KoalaBear", .num_params = 16, .params = { - {.name = "duty_cycle_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "deadband_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "current_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_enabled_a" , .type = BOOL , .read = 1 , .write = 1 }, - {.name = "pid_kp_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_ki_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_kd_a" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "enc_a" , .type = FLOAT , .read = 1 , .write = 1 }, + {.name = "duty_cycle_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "deadband_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "current_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_enabled_a", .type = BOOL, .read = 1, .write = 1}, + {.name = "pid_kp_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_ki_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_kd_a", .type = FLOAT, .read = 1, .write = 1}, + {.name = "enc_a", .type = FLOAT, .read = 1, .write = 1}, // Same params as above except for motor b - {.name = "duty_cycle_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "deadband_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "current_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_enabled_b" , .type = BOOL , .read = 1 , .write = 1 }, - {.name = "pid_kp_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_ki_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "pid_kd_b" , .type = FLOAT , .read = 1 , .write = 1 }, - {.name = "enc_b" , .type = FLOAT , .read = 1 , .write = 1 }, - } -}; + {.name = "duty_cycle_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "deadband_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "current_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_enabled_b", .type = BOOL, .read = 1, .write = 1}, + {.name = "pid_kp_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_ki_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "pid_kd_b", .type = FLOAT, .read = 1, .write = 1}, + {.name = "enc_b", .type = FLOAT, .read = 1, .write = 1}, + }}; // *********************** VIRTUAL DEVICE DEFINITIONS *********************** // @@ -119,32 +107,27 @@ device_t TimeTestDevice = { .type = 60, .name = "TimeTestDevice", .num_params = 2, - .params = { - {.name = "GET_TIME" , .type = BOOL , .read = 1, .write = 1}, - {.name = "TIMESTAMP" , .type = INT , .read = 1, .write = 0} - } -}; + .params = { + {.name = "GET_TIME", .type = BOOL, .read = 1, .write = 1}, + {.name = "TIMESTAMP", .type = INT, .read = 1, .write = 0}}}; device_t UnstableTestDevice = { .type = 61, .name = "UnstableTestDevice", .num_params = 1, .params = { - {.name = "NUM_ACTIONS" , .type = INT , .read = 1, .write = 0} - } -}; + {.name = "NUM_ACTIONS", .type = INT, .read = 1, .write = 0}}}; device_t SimpleTestDevice = { .type = 62, .name = "SimpleTestDevice", .num_params = 4, .params = { - {.name = "INCREASING" , .type = INT , .read = 1, .write = 0}, - {.name = "DOUBLING" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "FLIP_FLOP" , .type = BOOL , .read = 1, .write = 0}, - {.name = "MY_INT" , .type = INT , .read = 1, .write = 1}, - } -}; + {.name = "INCREASING", .type = INT, .read = 1, .write = 0}, + {.name = "DOUBLING", .type = FLOAT, .read = 1, .write = 0}, + {.name = "FLIP_FLOP", .type = BOOL, .read = 1, .write = 0}, + {.name = "MY_INT", .type = INT, .read = 1, .write = 1}, + }}; device_t GeneralTestDevice = { .type = 63, @@ -152,49 +135,46 @@ device_t GeneralTestDevice = { .num_params = 32, .params = { // Read-only - {.name = "INCREASING_ODD" , .type = INT , .read = 1, .write = 0}, - {.name = "DECREASING_ODD" , .type = INT , .read = 1, .write = 0}, - {.name = "INCREASING_EVEN" , .type = INT , .read = 1, .write = 0}, - {.name = "DECREASING_EVEN" , .type = INT , .read = 1, .write = 0}, - {.name = "INCREASING_FLIP" , .type = INT , .read = 1, .write = 0}, - {.name = "ALWAYS_LEET" , .type = INT , .read = 1, .write = 0}, - {.name = "DOUBLING" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "DOUBLING_NEG" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "HALFING" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "HALFING_NEG" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "EXP_ONE_PT_ONE" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "EXP_ONE_PT_TWO" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "ALWAYS_PI" , .type = FLOAT , .read = 1, .write = 0}, - {.name = "FLIP_FLOP" , .type = BOOL , .read = 1, .write = 0}, - {.name = "ALWAYS_TRUE" , .type = BOOL , .read = 1, .write = 0}, - {.name = "ALWAYS_FALSE" , .type = BOOL , .read = 1, .write = 0}, + {.name = "INCREASING_ODD", .type = INT, .read = 1, .write = 0}, + {.name = "DECREASING_ODD", .type = INT, .read = 1, .write = 0}, + {.name = "INCREASING_EVEN", .type = INT, .read = 1, .write = 0}, + {.name = "DECREASING_EVEN", .type = INT, .read = 1, .write = 0}, + {.name = "INCREASING_FLIP", .type = INT, .read = 1, .write = 0}, + {.name = "ALWAYS_LEET", .type = INT, .read = 1, .write = 0}, + {.name = "DOUBLING", .type = FLOAT, .read = 1, .write = 0}, + {.name = "DOUBLING_NEG", .type = FLOAT, .read = 1, .write = 0}, + {.name = "HALFING", .type = FLOAT, .read = 1, .write = 0}, + {.name = "HALFING_NEG", .type = FLOAT, .read = 1, .write = 0}, + {.name = "EXP_ONE_PT_ONE", .type = FLOAT, .read = 1, .write = 0}, + {.name = "EXP_ONE_PT_TWO", .type = FLOAT, .read = 1, .write = 0}, + {.name = "ALWAYS_PI", .type = FLOAT, .read = 1, .write = 0}, + {.name = "FLIP_FLOP", .type = BOOL, .read = 1, .write = 0}, + {.name = "ALWAYS_TRUE", .type = BOOL, .read = 1, .write = 0}, + {.name = "ALWAYS_FALSE", .type = BOOL, .read = 1, .write = 0}, // Read and Write - {.name = "RED_INT" , .type = INT , .read = 1, .write = 1}, - {.name = "ORANGE_INT" , .type = INT , .read = 1, .write = 1}, - {.name = "GREEN_INT" , .type = INT , .read = 1, .write = 1}, - {.name = "BLUE_INT" , .type = INT , .read = 1, .write = 1}, - {.name = "PURPLE_INT" , .type = INT , .read = 1, .write = 1}, - {.name = "RED_FLOAT" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "ORANGE_FLOAT" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "GREEN_FLOAT" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "BLUE_FLOAT" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "PURPLE_FLOAT" , .type = FLOAT , .read = 1, .write = 1}, - {.name = "RED_BOOL" , .type = BOOL , .read = 1, .write = 1}, - {.name = "ORANGE_BOOL" , .type = BOOL , .read = 1, .write = 1}, - {.name = "GREEN_BOOL" , .type = BOOL , .read = 1, .write = 1}, - {.name = "BLUE_BOOL" , .type = BOOL , .read = 1, .write = 1}, - {.name = "PURPLE_BOOL" , .type = BOOL , .read = 1, .write = 1}, - {.name = "YELLOW_BOOL" , .type = BOOL , .read = 1, .write = 1} - } -}; + {.name = "RED_INT", .type = INT, .read = 1, .write = 1}, + {.name = "ORANGE_INT", .type = INT, .read = 1, .write = 1}, + {.name = "GREEN_INT", .type = INT, .read = 1, .write = 1}, + {.name = "BLUE_INT", .type = INT, .read = 1, .write = 1}, + {.name = "PURPLE_INT", .type = INT, .read = 1, .write = 1}, + {.name = "RED_FLOAT", .type = FLOAT, .read = 1, .write = 1}, + {.name = "ORANGE_FLOAT", .type = FLOAT, .read = 1, .write = 1}, + {.name = "GREEN_FLOAT", .type = FLOAT, .read = 1, .write = 1}, + {.name = "BLUE_FLOAT", .type = FLOAT, .read = 1, .write = 1}, + {.name = "PURPLE_FLOAT", .type = FLOAT, .read = 1, .write = 1}, + {.name = "RED_BOOL", .type = BOOL, .read = 1, .write = 1}, + {.name = "ORANGE_BOOL", .type = BOOL, .read = 1, .write = 1}, + {.name = "GREEN_BOOL", .type = BOOL, .read = 1, .write = 1}, + {.name = "BLUE_BOOL", .type = BOOL, .read = 1, .write = 1}, + {.name = "PURPLE_BOOL", .type = BOOL, .read = 1, .write = 1}, + {.name = "YELLOW_BOOL", .type = BOOL, .read = 1, .write = 1}}}; // ************************ DEVICE UTILITY FUNCTIONS ************************ // // An array that holds pointers to the structs of each lowcar device device_t* DEVICES[DEVICES_LENGTH] = {0}; // A hack to initialize DEVICES. https://stackoverflow.com/a/6991475 -__attribute__((constructor)) -void devices_arr_init() { +__attribute__((constructor)) void devices_arr_init() { DEVICES[DummyDevice.type] = &DummyDevice; DEVICES[LimitSwitch.type] = &LimitSwitch; DEVICES[LineFollower.type] = &LineFollower; @@ -260,11 +240,9 @@ int8_t get_param_idx(uint8_t dev_type, char* param_name) { char* BUTTON_NAMES[] = { "button_a", "button_b", "button_x", "button_y", "l_bumper", "r_bumper", "l_trigger", "r_trigger", - "button_back", "button_start", "l_stick", "r_stick", "dpad_up", "dpad_down", "dpad_left", "dpad_right", "button_xbox" -}; + "button_back", "button_start", "l_stick", "r_stick", "dpad_up", "dpad_down", "dpad_left", "dpad_right", "button_xbox"}; char* JOYSTICK_NAMES[] = { - "joystick_left_x", "joystick_left_y", "joystick_right_x", "joystick_right_y" -}; + "joystick_left_x", "joystick_left_y", "joystick_right_x", "joystick_right_y"}; char** get_button_names() { return BUTTON_NAMES; @@ -278,29 +256,29 @@ char** get_joystick_names() { /* Returns the number of milliseconds since the Unix Epoch */ uint64_t millis() { - struct timeval time; // Holds the current time in seconds + microseconds + struct timeval time; // Holds the current time in seconds + microseconds gettimeofday(&time, NULL); - uint64_t s1 = (uint64_t)(time.tv_sec) * 1000; // Convert seconds to milliseconds - uint64_t s2 = (time.tv_usec / 1000); // Convert microseconds to milliseconds + uint64_t s1 = (uint64_t)(time.tv_sec) * 1000; // Convert seconds to milliseconds + uint64_t s2 = (time.tv_usec / 1000); // Convert microseconds to milliseconds return s1 + s2; } // ********************* READ/WRITE TO FILE DESCRIPTOR ********************** // -int readn (int fd, void *buf, uint16_t n) { +int readn(int fd, void* buf, uint16_t n) { uint16_t n_remain = n; uint16_t n_read; - char *curr = buf; + char* curr = buf; while (n_remain > 0) { if ((n_read = read(fd, curr, n_remain)) < 0) { - if (errno == EINTR) { // read interrupted by signal; read again + if (errno == EINTR) { // read interrupted by signal; read again n_read = 0; } else { perror("read"); return -1; } - } else if (n_read == 0) { // received EOF + } else if (n_read == 0) { // received EOF return 0; } n_remain -= n_read; @@ -309,14 +287,14 @@ int readn (int fd, void *buf, uint16_t n) { return (n - n_remain); } -int writen (int fd, void *buf, uint16_t n) { +int writen(int fd, void* buf, uint16_t n) { uint16_t n_remain = n; uint16_t n_written; - char *curr = buf; + char* curr = buf; while (n_remain > 0) { if ((n_written = write(fd, curr, n_remain)) <= 0) { - if (n_written < 0 && errno == EINTR) { // write interrupted by signal, write again + if (n_written < 0 && errno == EINTR) { // write interrupted by signal, write again n_written = 0; } else { perror("write"); diff --git a/runtime_util/runtime_util.h b/runtime_util/runtime_util.h old mode 100755 new mode 100644 index 418804ed..21be60ab --- a/runtime_util/runtime_util.h +++ b/runtime_util/runtime_util.h @@ -3,34 +3,34 @@ // ************************* COMMON STANDARD HEADERS ************************ // -#include // for printf, perror, fprintf, fopen, etc. -#include // for malloc, free -#include // for uint32_t, int16_t, uint8_t, etc. -#include // for strcmp, strcpy, strlen, memset, etc. -#include // for various error numbers (EINTR, EAGAIN, EPIPE, etc.) and errno -#include // for thread-functions: pthread_create, pthread_cancel, pthread_join, etc. -#include // for F_OK, R_OK, SEEK_SET, SEEK_END, access, ftruncate, read, write, etc. -#include // for setting signal function (setting signal handler) -#include // for time-related structures and time functions -#include // for file opening constants (O_CREAT, O_RDONLY, O_RDWR, etc.) -#include // for various system-related types and functions (sem_t, mkfifo) -#include // for bind, listen, accept, socket -#include // for struct sockaddr_un +#include // for various error numbers (EINTR, EAGAIN, EPIPE, etc.) and errno +#include // for file opening constants (O_CREAT, O_RDONLY, O_RDWR, etc.) +#include // for thread-functions: pthread_create, pthread_cancel, pthread_join, etc. +#include // for setting signal function (setting signal handler) +#include // for uint32_t, int16_t, uint8_t, etc. +#include // for printf, perror, fprintf, fopen, etc. +#include // for malloc, free +#include // for strcmp, strcpy, strlen, memset, etc. +#include // for bind, listen, accept, socket +#include // for various system-related types and functions (sem_t, mkfifo) +#include // for time-related structures and time functions +#include // for struct sockaddr_un +#include // for F_OK, R_OK, SEEK_SET, SEEK_END, access, ftruncate, read, write, etc. // ***************************** DEFINED CONSTANTS ************************** // -#define MAX_DEVICES 32 // Maximum number of connected devices -#define MAX_PARAMS 32 // Maximum number of parameters supported +#define MAX_DEVICES 32 // Maximum number of connected devices +#define MAX_PARAMS 32 // Maximum number of parameters supported -#define DEVICES_LENGTH 64 // The largest device type number + 1. +#define DEVICES_LENGTH 64 // The largest device type number + 1. -#define NUM_DESC_FIELDS 5 // Number of fields in the robot description +#define NUM_DESC_FIELDS 5 // Number of fields in the robot description #define NUM_GAMEPAD_BUTTONS 17 // Number of gamepad buttons -#define MAX_LOG_LEN 512 // The maximum number of characters in a log message +#define MAX_LOG_LEN 512 // The maximum number of characters in a log message -#define CHALLENGE_LEN 128 // The maximum input/output string length for a challenge +#define CHALLENGE_LEN 128 // The maximum input/output string length for a challenge #define CHALLENGE_SOCKET "/tmp/challenge.sock" // The interval (microseconds) at which we wait between detecting connects/disconnects @@ -38,67 +38,103 @@ // enumerated names of processes typedef enum process { - DEV_HANDLER, EXECUTOR, NET_HANDLER, SHM, TEST + DEV_HANDLER, + EXECUTOR, + NET_HANDLER, + SHM, + TEST } process_t; // enumerated names for the buttons on the gamepad typedef enum gp_buttons { - BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y, L_BUMPER, R_BUMPER, L_TRIGGER, R_TRIGGER, - BUTTON_BACK, BUTTON_START, L_STICK, R_STICK, DPAD_UP, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, BUTTON_XBOX + BUTTON_A, + BUTTON_B, + BUTTON_X, + BUTTON_Y, + L_BUMPER, + R_BUMPER, + L_TRIGGER, + R_TRIGGER, + BUTTON_BACK, + BUTTON_START, + L_STICK, + R_STICK, + DPAD_UP, + DPAD_DOWN, + DPAD_LEFT, + DPAD_RIGHT, + BUTTON_XBOX } gp_button_t; // enumerated names for the joystick params of the gamepad typedef enum gp_joysticks { - JOYSTICK_LEFT_X, JOYSTICK_LEFT_Y, JOYSTICK_RIGHT_X, JOYSTICK_RIGHT_Y + JOYSTICK_LEFT_X, + JOYSTICK_LEFT_Y, + JOYSTICK_RIGHT_X, + JOYSTICK_RIGHT_Y } gp_joystick_t; // enumerated names for the different values the robot description fields can take on typedef enum robot_desc_vals { - IDLE, AUTO, TELEOP, CHALLENGE, // values for robot.run_mode - CONNECTED, DISCONNECTED, // values for robot.dawn, robot.shepherd, robot.gamepad - LEFT, RIGHT // values for robot.startpos + // values for robot.run_mode + IDLE, + AUTO, + TELEOP, + CHALLENGE, + // values for robot.dawn, robot.shepherd, robot.gamepad + CONNECTED, + DISCONNECTED, + // values for robot.startpos + LEFT, + RIGHT } robot_desc_val_t; // enumerated names for the fields in the robot description typedef enum robot_descs { - RUN_MODE, DAWN, SHEPHERD, GAMEPAD, START_POS + RUN_MODE, + DAWN, + SHEPHERD, + GAMEPAD, + START_POS } robot_desc_field_t; // enumerated names for the data types device parameters can be typedef enum param_type { - INT, FLOAT, BOOL + INT, + FLOAT, + BOOL } param_type_t; // ***************************** CUSTOM STRUCTS ***************************** // // hold a single param value. One-to-one mapping to param_val_t enum typedef union { - int32_t p_i; // data if int - float p_f; // data if float - uint8_t p_b; // data if bool + int32_t p_i; // data if int + float p_f; // data if float + uint8_t p_b; // data if bool } param_val_t; // holds the device identification information of a single device typedef struct dev_id { - uint8_t type; // The device type (ex: 0 for DummyDevice) - uint8_t year; // The device year - uint64_t uid; // The unique id for a specific device assigned when flashed + uint8_t type; // The device type (ex: 0 for DummyDevice) + uint8_t year; // The device year + uint64_t uid; // The unique id for a specific device assigned when flashed } dev_id_t; // A struct defining the type and access level of a device parameter typedef struct param_desc { - char* name; // Parameter name - param_type_t type; // Data type - uint8_t read; // Whether or not the param is readable - uint8_t write; // Whether or not the param is writable + char* name; // Parameter name + param_type_t type; // Data type + uint8_t read; // Whether or not the param is readable + uint8_t write; // Whether or not the param is writable } param_desc_t; // A struct defining a kind of device (ex: LimitSwitch, KoalaBear) typedef struct device { - uint8_t type; // The type of device - char* name; // Device name (ex: "LimitSwitch") - uint8_t num_params; // Number of params the device has - param_desc_t params[MAX_PARAMS]; // Description of each parameter + uint8_t type; // The type of device + char* name; // Device name (ex: "LimitSwitch") + uint8_t num_params; // Number of params the device has + param_desc_t params[MAX_PARAMS]; // Description of each parameter } device_t; // ************************ DEVICE UTILITY FUNCTIONS ************************ // @@ -185,7 +221,7 @@ uint64_t millis(); * 0: read EOF on fd * -1: read errored out */ -int readn(int fd, void *buf, uint16_t n); +int readn(int fd, void* buf, uint16_t n); /** * Read n bytes from buf to fd; return number of bytes written to buf (deals with interrupts and unbuffered writes) @@ -197,6 +233,6 @@ int readn(int fd, void *buf, uint16_t n); * >= 0: number of bytes written into buf * -1: write errored out */ -int writen(int fd, void *buf, uint16_t n); +int writen(int fd, void* buf, uint16_t n); #endif diff --git a/shm_wrapper/shm_start.c b/shm_wrapper/shm_start.c index c553c45d..f048ed16 100644 --- a/shm_wrapper/shm_start.c +++ b/shm_wrapper/shm_start.c @@ -1,6 +1,6 @@ #include "shm_wrapper.h" -char sname[SNAME_SIZE]; // being lazy here but this is for holding all the semaphore names +char sname[SNAME_SIZE]; // being lazy here but this is for holding all the semaphore names // ************************************ SHM UTILITY *********************************************** // @@ -12,8 +12,8 @@ char sname[SNAME_SIZE]; // being lazy here but this is for holding all the sem * sem_desc: string that describes the semaphore being created and opened, displayed with error message * Returns a pointer to the semaphore that was created and opened. */ -static sem_t *my_sem_open_create(char *sem_name, char *sem_desc) { - sem_t *ret; +static sem_t* my_sem_open_create(char* sem_name, char* sem_desc) { + sem_t* ret; if ((ret = sem_open(sem_name, O_CREAT, 0660, 1)) == SEM_FAILED) { log_printf(FATAL, "sem_open: %s. %s", sem_desc, strerror(errno)); exit(1); @@ -29,9 +29,9 @@ static sem_t *my_sem_open_create(char *sem_name, char *sem_desc) { int main() { // set up logger_init(SHM); - + int fd_shm; - + // create all semaphores with initial value 1 catalog_sem = my_sem_open_create(CATALOG_MUTEX_NAME, "catalog mutex"); cmd_map_sem = my_sem_open_create(CMDMAP_MUTEX_NAME, "cmd map mutex"); @@ -40,18 +40,18 @@ int main() { rd_sem = my_sem_open_create(RD_MUTEX_NAME, "robot desc mutex"); log_data_sem = my_sem_open_create(LOG_DATA_MUTEX, "log data mutex"); for (int i = 0; i < MAX_DEVICES; i++) { - generate_sem_name(DATA, i, sname); // get the data name - if ((sems[i].data_sem = sem_open((const char *) sname, O_CREAT, 0660, 1)) == SEM_FAILED) { + generate_sem_name(DATA, i, sname); // get the data name + if ((sems[i].data_sem = sem_open((const char*) sname, O_CREAT, 0660, 1)) == SEM_FAILED) { log_printf(FATAL, "sem_open: data sem for dev_ix %d: %s", i, strerror(errno)); exit(1); } - generate_sem_name(COMMAND, i, sname); // get the command name - if ((sems[i].command_sem = sem_open((const char *) sname, O_CREAT, 0660, 1)) == SEM_FAILED) { + generate_sem_name(COMMAND, i, sname); // get the command name + if ((sems[i].command_sem = sem_open((const char*) sname, O_CREAT, 0660, 1)) == SEM_FAILED) { log_printf(FATAL, "sem_open: command sem for dev_ix %d: %s", i, strerror(errno)); exit(1); } } - + // create device shm block if ((fd_shm = shm_open(DEV_SHM_NAME, O_RDWR | O_CREAT, 0660)) == -1) { log_printf(FATAL, "shm_open: %s", strerror(errno)); @@ -68,7 +68,7 @@ int main() { if (close(fd_shm) == -1) { log_printf(ERROR, "close: %s", strerror(errno)); } - + // create gamepad shm block if ((fd_shm = shm_open(GPAD_SHM_NAME, O_RDWR | O_CREAT, 0660)) == -1) { log_printf(FATAL, "shm_open gamepad_shm: %s", strerror(errno)); @@ -85,7 +85,7 @@ int main() { if (close(fd_shm) == -1) { log_printf(ERROR, "close gamepad_shm: %s", strerror(errno)); } - + // create robot description shm block if ((fd_shm = shm_open(ROBOT_DESC_SHM_NAME, O_RDWR | O_CREAT, 0660)) == -1) { log_printf(FATAL, "shm_open robot_desc_shm: %s", strerror(errno)); @@ -119,7 +119,7 @@ int main() { if (close(fd_shm) == -1) { log_printf(ERROR, "close log_data_shm: %s", strerror(errno)); } - + // initialize everything dev_shm_ptr->catalog = 0; for (int i = 0; i < MAX_DEVICES + 1; i++) { @@ -140,6 +140,6 @@ int main() { memset(log_data_shm_ptr, 0, sizeof(log_data_shm_t)); log_printf(INFO, "SHM created"); - - return 0; // returns to start everything + + return 0; // returns to start everything } diff --git a/shm_wrapper/shm_stop.c b/shm_wrapper/shm_stop.c index ad22b0c4..9108d7b3 100644 --- a/shm_wrapper/shm_stop.c +++ b/shm_wrapper/shm_stop.c @@ -1,6 +1,6 @@ #include "shm_wrapper.h" -char sname[SNAME_SIZE]; // being lazy here but this is for holding all the semaphore names +char sname[SNAME_SIZE]; // being lazy here but this is for holding all the semaphore names // *********************************** SHM PROCESS UTILITIES *********************************************** // @@ -10,10 +10,10 @@ char sname[SNAME_SIZE]; // being lazy here but this is for holding all the sem * shm_name: name of shared memory block (ex. "/dev-shm") * shm_desc: description of shared memory block, to be printed with descriptive error message should shm_unlink() fail */ -static void my_shm_unlink(char *shm_name, char *shm_desc) { - if (shm_unlink(shm_name) == -1) { - log_printf(ERROR, "shm_unlink: %s. %s", shm_desc, strerror(errno)); - } +static void my_shm_unlink(char* shm_name, char* shm_desc) { + if (shm_unlink(shm_name) == -1) { + log_printf(ERROR, "shm_unlink: %s. %s", shm_desc, strerror(errno)); + } } /** @@ -22,10 +22,10 @@ static void my_shm_unlink(char *shm_name, char *shm_desc) { * sem_name: name of semaphore (ex. "/ct-mutex") * sem_desc: description of semaphore, to be printed with descriptive error message should sem_unlink() fail */ -static void my_sem_unlink(char *sem_name, char *sem_desc) { - if (sem_unlink(sem_name) == -1) { - log_printf(ERROR, "sem_unlink: %s. %s", sem_desc, strerror(errno)); - } +static void my_sem_unlink(char* sem_name, char* sem_desc) { + if (sem_unlink(sem_name) == -1) { + log_printf(ERROR, "sem_unlink: %s. %s", sem_desc, strerror(errno)); + } } /** @@ -37,38 +37,38 @@ int main() { logger_init(SHM); shm_init(); - // unlink all shared memory blocks - my_shm_unlink(DEV_SHM_NAME, "dev_shm"); - my_shm_unlink(GPAD_SHM_NAME, "gamepad_shm"); - my_shm_unlink(ROBOT_DESC_SHM_NAME, "robot_desc_shm"); - my_shm_unlink(LOG_DATA_SHM, "log_data_shm"); - - // unlink all semaphores - my_sem_unlink(CATALOG_MUTEX_NAME, "catalog mutex"); - my_sem_unlink(CMDMAP_MUTEX_NAME, "cmd map mutex"); - my_sem_unlink(SUBMAP_MUTEX_NAME, "sub map mutex"); - my_sem_unlink(GP_MUTEX_NAME, "gamepad mutex"); - my_sem_unlink(RD_MUTEX_NAME, "robot desc mutex"); - my_sem_unlink(LOG_DATA_MUTEX, "log data mutex"); - for (int i = 0; i < MAX_DEVICES; i++) { - generate_sem_name(DATA, i, sname); - if (sem_unlink((const char *) sname) == -1) { - log_printf(ERROR, "sem_unlink: data_sem for dev_ix %d. %s", i, strerror(errno)); - } - generate_sem_name(COMMAND, i, sname); - if (sem_unlink((const char *) sname) == -1) { - log_printf(ERROR, "sem_unlink: command_sem for dev_ix %d. %s", i, strerror(errno)); - } - } + // unlink all shared memory blocks + my_shm_unlink(DEV_SHM_NAME, "dev_shm"); + my_shm_unlink(GPAD_SHM_NAME, "gamepad_shm"); + my_shm_unlink(ROBOT_DESC_SHM_NAME, "robot_desc_shm"); + my_shm_unlink(LOG_DATA_SHM, "log_data_shm"); + + // unlink all semaphores + my_sem_unlink(CATALOG_MUTEX_NAME, "catalog mutex"); + my_sem_unlink(CMDMAP_MUTEX_NAME, "cmd map mutex"); + my_sem_unlink(SUBMAP_MUTEX_NAME, "sub map mutex"); + my_sem_unlink(GP_MUTEX_NAME, "gamepad mutex"); + my_sem_unlink(RD_MUTEX_NAME, "robot desc mutex"); + my_sem_unlink(LOG_DATA_MUTEX, "log data mutex"); + for (int i = 0; i < MAX_DEVICES; i++) { + generate_sem_name(DATA, i, sname); + if (sem_unlink((const char*) sname) == -1) { + log_printf(ERROR, "sem_unlink: data_sem for dev_ix %d. %s", i, strerror(errno)); + } + generate_sem_name(COMMAND, i, sname); + if (sem_unlink((const char*) sname) == -1) { + log_printf(ERROR, "sem_unlink: command_sem for dev_ix %d. %s", i, strerror(errno)); + } + } // Using shm_init() calls shm_stop() automatically on process exit, so semaphores and shm blocks will be closed on exit - - log_printf(INFO, "SHM destroyed. Runtime Funtime is no more"); + + log_printf(INFO, "SHM destroyed. Runtime Funtime is no more"); /* * Under normal production circumstances, this program should never be run (it only runs when net_handler, executor, or dev_handler * crash abnormally). So, systemd needs to know that this process "failed" so that it can run shm_start to try and boot up Runtime * again. A nonzero exit status is a failure, so we return 1 here to tell systemd that this process "failed". */ - return 1; + return 1; } diff --git a/shm_wrapper/shm_wrapper.c b/shm_wrapper/shm_wrapper.c index 87ad55a9..a58e8ce0 100644 --- a/shm_wrapper/shm_wrapper.c +++ b/shm_wrapper/shm_wrapper.c @@ -2,19 +2,19 @@ // *********************************** WRAPPER-SPECIFIC GLOBAL VARS **************************************** // -dual_sem_t sems[MAX_DEVICES]; // array of semaphores, two for each possible device (one for data and one for commands) -dev_shm_t *dev_shm_ptr; // points to memory-mapped shared memory block for device data and commands -sem_t *catalog_sem; // semaphore used as a mutex on the catalog -sem_t *cmd_map_sem; // semaphore used as a mutex on the command bitmap -sem_t *sub_map_sem; // semaphore used as a mutex on the subscription bitmap +dual_sem_t sems[MAX_DEVICES]; // array of semaphores, two for each possible device (one for data and one for commands) +dev_shm_t* dev_shm_ptr; // points to memory-mapped shared memory block for device data and commands +sem_t* catalog_sem; // semaphore used as a mutex on the catalog +sem_t* cmd_map_sem; // semaphore used as a mutex on the command bitmap +sem_t* sub_map_sem; // semaphore used as a mutex on the subscription bitmap -gamepad_shm_t *gp_shm_ptr; // points to memory-mapped shared memory block for gamepad -robot_desc_shm_t *rd_shm_ptr; // points to memory-mapped shared memory block for robot description -sem_t *gp_sem; // semaphore used as a mutex on the gamepad -sem_t *rd_sem; // semaphore used as a mutex on the robot description +gamepad_shm_t* gp_shm_ptr; // points to memory-mapped shared memory block for gamepad +robot_desc_shm_t* rd_shm_ptr; // points to memory-mapped shared memory block for robot description +sem_t* gp_sem; // semaphore used as a mutex on the gamepad +sem_t* rd_sem; // semaphore used as a mutex on the robot description -log_data_shm_t *log_data_shm_ptr; // points to shared memory block for log data specified by executor -sem_t *log_data_sem; // semaphore used as a mutex on the log data +log_data_shm_t* log_data_shm_ptr; // points to shared memory block for log data specified by executor +sem_t* log_data_sem; // semaphore used as a mutex on the log data // ****************************************** SEMAPHORE UTILITIES ***************************************** // @@ -24,10 +24,10 @@ sem_t *log_data_sem; // semaphore used as a mutex on the log data * sem: pointer to a semaphore to wait on * sem_desc: string that describes the semaphore being waited on, displayed with error message */ -static void my_sem_wait(sem_t *sem, char *sem_desc) { - if (sem_wait(sem) == -1) { - log_printf(ERROR, "sem_wait: %s. %s", sem_desc, strerror(errno)); - } +static void my_sem_wait(sem_t* sem, char* sem_desc) { + if (sem_wait(sem) == -1) { + log_printf(ERROR, "sem_wait: %s. %s", sem_desc, strerror(errno)); + } } /** @@ -36,10 +36,10 @@ static void my_sem_wait(sem_t *sem, char *sem_desc) { * sem: pointer to a semaphore to post * sem_desc: string that describes the semaphore being posted, displayed with error message */ -static void my_sem_post(sem_t *sem, char *sem_desc) { - if (sem_post(sem) == -1) { - log_printf(ERROR, "sem_post: %s. %s", sem_desc, strerror(errno)); - } +static void my_sem_post(sem_t* sem, char* sem_desc) { + if (sem_post(sem) == -1) { + log_printf(ERROR, "sem_post: %s. %s", sem_desc, strerror(errno)); + } } /** @@ -50,13 +50,13 @@ static void my_sem_post(sem_t *sem, char *sem_desc) { * sem_desc: string that describes the semaphore being opened, displayed with error message * Returns a pointer to the semaphore that was opened. */ -static sem_t *my_sem_open(char *sem_name, char *sem_desc) { - sem_t *ret; - if ((ret = sem_open(sem_name, 0, 0, 0)) == SEM_FAILED) { - log_printf(FATAL, "sem_open: %s. %s", sem_desc, strerror(errno)); - exit(1); - } - return ret; +static sem_t* my_sem_open(char* sem_name, char* sem_desc) { + sem_t* ret; + if ((ret = sem_open(sem_name, 0, 0, 0)) == SEM_FAILED) { + log_printf(FATAL, "sem_open: %s. %s", sem_desc, strerror(errno)); + exit(1); + } + return ret; } /** @@ -65,10 +65,10 @@ static sem_t *my_sem_open(char *sem_name, char *sem_desc) { * sem: pointer to a semaphore to close * sem_desc: string that describes the semaphore being closed, displayed with error message */ -static void my_sem_close(sem_t *sem, char *sem_desc) { - if (sem_close(sem) == -1) { - log_printf(ERROR, "sem_close: %s. %s", sem_desc, strerror(errno)); - } +static void my_sem_close(sem_t* sem, char* sem_desc) { + if (sem_close(sem) == -1) { + log_printf(ERROR, "sem_close: %s. %s", sem_desc, strerror(errno)); + } } // ******************************************** HELPER FUNCTIONS ****************************************** // @@ -80,10 +80,10 @@ static void my_sem_close(sem_t *sem, char *sem_desc) { * bitmap: bitmap to print */ static void print_bitmap(int num_bits, uint32_t bitmap) { - for (int i = 0; i < num_bits; i++) { - printf("%d", (bitmap & (1 << i)) ? 1 : 0); - } - printf("\n"); + for (int i = 0; i < num_bits; i++) { + printf("%d", (bitmap & (1 << i)) ? 1 : 0); + } + printf("\n"); } /** @@ -91,17 +91,17 @@ static void print_bitmap(int num_bits, uint32_t bitmap) { * Arguments: * dev_uid: 64-bit unique ID of the device * Returns: device index in shared memory of the specified device, -1 if specified device is not in shared memory - */ + */ static int get_dev_ix_from_uid(uint64_t dev_uid) { - int dev_ix = -1; + int dev_ix = -1; - for (int i = 0; i < MAX_DEVICES; i++) { - if ((dev_shm_ptr->catalog & (1 << i)) && (dev_shm_ptr->dev_ids[i].uid == dev_uid)) { - dev_ix = i; - break; - } - } - return dev_ix; + for (int i = 0; i < MAX_DEVICES; i++) { + if ((dev_shm_ptr->catalog & (1 << i)) && (dev_shm_ptr->dev_ids[i].uid == dev_uid)) { + dev_ix = i; + break; + } + } + return dev_ix; } /** @@ -115,40 +115,40 @@ static int get_dev_ix_from_uid(uint64_t dev_uid) { * params: pointer to array of param_val_t's that is at least as long as highest requested param number * device data will be read into the corresponding param_val_t's */ -static void device_read_helper(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t *params) { - // grab semaphore for the appropriate stream and device - if (stream == DATA) { - my_sem_wait(sems[dev_ix].data_sem, "data sem @device_read"); - } else { - my_sem_wait(sems[dev_ix].command_sem, "command sem @device_read"); - } - - // read all requested params - for (int i = 0; i < MAX_PARAMS; i++) { - if (params_to_read & (1 << i)) { - params[i] = dev_shm_ptr->params[stream][dev_ix][i]; - } - } - - // if the device handler has processed the command, then turn off the change - // if stream = downstream and process = dev_handler then also update params bitmap - if (process == DEV_HANDLER && stream == COMMAND) { - // wait on cmd_map_sem - my_sem_wait(cmd_map_sem, "cmd_map_sem @device_read"); - - dev_shm_ptr->cmd_map[0] &= (~(1 << dev_ix)); // turn off changed device bit in cmd_map[0] - dev_shm_ptr->cmd_map[dev_ix + 1] &= (~params_to_read); // turn off bits for params that were changed and then read in cmd_map[dev_ix + 1] - - // release cmd_map_sem - my_sem_post(cmd_map_sem, "cmd_map_sem @device_read"); - } - - // release semaphore for appropriate stream and device - if (stream == DATA) { - my_sem_post(sems[dev_ix].data_sem, "data sem @device_read"); - } else { - my_sem_post(sems[dev_ix].command_sem, "command sem @device_read"); - } +static void device_read_helper(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t* params) { + // grab semaphore for the appropriate stream and device + if (stream == DATA) { + my_sem_wait(sems[dev_ix].data_sem, "data sem @device_read"); + } else { + my_sem_wait(sems[dev_ix].command_sem, "command sem @device_read"); + } + + // read all requested params + for (int i = 0; i < MAX_PARAMS; i++) { + if (params_to_read & (1 << i)) { + params[i] = dev_shm_ptr->params[stream][dev_ix][i]; + } + } + + // if the device handler has processed the command, then turn off the change + // if stream = downstream and process = dev_handler then also update params bitmap + if (process == DEV_HANDLER && stream == COMMAND) { + // wait on cmd_map_sem + my_sem_wait(cmd_map_sem, "cmd_map_sem @device_read"); + + dev_shm_ptr->cmd_map[0] &= (~(1 << dev_ix)); // turn off changed device bit in cmd_map[0] + dev_shm_ptr->cmd_map[dev_ix + 1] &= (~params_to_read); // turn off bits for params that were changed and then read in cmd_map[dev_ix + 1] + + // release cmd_map_sem + my_sem_post(cmd_map_sem, "cmd_map_sem @device_read"); + } + + // release semaphore for appropriate stream and device + if (stream == DATA) { + my_sem_post(sems[dev_ix].data_sem, "data sem @device_read"); + } else { + my_sem_post(sems[dev_ix].command_sem, "command sem @device_read"); + } } /** @@ -163,40 +163,40 @@ static void device_read_helper(int dev_ix, process_t process, stream_t stream, u * params: pointer to array of param_val_t's that is at least as long as highest requested param number * device data will be written into the corresponding param_val_t's */ -static void device_write_helper(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t *params) { - // grab semaphore for the appropriate stream and device - if (stream == DATA) { - my_sem_wait(sems[dev_ix].data_sem, "data sem @device_write"); - } else { - my_sem_wait(sems[dev_ix].command_sem, "command sem @device_write"); - } - - // write all requested params - for (int i = 0; i < MAX_PARAMS; i++) { - if (params_to_write & (1 << i)) { - dev_shm_ptr->params[stream][dev_ix][i] = params[i]; - } - } - - // turn on flag if executor is sending a command to the device - // if stream = downstream and process = executor then also update params bitmap - if (process == EXECUTOR && stream == COMMAND) { - // wait on cmd_map_sem - my_sem_wait(cmd_map_sem, "cmd_map_sem @device_write"); - - dev_shm_ptr->cmd_map[0] |= (1 << dev_ix); // turn on changed device bit in cmd_map[0] - dev_shm_ptr->cmd_map[dev_ix + 1] |= params_to_write; // turn on bits for params that were written in cmd_map[dev_ix + 1] - - // release cmd_map_sem - my_sem_post(cmd_map_sem, "cmd_map_sem @device_write"); - } - - // release semaphore for appropriate stream and device - if (stream == DATA) { - my_sem_post(sems[dev_ix].data_sem, "data sem @device_write"); - } else { - my_sem_post(sems[dev_ix].command_sem, "command sem @device_write"); - } +static void device_write_helper(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t* params) { + // grab semaphore for the appropriate stream and device + if (stream == DATA) { + my_sem_wait(sems[dev_ix].data_sem, "data sem @device_write"); + } else { + my_sem_wait(sems[dev_ix].command_sem, "command sem @device_write"); + } + + // write all requested params + for (int i = 0; i < MAX_PARAMS; i++) { + if (params_to_write & (1 << i)) { + dev_shm_ptr->params[stream][dev_ix][i] = params[i]; + } + } + + // turn on flag if executor is sending a command to the device + // if stream = downstream and process = executor then also update params bitmap + if (process == EXECUTOR && stream == COMMAND) { + // wait on cmd_map_sem + my_sem_wait(cmd_map_sem, "cmd_map_sem @device_write"); + + dev_shm_ptr->cmd_map[0] |= (1 << dev_ix); // turn on changed device bit in cmd_map[0] + dev_shm_ptr->cmd_map[dev_ix + 1] |= params_to_write; // turn on bits for params that were written in cmd_map[dev_ix + 1] + + // release cmd_map_sem + my_sem_post(cmd_map_sem, "cmd_map_sem @device_write"); + } + + // release semaphore for appropriate stream and device + if (stream == DATA) { + my_sem_post(sems[dev_ix].data_sem, "data sem @device_write"); + } else { + my_sem_post(sems[dev_ix].command_sem, "command sem @device_write"); + } } /** @@ -204,671 +204,673 @@ static void device_write_helper(int dev_ix, process_t process, stream_t stream, * Closes all semaphores; unmaps all shared memory (but does not unlink anything) */ static void shm_close() { - // close all the semaphores - for (int i = 0; i < MAX_DEVICES; i++) { - my_sem_close(sems[i].data_sem, "data sem"); - my_sem_close(sems[i].command_sem, "command sem"); - } - my_sem_close(catalog_sem, "catalog sem"); - my_sem_close(cmd_map_sem, "cmd map sem"); - my_sem_close(sub_map_sem, "sub map sem"); - my_sem_close(gp_sem, "gamepad_mutex"); - my_sem_close(rd_sem, "robot_desc_mutex"); - my_sem_close(log_data_sem, "log data mutex"); - - // unmap all shared memory blocks - if (munmap(dev_shm_ptr, sizeof(dev_shm_t)) == -1) { - log_printf(ERROR, "munmap: dev_shm. %s", strerror(errno)); - } - if (munmap(gp_shm_ptr, sizeof(gamepad_shm_t)) == -1) { - log_printf(ERROR, "munmap: gp_shm. %s", strerror(errno)); - } - if (munmap(rd_shm_ptr, sizeof(robot_desc_shm_t)) == -1) { - log_printf(ERROR, "munmap: robot_desc_shm. %s", strerror(errno)); - } - if (munmap(log_data_shm_ptr, sizeof(log_data_shm_t)) == -1) { - log_printf(ERROR, "munmap: log_data_shm_ptr. %s", strerror(errno)); - } + // close all the semaphores + for (int i = 0; i < MAX_DEVICES; i++) { + my_sem_close(sems[i].data_sem, "data sem"); + my_sem_close(sems[i].command_sem, "command sem"); + } + my_sem_close(catalog_sem, "catalog sem"); + my_sem_close(cmd_map_sem, "cmd map sem"); + my_sem_close(sub_map_sem, "sub map sem"); + my_sem_close(gp_sem, "gamepad_mutex"); + my_sem_close(rd_sem, "robot_desc_mutex"); + my_sem_close(log_data_sem, "log data mutex"); + + // unmap all shared memory blocks + if (munmap(dev_shm_ptr, sizeof(dev_shm_t)) == -1) { + log_printf(ERROR, "munmap: dev_shm. %s", strerror(errno)); + } + if (munmap(gp_shm_ptr, sizeof(gamepad_shm_t)) == -1) { + log_printf(ERROR, "munmap: gp_shm. %s", strerror(errno)); + } + if (munmap(rd_shm_ptr, sizeof(robot_desc_shm_t)) == -1) { + log_printf(ERROR, "munmap: robot_desc_shm. %s", strerror(errno)); + } + if (munmap(log_data_shm_ptr, sizeof(log_data_shm_t)) == -1) { + log_printf(ERROR, "munmap: log_data_shm_ptr. %s", strerror(errno)); + } } // ************************************ PUBLIC PRINTING UTILITIES ***************************************** // void print_cmd_map() { - uint32_t cmd_map[MAX_DEVICES + 1]; - get_cmd_map(cmd_map); + uint32_t cmd_map[MAX_DEVICES + 1]; + get_cmd_map(cmd_map); - printf("Changed devices: "); - print_bitmap(MAX_DEVICES, cmd_map[0]); + printf("Changed devices: "); + print_bitmap(MAX_DEVICES, cmd_map[0]); - printf("Changed params:\n"); - for (int i = 1; i < 33; i++) { - if (cmd_map[0] & (1 << (i - 1))) { - printf("\tDevice %d: ", i - 1); - print_bitmap(MAX_PARAMS, cmd_map[i]); - } - } + printf("Changed params:\n"); + for (int i = 1; i < 33; i++) { + if (cmd_map[0] & (1 << (i - 1))) { + printf("\tDevice %d: ", i - 1); + print_bitmap(MAX_PARAMS, cmd_map[i]); + } + } } void print_sub_map(process_t process) { - uint32_t sub_map[MAX_DEVICES + 1]; - get_sub_requests(sub_map, process); + uint32_t sub_map[MAX_DEVICES + 1]; + get_sub_requests(sub_map, process); - printf("Requested devices: "); - print_bitmap(MAX_DEVICES, sub_map[0]); + printf("Requested devices: "); + print_bitmap(MAX_DEVICES, sub_map[0]); - printf("Requested params:\n"); - for (int i = 1; i < 33; i++) { - if (sub_map[0] & (1 << (i - 1))) { - printf("\tDevice %d: ", i - 1); - print_bitmap(MAX_PARAMS, sub_map[i]); - } - } + printf("Requested params:\n"); + for (int i = 1; i < 33; i++) { + if (sub_map[0] & (1 << (i - 1))) { + printf("\tDevice %d: ", i - 1); + print_bitmap(MAX_PARAMS, sub_map[i]); + } + } } void print_dev_ids() { - dev_id_t dev_ids[MAX_DEVICES]; - uint32_t catalog; + dev_id_t dev_ids[MAX_DEVICES]; + uint32_t catalog; - get_device_identifiers(dev_ids); - get_catalog(&catalog); + get_device_identifiers(dev_ids); + get_catalog(&catalog); - if (catalog == 0) { - printf("no connected devices\n"); - } else { - for (int i = 0; i < MAX_DEVICES; i++) { - if (catalog & (1 << i)) { - printf("dev_ix = %d: type = %d, year = %d, uid = %llu\n", i, dev_ids[i].type, dev_ids[i].year, dev_ids[i].uid); - } - } - } + if (catalog == 0) { + printf("no connected devices\n"); + } else { + for (int i = 0; i < MAX_DEVICES; i++) { + if (catalog & (1 << i)) { + printf("dev_ix = %d: type = %d, year = %d, uid = %llu\n", i, dev_ids[i].type, dev_ids[i].year, dev_ids[i].uid); + } + } + } } void print_catalog() { - uint32_t catalog; + uint32_t catalog; - get_catalog(&catalog); - print_bitmap(MAX_DEVICES, catalog); + get_catalog(&catalog); + print_bitmap(MAX_DEVICES, catalog); } void print_params(uint32_t devices) { - dev_id_t dev_ids[MAX_DEVICES]; - uint32_t catalog; - device_t *device; - - get_device_identifiers(dev_ids); - get_catalog(&catalog); - - for (int i = 0; i < MAX_DEVICES; i++) { - if ((catalog & (1 << i)) && (devices & (1 << i))) { - device = get_device(dev_ids[i].type); - if (device == NULL) { - printf("Device at index %d with type %d is invalid\n", i, dev_ids[i].type); - continue; - } - printf("dev_ix = %d: name = %s, type = %d, year = %d, uid = %llu\n", i, device->name, dev_ids[i].type, dev_ids[i].year, dev_ids[i].uid); - - for (int s = 0; s < 2; s++) { - //print out the stream header - if (s == 0) { printf("\tDATA stream:\n"); } - else if (s == 1) { printf("\tCOMMAND stream:\n"); } - - //print all params for the device for that stream - for (int j = 0; j < device->num_params; j++) { - switch (device->params[j].type) { - case INT: - printf("\t\tparam_idx = %d, name = %s, value = %d\n", j, device->params[j].name, dev_shm_ptr->params[s][i][j].p_i); - break; - case FLOAT: - printf("\t\tparam_idx = %d, name = %s, value = %f\n", j, device->params[j].name, dev_shm_ptr->params[s][i][j].p_f); - break; - case BOOL: - printf("\t\tparam_idx = %d, name = %s, value = %s\n", j, device->params[j].name, (dev_shm_ptr->params[s][i][j].p_b) ? "True" : "False"); - break; - } - } - } - } - } + dev_id_t dev_ids[MAX_DEVICES]; + uint32_t catalog; + device_t* device; + + get_device_identifiers(dev_ids); + get_catalog(&catalog); + + for (int i = 0; i < MAX_DEVICES; i++) { + if ((catalog & (1 << i)) && (devices & (1 << i))) { + device = get_device(dev_ids[i].type); + if (device == NULL) { + printf("Device at index %d with type %d is invalid\n", i, dev_ids[i].type); + continue; + } + printf("dev_ix = %d: name = %s, type = %d, year = %d, uid = %llu\n", i, device->name, dev_ids[i].type, dev_ids[i].year, dev_ids[i].uid); + + for (int s = 0; s < 2; s++) { + //print out the stream header + if (s == 0) { + printf("\tDATA stream:\n"); + } else if (s == 1) { + printf("\tCOMMAND stream:\n"); + } + + //print all params for the device for that stream + for (int j = 0; j < device->num_params; j++) { + switch (device->params[j].type) { + case INT: + printf("\t\tparam_idx = %d, name = %s, value = %d\n", j, device->params[j].name, dev_shm_ptr->params[s][i][j].p_i); + break; + case FLOAT: + printf("\t\tparam_idx = %d, name = %s, value = %f\n", j, device->params[j].name, dev_shm_ptr->params[s][i][j].p_f); + break; + case BOOL: + printf("\t\tparam_idx = %d, name = %s, value = %s\n", j, device->params[j].name, (dev_shm_ptr->params[s][i][j].p_b) ? "True" : "False"); + break; + } + } + } + } + } } void print_robot_desc() { - // wait on rd_sem - my_sem_wait(rd_sem, "robot_desc_mutex (in print)"); - - printf("Current Robot Description:\n"); - for (int i = 0; i < NUM_DESC_FIELDS; i++) { - switch (i) { - case RUN_MODE: - printf("\tRUN_MODE = %s\n", (rd_shm_ptr->fields[RUN_MODE] == IDLE) ? "IDLE" : - ((rd_shm_ptr->fields[RUN_MODE] == AUTO) ? "AUTO" : ((rd_shm_ptr->fields[RUN_MODE] == TELEOP) ? "TELEOP" : "CHALLENGE"))); - break; - case DAWN: - printf("\tDAWN = %s\n", (rd_shm_ptr->fields[DAWN] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); - break; - case SHEPHERD: - printf("\tSHEPHERD = %s\n", (rd_shm_ptr->fields[SHEPHERD] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); - break; - case GAMEPAD: - printf("\tGAMEPAD = %s\n", (rd_shm_ptr->fields[GAMEPAD] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); - break; - case START_POS: - printf("\tSTART_POS = %s\n", (rd_shm_ptr->fields[START_POS] == LEFT) ? "LEFT" : "RIGHT"); - break; - default: - printf("unknown field\n"); - } - } - printf("\n"); - fflush(stdout); - - //release rd_sem - my_sem_post(rd_sem, "robot_desc_mutex (in print)"); + // wait on rd_sem + my_sem_wait(rd_sem, "robot_desc_mutex (in print)"); + + printf("Current Robot Description:\n"); + for (int i = 0; i < NUM_DESC_FIELDS; i++) { + switch (i) { + case RUN_MODE: + printf("\tRUN_MODE = %s\n", (rd_shm_ptr->fields[RUN_MODE] == IDLE) ? "IDLE" : ((rd_shm_ptr->fields[RUN_MODE] == AUTO) ? "AUTO" : ((rd_shm_ptr->fields[RUN_MODE] == TELEOP) ? "TELEOP" : "CHALLENGE"))); + break; + case DAWN: + printf("\tDAWN = %s\n", (rd_shm_ptr->fields[DAWN] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); + break; + case SHEPHERD: + printf("\tSHEPHERD = %s\n", (rd_shm_ptr->fields[SHEPHERD] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); + break; + case GAMEPAD: + printf("\tGAMEPAD = %s\n", (rd_shm_ptr->fields[GAMEPAD] == CONNECTED) ? "CONNECTED" : "DISCONNECTED"); + break; + case START_POS: + printf("\tSTART_POS = %s\n", (rd_shm_ptr->fields[START_POS] == LEFT) ? "LEFT" : "RIGHT"); + break; + default: + printf("unknown field\n"); + } + } + printf("\n"); + fflush(stdout); + + //release rd_sem + my_sem_post(rd_sem, "robot_desc_mutex (in print)"); } void print_gamepad_state() { - char **button_names = get_button_names(); - char **joystick_names = get_joystick_names(); - uint32_t buttons; - float joysticks[4]; + char** button_names = get_button_names(); + char** joystick_names = get_joystick_names(); + uint32_t buttons; + float joysticks[4]; - printf("Current Gamepad State:\n"); - if (gamepad_read(&buttons, joysticks) == -1) { + printf("Current Gamepad State:\n"); + if (gamepad_read(&buttons, joysticks) == -1) { printf("\tNo gamepad currently connected\n"); } else { printf("\tPushed Buttons:\n"); - // only print pushed buttons (so we don't print out many lines of output each time we all this function) - for (int i = 0; i < NUM_GAMEPAD_BUTTONS; i++) { - if (buttons & (1 << i)) { - printf("\t\t%s\n", button_names[i]); - } - } - printf("\tJoystick Positions:\n"); - // print joystick positions - for (int i = 0; i < 4; i++) { - printf("\t\t%s = %f\n", joystick_names[i], joysticks[i]); - } - printf("\n"); - } + // only print pushed buttons (so we don't print out many lines of output each time we all this function) + for (int i = 0; i < NUM_GAMEPAD_BUTTONS; i++) { + if (buttons & (1 << i)) { + printf("\t\t%s\n", button_names[i]); + } + } + printf("\tJoystick Positions:\n"); + // print joystick positions + for (int i = 0; i < 4; i++) { + printf("\t\t%s = %f\n", joystick_names[i], joysticks[i]); + } + printf("\n"); + } fflush(stdout); } void print_custom_data() { - // wait on log_data_sem - my_sem_wait(log_data_sem, "log_data_mutex (in print)"); - - // print out contents of custom log data shared memory block - printf("Custom logged data (Device %d):\n", MAX_DEVICES); - for (int i = 0; i < log_data_shm_ptr->num_params; i++) { - printf("\t%s: ", log_data_shm_ptr->names[i]); - switch (log_data_shm_ptr->types[i]) { - case INT: - printf("%d\n", log_data_shm_ptr->params[i].p_i); - break; - case FLOAT: - printf("%f\n", log_data_shm_ptr->params[i].p_f); - break; - case BOOL: - printf("%s\n", log_data_shm_ptr->params[i].p_b == 1 ? "True" : "False"); - break; - } - } - - // release log_data_sem - my_sem_post(log_data_sem, "log_data_mutex (in print)"); + // wait on log_data_sem + my_sem_wait(log_data_sem, "log_data_mutex (in print)"); + + // print out contents of custom log data shared memory block + printf("Custom logged data (Device %d):\n", MAX_DEVICES); + for (int i = 0; i < log_data_shm_ptr->num_params; i++) { + printf("\t%s: ", log_data_shm_ptr->names[i]); + switch (log_data_shm_ptr->types[i]) { + case INT: + printf("%d\n", log_data_shm_ptr->params[i].p_i); + break; + case FLOAT: + printf("%f\n", log_data_shm_ptr->params[i].p_f); + break; + case BOOL: + printf("%s\n", log_data_shm_ptr->params[i].p_b == 1 ? "True" : "False"); + break; + } + } + + // release log_data_sem + my_sem_post(log_data_sem, "log_data_mutex (in print)"); } // ************************************ PUBLIC WRAPPER FUNCTIONS ****************************************** // -void generate_sem_name(stream_t stream, int dev_ix, char *name) { - if (stream == DATA) { - sprintf(name, "/data_sem_%d", dev_ix); - } else if (stream == COMMAND) { - sprintf(name, "/command_sem_%d", dev_ix); - } +void generate_sem_name(stream_t stream, int dev_ix, char* name) { + if (stream == DATA) { + sprintf(name, "/data_sem_%d", dev_ix); + } else if (stream == COMMAND) { + sprintf(name, "/command_sem_%d", dev_ix); + } } void shm_init() { - int fd_shm; // file descriptor of the memory-mapped shared memory - char sname[SNAME_SIZE]; // for holding semaphore names - - // open all the semaphores - catalog_sem = my_sem_open(CATALOG_MUTEX_NAME, "catalog mutex"); - cmd_map_sem = my_sem_open(CMDMAP_MUTEX_NAME, "cmd map mutex"); - sub_map_sem = my_sem_open(SUBMAP_MUTEX_NAME, "sub map mutex"); - gp_sem = my_sem_open(GP_MUTEX_NAME, "gamepad mutex"); - rd_sem = my_sem_open(RD_MUTEX_NAME, "robot desc mutex"); - log_data_sem = my_sem_open(LOG_DATA_MUTEX, "log data mutex"); - for (int i = 0; i < MAX_DEVICES; i++) { - generate_sem_name(DATA, i, sname); // get the data name - if ((sems[i].data_sem = sem_open((const char *) sname, 0, 0, 0)) == SEM_FAILED) { - log_printf(ERROR, "sem_open: data sem for dev_ix %d: %s", i, strerror(errno)); - } - generate_sem_name(COMMAND, i, sname); // get the command name - if ((sems[i].command_sem = sem_open((const char *) sname, 0, 0, 0)) == SEM_FAILED) { - log_printf(ERROR, "sem_open: command sem for dev_ix %d: %s", i, strerror(errno)); - } - } - - // open dev shm block and map to client process virtual memory - if ((fd_shm = shm_open(DEV_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT - log_printf(FATAL, "shm_open dev_shm %s", strerror(errno)); - exit(1); - } - if ((dev_shm_ptr = mmap(NULL, sizeof(dev_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { - log_printf(FATAL, "mmap dev_shm: %s", strerror(errno)); - exit(1); - } - if (close(fd_shm) == -1) { - log_printf(ERROR, "close dev_shm %s", strerror(errno)); - } - - // open gamepad shm block and map to client process virtual memory - if ((fd_shm = shm_open(GPAD_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT - log_printf(FATAL, "shm_open: gamepad_shm. %s", strerror(errno)); - exit(1); - } - if ((gp_shm_ptr = mmap(NULL, sizeof(gamepad_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { - log_printf(FATAL, "mmap: gamepad_shm. %s", strerror(errno)); - exit(1); - } - if (close(fd_shm) == -1) { - log_printf(ERROR, "close: gamepad_shm. %s", strerror(errno)); - } - - // open robot desc shm block and map to client process virtual memory - if ((fd_shm = shm_open(ROBOT_DESC_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT - log_printf(FATAL, "shm_open: robot_desc_shm. %s", strerror(errno)); - exit(1); - } - if ((rd_shm_ptr = mmap(NULL, sizeof(robot_desc_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { - log_printf(FATAL, "mmap: robot_desc_shm. %s", strerror(errno)); - exit(1); - } - if (close(fd_shm) == -1) { - log_printf(ERROR, "close: robot_desc_shm. %s", strerror(errno)); - } - - // create log data shm block and map to client process virtual memory - if ((fd_shm = shm_open(LOG_DATA_SHM, O_RDWR | O_CREAT, 0660)) == -1) { - log_printf(FATAL, "shm_open log_data_shm: %s", strerror(errno)); // no O_CREAT - exit(1); - } - if ((log_data_shm_ptr = mmap(NULL, sizeof(log_data_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { - log_printf(FATAL, "mmap log_data_shm: %s", strerror(errno)); - exit(1); - } - if (close(fd_shm) == -1) { - log_printf(ERROR, "close log_data_shm: %s", strerror(errno)); - } - - atexit(shm_close); -} - -void device_connect(dev_id_t dev_id, int *dev_ix) { - // wait on catalog_sem - my_sem_wait(catalog_sem, "catalog_sem"); - - // find a valid dev_ix - for (*dev_ix = 0; *dev_ix < MAX_DEVICES; (*dev_ix)++) { - if (!(dev_shm_ptr->catalog & (1 << *dev_ix))) { // if the spot at dev_ix is free - break; - } - } - if (*dev_ix == MAX_DEVICES) { + int fd_shm; // file descriptor of the memory-mapped shared memory + char sname[SNAME_SIZE]; // for holding semaphore names + + // open all the semaphores + catalog_sem = my_sem_open(CATALOG_MUTEX_NAME, "catalog mutex"); + cmd_map_sem = my_sem_open(CMDMAP_MUTEX_NAME, "cmd map mutex"); + sub_map_sem = my_sem_open(SUBMAP_MUTEX_NAME, "sub map mutex"); + gp_sem = my_sem_open(GP_MUTEX_NAME, "gamepad mutex"); + rd_sem = my_sem_open(RD_MUTEX_NAME, "robot desc mutex"); + log_data_sem = my_sem_open(LOG_DATA_MUTEX, "log data mutex"); + for (int i = 0; i < MAX_DEVICES; i++) { + generate_sem_name(DATA, i, sname); // get the data name + if ((sems[i].data_sem = sem_open((const char*) sname, 0, 0, 0)) == SEM_FAILED) { + log_printf(ERROR, "sem_open: data sem for dev_ix %d: %s", i, strerror(errno)); + } + generate_sem_name(COMMAND, i, sname); // get the command name + if ((sems[i].command_sem = sem_open((const char*) sname, 0, 0, 0)) == SEM_FAILED) { + log_printf(ERROR, "sem_open: command sem for dev_ix %d: %s", i, strerror(errno)); + } + } + + // open dev shm block and map to client process virtual memory + if ((fd_shm = shm_open(DEV_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT + log_printf(FATAL, "shm_open dev_shm %s", strerror(errno)); + exit(1); + } + if ((dev_shm_ptr = mmap(NULL, sizeof(dev_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { + log_printf(FATAL, "mmap dev_shm: %s", strerror(errno)); + exit(1); + } + if (close(fd_shm) == -1) { + log_printf(ERROR, "close dev_shm %s", strerror(errno)); + } + + // open gamepad shm block and map to client process virtual memory + if ((fd_shm = shm_open(GPAD_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT + log_printf(FATAL, "shm_open: gamepad_shm. %s", strerror(errno)); + exit(1); + } + if ((gp_shm_ptr = mmap(NULL, sizeof(gamepad_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { + log_printf(FATAL, "mmap: gamepad_shm. %s", strerror(errno)); + exit(1); + } + if (close(fd_shm) == -1) { + log_printf(ERROR, "close: gamepad_shm. %s", strerror(errno)); + } + + // open robot desc shm block and map to client process virtual memory + if ((fd_shm = shm_open(ROBOT_DESC_SHM_NAME, O_RDWR, 0)) == -1) { // no O_CREAT + log_printf(FATAL, "shm_open: robot_desc_shm. %s", strerror(errno)); + exit(1); + } + if ((rd_shm_ptr = mmap(NULL, sizeof(robot_desc_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { + log_printf(FATAL, "mmap: robot_desc_shm. %s", strerror(errno)); + exit(1); + } + if (close(fd_shm) == -1) { + log_printf(ERROR, "close: robot_desc_shm. %s", strerror(errno)); + } + + // create log data shm block and map to client process virtual memory + if ((fd_shm = shm_open(LOG_DATA_SHM, O_RDWR | O_CREAT, 0660)) == -1) { + log_printf(FATAL, "shm_open log_data_shm: %s", strerror(errno)); // no O_CREAT + exit(1); + } + if ((log_data_shm_ptr = mmap(NULL, sizeof(log_data_shm_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0)) == MAP_FAILED) { + log_printf(FATAL, "mmap log_data_shm: %s", strerror(errno)); + exit(1); + } + if (close(fd_shm) == -1) { + log_printf(ERROR, "close log_data_shm: %s", strerror(errno)); + } + + atexit(shm_close); +} + +void device_connect(dev_id_t dev_id, int* dev_ix) { + // wait on catalog_sem + my_sem_wait(catalog_sem, "catalog_sem"); + + // find a valid dev_ix + for (*dev_ix = 0; *dev_ix < MAX_DEVICES; (*dev_ix)++) { + if (!(dev_shm_ptr->catalog & (1 << *dev_ix))) { // if the spot at dev_ix is free + break; + } + } + if (*dev_ix == MAX_DEVICES) { log_printf(ERROR, "device_connect: maximum device limit %d reached, connection refused", MAX_DEVICES); - my_sem_post(catalog_sem, "catalog_sem"); // release the catalog semaphore - *dev_ix = -1; - return; - } + my_sem_post(catalog_sem, "catalog_sem"); // release the catalog semaphore + *dev_ix = -1; + return; + } - // wait on associated data and command sems - my_sem_wait(sems[*dev_ix].data_sem, "data_sem"); - my_sem_wait(sems[*dev_ix].command_sem, "command_sem"); - my_sem_wait(sub_map_sem, "sub_map_sem"); + // wait on associated data and command sems + my_sem_wait(sems[*dev_ix].data_sem, "data_sem"); + my_sem_wait(sems[*dev_ix].command_sem, "command_sem"); + my_sem_wait(sub_map_sem, "sub_map_sem"); - // fill in dev_id for that device with provided values - dev_shm_ptr->dev_ids[*dev_ix].type = dev_id.type; - dev_shm_ptr->dev_ids[*dev_ix].year = dev_id.year; - dev_shm_ptr->dev_ids[*dev_ix].uid = dev_id.uid; + // fill in dev_id for that device with provided values + dev_shm_ptr->dev_ids[*dev_ix].type = dev_id.type; + dev_shm_ptr->dev_ids[*dev_ix].year = dev_id.year; + dev_shm_ptr->dev_ids[*dev_ix].uid = dev_id.uid; - // update the catalog - dev_shm_ptr->catalog |= (1 << *dev_ix); + // update the catalog + dev_shm_ptr->catalog |= (1 << *dev_ix); - // reset param values to 0 - for (int i = 0; i < MAX_PARAMS; i++) { - dev_shm_ptr->params[DATA][*dev_ix][i] = (const param_val_t) {0}; - dev_shm_ptr->params[COMMAND][*dev_ix][i] = (const param_val_t) {0}; - } + // reset param values to 0 + for (int i = 0; i < MAX_PARAMS; i++) { + dev_shm_ptr->params[DATA][*dev_ix][i] = (const param_val_t){0}; + dev_shm_ptr->params[COMMAND][*dev_ix][i] = (const param_val_t){0}; + } - // reset executor subscriptions to off - dev_shm_ptr->exec_sub_map[0] &= ~(1 << *dev_ix); - dev_shm_ptr->exec_sub_map[*dev_ix + 1] = 0; + // reset executor subscriptions to off + dev_shm_ptr->exec_sub_map[0] &= ~(1 << *dev_ix); + dev_shm_ptr->exec_sub_map[*dev_ix + 1] = 0; - // reset net_handler subscriptions to on - dev_shm_ptr->net_sub_map[0] |= 1 << *dev_ix; - dev_shm_ptr->net_sub_map[*dev_ix + 1] = -1; + // reset net_handler subscriptions to on + dev_shm_ptr->net_sub_map[0] |= 1 << *dev_ix; + dev_shm_ptr->net_sub_map[*dev_ix + 1] = -1; - my_sem_post(sub_map_sem, "sub_map_sem"); - // release associated data and command sems - my_sem_post(sems[*dev_ix].data_sem, "data_sem"); - my_sem_post(sems[*dev_ix].command_sem, "command_sem"); + my_sem_post(sub_map_sem, "sub_map_sem"); + // release associated data and command sems + my_sem_post(sems[*dev_ix].data_sem, "data_sem"); + my_sem_post(sems[*dev_ix].command_sem, "command_sem"); - // release catalog_sem - my_sem_post(catalog_sem, "catalog_sem"); + // release catalog_sem + my_sem_post(catalog_sem, "catalog_sem"); } void device_disconnect(int dev_ix) { - // wait on catalog_sem - my_sem_wait(catalog_sem, "catalog_sem"); + // wait on catalog_sem + my_sem_wait(catalog_sem, "catalog_sem"); - // wait on associated data and command sems - my_sem_wait(sems[dev_ix].data_sem, "data_sem"); - my_sem_wait(sems[dev_ix].command_sem, "command_sem"); - my_sem_wait(cmd_map_sem, "cmd_map_sem"); + // wait on associated data and command sems + my_sem_wait(sems[dev_ix].data_sem, "data_sem"); + my_sem_wait(sems[dev_ix].command_sem, "command_sem"); + my_sem_wait(cmd_map_sem, "cmd_map_sem"); - // update the catalog - dev_shm_ptr->catalog &= (~(1 << dev_ix)); + // update the catalog + dev_shm_ptr->catalog &= (~(1 << dev_ix)); - // reset cmd bitmap values to 0 - dev_shm_ptr->cmd_map[0] &= (~(1 << dev_ix)); // reset the changed bit flag in cmd_map[0] - dev_shm_ptr->cmd_map[dev_ix + 1] = 0; // turn off all changed bits for the device + // reset cmd bitmap values to 0 + dev_shm_ptr->cmd_map[0] &= (~(1 << dev_ix)); // reset the changed bit flag in cmd_map[0] + dev_shm_ptr->cmd_map[dev_ix + 1] = 0; // turn off all changed bits for the device - my_sem_post(cmd_map_sem, "cmd_map_sem"); - // release associated upstream and downstream sems - my_sem_post(sems[dev_ix].data_sem, "data_sem"); - my_sem_post(sems[dev_ix].command_sem, "command_sem"); + my_sem_post(cmd_map_sem, "cmd_map_sem"); + // release associated upstream and downstream sems + my_sem_post(sems[dev_ix].data_sem, "data_sem"); + my_sem_post(sems[dev_ix].command_sem, "command_sem"); - // release catalog_sem - my_sem_post(catalog_sem, "catalog_sem"); + // release catalog_sem + my_sem_post(catalog_sem, "catalog_sem"); } -int device_read(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t *params) { - // check catalog to see if dev_ix is valid, if not then return immediately - if (!(dev_shm_ptr->catalog & (1 << dev_ix))) { - log_printf(ERROR, "no device at dev_ix = %d, read failed", dev_ix); - return -1; - } +int device_read(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t* params) { + // check catalog to see if dev_ix is valid, if not then return immediately + if (!(dev_shm_ptr->catalog & (1 << dev_ix))) { + log_printf(ERROR, "no device at dev_ix = %d, read failed", dev_ix); + return -1; + } - // call the helper to do the actual reading - device_read_helper(dev_ix, process, stream, params_to_read, params); - return 0; + // call the helper to do the actual reading + device_read_helper(dev_ix, process, stream, params_to_read, params); + return 0; } -int device_read_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_read, param_val_t *params) { - int dev_ix; +int device_read_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_read, param_val_t* params) { + int dev_ix; - // if device doesn't exist, return immediately - if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { - log_printf(ERROR, "no device at dev_uid = %llu, read failed", dev_uid); - return -1; - } + // if device doesn't exist, return immediately + if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { + log_printf(ERROR, "no device at dev_uid = %llu, read failed", dev_uid); + return -1; + } - // call the helper to do the actual reading - device_read_helper(dev_ix, process, stream, params_to_read, params); - return 0; + // call the helper to do the actual reading + device_read_helper(dev_ix, process, stream, params_to_read, params); + return 0; } -int device_write(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t *params) { - // check catalog to see if dev_ix is valid, if not then return immediately - if (!(dev_shm_ptr->catalog & (1 << dev_ix))) { - log_printf(ERROR, "no device at dev_ix = %d, write failed", dev_ix); - return -1; - } +int device_write(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t* params) { + // check catalog to see if dev_ix is valid, if not then return immediately + if (!(dev_shm_ptr->catalog & (1 << dev_ix))) { + log_printf(ERROR, "no device at dev_ix = %d, write failed", dev_ix); + return -1; + } - // call the helper to do the actual reading - device_write_helper(dev_ix, process, stream, params_to_write, params); - return 0; + // call the helper to do the actual reading + device_write_helper(dev_ix, process, stream, params_to_write, params); + return 0; } -int device_write_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_write, param_val_t *params) { - int dev_ix; +int device_write_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_write, param_val_t* params) { + int dev_ix; - // if device doesn't exist, return immediately - if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { - log_printf(ERROR, "no device at dev_uid = %llu, write failed", dev_uid); - return -1; - } + // if device doesn't exist, return immediately + if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { + log_printf(ERROR, "no device at dev_uid = %llu, write failed", dev_uid); + return -1; + } - // call the helper to do the actual reading - device_write_helper(dev_ix, process, stream, params_to_write, params); - return 0; + // call the helper to do the actual reading + device_write_helper(dev_ix, process, stream, params_to_write, params); + return 0; } int place_sub_request(uint64_t dev_uid, process_t process, uint32_t params_to_sub) { - int dev_ix; // dev_ix that we're operating on - uint32_t *curr_sub_map; // sub map that we're operating on - - // validate request and obtain dev_ix, sub_map - if (process != NET_HANDLER && process != EXECUTOR) { - log_printf(ERROR, "calling place_sub_request from process %u", process); - return -1; - } - if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { - log_printf(ERROR, "no device at dev_uid = %llu, sub request failed", dev_uid); - return -1; - } - curr_sub_map = (process == NET_HANDLER) ? dev_shm_ptr->net_sub_map : dev_shm_ptr->exec_sub_map; - - // wait on sub_map_sem - my_sem_wait(sub_map_sem, "sub_map_sem"); - - // only fill in params_to_sub if it's different from what's already there - if (curr_sub_map[dev_ix + 1] != params_to_sub) { - curr_sub_map[dev_ix + 1] = params_to_sub; - curr_sub_map[0] |= (1 << dev_ix); // turn on corresponding bit - } - - // release sub_map_sem - my_sem_post(sub_map_sem, "sub_map_sem"); - - return 0; + int dev_ix; // dev_ix that we're operating on + uint32_t* curr_sub_map; // sub map that we're operating on + + // validate request and obtain dev_ix, sub_map + if (process != NET_HANDLER && process != EXECUTOR) { + log_printf(ERROR, "calling place_sub_request from process %u", process); + return -1; + } + if ((dev_ix = get_dev_ix_from_uid(dev_uid)) == -1) { + log_printf(ERROR, "no device at dev_uid = %llu, sub request failed", dev_uid); + return -1; + } + curr_sub_map = (process == NET_HANDLER) ? dev_shm_ptr->net_sub_map : dev_shm_ptr->exec_sub_map; + + // wait on sub_map_sem + my_sem_wait(sub_map_sem, "sub_map_sem"); + + // only fill in params_to_sub if it's different from what's already there + if (curr_sub_map[dev_ix + 1] != params_to_sub) { + curr_sub_map[dev_ix + 1] = params_to_sub; + curr_sub_map[0] |= (1 << dev_ix); // turn on corresponding bit + } + + // release sub_map_sem + my_sem_post(sub_map_sem, "sub_map_sem"); + + return 0; } void get_sub_requests(uint32_t sub_map[MAX_DEVICES + 1], process_t process) { - // wait on sub_map_sem - my_sem_wait(sub_map_sem, "sub_map_sem"); - - // bitwise OR the changes into sub_map[0]; if no changes then return - if (process == NET_HANDLER) { - sub_map[0] = dev_shm_ptr->net_sub_map[0]; - } else if (process == EXECUTOR) { - sub_map[0] = dev_shm_ptr->exec_sub_map[0]; - } else { - sub_map[0] = dev_shm_ptr->net_sub_map[0] | dev_shm_ptr->exec_sub_map[0]; - } - - if (sub_map[0] == 0 && process == DEV_HANDLER) { - my_sem_post(sub_map_sem, "sub_map_sem"); - return; - } - - // bitwise OR each valid element together into sub_map[i] - for (int i = 1; i < MAX_DEVICES + 1; i++) { - if (dev_shm_ptr->catalog & (1 << (i - 1))) { // if device exists - if (process == NET_HANDLER) { - sub_map[i] = dev_shm_ptr->net_sub_map[i]; - } else if (process == EXECUTOR) { - sub_map[i] = dev_shm_ptr->exec_sub_map[i]; - } else { - sub_map[i] = dev_shm_ptr->net_sub_map[i] | dev_shm_ptr->exec_sub_map[i]; - } - } else { - sub_map[0] &= ~(1 << (i - 1)); - sub_map[i] = 0; - } - } - - if (process == DEV_HANDLER) { - // reset the change indicator eleemnts in net_sub_map and exec_sub_map - dev_shm_ptr->net_sub_map[0] = dev_shm_ptr->exec_sub_map[0] = 0; - } - - // release sub_map_sem - my_sem_post(sub_map_sem, "sub_map_sem"); + // wait on sub_map_sem + my_sem_wait(sub_map_sem, "sub_map_sem"); + + // bitwise OR the changes into sub_map[0]; if no changes then return + if (process == NET_HANDLER) { + sub_map[0] = dev_shm_ptr->net_sub_map[0]; + } else if (process == EXECUTOR) { + sub_map[0] = dev_shm_ptr->exec_sub_map[0]; + } else { + sub_map[0] = dev_shm_ptr->net_sub_map[0] | dev_shm_ptr->exec_sub_map[0]; + } + + if (sub_map[0] == 0 && process == DEV_HANDLER) { + my_sem_post(sub_map_sem, "sub_map_sem"); + return; + } + + // bitwise OR each valid element together into sub_map[i] + for (int i = 1; i < MAX_DEVICES + 1; i++) { + if (dev_shm_ptr->catalog & (1 << (i - 1))) { // if device exists + if (process == NET_HANDLER) { + sub_map[i] = dev_shm_ptr->net_sub_map[i]; + } else if (process == EXECUTOR) { + sub_map[i] = dev_shm_ptr->exec_sub_map[i]; + } else { + sub_map[i] = dev_shm_ptr->net_sub_map[i] | dev_shm_ptr->exec_sub_map[i]; + } + } else { + sub_map[0] &= ~(1 << (i - 1)); + sub_map[i] = 0; + } + } + + if (process == DEV_HANDLER) { + // reset the change indicator eleemnts in net_sub_map and exec_sub_map + dev_shm_ptr->net_sub_map[0] = dev_shm_ptr->exec_sub_map[0] = 0; + } + + // release sub_map_sem + my_sem_post(sub_map_sem, "sub_map_sem"); } void get_cmd_map(uint32_t bitmap[MAX_DEVICES + 1]) { - // wait on cmd_map_sem - my_sem_wait(cmd_map_sem, "cmd_map_sem"); + // wait on cmd_map_sem + my_sem_wait(cmd_map_sem, "cmd_map_sem"); - for (int i = 0; i < MAX_DEVICES + 1; i++) { - bitmap[i] = dev_shm_ptr->cmd_map[i]; - } + for (int i = 0; i < MAX_DEVICES + 1; i++) { + bitmap[i] = dev_shm_ptr->cmd_map[i]; + } - // release cmd_map_sem - my_sem_post(cmd_map_sem, "cmd_map_sem"); + // release cmd_map_sem + my_sem_post(cmd_map_sem, "cmd_map_sem"); } void get_device_identifiers(dev_id_t dev_ids[MAX_DEVICES]) { - // wait on catalog_sem - my_sem_wait(catalog_sem, "catalog_sem"); + // wait on catalog_sem + my_sem_wait(catalog_sem, "catalog_sem"); - for (int i = 0; i < MAX_DEVICES; i++) { - dev_ids[i] = dev_shm_ptr->dev_ids[i]; - } + for (int i = 0; i < MAX_DEVICES; i++) { + dev_ids[i] = dev_shm_ptr->dev_ids[i]; + } - // release catalog_sem - my_sem_post(catalog_sem, "catalog_sem"); + // release catalog_sem + my_sem_post(catalog_sem, "catalog_sem"); } -void get_catalog(uint32_t *catalog) { - // wait on catalog_sem - my_sem_wait(catalog_sem, "catalog_sem"); +void get_catalog(uint32_t* catalog) { + // wait on catalog_sem + my_sem_wait(catalog_sem, "catalog_sem"); - *catalog = dev_shm_ptr->catalog; + *catalog = dev_shm_ptr->catalog; - // release catalog_sem - my_sem_post(catalog_sem, "catalog_sem"); + // release catalog_sem + my_sem_post(catalog_sem, "catalog_sem"); } robot_desc_val_t robot_desc_read(robot_desc_field_t field) { - robot_desc_val_t ret; + robot_desc_val_t ret; - // wait on rd_sem - my_sem_wait(rd_sem, "robot_desc_mutex"); + // wait on rd_sem + my_sem_wait(rd_sem, "robot_desc_mutex"); - // read the value out, and turn off the appropriate element - ret = rd_shm_ptr->fields[field]; + // read the value out, and turn off the appropriate element + ret = rd_shm_ptr->fields[field]; - // release rd_sem - my_sem_post(rd_sem, "robot_desc_mutex"); + // release rd_sem + my_sem_post(rd_sem, "robot_desc_mutex"); - return ret; + return ret; } void robot_desc_write(robot_desc_field_t field, robot_desc_val_t val) { - // wait on rd_sem - my_sem_wait(rd_sem, "robot_desc_mutex"); + // wait on rd_sem + my_sem_wait(rd_sem, "robot_desc_mutex"); - // write the val into the field, and set appropriate pending element to 1 - rd_shm_ptr->fields[field] = val; + // write the val into the field, and set appropriate pending element to 1 + rd_shm_ptr->fields[field] = val; - // release rd_sem - my_sem_post(rd_sem, "robot_desc_mutex"); + // release rd_sem + my_sem_post(rd_sem, "robot_desc_mutex"); } -int gamepad_read(uint32_t *pressed_buttons, float joystick_vals[4]) { - // wait on rd_sem - my_sem_wait(rd_sem, "robot_desc_mutex"); +int gamepad_read(uint32_t* pressed_buttons, float joystick_vals[4]) { + // wait on rd_sem + my_sem_wait(rd_sem, "robot_desc_mutex"); - // if no gamepad connected, then release rd_sem and return - if (rd_shm_ptr->fields[GAMEPAD] == DISCONNECTED) { - log_printf(ERROR, "tried to read, but no gamepad connected"); - my_sem_post(rd_sem, "robot_desc_mutex"); - return -1; - } + // if no gamepad connected, then release rd_sem and return + if (rd_shm_ptr->fields[GAMEPAD] == DISCONNECTED) { + log_printf(ERROR, "tried to read, but no gamepad connected"); + my_sem_post(rd_sem, "robot_desc_mutex"); + return -1; + } - // release rd_sem - my_sem_post(rd_sem, "robot_desc_mutex"); + // release rd_sem + my_sem_post(rd_sem, "robot_desc_mutex"); - // wait on gp_sem - my_sem_wait(gp_sem, "gamepad_mutex"); + // wait on gp_sem + my_sem_wait(gp_sem, "gamepad_mutex"); - *pressed_buttons = gp_shm_ptr->buttons; - for (int i = 0; i < 4; i++) { - joystick_vals[i] = gp_shm_ptr->joysticks[i]; - } + *pressed_buttons = gp_shm_ptr->buttons; + for (int i = 0; i < 4; i++) { + joystick_vals[i] = gp_shm_ptr->joysticks[i]; + } - // release gp_sem - my_sem_post(gp_sem, "gamepad_mutex"); + // release gp_sem + my_sem_post(gp_sem, "gamepad_mutex"); - return 0; + return 0; } int gamepad_write(uint32_t pressed_buttons, float joystick_vals[4]) { - // wait on rd_sem - my_sem_wait(rd_sem, "robot_desc_mutex"); - - // if no gamepad connected, then release rd_sem and return - if (rd_shm_ptr->fields[GAMEPAD] == DISCONNECTED) { - log_printf(ERROR, "tried to write, but no gamepad connected"); - my_sem_post(rd_sem, "robot_desc_mutex"); - return -1; - } - - // release rd_sem - my_sem_post(rd_sem, "robot_desc_mutex"); - - // wait on gp_sem - my_sem_wait(gp_sem, "gamepad_mutex"); - - gp_shm_ptr->buttons = pressed_buttons; - for (int i = 0; i < 4; i++) { - gp_shm_ptr->joysticks[i] = joystick_vals[i]; - } - - // release gp_sem - my_sem_post(gp_sem, "gamepad_mutex"); - - return 0; -} - -int log_data_write(char *key, param_type_t type, param_val_t value) { - // wait on log_data_sem - my_sem_wait(log_data_sem, "log_data_mutex"); - - // find the index corresponding to this key in the log_data shm block - int idx = 0; - for ( ; idx < log_data_shm_ptr->num_params; idx++) { - if (strcmp(key, log_data_shm_ptr->names[idx]) == 0) { - break; - } - } - - // return if we didn't find the log data corresponding to this key - if (idx == UCHAR_MAX) { - log_printf(ERROR, "Maximum number of %d log data keys reached. can't add key %s", UCHAR_MAX, key); - return -1; - } - - // copy over the name, type, and parameter of the log data into the shared memory block - strcpy(log_data_shm_ptr->names[idx], key); - log_data_shm_ptr->types[idx] = type; - log_data_shm_ptr->params[idx] = value; - - // if this a new parameter, increment the number of parameters in log data shared memory block - if (idx == log_data_shm_ptr->num_params) { - log_data_shm_ptr->num_params++; - } - - // release log_data_sem - my_sem_post(log_data_sem, "log_data_mutex"); - - return 0; -} - -void log_data_read(uint8_t *num_params, char names[UCHAR_MAX][64], param_type_t types[UCHAR_MAX], param_val_t values[UCHAR_MAX]) { - // wait on log_data_sem - my_sem_wait(log_data_sem, "log_data_mutex"); - - // read all of the data in the log data shared memory block into provided pointers - *num_params = log_data_shm_ptr->num_params; - for (int i = 0; i < *num_params; i++) { - strcpy(names[i], log_data_shm_ptr->names[i]); - types[i] = log_data_shm_ptr->types[i]; - values[i] = log_data_shm_ptr->params[i]; - } - - // release log_data_sem - my_sem_post(log_data_sem, "log_data_mutex"); + // wait on rd_sem + my_sem_wait(rd_sem, "robot_desc_mutex"); + + // if no gamepad connected, then release rd_sem and return + if (rd_shm_ptr->fields[GAMEPAD] == DISCONNECTED) { + log_printf(ERROR, "tried to write, but no gamepad connected"); + my_sem_post(rd_sem, "robot_desc_mutex"); + return -1; + } + + // release rd_sem + my_sem_post(rd_sem, "robot_desc_mutex"); + + // wait on gp_sem + my_sem_wait(gp_sem, "gamepad_mutex"); + + gp_shm_ptr->buttons = pressed_buttons; + for (int i = 0; i < 4; i++) { + gp_shm_ptr->joysticks[i] = joystick_vals[i]; + } + + // release gp_sem + my_sem_post(gp_sem, "gamepad_mutex"); + + return 0; +} + +int log_data_write(char* key, param_type_t type, param_val_t value) { + // wait on log_data_sem + my_sem_wait(log_data_sem, "log_data_mutex"); + + // find the index corresponding to this key in the log_data shm block + int idx = 0; + for (; idx < log_data_shm_ptr->num_params; idx++) { + if (strcmp(key, log_data_shm_ptr->names[idx]) == 0) { + break; + } + } + + // return if we didn't find the log data corresponding to this key + if (idx == UCHAR_MAX) { + log_printf(ERROR, "Maximum number of %d log data keys reached. can't add key %s", UCHAR_MAX, key); + return -1; + } + + // copy over the name, type, and parameter of the log data into the shared memory block + strcpy(log_data_shm_ptr->names[idx], key); + log_data_shm_ptr->types[idx] = type; + log_data_shm_ptr->params[idx] = value; + + // if this a new parameter, increment the number of parameters in log data shared memory block + if (idx == log_data_shm_ptr->num_params) { + log_data_shm_ptr->num_params++; + } + + // release log_data_sem + my_sem_post(log_data_sem, "log_data_mutex"); + + return 0; +} + +void log_data_read(uint8_t* num_params, char names[UCHAR_MAX][64], param_type_t types[UCHAR_MAX], param_val_t values[UCHAR_MAX]) { + // wait on log_data_sem + my_sem_wait(log_data_sem, "log_data_mutex"); + + // read all of the data in the log data shared memory block into provided pointers + *num_params = log_data_shm_ptr->num_params; + for (int i = 0; i < *num_params; i++) { + strcpy(names[i], log_data_shm_ptr->names[i]); + types[i] = log_data_shm_ptr->types[i]; + values[i] = log_data_shm_ptr->params[i]; + } + + // release log_data_sem + my_sem_post(log_data_sem, "log_data_mutex"); } diff --git a/shm_wrapper/shm_wrapper.h b/shm_wrapper/shm_wrapper.h index f3a5c906..6f03f26b 100644 --- a/shm_wrapper/shm_wrapper.h +++ b/shm_wrapper/shm_wrapper.h @@ -1,18 +1,18 @@ #ifndef SHM_WRAPPER_H #define SHM_WRAPPER_H -#include // for semaphores -#include // for posix shared memory -#include // for UCHAR_MAX +#include // for UCHAR_MAX +#include // for semaphores +#include // for posix shared memory #include "../logger/logger.h" // for logger #include "../runtime_util/runtime_util.h" // for runtime constants // names of various objects used in shm_wrapper; should not be used outside of shm_wrapper.c, shm_start.c, and shm_stop.c -#define CATALOG_MUTEX_NAME "/ct-mutex" // name of semaphore used as a mutex on the catalog -#define CMDMAP_MUTEX_NAME "/cmap-mutex" // name of semaphore used as a mutex on the command bitmap -#define SUBMAP_MUTEX_NAME "/smap-mutex" // name of semaphore used as a mutex on the various subcription bitmaps -#define DEV_SHM_NAME "/dev-shm" // name of shared memory block across devices +#define CATALOG_MUTEX_NAME "/ct-mutex" // name of semaphore used as a mutex on the catalog +#define CMDMAP_MUTEX_NAME "/cmap-mutex" // name of semaphore used as a mutex on the command bitmap +#define SUBMAP_MUTEX_NAME "/smap-mutex" // name of semaphore used as a mutex on the various subcription bitmaps +#define DEV_SHM_NAME "/dev-shm" // name of shared memory block across devices #define GPAD_SHM_NAME "/gp-shm" // name of shared memory block for gamepad #define ROBOT_DESC_SHM_NAME "/rd-shm" // name of shared memory block for robot description @@ -21,46 +21,47 @@ #define LOG_DATA_SHM "/log-data-shm" // name of shared memory block for Robot.log data #define LOG_DATA_MUTEX "/log-data-sem" // name of semaphore used as mutex over Robot.log shm -#define SNAME_SIZE 32 // size of buffers that hold semaphore names, in bytes +#define SNAME_SIZE 32 // size of buffers that hold semaphore names, in bytes // *********************************** SHM TYPEDEFS ****************************************************** // // enumerated names for the two associated blocks per device -typedef enum stream { DATA, COMMAND } stream_t; +typedef enum stream { DATA, + COMMAND } stream_t; // shared memory block that holds device information, data, and commands has this structure typedef struct { - uint32_t catalog; // catalog of valid devices - uint32_t cmd_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params of device commands from executor to dev_handler) - uint32_t net_sub_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params in which data net_handler is subscribed to) - uint32_t exec_sub_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params in which data executor is subscribed to) - param_val_t params[2][MAX_DEVICES][MAX_PARAMS]; // all the device parameter info, data and commands - dev_id_t dev_ids[MAX_DEVICES]; // all the device identification info + uint32_t catalog; // catalog of valid devices + uint32_t cmd_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params of device commands from executor to dev_handler) + uint32_t net_sub_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params in which data net_handler is subscribed to) + uint32_t exec_sub_map[MAX_DEVICES + 1]; // bitmap is 33 32-bit integers (changed devices and changed params in which data executor is subscribed to) + param_val_t params[2][MAX_DEVICES][MAX_PARAMS]; // all the device parameter info, data and commands + dev_id_t dev_ids[MAX_DEVICES]; // all the device identification info } dev_shm_t; // two mutex semaphores for each device typedef struct { - sem_t *data_sem; // semaphore on the data stream of a device - sem_t *command_sem; // semaphore on the command stream of a device + sem_t* data_sem; // semaphore on the data stream of a device + sem_t* command_sem; // semaphore on the command stream of a device } dual_sem_t; // shared memory for gamepad typedef struct { - uint32_t buttons; // bitmap for which buttons are pressed - float joysticks[4]; // array to hold joystick positions + uint32_t buttons; // bitmap for which buttons are pressed + float joysticks[4]; // array to hold joystick positions } gamepad_shm_t; // shared memory for robot description typedef struct { - uint8_t fields[NUM_DESC_FIELDS]; // array to hold the robot state (each is a uint8_t) + uint8_t fields[NUM_DESC_FIELDS]; // array to hold the robot state (each is a uint8_t) } robot_desc_shm_t; // shared memory for Robot.log data typedef struct { - uint8_t num_params; // number of quantities the student wants to log - char names[UCHAR_MAX][64]; // keys (names) of quantities that student wants to log - param_val_t params[UCHAR_MAX]; // values of quantities that student wants to log - param_type_t types[UCHAR_MAX]; // types of the values that student wants to log + uint8_t num_params; // number of quantities the student wants to log + char names[UCHAR_MAX][64]; // keys (names) of quantities that student wants to log + param_val_t params[UCHAR_MAX]; // values of quantities that student wants to log + param_type_t types[UCHAR_MAX]; // types of the values that student wants to log } log_data_shm_t; // *********************************** SHM EXTERNAL VARIABLES ******************************************** // @@ -68,19 +69,19 @@ typedef struct { // DO NOT USE THESE UNDER NORMAL CIRCUMSTANCES // THESE ARE ONLY USED TO SIMPLIFY CODE IN SHM_START AND SHM_STOP -extern dual_sem_t sems[MAX_DEVICES]; // array of semaphores, two for each possible device (one for data and one for commands) -extern dev_shm_t *dev_shm_ptr; // points to memory-mapped shared memory block for device data and commands -extern sem_t *catalog_sem; // semaphore used as a mutex on the catalog -extern sem_t *cmd_map_sem; // semaphore used as a mutex on the command bitmap -extern sem_t *sub_map_sem; // semaphore used as a mutex on the subscription bitmap +extern dual_sem_t sems[MAX_DEVICES]; // array of semaphores, two for each possible device (one for data and one for commands) +extern dev_shm_t* dev_shm_ptr; // points to memory-mapped shared memory block for device data and commands +extern sem_t* catalog_sem; // semaphore used as a mutex on the catalog +extern sem_t* cmd_map_sem; // semaphore used as a mutex on the command bitmap +extern sem_t* sub_map_sem; // semaphore used as a mutex on the subscription bitmap -extern gamepad_shm_t *gp_shm_ptr; // points to memory-mapped shared memory block for gamepad -extern robot_desc_shm_t *rd_shm_ptr; // points to memory-mapped shared memory block for robot description -extern sem_t *gp_sem; // semaphore used as a mutex on the gamepad -extern sem_t *rd_sem; // semaphore used as a mutex on the robot description +extern gamepad_shm_t* gp_shm_ptr; // points to memory-mapped shared memory block for gamepad +extern robot_desc_shm_t* rd_shm_ptr; // points to memory-mapped shared memory block for robot description +extern sem_t* gp_sem; // semaphore used as a mutex on the gamepad +extern sem_t* rd_sem; // semaphore used as a mutex on the robot description -extern log_data_shm_t *log_data_shm_ptr; // points to shared memory block for log data specified by executor -extern sem_t *log_data_sem; // semaphore used as a mutex on the log data +extern log_data_shm_t* log_data_shm_ptr; // points to shared memory block for log data specified by executor +extern sem_t* log_data_sem; // semaphore used as a mutex on the log data // ******************************************* PRINTING UTILITIES ***************************************** // @@ -137,7 +138,7 @@ void print_custom_data(); * dev_ix: index of device whose STREAM is being created * name: pointer to a buffer of size SNAME_SIZE into which the name of the semaphore will be put */ -void generate_sem_name (stream_t stream, int dev_ix, char *name); +void generate_sem_name(stream_t stream, int dev_ix, char* name); /** * Call this function from every process that wants to use the shared memory wrapper @@ -155,7 +156,7 @@ void shm_init(); * dev_ix: the index that the device was assigned will be put here * Returns device index of connected device in dev_ix on success; sets *dev_ix = -1 on failure */ -void device_connect(dev_id_t dev_id, int *dev_ix); +void device_connect(dev_id_t dev_id, int* dev_ix); /** * Should only be called from device handler @@ -179,13 +180,13 @@ void device_disconnect(int dev_ix); * 0 on success * -1 on failure (specified device is not connected in shm) */ -int device_read(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t *params); +int device_read(int dev_ix, process_t process, stream_t stream, uint32_t params_to_read, param_val_t* params); /** * This function is the exact same as the above function, but instead uses the 64-bit device UID to identify * the device that should be read, rather than the device index. */ -int device_read_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_read, param_val_t *params); +int device_read_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_read, param_val_t* params); /** * Should be called from every process wanting to write to the device data @@ -202,13 +203,13 @@ int device_read_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32 * 0 on success * -1 on failure (specified device is not connected in shm) */ -int device_write(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t *params); +int device_write(int dev_ix, process_t process, stream_t stream, uint32_t params_to_write, param_val_t* params); /** * This function is the exact same as the above function, but instead uses the 64-bit device UID to identify * the device that should be written, rather than the device index. */ -int device_write_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_write, param_val_t *params); +int device_write_uid(uint64_t dev_uid, process_t process, stream_t stream, uint32_t params_to_write, param_val_t* params); /** * Send a sub request to dev_handler for a particular device. Takes care of updating the changed bits. @@ -257,7 +258,7 @@ void get_device_identifiers(dev_id_t dev_ids[MAX_DEVICES]); * Arguments: * catalog: pointer to 32-bit integer into which the current catalog will be read into */ -void get_catalog(uint32_t *catalog); +void get_catalog(uint32_t* catalog); /** * Reads the specified robot description field. Blocks on the robot description semaphore. @@ -285,7 +286,7 @@ void robot_desc_write(robot_desc_field_t field, robot_desc_val_t val); * 0 on success * -1 on failure (if gamepad is not connected) */ -int gamepad_read(uint32_t *pressed_buttons, float joystick_vals[4]); +int gamepad_read(uint32_t* pressed_buttons, float joystick_vals[4]); /** * This function writes the given state of the gamepad to shared memory. @@ -310,7 +311,7 @@ int gamepad_write(uint32_t pressed_buttons, float joystick_vals[4]); * 0 on success * -1 on failure (maximum number of custom parameters is reached so this parameter isn't written) */ -int log_data_write(char *key, param_type_t type, param_val_t value); +int log_data_write(char* key, param_type_t type, param_val_t value); /** * Reads the custom log data from shared memory. @@ -320,6 +321,6 @@ int log_data_write(char *key, param_type_t type, param_val_t value); * types: array that will be filled with the parameter types, up to `num_params` * values: array that will be filled with the parameter values, up to `num_params` */ -void log_data_read(uint8_t *num_params, char names[UCHAR_MAX][64], param_type_t types[UCHAR_MAX], param_val_t values[UCHAR_MAX]); +void log_data_read(uint8_t* num_params, char names[UCHAR_MAX][64], param_type_t types[UCHAR_MAX], param_val_t values[UCHAR_MAX]); #endif \ No newline at end of file diff --git a/shm_wrapper/shm_wrapper_test1.c b/shm_wrapper/shm_wrapper_test1.c index 194036c8..a391f3bf 100644 --- a/shm_wrapper/shm_wrapper_test1.c +++ b/shm_wrapper/shm_wrapper_test1.c @@ -1,10 +1,10 @@ +#include +#include +#include #include #include -#include -#include #include -#include -#include +#include #include "shm_wrapper.h" // test process 1 for shm_wrapper. is a dummy device handler. @@ -14,21 +14,21 @@ void device_connect_fields(uint16_t type, uint8_t year, uint64_t uid) { int dev_ix; - dev_id_t dev_id = { type, year, uid }; + dev_id_t dev_id = {type, year, uid}; device_connect(dev_id, &dev_ix); } void sync() { param_val_t params_in[MAX_PARAMS]; param_val_t params_out[MAX_PARAMS]; - - device_connect_fields(0, 0, 48482); // this will connect in dev_ix = 0 + + device_connect_fields(0, 0, 48482); // this will connect in dev_ix = 0 params_in[0].p_b = 0; - device_write(0, DEV_HANDLER, DATA, 1, params_in); // write a 0 to the upstream block + device_write(0, DEV_HANDLER, DATA, 1, params_in); // write a 0 to the upstream block params_in[0].p_b = 1; while (1) { - device_write(0, DEV_HANDLER, COMMAND, 1, params_in); // write 1 to the downstream block - device_read(0, DEV_HANDLER, DATA, 1, params_out); // wait on a 1 in the upstream block + device_write(0, DEV_HANDLER, COMMAND, 1, params_in); // write 1 to the downstream block + device_read(0, DEV_HANDLER, DATA, 1, params_out); // wait on a 1 in the upstream block if (params_out[0].p_b) { break; } @@ -42,18 +42,18 @@ void sync() { // *************************************************************************************************** // // test the param bitmap and sanity check to make sure shm connection is functioning -void sanity_test() { +void sanity_test() { param_val_t params_out[MAX_PARAMS]; uint32_t pmap[33]; - + sync(); - + device_connect_fields(0, 3, 382726112); - + print_dev_ids(); - + printf("Beginning sanity test...\n"); - + // process2 writes five times to this block; we read it out and print it for (int i = 0; i < 5; i++) { // test to see if anything has changed @@ -69,18 +69,18 @@ void sanity_test() { if (pmap[0] & (1 << j)) { device_read(j, DEV_HANDLER, COMMAND, pmap[j + 1], params_out); for (int k = 0; k < MAX_PARAMS; k++) { - if (pmap[j+1] & (1 << k)) { + if (pmap[j + 1] & (1 << k)) { printf("num = %d, p_i = %d, p_f = %f, p_b = %u\n", i, params_out[i].p_i, params_out[i].p_f, params_out[i].p_b); } } } } } - + sleep(1); - + device_disconnect(0); - + printf("Done!\n"); } @@ -92,11 +92,11 @@ void sanity_test() { void dev_conn_test() { dev_id_t new_dev; int dev_ix; - + sync(); - + printf("Beginning device connection test...\n"); - + // connect as many devices as possible for (int i = 0; i < MAX_DEVICES; i++) { // randomly chosen quadratic function that is positive and integral in range [0, 32] for the lols @@ -104,30 +104,30 @@ void dev_conn_test() { } print_dev_ids(); device_connect_fields(1, 2, 4845873); - device_connect(new_dev, &dev_ix); // trying to connect one more should error + device_connect(new_dev, &dev_ix); // trying to connect one more should error sleep(1); - + // try and disconnect 3 devices and then adding 3 more devices device_disconnect(2); device_disconnect(8); device_disconnect(7); print_dev_ids(); - + sleep(1); - + device_connect_fields(10, 0, 65456874); device_connect_fields(14, 2, 32558656); device_connect_fields(3, 1, 798645325); print_dev_ids(); - + sleep(1); - + // disconnect all devices for (int i = 0; i < MAX_DEVICES; i++) { device_disconnect(i); } print_dev_ids(); - + printf("Done!\n\n"); } @@ -139,69 +139,69 @@ void single_thread_load_test() { // writing will be done from process2 // process1 just needs to read from the block as fast as possible int i = 0; - + param_val_t params_out[MAX_PARAMS]; param_val_t params_test[MAX_PARAMS]; uint32_t pmap[MAX_DEVICES + 1]; - + sync(); - + printf("Beginning single threaded load test...\n"); - - device_connect_fields(0, 1, 4894249); // this is going to connect at dev_ix = 0 - device_connect_fields(1, 2, 9848990); // this is going to connect at dev_ix = 1 - + + device_connect_fields(0, 1, 4894249); // this is going to connect at dev_ix = 0 + device_connect_fields(1, 2, 9848990); // this is going to connect at dev_ix = 1 + // write params_test[0].p_b = 0 into the shared memory block for second device so we don't exit the test prematurely - params_test[0].p_b = 0; + params_test[0].p_b = 0; device_write(1, DEV_HANDLER, DATA, 1, params_test); - + // use the second device's p_b on param 0 to indicate when test is done - // we literally just sit here pulling information from the block as fast as possible + // we literally just sit here pulling information from the block as fast as possible // until process2 says we're good while (1) { // check if time to stop i++; if (i == 1000) { - device_read(1, DEV_HANDLER, DATA, 1, params_test); // use the upstream block to not touch the param bitmap + device_read(1, DEV_HANDLER, DATA, 1, params_test); // use the upstream block to not touch the param bitmap if (params_test[0].p_b) { break; } i = 0; } - + // if something changed, pull it out get_cmd_map(pmap); if (pmap[0]) { device_read(0, DEV_HANDLER, COMMAND, pmap[1], params_out); } } - + device_disconnect(1); device_disconnect(0); - + sleep(1); - + printf("Done!\n"); } // *************************************************************************************************** // // threaded function for reading in Dual Thread Read Write Test -void *read_thread_dtrwt(void *arg) { +void* read_thread_dtrwt(void* arg) { int prev_val = 0, count = 0, i = 0; param_val_t params_test[MAX_PARAMS]; param_val_t params_out[MAX_PARAMS]; uint32_t pmap[MAX_DEVICES + 1]; - + // we are reading from the device command block // use the device command block on device 1 so that tester2 can signal end of test - params_test[0].p_b = 0; - device_write(1, DEV_HANDLER, COMMAND, 1, params_test); - - // use the second device device's p_b on param 0 to indicate when test is done - // sit here pulling information from the block as fast as possible, - // and count how many unique values we get until tester2 says we're done + params_test[0].p_b = 0; + device_write(1, DEV_HANDLER, COMMAND, 1, params_test); + + // use the second device device's p_b on param 0 to indicate when test is done + // sit here pulling information from the block as fast as possible, + // and count how many unique values we get until tester2 says we're done while (1) { - // check if time to stop + // check if time to stop i++; if (i == 1000) { device_read(1, DEV_HANDLER, COMMAND, 1, params_test); @@ -210,7 +210,7 @@ void *read_thread_dtrwt(void *arg) { } i = 0; } - + // if something changed, pull it out and record it get_cmd_map(pmap); if (pmap[0]) { @@ -222,16 +222,16 @@ void *read_thread_dtrwt(void *arg) { } } printf("read_thread from tester1 pulled %d unique values from tester2 on downstream block\n", count); - + return NULL; } // threaded function for writing in Dual Thread Read Write Test -void *write_thread_dtrwt(void *arg) { - const int trials = 100000; //write 100000 times to the block +void* write_thread_dtrwt(void* arg) { + const int trials = 100000; //write 100000 times to the block param_val_t params_test[MAX_PARAMS]; param_val_t params_in[MAX_PARAMS]; - + // we are writing to the device data block // write 100,000 times on the device upstream block as fast as possible params_in[0].p_i = 1; @@ -240,11 +240,11 @@ void *write_thread_dtrwt(void *arg) { device_write(0, DEV_HANDLER, DATA, 1, params_in); } printf("write_thread from tester1 wrote %d values to upstream block\n", trials); - + // signal on the device data block on device 1 so tester2 can stop reading params_test[0].p_b = 1; device_write(1, DEV_HANDLER, DATA, 1, params_test); - + return NULL; } @@ -253,35 +253,35 @@ void *write_thread_dtrwt(void *arg) { // writing to the upstream block and reading from the downstream block void dual_thread_read_write_test() { int status; - pthread_t read_tid, write_tid; // thread_ids for the two threads - + pthread_t read_tid, write_tid; // thread_ids for the two threads + sync(); - + printf("Beginning dual thread read write test...\n"); - + device_connect_fields(0, 1, 4894249); device_connect_fields(1, 2, 3556498); - + // create threads if ((status = pthread_create(&read_tid, NULL, read_thread_dtrwt, NULL)) != 0) { printf("read pthread creation failed with exit code %d\n", status); } printf("Read thread created\n"); - + if ((status = pthread_create(&write_tid, NULL, write_thread_dtrwt, NULL)) != 0) { printf("write pthread creation failed with exit code %d\n", status); } printf("Write thread created\n"); - + // wait for the threads to finish pthread_join(read_tid, NULL); pthread_join(write_tid, NULL); - + device_disconnect(0); device_disconnect(1); - + sleep(1); - + printf("Done!\n"); } @@ -294,50 +294,50 @@ void single_thread_load_test_uid() { // process1 just needs to read from the block as fast as possible int dev_uid = 0; int i = 0; - + param_val_t params_out[MAX_PARAMS]; param_val_t params_test[MAX_PARAMS]; uint32_t pmap[MAX_DEVICES + 1]; - + sync(); - + printf("Beginning single threaded load test using UID functions...\n"); - + dev_uid = 4894249; - - device_connect_fields(0, 1, dev_uid); // this is going to connect at dev_ix = 0 - device_connect_fields(1, 2, 9848990); // this is going to connect at dev_ix = 1 - + + device_connect_fields(0, 1, dev_uid); // this is going to connect at dev_ix = 0 + device_connect_fields(1, 2, 9848990); // this is going to connect at dev_ix = 1 + // write params_test[0].p_b = 0 into the shared memory block for second device so we don't exit the test prematurely - params_test[0].p_b = 0; + params_test[0].p_b = 0; device_write(1, DEV_HANDLER, DATA, 1, params_test); - + // use the second device's p_b on param 0 to indicate when test is done - // we literally just sit here pulling information from the block as fast as possible + // we literally just sit here pulling information from the block as fast as possible // until process2 says we're good while (1) { // check if time to stop i++; if (i == 1000) { - device_read(1, DEV_HANDLER, DATA, 1, params_test); // use the upstream block to not touch the param bitmap + device_read(1, DEV_HANDLER, DATA, 1, params_test); // use the upstream block to not touch the param bitmap if (params_test[0].p_b) { break; } i = 0; } - + // if something changed, pull it out get_cmd_map(pmap); if (pmap[0]) { device_read_uid(dev_uid, DEV_HANDLER, COMMAND, pmap[1], params_out); } } - + device_disconnect(1); device_disconnect(0); - + sleep(1); - + printf("Done!\n"); } @@ -347,36 +347,36 @@ void single_thread_load_test_uid() { void sanity_gamepad_test() { uint32_t buttons; float joystick_vals[4]; - + sync(); - + printf("Begin sanity gamepad test...\n"); - - buttons = 34788240; // push some random buttons + + buttons = 34788240; // push some random buttons joystick_vals[JOYSTICK_LEFT_X] = -0.4854; joystick_vals[JOYSTICK_LEFT_Y] = 0.58989; joystick_vals[JOYSTICK_RIGHT_X] = 0.9898; joystick_vals[JOYSTICK_RIGHT_Y] = -0.776; - + gamepad_write(buttons, joystick_vals); print_gamepad_state(); sleep(1); - - buttons = 0; // no buttons pushed + + buttons = 0; // no buttons pushed gamepad_write(buttons, joystick_vals); print_gamepad_state(); sleep(1); - - buttons = 789597848; // push smoe different random buttons + + buttons = 789597848; // push smoe different random buttons joystick_vals[JOYSTICK_LEFT_X] = -0.9489; joystick_vals[JOYSTICK_LEFT_Y] = 0.0; joystick_vals[JOYSTICK_RIGHT_X] = 1.0; joystick_vals[JOYSTICK_RIGHT_Y] = -1.0; - + gamepad_write(buttons, joystick_vals); print_gamepad_state(); sleep(1); - + buttons = 0; for (int i = 0; i < 4; i++) { joystick_vals[i] = 0.0; @@ -391,9 +391,9 @@ void sanity_gamepad_test() { // sanity robot description test void sanity_robot_desc_test() { sync(); - + printf("Begin sanity robot desc test...\n"); - + for (int i = 0; i < 11; i++) { switch (i) { case 0: @@ -424,7 +424,7 @@ void sanity_robot_desc_test() { robot_desc_write(RUN_MODE, IDLE); break; } - usleep(200000); // sleep for 0.2 sec + usleep(200000); // sleep for 0.2 sec } printf("Done!\n\n"); } @@ -434,15 +434,15 @@ void sanity_robot_desc_test() { // check that device subscriptions are working void subscription_test() { uint32_t sub_map[MAX_DEVICES + 1]; - + sync(); - + printf("Begin subscription test...\n"); - + device_connect_fields(0, 3, 382726112); device_connect_fields(1, 3, 248742981); device_connect_fields(2, 3, 893489237); - + for (int i = 0; i < 6; i++) { printf("Processing case %d from test2\n", i - 1); get_sub_requests(sub_map, DEV_HANDLER); @@ -458,11 +458,11 @@ void subscription_test() { } sleep(1); } - + device_disconnect(0); device_disconnect(1); device_disconnect(2); - + printf("Done!\n"); } @@ -477,24 +477,24 @@ void ctrl_c_handler(int sig_num) { int main() { shm_init(); logger_init(DEV_HANDLER); - signal(SIGINT, ctrl_c_handler); // hopefully fails gracefully when pressing Ctrl-C in the terminal - + signal(SIGINT, ctrl_c_handler); // hopefully fails gracefully when pressing Ctrl-C in the terminal + sanity_test(); - + dev_conn_test(); - + single_thread_load_test(); - + dual_thread_read_write_test(); - + single_thread_load_test_uid(); - + robot_desc_write(GAMEPAD, CONNECTED); sanity_gamepad_test(); - + sanity_robot_desc_test(); - + subscription_test(); - + return 0; } \ No newline at end of file diff --git a/shm_wrapper/shm_wrapper_test2.c b/shm_wrapper/shm_wrapper_test2.c index 142a6447..14d15b87 100644 --- a/shm_wrapper/shm_wrapper_test2.c +++ b/shm_wrapper/shm_wrapper_test2.c @@ -1,10 +1,10 @@ +#include +#include +#include #include #include -#include -#include #include -#include -#include +#include #include "shm_wrapper.h" // test process 2 for shm_wrapper. is a dummy executor @@ -26,11 +26,11 @@ void sync() { } params_in[0].p_b = 0; - device_write(0, EXECUTOR, COMMAND, 1, params_in); // write a 0 to the downstream block + device_write(0, EXECUTOR, COMMAND, 1, params_in); // write a 0 to the downstream block params_in[0].p_b = 1; while (1) { - device_write(0, EXECUTOR, DATA, 1, params_in); // write 1 to the upstream block - device_read(0, EXECUTOR, COMMAND, 1, params_out); // wait on a 1 in the downstream block + device_write(0, EXECUTOR, DATA, 1, params_in); // write 1 to the upstream block + device_read(0, EXECUTOR, COMMAND, 1, params_out); // wait on a 1 in the downstream block if (params_out[0].p_b) { break; } @@ -55,11 +55,11 @@ void sanity_test() { params_in[1].p_i = 10; params_in[1].p_f = -0.9; params_in[1].p_b = 1; - + sync(); - + print_dev_ids(); - + // write 5 times to the command block of the device at varying times for (int i = 0; i < 5; i++) { params_in[1].p_i += 10; @@ -67,12 +67,12 @@ void sanity_test() { params_in[1].p_b = 1 - params_in[1].p_b; device_write(0, EXECUTOR, COMMAND, 2, params_in); - + print_cmd_map(); - + sleep((unsigned int) ((float) (i + 2)) / 2.0); } - + print_cmd_map(); } @@ -83,12 +83,12 @@ void sanity_test() { // test disconnecting devices in quick succession void dev_conn_test() { sync(); - + // process2's job is simply to monitor what's going on in the catalog // as devices connect and disconnect. all the work is being done from process1 for (int i = 0; i < 7; i++) { print_dev_ids(); - usleep(500000); // sleep for 0.5 seconds between prints + usleep(500000); // sleep for 0.5 seconds between prints } } @@ -96,26 +96,26 @@ void dev_conn_test() { // test to find approximately how many read/write operations // can be done in a second on a device downstream block between // exeuctor and device handler -void single_thread_load_test() { - int count = 100; //starting number of writes to complete +void single_thread_load_test() { + int count = 100; //starting number of writes to complete double gain = 40000; - - double range = 0.01; // tolerance range of time taken around 1 second for test to complete - int counts[5]; // to hold the counts that resulted in those times + + double range = 0.01; // tolerance range of time taken around 1 second for test to complete + int counts[5]; // to hold the counts that resulted in those times int good_trials = 0; - + struct timeval start, end; double time_taken; - + uint32_t catalog = 0; uint32_t pmap[MAX_DEVICES + 1]; param_val_t params_in[MAX_PARAMS]; params_in[0].p_b = 0; params_in[0].p_i = 1; params_in[0].p_f = 2.0; - + sync(); - + // wait until the two devices connect while (1) { get_catalog(&catalog); @@ -123,7 +123,7 @@ void single_thread_load_test() { break; } } - + // adjust the count until 5 trials lie within 0.01 second of 1 second while (good_trials < 5) { gettimeofday(&start, NULL); @@ -135,26 +135,26 @@ void single_thread_load_test() { break; } } - device_write(0, EXECUTOR, COMMAND, 1, params_in); // write into block + device_write(0, EXECUTOR, COMMAND, 1, params_in); // write into block } gettimeofday(&end, NULL); - - time_taken = (double)(end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec) / 1000000.0); + + time_taken = (double) (end.tv_sec - start.tv_sec) + ((double) (end.tv_usec - start.tv_usec) / 1000000.0); if (time_taken > (1.0 - range) && time_taken < (1.0 + range)) { counts[good_trials++] = count; } else { - count += (int)((1.0 - time_taken) * gain); + count += (int) ((1.0 - time_taken) * gain); } printf("count = %d completed in %f seconds for %f writes / second\n", count, time_taken, (double) count / time_taken); } - + // manually calculate and print the average bc laziness :P - printf("\naverage: %f writes / second\n", (double)(counts[0] + counts[1] + counts[2] + counts[3] + counts[4]) / 5.0); - + printf("\naverage: %f writes / second\n", (double) (counts[0] + counts[1] + counts[2] + counts[3] + counts[4]) / 5.0); + // tell process1 to stop reading params_in[0].p_b = 1; device_write(1, EXECUTOR, DATA, 1, params_in); - + // wait for devices to disconnect while (1) { get_catalog(&catalog); @@ -167,18 +167,18 @@ void single_thread_load_test() { // *************************************************************************************************** // // threaded function for reading in Dual Thread Read Write Test -void *read_thread_dtrwt(void *arg) { +void* read_thread_dtrwt(void* arg) { int prev_val = 0, count = 0, i = 0; param_val_t params_test[MAX_PARAMS]; param_val_t params_out[MAX_PARAMS]; - + // we are reading from the device data block // use the device data block on device 1 so that tester2 can signal end of test params_test[0].p_b = 0; device_write(1, EXECUTOR, DATA, 1, params_test); - + // use the second device device's p_b on param 0 to indicate when test is done - // sit here pulling information from the block as fast as possible, + // sit here pulling information from the block as fast as possible, // and count how many unique values we get until tester1 says we're done while (1) { // check if time to stop @@ -190,7 +190,7 @@ void *read_thread_dtrwt(void *arg) { } i = 0; } - + // pull from that block and record it if changed device_read(0, EXECUTOR, DATA, 1, params_out); if (prev_val != params_out[0].p_i) { @@ -199,17 +199,17 @@ void *read_thread_dtrwt(void *arg) { } } printf("read_thread from tester2 pulled %d unique values from tester2 on upstream block\n", count); - + return NULL; } // threaded function for writing in Dual Thread Read Write Test -void *write_thread_dtrwt(void *arg) { - const int trials = 100000; // write 100,000 times to the block +void* write_thread_dtrwt(void* arg) { + const int trials = 100000; // write 100,000 times to the block param_val_t params_test[MAX_PARAMS]; param_val_t params_in[MAX_PARAMS]; uint32_t pmap[MAX_DEVICES + 1]; - + // we are writing to the device command block // write 100,000 times on the device command block as fast as possible params_in[0].p_i = 1; @@ -221,14 +221,14 @@ void *write_thread_dtrwt(void *arg) { break; } } - device_write(0, EXECUTOR, COMMAND, 1, params_in); // write into block + device_write(0, EXECUTOR, COMMAND, 1, params_in); // write into block } printf("write_thread from tester2 wrote %d values to downstream block\n", trials); - + // signal on the device downnstream block on device 1 so tester1 can stop reading params_test[0].p_b = 1; device_write(1, EXECUTOR, COMMAND, 1, params_test); - + return NULL; } @@ -237,29 +237,29 @@ void *write_thread_dtrwt(void *arg) { // writing to the downstream block and reading from the upstream block void dual_thread_read_write_test() { int status; - pthread_t read_tid, write_tid; // thread_ids for the two threads - + pthread_t read_tid, write_tid; // thread_ids for the two threads + sync(); - + printf("Beginning dual thread read write test...\n"); - + // create threads if ((status = pthread_create(&read_tid, NULL, read_thread_dtrwt, NULL)) != 0) { printf("read pthread creation failed with exit code %d\n", status); } printf("Read thread created\n"); - + if ((status = pthread_create(&write_tid, NULL, write_thread_dtrwt, NULL)) != 0) { printf("write pthread creation failed with exit code %d\n", status); } printf("Write thread created\n"); - + // wait for the threads to finish pthread_join(read_tid, NULL); pthread_join(write_tid, NULL); - + sleep(1); - + printf("Done!\n"); } @@ -271,26 +271,26 @@ void dual_thread_read_write_test() { void single_thread_load_test_uid() { uint64_t dev_uid = 0; dev_id_t dev_ids[MAX_DEVICES]; - - int count = 100; // starting number of writes to complete + + int count = 100; // starting number of writes to complete double gain = 40000; - - double range = 0.01; // tolerance range of time taken around 1 second for test to complete - int counts[5]; // to hold the counts that resulted in those times + + double range = 0.01; // tolerance range of time taken around 1 second for test to complete + int counts[5]; // to hold the counts that resulted in those times int good_trials = 0; - + struct timeval start, end; double time_taken; - + uint32_t catalog = 0; uint32_t pmap[MAX_DEVICES + 1]; param_val_t params_in[MAX_PARAMS]; params_in[0].p_b = 0; params_in[0].p_i = 1; params_in[0].p_f = 2.0; - + sync(); - + // wait until the two devices connect while (1) { get_catalog(&catalog); @@ -298,10 +298,10 @@ void single_thread_load_test_uid() { break; } } - + get_device_identifiers(dev_ids); dev_uid = dev_ids[0].uid; - + // adjust the count until 5 trials lie within 0.01 second of 1 second while (good_trials < 5) { gettimeofday(&start, NULL); @@ -313,26 +313,26 @@ void single_thread_load_test_uid() { break; } } - device_write_uid(dev_uid, EXECUTOR, COMMAND, 1, params_in); // write into block + device_write_uid(dev_uid, EXECUTOR, COMMAND, 1, params_in); // write into block } gettimeofday(&end, NULL); - - time_taken = (double)(end.tv_sec - start.tv_sec) + ((double)(end.tv_usec - start.tv_usec) / 1000000.0); + + time_taken = (double) (end.tv_sec - start.tv_sec) + ((double) (end.tv_usec - start.tv_usec) / 1000000.0); if (time_taken > (1.0 - range) && time_taken < (1.0 + range)) { counts[good_trials++] = count; } else { - count += (int)((1.0 - time_taken) * gain); + count += (int) ((1.0 - time_taken) * gain); } printf("count = %d completed in %f seconds for %f writes / second using UID functions\n", count, time_taken, (double) count / time_taken); } - + // manually calculate and print the average bc laziness :P - printf("\naverage: %f writes / second using UID functions\n", (double)(counts[0] + counts[1] + counts[2] + counts[3] + counts[4]) / 5.0); - + printf("\naverage: %f writes / second using UID functions\n", (double) (counts[0] + counts[1] + counts[2] + counts[3] + counts[4]) / 5.0); + // tell process1 to stop reading params_in[0].p_b = 1; device_write(1, EXECUTOR, DATA, 1, params_in); - + // wait for devices to disconnect while (1) { get_catalog(&catalog); @@ -349,11 +349,11 @@ void single_thread_load_test_uid() { void sanity_gamepad_test() { uint32_t buttons; float joystick_vals[4]; - + sync(); - + printf("Begin sanity gamepad test...\n"); - + for (int i = 0; i < 7; i++) { gamepad_read(&buttons, joystick_vals); printf("buttons = %d\t joystick_vals = (", buttons); @@ -361,7 +361,7 @@ void sanity_gamepad_test() { printf("%f, ", joystick_vals[j]); } printf(")\n"); - usleep(500000); // sleep for half a second + usleep(500000); // sleep for half a second } printf("Done!\n\n"); } @@ -371,13 +371,13 @@ void sanity_gamepad_test() { // sanity robot description test void sanity_robot_desc_test() { int count = 0; - robot_desc_val_t curr[6] = { IDLE, DISCONNECTED, DISCONNECTED, CONNECTED }; - robot_desc_val_t prev[6] = { IDLE, DISCONNECTED, DISCONNECTED, CONNECTED }; - + robot_desc_val_t curr[6] = {IDLE, DISCONNECTED, DISCONNECTED, CONNECTED}; + robot_desc_val_t prev[6] = {IDLE, DISCONNECTED, DISCONNECTED, CONNECTED}; + sync(); - + printf("Begin sanity robot desc test...\n"); - + while (count < 9) { for (int i = 0; i < NUM_DESC_FIELDS; i++) { curr[i] = robot_desc_read(i); @@ -396,44 +396,44 @@ void sanity_robot_desc_test() { // *************************************************************************************************** // // check that device subscriptions are working -void subscription_test () { +void subscription_test() { uint64_t id0, id1, id2; dev_id_t dev_ids[MAX_DEVICES]; - + sync(); - + printf("Begin subscription test...\n"); - - usleep(100000); // put this program out of sync with test1 loop - + + usleep(100000); // put this program out of sync with test1 loop + get_device_identifiers(dev_ids); id0 = dev_ids[0].uid; id1 = dev_ids[1].uid; id2 = dev_ids[2].uid; - + for (int i = 0; i < 5; i++) { - switch(i) { - case 0: // sanity + switch (i) { + case 0: // sanity place_sub_request(id0, EXECUTOR, 1); break; - case 1: // different processes + case 1: // different processes place_sub_request(id1, NET_HANDLER, 2); place_sub_request(id2, EXECUTOR, 3); break; - case 2: // setting the same subscription + case 2: // setting the same subscription place_sub_request(id0, EXECUTOR, 1); break; - case 3: // removing a param from subscription + case 3: // removing a param from subscription place_sub_request(id2, EXECUTOR, 1); break; - case 4: // don't do anything + case 4: // don't do anything break; default: - break; + break; } sleep(1); } - + printf("Done!\n"); } @@ -445,26 +445,26 @@ void ctrl_c_handler(int sig_num) { exit(1); } -int main() { +int main() { shm_init(); logger_init(EXECUTOR); - signal(SIGINT, ctrl_c_handler); // hopefully fails gracefully when pressing Ctrl-C in the terminal - - sanity_test(); - + signal(SIGINT, ctrl_c_handler); // hopefully fails gracefully when pressing Ctrl-C in the terminal + + sanity_test(); + dev_conn_test(); - + single_thread_load_test(); - + dual_thread_read_write_test(); - + single_thread_load_test_uid(); - + sanity_gamepad_test(); - + sanity_robot_desc_test(); - + subscription_test(); - + return 0; } \ No newline at end of file diff --git a/tests/cli/dev_handler_cli.c b/tests/cli/dev_handler_cli.c index 18e5b233..81d9620f 100644 --- a/tests/cli/dev_handler_cli.c +++ b/tests/cli/dev_handler_cli.c @@ -1,17 +1,16 @@ #include "../client/dev_handler_client.h" -#define MAX_CMD_LEN 64 // maximum length of a CLI command +#define MAX_CMD_LEN 64 // maximum length of a CLI command -#define NUMBER_OF_TEST_DEVICES 5 // number of test devices to connect -#define MAX_STRING_SIZE 64 // maximum length of a device name +#define NUMBER_OF_TEST_DEVICES 5 // number of test devices to connect +#define MAX_STRING_SIZE 64 // maximum length of a device name -char devices[NUMBER_OF_TEST_DEVICES][MAX_STRING_SIZE] = { +char devices[NUMBER_OF_TEST_DEVICES][MAX_STRING_SIZE] = { "GeneralTestDevice", "SimpleTestDevice", "UnresponsiveTestDevice", "ForeignTestDevice", - "UnstableTestDevice" -}; + "UnstableTestDevice"}; char nextcmd[MAX_CMD_LEN]; @@ -37,12 +36,12 @@ void clean_up() { } // removes trailing newline from commands entered in by user -void remove_newline(char *nextcmd) { +void remove_newline(char* nextcmd) { nextcmd[strlen(nextcmd) - 1] = '\0'; } void prompt_device_connect() { - while(1) { + while (1) { // prints out list of available test devices printf("This is the list of devices by name. Type in number on left to use device\n"); for (int i = 0; i < NUMBER_OF_TEST_DEVICES; i++) { @@ -52,10 +51,10 @@ void prompt_device_connect() { printf("Device?\n"); fflush(stdout); printf("> "); - + // get next command entered by user and process it fgets(nextcmd, MAX_CMD_LEN, stdin); - char *input; + char* input; long int dev_number = strtol(nextcmd, &input, 0); if (dev_number >= 0 && dev_number < NUMBER_OF_TEST_DEVICES && strlen(input) == 1 && strlen(nextcmd) > 1) { // get the UID of the device @@ -66,7 +65,7 @@ void prompt_device_connect() { uint64_t uid; remove_newline(nextcmd); uid = strtoull(nextcmd, NULL, 0); - + // connect the virtual device printf("Connecting %s with UID of value 0x%016llX\n", devices[dev_number], uid); if (connect_virtual_device(devices[dev_number], uid) == -1) { @@ -76,7 +75,7 @@ void prompt_device_connect() { } fflush(stdout); break; - } else if (dev_number == NUMBER_OF_TEST_DEVICES) { // if we connected too many devices + } else if (dev_number == NUMBER_OF_TEST_DEVICES) { // if we connected too many devices printf("Device connecting cancelled \n"); break; } else { @@ -86,30 +85,30 @@ void prompt_device_connect() { } void prompt_device_disconnect() { - while(1) { + while (1) { // list the connected virtual devices list_devices(); - + // ask for the device to disconnect printf("Socket Number?\n"); fflush(stdout); printf("> "); fgets(nextcmd, MAX_CMD_LEN, stdin); remove_newline(nextcmd); - char *input; + char* input; int port_num = strtol(nextcmd, &input, 0); - + // perform some validation on the input, then disconnect the virtual device if (strlen(input) == 0 && strlen(input) == 0 && strlen(nextcmd) > 0) { printf("Disconnecting port %d\n", port_num); - if(disconnect_virtual_device(port_num) == 0) { + if (disconnect_virtual_device(port_num) == 0) { printf("Device disconnected!\n"); break; } else { printf("Device disconnect unsuccesful!\n"); break; } - } else if (strcmp(input, "cancel") == 0) { // break immediately if cancelling + } else if (strcmp(input, "cancel") == 0) { // break immediately if cancelling printf("Cancelling disconnect!\n"); break; } else { @@ -124,7 +123,7 @@ int main() { // setup signal(SIGINT, clean_up); int stop = 1; - + // start dev handler printf("Starting Dev Handler CLI in the cloudddd...\n"); fflush(stdout); @@ -132,13 +131,13 @@ int main() { printf("Please enter device handler command:\n"); fflush(stdout); start_dev_handler(); - + // main loop while (stop) { // Get the next command printf("> "); fgets(nextcmd, MAX_CMD_LEN, stdin); - remove_newline(nextcmd); // Strip off \n character + remove_newline(nextcmd); // Strip off \n character // Compare input string against the available commands if (strcmp(nextcmd, "exit") == 0) { stop = 0; diff --git a/tests/cli/executor_cli.c b/tests/cli/executor_cli.c index 0dd471d8..1dec973f 100644 --- a/tests/cli/executor_cli.c +++ b/tests/cli/executor_cli.c @@ -1,9 +1,9 @@ #include "../client/executor_client.h" -#define MAX_CMD_LEN 64 // maximum length of an inputted command +#define MAX_CMD_LEN 64 // maximum length of an inputted command -char student_code[MAX_CMD_LEN] = {0}; // string that holds student code file name to use -char challenge_code[MAX_CMD_LEN] = {0}; // string that holds challenge code file name to use +char student_code[MAX_CMD_LEN] = {0}; // string that holds student code file name to use +char challenge_code[MAX_CMD_LEN] = {0}; // string that holds challenge code file name to use void display_help() { printf("This is the main menu.\n"); @@ -31,21 +31,21 @@ void change_challenge_code() { } int main() { - char nextcmd[MAX_CMD_LEN]; // to hold nextline + char nextcmd[MAX_CMD_LEN]; // to hold nextline int stop = 0; - + printf("Starting Executor CLI...\n"); strcpy(student_code, "studentcode"); - strcpy(challenge_code, student_code); // Change to "challenges" once Dawn separates challenges into another Python file - //start executor process - start_executor(student_code, challenge_code); - + strcpy(challenge_code, student_code); // Change to "challenges" once Dawn separates challenges into another Python file + //start executor process + start_executor(student_code, challenge_code); + // command-line loop which prompts user for commands to send to net_handler while (!stop) { // get the next command printf("> "); fgets(nextcmd, MAX_CMD_LEN, stdin); - + // compare input string against the available commands if (strcmp(nextcmd, "exit\n") == 0) { stop = 1; @@ -60,12 +60,12 @@ int main() { display_help(); } } - + printf("Exiting Executor CLI...\n"); - + stop_executor(); - + printf("Done!\n"); - + return 0; } diff --git a/tests/cli/net_handler_cli.c b/tests/cli/net_handler_cli.c index 1fa5e55d..d279a363 100644 --- a/tests/cli/net_handler_cli.c +++ b/tests/cli/net_handler_cli.c @@ -8,7 +8,7 @@ void prompt_run_mode() { robot_desc_field_t client = SHEPHERD; robot_desc_val_t mode = IDLE; char nextcmd[MAX_CMD_LEN]; - + // get client to send as while (1) { printf("Send as DAWN or SHEPHERD: "); @@ -25,7 +25,7 @@ void prompt_run_mode() { printf("Invalid response to prompt: %s", nextcmd); } } - + // get mode to send while (1) { printf("Send mode IDLE, AUTO, or TELEOP: "); @@ -45,7 +45,7 @@ void prompt_run_mode() { printf("Invalid response to prompt: %s", nextcmd); } } - + // send printf("Sending Run Mode message!\n\n"); send_run_mode(client, mode); @@ -55,7 +55,7 @@ void prompt_start_pos() { robot_desc_field_t client = SHEPHERD; robot_desc_val_t pos = LEFT; char nextcmd[MAX_CMD_LEN]; - + // get client to send as while (1) { printf("Send as DAWN or SHEPHERD: "); @@ -72,7 +72,7 @@ void prompt_start_pos() { printf("Invalid response to prompt: %s", nextcmd); } } - + // get pos to send while (1) { printf("Send pos LEFT or RIGHT: "); @@ -89,7 +89,7 @@ void prompt_start_pos() { printf("Invalid response to prompt: %s", nextcmd); } } - + // send printf("Sending Start Pos message!\n\n"); send_start_pos(client, pos); @@ -99,10 +99,10 @@ void prompt_gamepad_state() { uint32_t buttons = 0; float joystick_vals[4]; char nextcmd[MAX_CMD_LEN]; - char **list_of_names; + char** list_of_names; int button_ix = 0; int set_joysticks = 0; - + // get which buttons are pressed printf("Specify which of the following buttons are pressed\n\t(type the number corresponding to the named button):\n"); list_of_names = get_button_names(); @@ -111,30 +111,30 @@ void prompt_gamepad_state() { } printf("After you have finished setting buttons, type \"done\"\n"); printf("If you accidentally set a button, you can unset the button by typing its name again\n"); - + while (1) { printf("Set/unset this button: "); fgets(nextcmd, MAX_CMD_LEN, stdin); - + // check for these first if (strcmp(nextcmd, "done\n") == 0) { break; } else if (strcmp(nextcmd, "abort\n") == 0) { return; } - + // get the index of the button that was specified errno = 0; if ((button_ix = (int) strtol(nextcmd, NULL, 10)) == 0 && errno != 0) { printf("Did not enter integer: %s\n", nextcmd); continue; } - + if (button_ix < 0 || button_ix >= NUM_GAMEPAD_BUTTONS) { printf("Not a valid button index: %s\n", nextcmd); continue; } - + // otherwise set that bit in buttons if (buttons & (1 << button_ix)) { buttons &= ~(1 << button_ix); @@ -144,22 +144,22 @@ void prompt_gamepad_state() { printf("\tSet button %s\n", list_of_names[button_ix]); } } - + // get the joystick values to send printf("Specify the values of the four joysticks (values -1.0 <= val <= 1.0):\n"); list_of_names = get_joystick_names(); for (int i = 0; i < 4; i++) { printf("\t%s\n", list_of_names[i]); } - + while (set_joysticks != 4) { printf("Set the value for %s: ", list_of_names[set_joysticks]); fgets(nextcmd, MAX_CMD_LEN, stdin); - + if (strcmp(nextcmd, "abort\n") == 0) { return; } - + errno = 0; if (((joystick_vals[set_joysticks] = strtof(nextcmd, NULL)) == 0) && errno != 0) { printf("Input is not a float: %s\n", nextcmd); @@ -171,7 +171,7 @@ void prompt_gamepad_state() { printf("\tOk! %s set to %f\n", list_of_names[set_joysticks], joystick_vals[set_joysticks]); set_joysticks++; } - + // send printf("Sending Gamepad State message!\n\n"); send_gamepad_state(buttons, joystick_vals); @@ -181,8 +181,8 @@ void prompt_challenge_data() { int client = SHEPHERD; char nextcmd[MAX_CMD_LEN]; int MAX_CHALLENGES = 32; - char **inputs = malloc(sizeof(char *) * MAX_CHALLENGES); - + char** inputs = malloc(sizeof(char*) * MAX_CHALLENGES); + // get client to send as while (1) { printf("Send as DAWN or SHEPHERD: "); @@ -199,31 +199,30 @@ void prompt_challenge_data() { printf("Invalid response to prompt: %s", nextcmd); } } - + // get challenge inputs to send int num_challenges; for (num_challenges = 0; num_challenges < MAX_CHALLENGES; num_challenges++) { // TODO: if we ever put the current names of challenges in runtime_util, make this print better - printf("Provide input for challenge %d (or done or abort): ", num_challenges); + printf("Provide input for challenge %d (or done or abort): ", num_challenges); fgets(nextcmd, MAX_CMD_LEN, stdin); - + if (strcmp(nextcmd, "done\n") == 0) { break; - } - else if (strcmp(nextcmd, "abort\n") == 0) { + } else if (strcmp(nextcmd, "abort\n") == 0) { return; } - + // we need to do this because nextcmd has a newline at the end - nextcmd[strlen(nextcmd) -1] = '\0'; + nextcmd[strlen(nextcmd) - 1] = '\0'; inputs[num_challenges] = malloc(strlen(nextcmd) + 1); strcpy(inputs[num_challenges], nextcmd); } - + // send printf("Sending Challenge Data message!\n\n"); send_challenge_data(client, inputs, num_challenges); - + // free pointers for (int i = 0; i < num_challenges; i++) { free(inputs[i]); @@ -233,13 +232,13 @@ void prompt_challenge_data() { void prompt_device_data() { char nextcmd[MAX_CMD_LEN]; - char dev_names[DEVICES_LENGTH][32]; // for holding the names of the devices + char dev_names[DEVICES_LENGTH][32]; // for holding the names of the devices int num_devices = 0; uint8_t dev_type; long long int temp; dev_data_t data[MAX_DEVICES]; - device_t *curr_dev; - + device_t* curr_dev; + // first get the list of device names for (uint8_t i = 0; i < DEVICES_LENGTH; i++) { if ((curr_dev = get_device(i)) != NULL) { @@ -248,7 +247,7 @@ void prompt_device_data() { strcpy(dev_names[i], ""); } } - + // enter prompt loop while (1) { // subscribe to another device? @@ -257,12 +256,12 @@ void prompt_device_data() { if (strcmp(nextcmd, "done\n") == 0) { break; } - + // ask for UID while (1) { printf("Enter the UID of the device, in base 10: "); fgets(nextcmd, MAX_CMD_LEN, stdin); - + if (strcmp(nextcmd, "abort\n") == 0) { return; } @@ -275,7 +274,7 @@ void prompt_device_data() { break; } } - + // ask for device type data[num_devices].name = NULL; printf("Specify the device type, one of the following\n\t(type the number corresponding to the device type):\n"); @@ -284,26 +283,26 @@ void prompt_device_data() { printf("\t%4d %s\n", i, dev_names[i]); } } - while (1) { + while (1) { printf("Enter the device type: "); fgets(nextcmd, MAX_CMD_LEN, stdin); if (strcmp(nextcmd, "abort\n") == 0) { return; } - + errno = 0; if ((dev_type = (uint8_t) strtol(nextcmd, NULL, 10)) == 0 && errno != 0) { printf("Did not enter integer: %s\n", nextcmd); continue; } - + if ((curr_dev = get_device(dev_type)) == NULL) { printf("Did not specify a valid device type: %s\n", nextcmd); continue; } break; } - + // fetch parameters and prompt user "y" or "n" on each one curr_dev = get_device(device_name_to_type(data[num_devices].name)); data[num_devices].params = 0; @@ -328,11 +327,11 @@ void prompt_device_data() { } num_devices++; } - + // send printf("Sending Device Data message!\n\n"); send_device_data(data, num_devices); - + // free everything for (int i = 0; i < num_devices; i++) { free(data[i].name); @@ -362,23 +361,23 @@ void sigint_handler(int signum) { } int main() { - char nextcmd[MAX_CMD_LEN]; // to hold nextline + char nextcmd[MAX_CMD_LEN]; // to hold nextline int stop = 0; - + signal(SIGINT, sigint_handler); - + printf("Starting Net Handler CLI...\n"); fflush(stdout); - + // start the net handler and connect all of its output locations to file descriptors in this process start_net_handler(); - + // command-line loop which prompts user for commands to send to net_handler while (!stop) { // get the next command printf("> "); fgets(nextcmd, MAX_CMD_LEN, stdin); - + // compare input string against the available commands if (strcmp(nextcmd, "exit\n") == 0) { stop = 1; @@ -402,12 +401,12 @@ int main() { } usleep(500000); } - + printf("Exiting Net Handler CLI...\n"); - + stop_net_handler(); - + printf("Done!\n"); - + return 0; } diff --git a/tests/cli/shm_cli.c b/tests/cli/shm_cli.c index 34216c42..812f0086 100644 --- a/tests/cli/shm_cli.c +++ b/tests/cli/shm_cli.c @@ -18,23 +18,23 @@ void sigint_handler(int signum) { } int main() { - char nextcmd[MAX_CMD_LEN]; // to hold nextline + char nextcmd[MAX_CMD_LEN]; // to hold nextline int stop = 0; - + signal(SIGINT, sigint_handler); - + printf("Starting Shared Memory CLI...\n"); fflush(stdout); - + // start shm process start_shm(); - + // command-line loop which prompts user for commands to send to net_handler while (!stop) { // get the next command printf("> "); fgets(nextcmd, MAX_CMD_LEN, stdin); - + // compare input string against the available commands if (strcmp(nextcmd, "exit\n") == 0) { stop = 1; @@ -47,12 +47,12 @@ int main() { display_help(); } } - + printf("Exiting Shared Memory CLI...\n"); - + stop_shm(); - + printf("Done!\n"); - + return 0; } \ No newline at end of file diff --git a/tests/client/dev_handler_client.c b/tests/client/dev_handler_client.c index 421a5d29..fa36effd 100644 --- a/tests/client/dev_handler_client.c +++ b/tests/client/dev_handler_client.c @@ -14,21 +14,20 @@ pid_t dev_handler_pid; // Struct grouping a virtual device's process id, socket fd, and name typedef struct { - pid_t pid; // The process id of the virtual device - int fd; // The socket's file descriptor - char *dev_name; // The name of the virtual device's name - uint64_t dev_uid; // The device uid + pid_t pid; // The process id of the virtual device + int fd; // The socket's file descriptor + char* dev_name; // The name of the virtual device's name + uint64_t dev_uid; // The device uid } device_socket_t; // ****************************** GLOBAL VARS ******************************* // /* Array of connected devices and their sockets * used_sockets[i] == NULL if unused */ -device_socket_t **used_sockets; +device_socket_t** used_sockets; // A hack to initialize. https://stackoverflow.com/a/6991475 -__attribute__((constructor)) -void used_sockets_init() { - used_sockets = malloc(MAX_DEVICES * sizeof(device_socket_t *)); +__attribute__((constructor)) void used_sockets_init() { + used_sockets = malloc(MAX_DEVICES * sizeof(device_socket_t*)); for (int i = 0; i < MAX_DEVICES; i++) { used_sockets[i] = NULL; } @@ -73,7 +72,7 @@ static int connect_socket() { strcpy(dev_socket_addr.sun_path, socket_name); // Bind socket address to socket - if (bind(server_fd, (struct sockaddr *) &dev_socket_addr, sizeof(dev_socket_addr)) < 0) { + if (bind(server_fd, (struct sockaddr*) &dev_socket_addr, sizeof(dev_socket_addr)) < 0) { printf("connect_socket: Couldn't bind socket -- %s\n", strerror(errno)); remove(socket_name); return -1; @@ -98,7 +97,7 @@ static int connect_socket() { struct timeval tv; tv.tv_sec = TIMEOUT / 1000; tv.tv_usec = 0; - setsockopt(connection_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)); + setsockopt(connection_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof(tv)); return socket_num; } @@ -107,21 +106,21 @@ static int connect_socket() { void start_dev_handler() { // Check to see if creation of child is successful - if((dev_handler_pid = fork()) < 0) { + if ((dev_handler_pid = fork()) < 0) { printf("fork: %s\n", strerror(errno)); - } else if (dev_handler_pid == 0) { // child created! + } else if (dev_handler_pid == 0) { // child created! // redirect to dev handler folder - if(chdir("../dev_handler") == -1) { + if (chdir("../dev_handler") == -1) { printf("chdir: %s\n", strerror(errno)); } // execute the device handler process - if (execlp("./dev_handler", "dev_handler", "virtual", (char *) 0) < 0) { + if (execlp("./dev_handler", "dev_handler", "virtual", (char*) 0) < 0) { printf("execlp: %s\n", strerror(errno)); } } } -void stop_dev_handler(){ +void stop_dev_handler() { // send signal to dev_handler and wait for termination if (kill(dev_handler_pid, SIGINT) < 0) { printf("kill dev_handler: %s\n", strerror(errno)); @@ -131,7 +130,7 @@ void stop_dev_handler(){ } } -int connect_virtual_device(char *dev_name, uint64_t uid) { +int connect_virtual_device(char* dev_name, uint64_t uid) { // Connect a socket int socket_num = connect_socket(); if (socket_num == -1) { @@ -148,7 +147,7 @@ int connect_virtual_device(char *dev_name, uint64_t uid) { if (pid < 0) { printf("connect_device: Couldn't spawn child process %s\n", dev_name); return -1; - } else if (pid == 0) { // Child process + } else if (pid == 0) { // Child process // Cd into virtual_devices dir where the device exe is if (chdir("client/virtual_devices") == -1) { printf("chdir: %s\n", strerror(errno)); @@ -158,11 +157,11 @@ int connect_virtual_device(char *dev_name, uint64_t uid) { sprintf(exe_name, "./%s", used_sockets[socket_num]->dev_name); sprintf(fd_str, "%d", used_sockets[socket_num]->fd); sprintf(uid_str, "0x%016llX", uid); - if (execlp(exe_name, used_sockets[socket_num]->dev_name, fd_str, uid_str, (char *) NULL) < 0) { + if (execlp(exe_name, used_sockets[socket_num]->dev_name, fd_str, uid_str, (char*) NULL) < 0) { printf("connect_device: execlp %s failed -- %s\n", exe_name, strerror(errno)); return -1; } - } else { // Parent process + } else { // Parent process // Take note of child pid so we can kill it in disconnect_device() used_sockets[socket_num]->pid = pid; } @@ -176,7 +175,7 @@ int disconnect_virtual_device(int socket_num) { } // Kill virtual device process kill(used_sockets[socket_num]->pid, SIGTERM); - waitpid(used_sockets[socket_num]->pid, NULL, 0); // Block until killed + waitpid(used_sockets[socket_num]->pid, NULL, 0); // Block until killed // CLose file descriptor close(used_sockets[socket_num]->fd); // Remove socket (dev handler should recognize disconnect after removal) diff --git a/tests/client/dev_handler_client.h b/tests/client/dev_handler_client.h index 22a8e73e..5f0c982a 100644 --- a/tests/client/dev_handler_client.h +++ b/tests/client/dev_handler_client.h @@ -1,16 +1,16 @@ #ifndef DEV_CLIENT_H #define DEV_CLIENT_H -#include // for exit() -#include // for printf() -#include // for errno -#include // for strerr() -#include // for sockets -#include // for sockaddr_un -#include // for int with specific widths -#include // for read() -#include // for SIGINT (Ctrl+C) -#include // for waitpid() +#include // for errno +#include // for SIGINT (Ctrl+C) +#include // for int with specific widths +#include // for printf() +#include // for exit() +#include // for strerr() +#include // for sockets +#include // for sockaddr_un +#include // for waitpid() +#include // for read() // Starts dev handler with "virtual" argument void start_dev_handler(); @@ -27,7 +27,7 @@ void stop_dev_handler(); * the socket number for the virtual device on success (nonnegative) * -1 on failure */ -int connect_virtual_device(char *dev_name, uint64_t uid); +int connect_virtual_device(char* dev_name, uint64_t uid); /** * Disconnects a virtual device from dev handler diff --git a/tests/client/executor_client.c b/tests/client/executor_client.c index 4d3423ef..01e808de 100644 --- a/tests/client/executor_client.c +++ b/tests/client/executor_client.c @@ -3,16 +3,16 @@ pid_t executor_pid; // for adding student code directory to PYTHONPATH -char *path_to_test_student_code = "../tests/student_code"; -char *PYTHONPATH = "PYTHONPATH"; +char* path_to_test_student_code = "../tests/student_code"; +char* PYTHONPATH = "PYTHONPATH"; -void start_executor(char *student_code, char *challenge_code) { +void start_executor(char* student_code, char* challenge_code) { // fork executor process if ((executor_pid = fork()) < 0) { printf("fork: %s\n", strerror(errno)); - } else if (executor_pid == 0) { // child - char *python_path = NULL; - char *new_python_path = malloc(strlen(path_to_test_student_code) + 1); + } else if (executor_pid == 0) { // child + char* python_path = NULL; + char* new_python_path = malloc(strlen(path_to_test_student_code) + 1); int len; // cd to the executor directory @@ -21,9 +21,9 @@ void start_executor(char *student_code, char *challenge_code) { } // add the directory with all the student code to PYTHONPATH if it's not already there - if ((python_path = getenv(PYTHONPATH)) == NULL) { // if PYTHONPATH is not defined + if ((python_path = getenv(PYTHONPATH)) == NULL) { // if PYTHONPATH is not defined strcpy(new_python_path, path_to_test_student_code); - } else { // if PYTHONPATH is defined + } else { // if PYTHONPATH is defined new_python_path = realloc(new_python_path, strlen(python_path) + 1 + strlen(path_to_test_student_code) + 1); new_python_path[0] = '\0'; strcat(new_python_path, python_path); @@ -33,7 +33,7 @@ void start_executor(char *student_code, char *challenge_code) { if (setenv(PYTHONPATH, new_python_path, 1) != 0) { fprintf(stderr, "start_executor: failed to set PYTHONPATH: %s\n", strerror(errno)); } - free(new_python_path); // setenv copies the strings so we need to free the allocated pointer + free(new_python_path); // setenv copies the strings so we need to free the allocated pointer // get rid of the newline at the end of the file name, if it's there len = strlen(student_code); diff --git a/tests/client/executor_client.h b/tests/client/executor_client.h index 239a5ef6..a9dc19da 100644 --- a/tests/client/executor_client.h +++ b/tests/client/executor_client.h @@ -1,10 +1,10 @@ #ifndef EXEC_CLIENT_H #define EXEC_CLIENT_H -#include "../../runtime_util/runtime_util.h" -#include #include +#include #include +#include "../../runtime_util/runtime_util.h" /** * Spawns the executor running student_code @@ -13,7 +13,7 @@ * Ex. for a file called example.py, the argument would be "example" * No return value. */ -void start_executor(char *student_code, char *challenge_code); +void start_executor(char* student_code, char* challenge_code); /** * Stops the executor spawned by start_executor diff --git a/tests/client/net_handler_client.c b/tests/client/net_handler_client.c index 3bd2552a..060e99d4 100644 --- a/tests/client/net_handler_client.c +++ b/tests/client/net_handler_client.c @@ -7,12 +7,12 @@ pthread_t dump_tid; // holds the thread id of the output dum pthread_mutex_t print_udp_mutex; // lock over whether to print the next received udp int print_next_udp; // 0 if we want to suppress incoming dev data, 1 to print incoming dev data to stdout -int nh_tcp_shep_fd = -1; // holds file descriptor for TCP Shepherd socket -int nh_tcp_dawn_fd = -1; // holds file descriptor for TCP Dawn socket -int nh_udp_fd = -1; // holds file descriptor for UDP Dawn socket -FILE *tcp_output_fp = NULL; // holds current output location of incoming TCP messages -FILE *udp_output_fp = NULL; // holds current output location of incoming UDP messages -FILE *null_fp = NULL; // file pointer to /dev/null +int nh_tcp_shep_fd = -1; // holds file descriptor for TCP Shepherd socket +int nh_tcp_dawn_fd = -1; // holds file descriptor for TCP Dawn socket +int nh_udp_fd = -1; // holds file descriptor for UDP Dawn socket +FILE* tcp_output_fp = NULL; // holds current output location of incoming TCP messages +FILE* udp_output_fp = NULL; // holds current output location of incoming UDP messages +FILE* null_fp = NULL; // file pointer to /dev/null // ************************************* HELPER FUNCTIONS ************************************** // @@ -35,39 +35,39 @@ static int connect_tcp(robot_desc_field_t client) { if ((setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(int))) != 0) { printf("setsockopt: failed to set listening socket for reuse of port: %s\n", strerror(errno)); } - + // set the elements of cli_addr - struct sockaddr_in cli_addr = {0}; // initialize everything to 0 - cli_addr.sin_family = AF_INET; // use IPv4 - cli_addr.sin_port = (client == SHEPHERD) ? htons(SHEPHERD_PORT) : htons(DAWN_PORT); // use specifid port to connect - cli_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use any address set on this machine to connect - + struct sockaddr_in cli_addr = {0}; // initialize everything to 0 + cli_addr.sin_family = AF_INET; // use IPv4 + cli_addr.sin_port = (client == SHEPHERD) ? htons(SHEPHERD_PORT) : htons(DAWN_PORT); // use specifid port to connect + cli_addr.sin_addr.s_addr = htonl(INADDR_ANY); // use any address set on this machine to connect + // bind the client side too, so that net_handler can verify it's the proper client - if ((bind(sockfd, (struct sockaddr *)&cli_addr, sizeof(struct sockaddr_in))) != 0) { + if ((bind(sockfd, (struct sockaddr*) &cli_addr, sizeof(struct sockaddr_in))) != 0) { printf("bind: failed to bind listening socket to client port: %s\n", strerror(errno)); close(sockfd); stop_net_handler(); exit(1); } - + // set the elements of serv_addr - struct sockaddr_in serv_addr = {0}; // initialize everything to 0 - serv_addr.sin_family = AF_INET; // use IPv4 - serv_addr.sin_port = htons(RASPI_PORT); // want to connect to raspi port + struct sockaddr_in serv_addr = {0}; // initialize everything to 0 + serv_addr.sin_family = AF_INET; // use IPv4 + serv_addr.sin_port = htons(RASPI_PORT); // want to connect to raspi port serv_addr.sin_addr.s_addr = inet_addr(RASPI_ADDR); - + // connect to the server - if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr_in)) != 0) { + if (connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(struct sockaddr_in)) != 0) { printf("connect: failed to connect to socket: %s\n", strerror(errno)); close(sockfd); stop_net_handler(); exit(1); } - + // send the verification byte uint8_t verif_byte = (client == SHEPHERD) ? 0 : 1; writen(sockfd, &verif_byte, 1); - + return sockfd; } @@ -82,18 +82,18 @@ static void recv_udp_data(int udp_fd) { struct sockaddr_in recvaddr; socklen_t addrlen = sizeof(recvaddr); int recv_size; - + // receive message from udp socket if ((recv_size = recvfrom(udp_fd, msg, max_size, 0, (struct sockaddr*) &recvaddr, &addrlen)) < 0) { fprintf(udp_output_fp, "recvfrom: %s\n", strerror(errno)); } - + // unpack the data DevData* dev_data = dev_data__unpack(NULL, recv_size, msg); if (dev_data == NULL) { printf("Error unpacking incoming message\n"); } - + // display the message's fields. for (int i = 0; i < dev_data->n_devices; i++) { fprintf(udp_output_fp, "Device No. %d:", i); @@ -117,11 +117,11 @@ static void recv_udp_data(int udp_fd) { } } } - + // free the unpacked message dev_data__free_unpacked(dev_data, NULL); fflush(udp_output_fp); - + // if we were asked to print the last UDP message, set output back to /dev/null pthread_mutex_lock(&print_udp_mutex); if (print_next_udp) { @@ -142,7 +142,7 @@ static int recv_tcp_data(robot_desc_field_t client, int tcp_fd) { // variables to read messages into Text* msg; net_msg_t msg_type; - uint8_t *buf; + uint8_t* buf; uint16_t len; char client_str[16]; if (client == SHEPHERD) { @@ -155,12 +155,12 @@ static int recv_tcp_data(robot_desc_field_t client, int tcp_fd) { if (parse_msg(tcp_fd, &msg_type, &len, &buf) == 0) { return -1; } - + // unpack the message if ((msg = text__unpack(NULL, len, buf)) == NULL) { fprintf(tcp_output_fp, "Error unpacking incoming message from %s\n", client_str); } - + // print the incoming message if (msg_type == LOG_MSG) { for (int i = 0; i < msg->n_payload; i++) { @@ -172,11 +172,11 @@ static int recv_tcp_data(robot_desc_field_t client, int tcp_fd) { } } fflush(tcp_output_fp); - + // free allocated memory free(buf); text__free_unpacked(msg, NULL); - + return 0; } @@ -187,19 +187,19 @@ static int recv_tcp_data(robot_desc_field_t client, int tcp_fd) { * args: thread arugments; always NULL * Returns: NULL */ -static void *output_dump(void *args) { +static void* output_dump(void* args) { const int sample_size = 20; // number of messages that need to come in before disabling output const uint64_t disable_threshold = 50; // if the interval between each of the past sample_size messages has been less than this many milliseconds, disable output const uint64_t enable_threshold = 1000; // if this many milliseconds have passed between now and last received message, enable output uint64_t last_received_time = 0, curr_time; uint32_t less_than_disable_thresh = 0; - + // set up the read_set argument for select() fd_set read_set; int maxfd = (nh_tcp_dawn_fd > nh_tcp_shep_fd) ? nh_tcp_dawn_fd : nh_tcp_shep_fd; maxfd = (nh_udp_fd > maxfd) ? nh_udp_fd : maxfd; maxfd++; - + // wait for net handler to create some output, then print that output to stdout of this process while (1) { // set up the read_set argument to selct() @@ -207,18 +207,18 @@ static void *output_dump(void *args) { FD_SET(nh_tcp_shep_fd, &read_set); FD_SET(nh_tcp_dawn_fd, &read_set); FD_SET(nh_udp_fd, &read_set); - + // prepare to accept cancellation requests over the select pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - + // wait for something to happen if (select(maxfd, &read_set, NULL, NULL, NULL) < 0) { printf("select: output dump: %s\n", strerror(errno)); } - + // deny all cancellation requests until the next loop pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - + // enable tcp output if more than enable_thresh has passed between last time and previous time if (FD_ISSET(nh_tcp_shep_fd, &read_set) || FD_ISSET(nh_tcp_dawn_fd, &read_set)) { curr_time = millis(); @@ -236,7 +236,7 @@ static void *output_dump(void *args) { } last_received_time = curr_time; } - + // print stuff from whichever file descriptors are ready for reading... if (FD_ISSET(nh_tcp_shep_fd, &read_set)) { if (recv_tcp_data(SHEPHERD, nh_tcp_shep_fd) == -1) { @@ -261,7 +261,7 @@ void start_net_handler() { // fork net_handler process if ((nh_pid = fork()) < 0) { printf("fork: %s\n", strerror(errno)); - } else if (nh_pid == 0) { // child + } else if (nh_pid == 0) { // child // cd to the net_handler directory if (chdir("../net_handler") == -1) { printf("chdir: %s\n", strerror(errno)); @@ -271,9 +271,9 @@ void start_net_handler() { if (execlp("./net_handler", "net_handler", NULL) < 0) { printf("execlp: %s\n", strerror(errno)); } - - } else { // parent - sleep(1); // allows net_handler to set itself up + + } else { // parent + sleep(1); // allows net_handler to set itself up // connect to the raspi networking ports to catch network output nh_tcp_dawn_fd = connect_tcp(DAWN); @@ -283,10 +283,10 @@ void start_net_handler() { stop_net_handler(); exit(1); } - udp_servaddr.sin_family = AF_INET; - udp_servaddr.sin_addr.s_addr = inet_addr(RASPI_ADDR); - udp_servaddr.sin_port = htons(RASPI_UDP_PORT); - + udp_servaddr.sin_family = AF_INET; + udp_servaddr.sin_addr.s_addr = inet_addr(RASPI_ADDR); + udp_servaddr.sin_port = htons(RASPI_UDP_PORT); + // open /dev/null null_fp = fopen("/dev/null", "w"); @@ -295,13 +295,13 @@ void start_net_handler() { printf("pthread_mutex_init: print udp mutex\n"); } print_next_udp = 0; - udp_output_fp = null_fp; // by default set to output to /dev/null + udp_output_fp = null_fp; // by default set to output to /dev/null // start the thread that is dumping output from net_handler to stdout of this process if (pthread_create(&dump_tid, NULL, output_dump, NULL) != 0) { printf("pthread_create: output dump\n"); } - usleep(400000); // allow time for thread to dump output before returning to client + usleep(400000); // allow time for thread to dump output before returning to client } } @@ -313,7 +313,7 @@ void stop_net_handler() { if (waitpid(nh_pid, NULL, 0) < 0) { printf("waitpid net handler: %s\n", strerror(errno)); } - + close_output(); } @@ -322,7 +322,7 @@ void close_output() { if (pthread_join(dump_tid, NULL) != 0) { printf("pthread_join: output dump\n"); } - + // close all the file descriptors if (nh_tcp_shep_fd != -1) { close(nh_tcp_shep_fd); @@ -337,9 +337,9 @@ void close_output() { void send_run_mode(robot_desc_field_t client, robot_desc_val_t mode) { RunMode run_mode = RUN_MODE__INIT; - uint8_t *send_buf; + uint8_t* send_buf; uint16_t len; - + // set the right mode switch (mode) { case (IDLE): @@ -354,12 +354,12 @@ void send_run_mode(robot_desc_field_t client, robot_desc_val_t mode) { default: printf("ERROR: sending run mode message\n"); } - + // build the message len = run_mode__get_packed_size(&run_mode); send_buf = make_buf(RUN_MODE_MSG, len); run_mode__pack(&run_mode, send_buf + BUFFER_OFFSET); - + // send the message if (client == SHEPHERD) { writen(nh_tcp_shep_fd, send_buf, len + BUFFER_OFFSET); @@ -367,14 +367,14 @@ void send_run_mode(robot_desc_field_t client, robot_desc_val_t mode) { writen(nh_tcp_dawn_fd, send_buf, len + BUFFER_OFFSET); } free(send_buf); - usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client + usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client } void send_start_pos(robot_desc_field_t client, robot_desc_val_t pos) { StartPos start_pos = START_POS__INIT; - uint8_t *send_buf; + uint8_t* send_buf; uint16_t len; - + // set the right mode switch (pos) { case (LEFT): @@ -386,12 +386,12 @@ void send_start_pos(robot_desc_field_t client, robot_desc_val_t pos) { default: printf("ERROR: sending run mode message\n"); } - + // build the message len = start_pos__get_packed_size(&start_pos); send_buf = make_buf(START_POS_MSG, len); start_pos__pack(&start_pos, send_buf + BUFFER_OFFSET); - + // send the message if (client == SHEPHERD) { writen(nh_tcp_shep_fd, send_buf, len + BUFFER_OFFSET); @@ -399,14 +399,14 @@ void send_start_pos(robot_desc_field_t client, robot_desc_val_t pos) { writen(nh_tcp_dawn_fd, send_buf, len + BUFFER_OFFSET); } free(send_buf); - usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client + usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client } void send_gamepad_state(uint32_t buttons, float joystick_vals[4]) { GpState gp_state = GP_STATE__INIT; - uint8_t *send_buf; + uint8_t* send_buf; uint16_t len; - + // build the message gp_state.connected = 1; gp_state.buttons = buttons; @@ -418,28 +418,28 @@ void send_gamepad_state(uint32_t buttons, float joystick_vals[4]) { len = gp_state__get_packed_size(&gp_state); send_buf = malloc(len); gp_state__pack(&gp_state, send_buf); - + // send the message - sendto(nh_udp_fd, send_buf, len, 0, (struct sockaddr *)&udp_servaddr, sizeof(struct sockaddr_in)); - + sendto(nh_udp_fd, send_buf, len, 0, (struct sockaddr*) &udp_servaddr, sizeof(struct sockaddr_in)); + // free everything free(gp_state.axes); free(send_buf); - usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client + usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client } -void send_challenge_data(robot_desc_field_t client, char **data, int num_challenges) { +void send_challenge_data(robot_desc_field_t client, char** data, int num_challenges) { Text challenge_data = TEXT__INIT; - uint8_t *send_buf; + uint8_t* send_buf; uint16_t len; - + // build the message challenge_data.payload = data; challenge_data.n_payload = num_challenges; len = text__get_packed_size(&challenge_data); send_buf = make_buf(CHALLENGE_DATA_MSG, len); text__pack(&challenge_data, send_buf + BUFFER_OFFSET); - + // send the message if (client == SHEPHERD) { writen(nh_tcp_shep_fd, send_buf, len + BUFFER_OFFSET); @@ -447,20 +447,20 @@ void send_challenge_data(robot_desc_field_t client, char **data, int num_challen writen(nh_tcp_dawn_fd, send_buf, len + BUFFER_OFFSET); } free(send_buf); - usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client + usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client } -void send_device_subs(dev_subs_t *subs, int num_devices) { +void send_device_subs(dev_subs_t* subs, int num_devices) { DevData dev_data = DEV_DATA__INIT; - uint8_t *send_buf; + uint8_t* send_buf; uint16_t len; - + // build the message - device_t *curr_device; + device_t* curr_device; uint8_t curr_type; dev_data.n_devices = num_devices; - dev_data.devices = malloc(sizeof(Device *) * num_devices); - + dev_data.devices = malloc(sizeof(Device*) * num_devices); + // set each device for (int i = 0; i < num_devices; i++) { if ((curr_type = device_name_to_type(subs[i].name)) == (uint8_t) -1) { @@ -468,18 +468,18 @@ void send_device_subs(dev_subs_t *subs, int num_devices) { } // fill in device fields curr_device = get_device(curr_type); - Device *dev = malloc(sizeof(Device)); + Device* dev = malloc(sizeof(Device)); device__init(dev); dev->name = curr_device->name; dev->uid = subs[i].uid; dev->type = curr_type; dev->n_params = curr_device->num_params; - dev->params = malloc(sizeof(Param *) * curr_device->num_params); - + dev->params = malloc(sizeof(Param*) * curr_device->num_params); + // set each param for (int j = 0; j < curr_device->num_params; j++) { // fill in param fields - Param *prm = malloc(sizeof(Param)); + Param* prm = malloc(sizeof(Param)); param__init(prm); prm->val_case = PARAM__VAL_BVAL; prm->bval = (subs[i].params & (1 << j)) ? 1 : 0; @@ -490,10 +490,10 @@ void send_device_subs(dev_subs_t *subs, int num_devices) { len = dev_data__get_packed_size(&dev_data); send_buf = make_buf(DEVICE_DATA_MSG, len); dev_data__pack(&dev_data, send_buf + BUFFER_OFFSET); - + // send the message writen(nh_tcp_dawn_fd, send_buf, len + BUFFER_OFFSET); - + // free everything for (int i = 0; i < num_devices; i++) { for (int j = 0; j < dev_data.devices[i]->n_params; j++) { @@ -503,7 +503,7 @@ void send_device_subs(dev_subs_t *subs, int num_devices) { free(dev_data.devices[i]); } free(dev_data.devices); - usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client + usleep(400000); // allow time for net handler and runtime to react and generate output before returning to client } void print_next_dev_data() { @@ -511,5 +511,5 @@ void print_next_dev_data() { print_next_udp = 1; udp_output_fp = stdout; pthread_mutex_unlock(&print_udp_mutex); - usleep(400000); // allow time for output_dump to react and generate output before returning to client + usleep(400000); // allow time for output_dump to react and generate output before returning to client } diff --git a/tests/client/net_handler_client.h b/tests/client/net_handler_client.h index 740ae3b1..ee27188e 100644 --- a/tests/client/net_handler_client.h +++ b/tests/client/net_handler_client.h @@ -1,15 +1,15 @@ #ifndef NET_CLIENT_H #define NET_CLIENT_H -#include "../../runtime_util/runtime_util.h" -#include "../../net_handler/net_util.h" #include #include +#include "../../net_handler/net_util.h" +#include "../../runtime_util/runtime_util.h" typedef struct { - uint64_t uid; // what the uid of this device is - char *name; // name of this device ("KoalaBear", "LimitSwitch", etc.) - uint32_t params; // which params to subscribe to + uint64_t uid; // what the uid of this device is + char* name; // name of this device ("KoalaBear", "LimitSwitch", etc.) + uint32_t params; // which params to subscribe to } dev_subs_t; /** @@ -63,7 +63,7 @@ void send_gamepad_state(uint32_t buttons, float joystick_vals[4]); * - num_challenges: number of challenge inputs sent, must match the number of challenges in "executor/challenges.txt" * No return value. */ -void send_challenge_data(robot_desc_field_t client, char **data, int num_challenges); +void send_challenge_data(robot_desc_field_t client, char** data, int num_challenges); /** * Sends device subscriptions from Dawn over TCP with the specified device subscriptions @@ -72,7 +72,7 @@ void send_challenge_data(robot_desc_field_t client, char **data, int num_challen * - num_devices: contains number of devices for which we are sending subscription requests * No return value. */ -void send_device_subs(dev_subs_t *subs, int num_devices); +void send_device_subs(dev_subs_t* subs, int num_devices); /** * Calling this function will let the next device data packet coming into Dawn from Runtime diff --git a/tests/client/shm_client.c b/tests/client/shm_client.c index 70022abd..75dcf2e5 100644 --- a/tests/client/shm_client.c +++ b/tests/client/shm_client.c @@ -2,11 +2,11 @@ void start_shm() { pid_t shm_pid; - + // fork shm_start process if ((shm_pid = fork()) < 0) { printf("fork: %s\n", strerror(errno)); - } else if (shm_pid == 0) { // child + } else if (shm_pid == 0) { // child // cd to the shm_wrapper directory if (chdir("../shm_wrapper") == -1) { printf("chdir: %s\n", strerror(errno)); @@ -16,12 +16,12 @@ void start_shm() { if (execlp("./shm_start", "shm", NULL) < 0) { printf("execlp: %s\n", strerror(errno)); } - } else { // parent + } else { // parent // wait for shm_start process to terminate if (waitpid(shm_pid, NULL, 0) < 0) { printf("waitpid shm: %s\n", strerror(errno)); } - + // init to the now-existing shared memory shm_init(); } @@ -29,11 +29,11 @@ void start_shm() { void stop_shm() { pid_t shm_pid; - + // fork shm_stop process if ((shm_pid = fork()) < 0) { printf("fork: %s\n", strerror(errno)); - } else if (shm_pid == 0) { // child + } else if (shm_pid == 0) { // child // cd to the shm_wrapper directory if (chdir("../shm_wrapper") == -1) { printf("chdir: %s\n", strerror(errno)); @@ -43,7 +43,7 @@ void stop_shm() { if (execlp("./shm_stop", "shm", NULL) < 0) { printf("execlp: %s\n", strerror(errno)); } - } else { // parent + } else { // parent // wait for shm_stop process to terminate if (waitpid(shm_pid, NULL, 0) < 0) { printf("waitpid shm: %s\n", strerror(errno)); @@ -52,7 +52,7 @@ void stop_shm() { } void print_shm() { - print_params(~0); // prints all devices + print_params(~0); // prints all devices print_cmd_map(); print_sub_map(); print_robot_desc(); diff --git a/tests/client/shm_client.h b/tests/client/shm_client.h index 5c7fec67..1326a9ea 100644 --- a/tests/client/shm_client.h +++ b/tests/client/shm_client.h @@ -1,8 +1,8 @@ #ifndef SHM_CLIENT_H #define SHM_CLIENT_H -#include "../../shm_wrapper/shm_wrapper.h" #include +#include "../../shm_wrapper/shm_wrapper.h" /** * Creates and initializes the shared memory process diff --git a/tests/client/virtual_devices/foreign_dev.c b/tests/client/virtual_devices/foreign_dev.c index 300eada2..45a92034 100644 --- a/tests/client/virtual_devices/foreign_dev.c +++ b/tests/client/virtual_devices/foreign_dev.c @@ -1,7 +1,7 @@ -#include // for srand() and rand() -#include // for time() as a seed -#include // for uint8_t -#include // for write() +#include // for uint8_t +#include // for srand() and rand() +#include // for time() as a seed +#include // for write() /** * ForeignTestDevice, a virtual device that sends nonsense to dev handler @@ -10,7 +10,7 @@ * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { // https://www.tutorialspoint.com/c_standard_library/c_function_srand.htm // Initialize random seed using the current time srand(time(NULL)); diff --git a/tests/client/virtual_devices/general_dev.c b/tests/client/virtual_devices/general_dev.c index 9e87cf6b..96eb31b1 100644 --- a/tests/client/virtual_devices/general_dev.c +++ b/tests/client/virtual_devices/general_dev.c @@ -2,8 +2,8 @@ * A virtual device that behaves like a proper lowcar device */ -#include // for atoi() -#include // for print +#include // for print +#include // for atoi() #include "virtual_device_util.h" @@ -12,14 +12,38 @@ // GeneralTestDevice params enum { // Read-only - INCREASING_ODD, DECREASING_ODD, INCREASING_EVEN, DECREASING_EVEN, - INCREASING_FLIP, ALWAYS_LEET, DOUBLING, DOUBLING_NEG, HALFING, - HALFING_NEG, EXP_ONE_PT_ONE, EXP_ONE_PT_TWO, ALWAYS_PI, FLIP_FLOP, - ALWAYS_TRUE, ALWAYS_FALSE, + INCREASING_ODD, + DECREASING_ODD, + INCREASING_EVEN, + DECREASING_EVEN, + INCREASING_FLIP, + ALWAYS_LEET, + DOUBLING, + DOUBLING_NEG, + HALFING, + HALFING_NEG, + EXP_ONE_PT_ONE, + EXP_ONE_PT_TWO, + ALWAYS_PI, + FLIP_FLOP, + ALWAYS_TRUE, + ALWAYS_FALSE, // Read and Write - RED_INT, ORANGE_INT, GREEN_INT, BLUE_INT, PURPLE_INT, - RED_FLOAT, ORANGE_FLOAT, GREEN_FLOAT, BLUE_FLOAT, PURPLE_FLOAT, - RED_BOOL, ORANGE_BOOL, GREEN_BOOL, BLUE_BOOL, PURPLE_BOOL, + RED_INT, + ORANGE_INT, + GREEN_INT, + BLUE_INT, + PURPLE_INT, + RED_FLOAT, + ORANGE_FLOAT, + GREEN_FLOAT, + BLUE_FLOAT, + PURPLE_FLOAT, + RED_BOOL, + ORANGE_BOOL, + GREEN_BOOL, + BLUE_BOOL, + PURPLE_BOOL, YELLOW_BOOL }; @@ -29,39 +53,39 @@ enum { * params: Array of params to be initialized */ void init_params(param_val_t params[]) { - params[INCREASING_ODD].p_i = 1; - params[DECREASING_ODD].p_i = -1; - params[INCREASING_EVEN].p_i = 0; - params[DECREASING_EVEN].p_i = 0; - params[INCREASING_FLIP].p_i = 0; - params[ALWAYS_LEET].p_i = 1337; - params[DOUBLING].p_f = 1; - params[DOUBLING_NEG].p_f = -1; - params[HALFING].p_f = 1048576; // 2^20 - params[HALFING_NEG].p_f = -1048576; - params[EXP_ONE_PT_ONE].p_f = 1; - params[EXP_ONE_PT_TWO].p_f = 1; - params[ALWAYS_PI].p_f = 3.14159265359; - params[FLIP_FLOP].p_b = 1; - params[ALWAYS_TRUE].p_b = 1; - params[ALWAYS_FALSE].p_b = 0; + params[INCREASING_ODD].p_i = 1; + params[DECREASING_ODD].p_i = -1; + params[INCREASING_EVEN].p_i = 0; + params[DECREASING_EVEN].p_i = 0; + params[INCREASING_FLIP].p_i = 0; + params[ALWAYS_LEET].p_i = 1337; + params[DOUBLING].p_f = 1; + params[DOUBLING_NEG].p_f = -1; + params[HALFING].p_f = 1048576; // 2^20 + params[HALFING_NEG].p_f = -1048576; + params[EXP_ONE_PT_ONE].p_f = 1; + params[EXP_ONE_PT_TWO].p_f = 1; + params[ALWAYS_PI].p_f = 3.14159265359; + params[FLIP_FLOP].p_b = 1; + params[ALWAYS_TRUE].p_b = 1; + params[ALWAYS_FALSE].p_b = 0; // Read and Write - params[RED_INT].p_i = 1; - params[ORANGE_INT].p_i = 2; - params[GREEN_INT].p_i = 3; - params[BLUE_INT].p_i = 4; - params[PURPLE_INT].p_i = 5; - params[RED_FLOAT].p_f = 6.6; - params[ORANGE_FLOAT].p_f = 7.7; - params[GREEN_FLOAT].p_f = 8.8; - params[BLUE_FLOAT].p_f = 9.9; - params[PURPLE_FLOAT].p_f = 10.1; - params[RED_BOOL].p_b = 1; - params[ORANGE_BOOL].p_b = 1; - params[GREEN_BOOL].p_b = 1; - params[BLUE_BOOL].p_b = 1; - params[PURPLE_BOOL].p_b = 1; - params[YELLOW_BOOL].p_b = 1; + params[RED_INT].p_i = 1; + params[ORANGE_INT].p_i = 2; + params[GREEN_INT].p_i = 3; + params[BLUE_INT].p_i = 4; + params[PURPLE_INT].p_i = 5; + params[RED_FLOAT].p_f = 6.6; + params[ORANGE_FLOAT].p_f = 7.7; + params[GREEN_FLOAT].p_f = 8.8; + params[BLUE_FLOAT].p_f = 9.9; + params[PURPLE_FLOAT].p_f = 10.1; + params[RED_BOOL].p_b = 1; + params[ORANGE_BOOL].p_b = 1; + params[GREEN_BOOL].p_b = 1; + params[BLUE_BOOL].p_b = 1; + params[PURPLE_BOOL].p_b = 1; + params[YELLOW_BOOL].p_b = 1; } /** @@ -75,11 +99,11 @@ void device_actions(param_val_t params[]) { params[INCREASING_EVEN].p_i += 2; params[DECREASING_EVEN].p_i -= 2; params[INCREASING_FLIP].p_i = (-1) * - (params[INCREASING_FLIP].p_i + ((params[INCREASING_FLIP].p_i % 2 == 0) ? 1 : -1)); // -1, 2, -3, 4, etc + (params[INCREASING_FLIP].p_i + ((params[INCREASING_FLIP].p_i % 2 == 0) ? 1 : -1)); // -1, 2, -3, 4, etc params[DOUBLING].p_f *= 2; params[DOUBLING_NEG].p_f *= 2; - params[HALFING].p_f /= 2; // 2^20 + params[HALFING].p_f /= 2; // 2^20 params[HALFING_NEG].p_f /= 2; params[EXP_ONE_PT_ONE].p_f *= 1.1; params[EXP_ONE_PT_TWO].p_f *= 1.2; @@ -94,7 +118,7 @@ void device_actions(param_val_t params[]) { * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { if (argc < 3) { printf("Incorrect number of arguments: %d out of %d\n", argc, 3); exit(1); @@ -104,7 +128,7 @@ int main(int argc, char *argv[]) { uint64_t uid = strtoull(argv[2], NULL, 0); uint8_t dev_type = device_name_to_type("GeneralTestDevice"); - device_t *dev = get_device(dev_type); + device_t* dev = get_device(dev_type); param_val_t params[dev->num_params]; init_params(params); diff --git a/tests/client/virtual_devices/simple_dev.c b/tests/client/virtual_devices/simple_dev.c index 8598f62b..3698eec1 100644 --- a/tests/client/virtual_devices/simple_dev.c +++ b/tests/client/virtual_devices/simple_dev.c @@ -43,7 +43,7 @@ void device_actions(param_val_t params[]) { * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { if (argc < 3) { printf("Incorrect number of arguments: %d out of %d\n", argc, 3); exit(1); @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { uint64_t uid = strtoull(argv[2], NULL, 0); uint8_t dev_type = device_name_to_type("SimpleTestDevice"); - device_t *dev = get_device(dev_type); + device_t* dev = get_device(dev_type); param_val_t params[dev->num_params]; init_params(params); diff --git a/tests/client/virtual_devices/time_dev.c b/tests/client/virtual_devices/time_dev.c index 2603fc03..8586ab1d 100644 --- a/tests/client/virtual_devices/time_dev.c +++ b/tests/client/virtual_devices/time_dev.c @@ -44,7 +44,7 @@ void device_actions(param_val_t params[]) { return; } else if (params[GET_TIME].p_b) { uint64_t time = millis(); - params[TIMESTAMP].p_i = time % 1000000000; // Send last 9 digits + params[TIMESTAMP].p_i = time % 1000000000; // Send last 9 digits params[GET_TIME].p_b = 0; } } @@ -54,7 +54,7 @@ void device_actions(param_val_t params[]) { * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { if (argc < 3) { printf("Incorrect number of arguments: %d out of %d\n", argc, 3); exit(1); @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) { uint64_t uid = strtoull(argv[2], NULL, 0); uint8_t dev_type = device_name_to_type("TimeTestDevice"); - device_t *dev = get_device(dev_type); + device_t* dev = get_device(dev_type); param_val_t params[dev->num_params]; init_params(params); diff --git a/tests/client/virtual_devices/unresponsive_dev.c b/tests/client/virtual_devices/unresponsive_dev.c index 9414213e..89721c8a 100644 --- a/tests/client/virtual_devices/unresponsive_dev.c +++ b/tests/client/virtual_devices/unresponsive_dev.c @@ -8,7 +8,7 @@ * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { // Do nothing. He's in for a long nap. while (1) { sleep(60); diff --git a/tests/client/virtual_devices/unstable_dev.c b/tests/client/virtual_devices/unstable_dev.c index 1ae50b7a..1ea7b916 100644 --- a/tests/client/virtual_devices/unstable_dev.c +++ b/tests/client/virtual_devices/unstable_dev.c @@ -44,7 +44,7 @@ void device_actions(param_val_t params[]) { * int: file descriptor for the socket * uint64_t: device uid */ -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { if (argc < 3) { printf("Incorrect number of arguments: %d out of %d\n", argc, 3); exit(1); @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) { uint64_t uid = strtoull(argv[2], NULL, 0); uint8_t dev_type = device_name_to_type("UnstableTestDevice"); - device_t *dev = get_device(dev_type); + device_t* dev = get_device(dev_type); param_val_t params[dev->num_params]; init_params(params); diff --git a/tests/client/virtual_devices/virtual_device_util.c b/tests/client/virtual_devices/virtual_device_util.c index a9cc6a4d..5ea6b1ad 100644 --- a/tests/client/virtual_devices/virtual_device_util.c +++ b/tests/client/virtual_devices/virtual_device_util.c @@ -1,7 +1,7 @@ #include "virtual_device_util.h" -message_t *make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid) { - message_t *msg = malloc(sizeof(message_t)); +message_t* make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid) { + message_t* msg = malloc(sizeof(message_t)); msg->message_id = ACKNOWLEDGEMENT; msg->max_payload_length = DEVICE_ID_SIZE; msg->payload = malloc(msg->max_payload_length); @@ -12,13 +12,13 @@ message_t *make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid) { return msg; } -int receive_message(int fd, message_t *msg) { - uint8_t last_byte_read = 0; // Variable to temporarily hold a read byte +int receive_message(int fd, message_t* msg) { + uint8_t last_byte_read = 0; // Variable to temporarily hold a read byte int num_bytes_read = 0; // Keep reading a byte until we get the delimiter byte while (1) { - num_bytes_read = read(fd, &last_byte_read, 1); // Waiting for first byte can block + num_bytes_read = read(fd, &last_byte_read, 1); // Waiting for first byte can block if (num_bytes_read == -1) { printf("Couldn't read first byte -- %s\n", strerror(errno)); return 1; @@ -38,7 +38,7 @@ int receive_message(int fd, message_t *msg) { } // Allocate buffer to read message into - uint8_t *data = malloc(DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_len); + uint8_t* data = malloc(DELIMITER_SIZE + COBS_LENGTH_SIZE + cobs_len); data[0] = 0x00; data[1] = cobs_len; @@ -60,9 +60,9 @@ int receive_message(int fd, message_t *msg) { return 0; } -void send_message(int fd, message_t *msg) { +void send_message(int fd, message_t* msg) { int len = calc_max_cobs_msg_length(msg); - uint8_t *data = malloc(len); + uint8_t* data = malloc(len); len = message_to_bytes(msg, data, len); int transferred = write(fd, data, len); if (transferred != len) { @@ -71,28 +71,28 @@ void send_message(int fd, message_t *msg) { free(data); } -void device_write(uint8_t type, message_t *dev_write, param_val_t params[]) { - device_t *dev = get_device(type); +void device_write(uint8_t type, message_t* dev_write, param_val_t params[]) { + device_t* dev = get_device(type); // Get bitmap from payload uint32_t pmap; memcpy(&pmap, &dev_write->payload[0], BITMAP_SIZE); // Process each parameter - uint8_t *payload_ptr = &dev_write->payload[BITMAP_SIZE]; + uint8_t* payload_ptr = &dev_write->payload[BITMAP_SIZE]; for (int i = 0; ((pmap >> i) > 0) && (i < MAX_PARAMS); i++) { if (pmap & (1 << i)) { // Write to the corresponding field in params[i] switch (dev->params[i].type) { case INT: // TODO: Check int size - params[i].p_i = *((int32_t *) payload_ptr); + params[i].p_i = *((int32_t*) payload_ptr); payload_ptr += sizeof(int32_t); break; case FLOAT: - params[i].p_f = *((float *) payload_ptr); + params[i].p_f = *((float*) payload_ptr); payload_ptr += sizeof(float); break; case BOOL: - params[i].p_b = *((uint8_t *) payload_ptr); + params[i].p_b = *((uint8_t*) payload_ptr); payload_ptr += sizeof(uint8_t); break; } @@ -100,18 +100,18 @@ void device_write(uint8_t type, message_t *dev_write, param_val_t params[]) { } } -message_t *make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]) { - message_t *dev_data = make_empty(MAX_PAYLOAD_SIZE); +message_t* make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]) { + message_t* dev_data = make_empty(MAX_PAYLOAD_SIZE); dev_data->message_id = DEVICE_DATA; // Copy pmap into payload memcpy(&dev_data->payload[0], &pmap, BITMAP_SIZE); dev_data->payload_length = BITMAP_SIZE; // Copy params into payload - device_t *dev = get_device(type); - uint8_t *payload_ptr = &dev_data->payload[BITMAP_SIZE]; + device_t* dev = get_device(type); + uint8_t* payload_ptr = &dev_data->payload[BITMAP_SIZE]; for (int i = 0; ((pmap >> i) > 0) && (i < MAX_PARAMS); i++) { if (pmap & (1 << i)) { - switch(dev->params[i].type) { + switch (dev->params[i].type) { case INT: memcpy(payload_ptr, ¶ms[i].p_i, sizeof(int32_t)); payload_ptr += sizeof(int32_t); @@ -135,10 +135,10 @@ message_t *make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]) { return dev_data; } -void lowcar_protocol(int fd, uint8_t type, uint8_t year, uint64_t uid, \ +void lowcar_protocol(int fd, uint8_t type, uint8_t year, uint64_t uid, param_val_t params[], void (*device_actions)(param_val_t[]), int32_t action_interval) { - message_t *incoming_msg = make_empty(MAX_PAYLOAD_SIZE); - message_t *outgoing_msg; + message_t* incoming_msg = make_empty(MAX_PAYLOAD_SIZE); + message_t* outgoing_msg; uint64_t last_sent_ping_time = 0; uint64_t last_received_ping_time = millis(); uint64_t last_sent_data_time = 0; diff --git a/tests/client/virtual_devices/virtual_device_util.h b/tests/client/virtual_devices/virtual_device_util.h index 3b5ce5a5..5229a486 100644 --- a/tests/client/virtual_devices/virtual_device_util.h +++ b/tests/client/virtual_devices/virtual_device_util.h @@ -20,7 +20,7 @@ * payload_length: sizeof(type) + sizeof(year) + sizeof(uid) * max_payload_length: same as above */ -message_t *make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid); +message_t* make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid); /** * Receives a message @@ -32,7 +32,7 @@ message_t *make_acknowledgement(uint8_t type, uint8_t year, uint64_t uid); * 1 on bad read * 2 on incorrect checksum */ -int receive_message(int fd, message_t *msg); +int receive_message(int fd, message_t* msg); /** * Sends a message @@ -40,7 +40,7 @@ int receive_message(int fd, message_t *msg); * fd: File descriptor to write to * msg: message_t to be sent */ -void send_message(int fd, message_t *msg); +void send_message(int fd, message_t* msg); /** * Processes a DEVICE_WRITE message, writing to params as appropriate @@ -49,7 +49,7 @@ void send_message(int fd, message_t *msg); * dev_write: A DEVICE_WRITE message to process * params: Array of params to be written to */ -void device_write(uint8_t type, message_t *dev_write, param_val_t params[]); +void device_write(uint8_t type, message_t* dev_write, param_val_t params[]); /** * Builds a DEVICE_DATA message, reading params as appropriate @@ -59,7 +59,7 @@ void device_write(uint8_t type, message_t *dev_write, param_val_t params[]); * pmap: bitmap indicating which params should be read into DEV_DATA * params: Array of params to be read from */ -message_t *make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]); +message_t* make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]); /** * Executes the lowcar protocol, receiving/responding to messages, and sending @@ -74,7 +74,7 @@ message_t *make_device_data(uint8_t type, uint32_t pmap, param_val_t params[]); * modifies the param values * action_interval: Number of milliseconds between each call to device_actions() */ -void lowcar_protocol(int fd, uint8_t type, uint8_t year, uint64_t uid, \ +void lowcar_protocol(int fd, uint8_t type, uint8_t year, uint64_t uid, param_val_t params[], void (*device_actions)(param_val_t[]), int32_t action_interval); #endif diff --git a/tests/integration/tc_68_1.c b/tests/integration/tc_68_1.c deleted file mode 100644 index 57c94c5f..00000000 --- a/tests/integration/tc_68_1.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../test.h" - -/** - * This test is a sanity test for testing the testing framework - * It sends the system into Auto mode and sets the robot to the Right starting position - * and checks that those actions are reflected in shared memory. - */ - -char check_1_output[] = - "Changed devices: 00000000000000000000000000000000\n" - "Changed params:\n" - "Requested devices: 00000000000000000000000000000000\n" - "Requested params:\n" - "Current Robot Description:\n" - "\tRUN_MODE = AUTO\n" - "\tDAWN = CONNECTED\n" - "\tSHEPHERD = CONNECTED\n" - "\tGAMEPAD = DISCONNECTED\n" - "\tSTART_POS = LEFT\n\n" - "Current Gamepad State:\n" - "\tNo gamepad currently connected\n"; - -char check_2_output[] = - "Changed devices: 00000000000000000000000000000000\n" - "Changed params:\n" - "Requested devices: 00000000000000000000000000000000\n" - "Requested params:\n" - "Current Robot Description:\n" - "\tRUN_MODE = AUTO\n" - "\tDAWN = CONNECTED\n" - "\tSHEPHERD = CONNECTED\n" - "\tGAMEPAD = DISCONNECTED\n" - "\tSTART_POS = RIGHT\n\n" - "Current Gamepad State:\n" - "\tNo gamepad currently connected\n"; - -int main() { - // setup - start_test("sanity"); - start_shm(); - start_net_handler(); - - // poke the system - send_run_mode(SHEPHERD, AUTO); - print_shm(); - send_start_pos(SHEPHERD, RIGHT); - print_shm(); - - // stop the system - stop_net_handler(); - stop_shm(); - end_test(); - - // do checks - in_rest_of_output(check_1_output); - in_rest_of_output(check_2_output); - return 0; -} diff --git a/tests/integration/tc_68_2.c b/tests/integration/tc_68_2.c deleted file mode 100644 index f8858680..00000000 --- a/tests/integration/tc_68_2.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "../test.h" - -/** - * This test is a decently comprehensive executor sanity check (and a demonstration of the test framework's executor-testing abilities) - * It tests to make sure the testing framework can load student code from our testing folder, runs two coding challenges, does a basic - * test of Robot.run(), checks that both auto and teleop mode work, and checks that an error is outputted to the screen when a Python - * exception occurs. - */ - -char check_output_1[] = "Autonomous setup has begun!\n"; - -char check_output_2[] = "autonomous printing again\n"; - -char check_output_3[] = "\tRUN_MODE = AUTO\n"; - -char check_output_4[] = "\tRUN_MODE = IDLE\n"; - -char check_output_5[] = - "Traceback (most recent call last):\n"; - -// we have to skip the File: because on the pi it's /home/pi/runtime -// but on Docker it's /root/runtime -char check_output_6[] = - "line 25, in teleop_main\n" - " oops = 1 / 0\n" - "ZeroDivisionError: division by zero\n"; - -char check_output_7[] = "Python function teleop_main call failed\n"; - -char check_output_8[] = "\tRUN_MODE = TELEOP\n"; - -char check_output_9[] = - "Challenge 0 result: 9302\n" - "Challenge 1 result: [2, 661, 35963]"; - -char check_output_10[] = "Suppressing output: too many messages..."; - -int main() { - // set everything up - start_test("executor sanity test"); - start_shm(); - start_net_handler(); - start_executor("executor_sanity", "executor_sanity"); - - // poke the system - // this section checks the autonomous code (should generate some print statements) - send_start_pos(SHEPHERD, RIGHT); - send_run_mode(SHEPHERD, AUTO); - sleep(1); - print_shm(); - sleep(2); - send_run_mode(SHEPHERD, IDLE); - print_shm(); - - // this section checks the teleop code (should generate division by zero error) - send_run_mode(DAWN, TELEOP); - print_shm(); - send_run_mode(DAWN, IDLE); - print_shm(); - - // this section runs the coding challenges (should not error or time out) - char *inputs[] = { "2039", "190172344" }; - send_challenge_data(DAWN, inputs, 2); - - // stop all the processes - stop_executor(); - stop_net_handler(); - stop_shm(); - end_test(); - - // check outputs - in_rest_of_output(check_output_1); - in_rest_of_output(check_output_2); - in_rest_of_output(check_output_3); - in_rest_of_output(check_output_2); - in_rest_of_output(check_output_4); - in_rest_of_output(check_output_5); - in_rest_of_output(check_output_6); - in_rest_of_output(check_output_7); - in_rest_of_output(check_output_8); - in_rest_of_output(check_output_9); - not_in_output(check_output_10); // check to make sure we don't get the suppressing messages bug - - return 0; -} diff --git a/tests/integration/tc_68_3.c b/tests/integration/tc_68_3.c deleted file mode 100644 index 888146c0..00000000 --- a/tests/integration/tc_68_3.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "../test.h" - -/** - * This test checks to make sure that device subscriptions made to nonexistent devices - * from Dawn are rejected by shared memory and an error message is sent back to Dawn. - */ - -char check_output_1[] = "no device at dev_uid = 50, sub request failed\n"; - -char check_output_2[] = "recv_new_msg: Invalid device subscription, device uid 50 is invalid\n"; - -char check_output_3[] = "no device at dev_uid = 100, sub request failed\n"; - -char check_output_4[] = "recv_new_msg: Invalid device subscription, device uid 100 is invalid\n"; - -int main() { - // setup - start_test("nonexistent device subscription"); - start_shm(); - start_net_handler(); - - // poke - dev_subs_t data1 = { .uid = 50, .name = "ServoControl", .params = 0b11 }; - dev_subs_t data2 = { .uid = 100, .name = "LimitSwitch", .params = 0b101 }; - dev_subs_t data_total[2] = { data1, data2 }; - send_device_subs(data_total, 2); - - // stop - stop_net_handler(); - stop_shm(); - end_test(); - - // check output - in_rest_of_output(check_output_1); - in_rest_of_output(check_output_2); - in_rest_of_output(check_output_3); - in_rest_of_output(check_output_4); - return 0; -} diff --git a/tests/integration/tc_68_4.c b/tests/integration/tc_68_4.c deleted file mode 100644 index 1ae03bc6..00000000 --- a/tests/integration/tc_68_4.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "../test.h" - -/** - * This test ensures that with no devices connected to the system, the - * shared memory starts sending custom data back to Dawn as soon as the - * first Gamepad State packet arrives on Runtime from Dawn. - */ - -char check_output_1[] = - "Current Robot Description:\n" - "\tRUN_MODE = IDLE\n" - "\tDAWN = CONNECTED\n" - "\tSHEPHERD = CONNECTED\n" - "\tGAMEPAD = CONNECTED\n" - "\tSTART_POS = LEFT\n\n" - "Current Gamepad State:\n" - "\tPushed Buttons:\n" - "\t\tbutton_a\n" - "\t\tl_trigger\n" - "\t\tdpad_down\n" - "\tJoystick Positions:\n" - "\t\tjoystick_left_x = -0.100000\n" - "\t\tjoystick_left_y = 0.000000\n" - "\t\tjoystick_right_x = 0.100000\n" - "\t\tjoystick_right_y = 0.990000\n"; - -char check_output_2[] = - "Device No. 0:\ttype = CustomData, uid = 0, itype = 32\n"; - -int main() { - // setup - start_test("UDP; no devices connected"); - start_shm(); - start_net_handler(); - - //poke system - uint32_t buttons = (1 << BUTTON_A) | (1 << L_TRIGGER) | (1 << DPAD_DOWN); - float joystick_vals[] = { -0.1, 0.0, 0.1, 0.99 }; - send_gamepad_state(buttons, joystick_vals); - print_shm(); - print_next_dev_data(); - - // stop all processes - stop_net_handler(); - stop_shm(); - end_test(); - - // check outputs - in_rest_of_output(check_output_1); - in_rest_of_output(check_output_2); - return 0; -} diff --git a/tests/integration/tc_71_1.c b/tests/integration/tc_71_1.c new file mode 100644 index 00000000..27278579 --- /dev/null +++ b/tests/integration/tc_71_1.c @@ -0,0 +1,58 @@ +#include "../test.h" + +/** + * This test is a sanity test for testing the testing framework + * It sends the system into Auto mode and sets the robot to the Right starting position + * and checks that those actions are reflected in shared memory. + */ + +char check_1_output[] = + "Changed devices: 00000000000000000000000000000000\n" + "Changed params:\n" + "Requested devices: 00000000000000000000000000000000\n" + "Requested params:\n" + "Current Robot Description:\n" + "\tRUN_MODE = AUTO\n" + "\tDAWN = CONNECTED\n" + "\tSHEPHERD = CONNECTED\n" + "\tGAMEPAD = DISCONNECTED\n" + "\tSTART_POS = LEFT\n\n" + "Current Gamepad State:\n" + "\tNo gamepad currently connected\n"; + +char check_2_output[] = + "Changed devices: 00000000000000000000000000000000\n" + "Changed params:\n" + "Requested devices: 00000000000000000000000000000000\n" + "Requested params:\n" + "Current Robot Description:\n" + "\tRUN_MODE = AUTO\n" + "\tDAWN = CONNECTED\n" + "\tSHEPHERD = CONNECTED\n" + "\tGAMEPAD = DISCONNECTED\n" + "\tSTART_POS = RIGHT\n\n" + "Current Gamepad State:\n" + "\tNo gamepad currently connected\n"; + +int main() { + // setup + start_test("sanity"); + start_shm(); + start_net_handler(); + + // poke the system + send_run_mode(SHEPHERD, AUTO); + print_shm(); + send_start_pos(SHEPHERD, RIGHT); + print_shm(); + + // stop the system + stop_net_handler(); + stop_shm(); + end_test(); + + // do checks + in_rest_of_output(check_1_output); + in_rest_of_output(check_2_output); + return 0; +} diff --git a/tests/integration/tc_68_10.c b/tests/integration/tc_71_10.c similarity index 91% rename from tests/integration/tc_68_10.c rename to tests/integration/tc_71_10.c index b22acd06..08c671b9 100644 --- a/tests/integration/tc_68_10.c +++ b/tests/integration/tc_71_10.c @@ -18,11 +18,11 @@ int main() { start_net_handler(); start_dev_handler(); start_executor("runtime_latency", ""); - sleep(1); // Let processes boot up + sleep(1); // Let processes boot up // Connect TimeTestDevice connect_virtual_device("TimeTestDevice", TIME_DEV_UID); - sleep(1); // Wait for ACK exchange + sleep(1); // Wait for ACK exchange // Connect gamepad uint32_t buttons = 0; @@ -33,7 +33,7 @@ int main() { send_run_mode(SHEPHERD, TELEOP); // Start the timer and press A - int32_t start = millis() % 1000000000; // 9 digits, just like TimeTestDevice + int32_t start = millis() % 1000000000; // 9 digits, just like TimeTestDevice buttons |= (1 << BUTTON_A); send_gamepad_state(buttons, joystick_vals); diff --git a/tests/integration/tc_68_11.c b/tests/integration/tc_71_11.c similarity index 77% rename from tests/integration/tc_68_11.c rename to tests/integration/tc_71_11.c index 750141cd..6b6401b7 100644 --- a/tests/integration/tc_68_11.c +++ b/tests/integration/tc_71_11.c @@ -18,10 +18,10 @@ int main() { sleep(1); // Get current parameters then wait - device_t *dev = get_device(device_name_to_type("SimpleTestDevice")); + device_t* dev = get_device(device_name_to_type("SimpleTestDevice")); param_val_t vals_before[dev->num_params]; device_read_uid(UID, EXECUTOR, DATA, 0b1111, vals_before); - sleep(1); // Device values will change in this time + sleep(1); // Device values will change in this time // Get parameters again param_val_t vals_after[dev->num_params]; @@ -35,13 +35,13 @@ int main() { end_test(); // Verify parameters changed as expected - vals_before[0].p_i++; // INCREASING: Increased by 1 + vals_before[0].p_i++; // INCREASING: Increased by 1 same_param_value("INCREASING", INT, vals_before[0], vals_after[0]); - vals_before[1].p_f *= 2; // DOUBLING: Doubled value + vals_before[1].p_f *= 2; // DOUBLING: Doubled value same_param_value("DOUBLING", FLOAT, vals_before[1], vals_after[1]); - vals_before[2].p_b = 1 - vals_before[2].p_b; // FLIP_FLOP: Opposite truth value + vals_before[2].p_b = 1 - vals_before[2].p_b; // FLIP_FLOP: Opposite truth value same_param_value("FLIP_FLOP", BOOL, vals_before[2], vals_after[2]); return 0; diff --git a/tests/integration/tc_68_12.c b/tests/integration/tc_71_12.c similarity index 93% rename from tests/integration/tc_68_12.c rename to tests/integration/tc_71_12.c index 53ab7b32..cffb3815 100644 --- a/tests/integration/tc_68_12.c +++ b/tests/integration/tc_71_12.c @@ -21,7 +21,7 @@ int main() { const int8_t doubling_idx = get_param_idx(simple_type, "DOUBLING"); // Get current parameters then wait - device_t *dev = get_device(simple_type); + device_t* dev = get_device(simple_type); param_val_t vals_before[dev->num_params]; device_read_uid(UID, EXECUTOR, DATA, (1 << doubling_idx), vals_before); @@ -29,7 +29,7 @@ int main() { param_val_t vals_to_write[dev->num_params]; vals_to_write[doubling_idx].p_f = -1; device_write_uid(UID, EXECUTOR, COMMAND, (1 << doubling_idx), vals_to_write); - sleep(1); // Device values will change in this time + sleep(1); // Device values will change in this time // Get parameters again param_val_t vals_after[dev->num_params]; diff --git a/tests/integration/tc_68_13.c b/tests/integration/tc_71_13.c similarity index 83% rename from tests/integration/tc_68_13.c rename to tests/integration/tc_71_13.c index 70bf5759..18765323 100644 --- a/tests/integration/tc_68_13.c +++ b/tests/integration/tc_71_13.c @@ -22,9 +22,9 @@ int main() { connect_virtual_device("UnstableTestDevice", i); } sleep(1); - print_dev_ids(); // All devices should be present - sleep(5); // All devices will time out - print_dev_ids(); // No devices + print_dev_ids(); // All devices should be present + sleep(5); // All devices will time out + print_dev_ids(); // No devices // Clean up disconnect_all_devices(); @@ -36,7 +36,7 @@ int main() { // Check output char expected_output[64]; for (int i = 0; i < NUM_TO_CONNECT; i++) { - sprintf(expected_output, "dev_ix = %d: type = %d", i, device_name_to_type("UnstableTestDevice")); // check each unstable device is connected + sprintf(expected_output, "dev_ix = %d: type = %d", i, device_name_to_type("UnstableTestDevice")); // check each unstable device is connected in_rest_of_output(expected_output); } for (int i = 0; i < NUM_TO_CONNECT; i++) { diff --git a/tests/integration/tc_68_14.c b/tests/integration/tc_71_14.c similarity index 84% rename from tests/integration/tc_68_14.c rename to tests/integration/tc_71_14.c index 04d05c66..94d6536e 100644 --- a/tests/integration/tc_68_14.c +++ b/tests/integration/tc_71_14.c @@ -14,9 +14,9 @@ char print_dev_ids_format[] = "dev_ix = %d: type = %d, year = %d, uid = %llu\n"; #define NUM_UNSTABLE 3 #define NUM_BAD_DEVS 10 -int main(){ +int main() { // Setup - if(NUM_GENERAL + NUM_UNSTABLE > MAX_DEVICES){ + if (NUM_GENERAL + NUM_UNSTABLE > MAX_DEVICES) { printf("Invalid Number Of Devices Connected"); exit(1); } @@ -30,47 +30,47 @@ int main(){ uint8_t unstable_dev_type = device_name_to_type("UnstableTestDevice"); uint64_t uid = 0; - print_dev_ids(); // No initial devices + print_dev_ids(); // No initial devices // Connect NUM_GENERAL devices for (int i = 0; i < NUM_GENERAL; i++) { connect_virtual_device("GeneralTestDevice", uid); uid++; } sleep(1); - print_dev_ids(); // Only GeneralTestDevices + print_dev_ids(); // Only GeneralTestDevices // Connect NUM_UNSTABLE unstable devices then let them time out - for(int i = 0; i < NUM_UNSTABLE; i++){ + for (int i = 0; i < NUM_UNSTABLE; i++) { connect_virtual_device("UnstableTestDevice", uid); uid++; } sleep(1); - print_dev_ids(); // NUM_GENERAL + NUM_UNSTABLE devices - sleep(5); // Unstable Devices should timeout - print_dev_ids(); // Only GeneralTestDevices + print_dev_ids(); // NUM_GENERAL + NUM_UNSTABLE devices + sleep(5); // Unstable Devices should timeout + print_dev_ids(); // Only GeneralTestDevices // Disconnect the unstable devices - for(int i = NUM_GENERAL; i < NUM_UNSTABLE; i++){ + for (int i = NUM_GENERAL; i < NUM_UNSTABLE; i++) { disconnect_virtual_device(i); } sleep(1); // Connect devices that dev handler should not connect to shm - for(int i = 0; i < NUM_BAD_DEVS; i++){ + for (int i = 0; i < NUM_BAD_DEVS; i++) { if (uid % 2) { connect_virtual_device("ForeignTestDevice", uid); - } else{ + } else { connect_virtual_device("UnresponsiveTestDevice", uid); } uid++; } sleep(2); - print_dev_ids(); // Only GeneralTestDevices + print_dev_ids(); // Only GeneralTestDevices // Clean up disconnect_all_devices(); sleep(2); - print_dev_ids(); // All Devices should be disconnected + print_dev_ids(); // All Devices should be disconnected stop_dev_handler(); stop_net_handler(); stop_shm(); @@ -97,7 +97,7 @@ int main(){ for (int i = NUM_GENERAL; i < NUM_UNSTABLE + NUM_GENERAL; i++) { sprintf(expected_output, "UnstableTestDevice (0x%016llX) timed out!", (uint64_t) i); in_rest_of_output(expected_output); - } + } // GeneralTestDevices remain in shm after UnstableTestDevices time out for (int i = 0; i < NUM_GENERAL; i++) { sprintf(expected_output, print_dev_ids_format, i, general_dev_type, general_dev_type, (uint64_t) i); @@ -109,7 +109,7 @@ int main(){ not_in_rest_of_output(unexpected_output); } // Error message when ForeignTestDevices and UnresponsiveTestDevices are connected - for (int i = 0; i < NUM_BAD_DEVS; i++){ + for (int i = 0; i < NUM_BAD_DEVS; i++) { in_rest_of_output(unknown_device); } // GeneralTestDevices remain in SHM after bad devices are handled @@ -122,6 +122,6 @@ int main(){ sprintf(unexpected_output, "dev_ix = %d", i); not_in_rest_of_output(unexpected_output); } - in_rest_of_output(no_device); // All Devices Disconnected properly + in_rest_of_output(no_device); // All Devices Disconnected properly return 0; } diff --git a/tests/integration/tc_68_15.c b/tests/integration/tc_71_15.c similarity index 94% rename from tests/integration/tc_68_15.c rename to tests/integration/tc_71_15.c index 15e31dd8..af0c4144 100644 --- a/tests/integration/tc_68_15.c +++ b/tests/integration/tc_71_15.c @@ -18,17 +18,17 @@ int main() { // Connect GeneralTestDevice connect_virtual_device("GeneralTestDevice", UID); - sleep(1); // Wait for ACK exchange + sleep(1); // Wait for ACK exchange // Get current parameters then wait - device_t *dev = get_device(device_name_to_type("GeneralTestDevice")); + device_t* dev = get_device(device_name_to_type("GeneralTestDevice")); param_val_t initial_vals[dev->num_params]; device_read_uid(UID, EXECUTOR, DATA, (uint32_t) -1, initial_vals); - sleep(1); // Device values will change in this time + sleep(1); // Device values will change in this time // Start autonomous mode send_run_mode(SHEPHERD, AUTO); - sleep(2); // Executor will write once + sleep(2); // Executor will write once // Get current parameters (ORANGE_FLOAT should be written to) param_val_t vals_post_auto[dev->num_params]; diff --git a/tests/integration/tc_68_16.c b/tests/integration/tc_71_16.c similarity index 93% rename from tests/integration/tc_68_16.c rename to tests/integration/tc_71_16.c index 4656a31b..f9cc1512 100644 --- a/tests/integration/tc_68_16.c +++ b/tests/integration/tc_71_16.c @@ -62,15 +62,15 @@ int main() { // poke the system connect_virtual_device("SimpleTestDevice", UID); start_executor("net_handler_integration", "challenges_sanity"); - usleep(1000000); // sleep 1.25 seconds to offset device from executor + usleep(1000000); // sleep 1.25 seconds to offset device from executor // send challenge data - char *inputs[] = { "2039", "190172344" }; - send_challenge_data(DAWN, inputs, 2); + char* inputs[] = {"2039", "190172344"}; + send_challenge_data(DAWN, inputs, 2); // send gamepad state - uint32_t buttons = 0; - float joystick_vals[] = { 0.0, 0.0, 0.0, 0.0 }; + uint32_t buttons = 0; + float joystick_vals[] = {0.0, 0.0, 0.0, 0.0}; send_gamepad_state(buttons, joystick_vals); // print device data diff --git a/tests/integration/tc_68_17.c b/tests/integration/tc_71_17.c similarity index 96% rename from tests/integration/tc_68_17.c rename to tests/integration/tc_71_17.c index 8e98e4e6..ca5c5b52 100644 --- a/tests/integration/tc_68_17.c +++ b/tests/integration/tc_71_17.c @@ -51,61 +51,61 @@ char check_16_output[] = int main() { int port1, port2, port3; - + // setup start_test("receive device data, general"); start_shm(); start_net_handler(); start_dev_handler(); - + // poke the system // send gamepad state so net_handler starts sending device data packets - uint32_t buttons = 0; - float joystick_vals[] = { 0.0, 0.0, 0.0, 0.0 }; + uint32_t buttons = 0; + float joystick_vals[] = {0.0, 0.0, 0.0, 0.0}; send_gamepad_state(buttons, joystick_vals); print_next_dev_data(); - + // connect two devices port1 = connect_virtual_device("SimpleTestDevice", UID1); port2 = connect_virtual_device("SimpleTestDevice", UID2); - + // print device data sleep(1); print_next_dev_data(); - + // disconnect first device disconnect_virtual_device(port1); - + // print device data sleep(1); print_next_dev_data(); - + // connect two more devices port1 = connect_virtual_device("SimpleTestDevice", UID3); port3 = connect_virtual_device("SimpleTestDevice", UID4); - + // print device data sleep(1); print_next_dev_data(); sleep(1); - + // disconnect all devices disconnect_virtual_device(port1); usleep(500000); disconnect_virtual_device(port2); usleep(500000); disconnect_virtual_device(port3); - + // print device data sleep(1); print_next_dev_data(); - + // stop the system stop_dev_handler(); stop_net_handler(); stop_shm(); end_test(); - + // check output in_rest_of_output(check_1_output); in_rest_of_output(check_2_output); diff --git a/tests/integration/tc_68_18.c b/tests/integration/tc_71_18.c similarity index 93% rename from tests/integration/tc_68_18.c rename to tests/integration/tc_71_18.c index 108ac14f..89e434d5 100644 --- a/tests/integration/tc_68_18.c +++ b/tests/integration/tc_71_18.c @@ -10,8 +10,8 @@ #define UID2 0x4321 // global variables to hold device subscriptions -dev_subs_t dev1_subs = { UID1, "SimpleTestDevice", 0 }; -dev_subs_t dev2_subs = { UID2, "SimpleTestDevice", 0 }; +dev_subs_t dev1_subs = {UID1, "SimpleTestDevice", 0}; +dev_subs_t dev2_subs = {UID2, "SimpleTestDevice", 0}; dev_subs_t dev_subs[2]; // check that certain names of parameters appear @@ -36,7 +36,7 @@ void send_subs(uint32_t dev1_params, uint32_t dev2_params) { dev_subs[0].params = dev1_params; dev_subs[1].params = dev2_params; send_device_subs(dev_subs, 2); - + // verify that we're receiving only those parameters sleep(1); print_next_dev_data(); @@ -50,39 +50,39 @@ int main() { start_dev_handler(); dev_subs[0] = dev1_subs; dev_subs[1] = dev2_subs; - + // connect two devices connect_virtual_device("SimpleTestDevice", UID1); connect_virtual_device("SimpleTestDevice", UID2); - + // send gamepad state so net_handler starts sending device data packets - uint32_t buttons = 0; - float joystick_vals[] = { 0.0, 0.0, 0.0, 0.0 }; + uint32_t buttons = 0; + float joystick_vals[] = {0.0, 0.0, 0.0, 0.0}; send_gamepad_state(buttons, joystick_vals); - + // verify that we're receiving all parameters sleep(1); print_next_dev_data(); - + // send subs that requests only a few parameters send_subs(0b11, 0b101); - + // send subs that requests fewer parameters send_subs(0b1, 0b100); - + // send subs that requests more parameters send_subs(0b11, 0b11); - + // send subs that requests the same parameters as last time send_subs(0b11, 0b11); - + // stop the system disconnect_all_devices(); stop_dev_handler(); stop_net_handler(); stop_shm(); end_test(); - + // check outputs // first sub request in_rest_of_output(dev1_header); @@ -96,7 +96,7 @@ int main() { in_rest_of_output(flipflop); in_rest_of_output(myint); in_rest_of_output(custom_dev_header); - + // second sub request in_rest_of_output(dev1_header); in_rest_of_output(increasing); @@ -105,7 +105,7 @@ int main() { in_rest_of_output(increasing); in_rest_of_output(flipflop); in_rest_of_output(custom_dev_header); - + // third sub request in_rest_of_output(dev1_header); in_rest_of_output(increasing); @@ -123,6 +123,6 @@ int main() { in_rest_of_output(doubling); in_rest_of_output(custom_dev_header); } - + return 0; } diff --git a/tests/integration/tc_71_2.c b/tests/integration/tc_71_2.c new file mode 100644 index 00000000..e2599eab --- /dev/null +++ b/tests/integration/tc_71_2.c @@ -0,0 +1,85 @@ +#include "../test.h" + +/** + * This test is a decently comprehensive executor sanity check (and a demonstration of the test framework's executor-testing abilities) + * It tests to make sure the testing framework can load student code from our testing folder, runs two coding challenges, does a basic + * test of Robot.run(), checks that both auto and teleop mode work, and checks that an error is outputted to the screen when a Python + * exception occurs. + */ + +char check_output_1[] = "Autonomous setup has begun!\n"; + +char check_output_2[] = "autonomous printing again\n"; + +char check_output_3[] = "\tRUN_MODE = AUTO\n"; + +char check_output_4[] = "\tRUN_MODE = IDLE\n"; + +char check_output_5[] = + "Traceback (most recent call last):\n"; + +// we have to skip the File: because on the pi it's /home/pi/runtime +// but on Docker it's /root/runtime +char check_output_6[] = + "line 25, in teleop_main\n" + " oops = 1 / 0\n" + "ZeroDivisionError: division by zero\n"; + +char check_output_7[] = "Python function teleop_main call failed\n"; + +char check_output_8[] = "\tRUN_MODE = TELEOP\n"; + +char check_output_9[] = + "Challenge 0 result: 9302\n" + "Challenge 1 result: [2, 661, 35963]"; + +char check_output_10[] = "Suppressing output: too many messages..."; + +int main() { + // set everything up + start_test("executor sanity test"); + start_shm(); + start_net_handler(); + start_executor("executor_sanity", "executor_sanity"); + + // poke the system + // this section checks the autonomous code (should generate some print statements) + send_start_pos(SHEPHERD, RIGHT); + send_run_mode(SHEPHERD, AUTO); + sleep(1); + print_shm(); + sleep(2); + send_run_mode(SHEPHERD, IDLE); + print_shm(); + + // this section checks the teleop code (should generate division by zero error) + send_run_mode(DAWN, TELEOP); + print_shm(); + send_run_mode(DAWN, IDLE); + print_shm(); + + // this section runs the coding challenges (should not error or time out) + char* inputs[] = {"2039", "190172344"}; + send_challenge_data(DAWN, inputs, 2); + + // stop all the processes + stop_executor(); + stop_net_handler(); + stop_shm(); + end_test(); + + // check outputs + in_rest_of_output(check_output_1); + in_rest_of_output(check_output_2); + in_rest_of_output(check_output_3); + in_rest_of_output(check_output_2); + in_rest_of_output(check_output_4); + in_rest_of_output(check_output_5); + in_rest_of_output(check_output_6); + in_rest_of_output(check_output_7); + in_rest_of_output(check_output_8); + in_rest_of_output(check_output_9); + not_in_output(check_output_10); // check to make sure we don't get the suppressing messages bug + + return 0; +} diff --git a/tests/integration/tc_71_3.c b/tests/integration/tc_71_3.c new file mode 100644 index 00000000..10944a6e --- /dev/null +++ b/tests/integration/tc_71_3.c @@ -0,0 +1,39 @@ +#include "../test.h" + +/** + * This test checks to make sure that device subscriptions made to nonexistent devices + * from Dawn are rejected by shared memory and an error message is sent back to Dawn. + */ + +char check_output_1[] = "no device at dev_uid = 50, sub request failed\n"; + +char check_output_2[] = "recv_new_msg: Invalid device subscription, device uid 50 is invalid\n"; + +char check_output_3[] = "no device at dev_uid = 100, sub request failed\n"; + +char check_output_4[] = "recv_new_msg: Invalid device subscription, device uid 100 is invalid\n"; + +int main() { + // setup + start_test("nonexistent device subscription"); + start_shm(); + start_net_handler(); + + // poke + dev_subs_t data1 = {.uid = 50, .name = "ServoControl", .params = 0b11}; + dev_subs_t data2 = {.uid = 100, .name = "LimitSwitch", .params = 0b101}; + dev_subs_t data_total[2] = {data1, data2}; + send_device_subs(data_total, 2); + + // stop + stop_net_handler(); + stop_shm(); + end_test(); + + // check output + in_rest_of_output(check_output_1); + in_rest_of_output(check_output_2); + in_rest_of_output(check_output_3); + in_rest_of_output(check_output_4); + return 0; +} diff --git a/tests/integration/tc_71_4.c b/tests/integration/tc_71_4.c new file mode 100644 index 00000000..4230c2e2 --- /dev/null +++ b/tests/integration/tc_71_4.c @@ -0,0 +1,52 @@ +#include "../test.h" + +/** + * This test ensures that with no devices connected to the system, the + * shared memory starts sending custom data back to Dawn as soon as the + * first Gamepad State packet arrives on Runtime from Dawn. + */ + +char check_output_1[] = + "Current Robot Description:\n" + "\tRUN_MODE = IDLE\n" + "\tDAWN = CONNECTED\n" + "\tSHEPHERD = CONNECTED\n" + "\tGAMEPAD = CONNECTED\n" + "\tSTART_POS = LEFT\n\n" + "Current Gamepad State:\n" + "\tPushed Buttons:\n" + "\t\tbutton_a\n" + "\t\tl_trigger\n" + "\t\tdpad_down\n" + "\tJoystick Positions:\n" + "\t\tjoystick_left_x = -0.100000\n" + "\t\tjoystick_left_y = 0.000000\n" + "\t\tjoystick_right_x = 0.100000\n" + "\t\tjoystick_right_y = 0.990000\n"; + +char check_output_2[] = + "Device No. 0:\ttype = CustomData, uid = 0, itype = 32\n"; + +int main() { + // setup + start_test("UDP; no devices connected"); + start_shm(); + start_net_handler(); + + //poke system + uint32_t buttons = (1 << BUTTON_A) | (1 << L_TRIGGER) | (1 << DPAD_DOWN); + float joystick_vals[] = {-0.1, 0.0, 0.1, 0.99}; + send_gamepad_state(buttons, joystick_vals); + print_shm(); + print_next_dev_data(); + + // stop all processes + stop_net_handler(); + stop_shm(); + end_test(); + + // check outputs + in_rest_of_output(check_output_1); + in_rest_of_output(check_output_2); + return 0; +} diff --git a/tests/integration/tc_68_5.c b/tests/integration/tc_71_5.c similarity index 80% rename from tests/integration/tc_68_5.c rename to tests/integration/tc_71_5.c index e0b7499d..cdd85f64 100644 --- a/tests/integration/tc_68_5.c +++ b/tests/integration/tc_71_5.c @@ -15,13 +15,13 @@ int main() { sleep(1); // Connect a device then disconnect it - print_dev_ids(); // No device + print_dev_ids(); // No device int socket_num = connect_virtual_device("SimpleTestDevice", 0x123); sleep(1); - print_dev_ids(); // One device - disconnect_virtual_device(socket_num); // Device will be at the 0th socket + print_dev_ids(); // One device + disconnect_virtual_device(socket_num); // Device will be at the 0th socket sleep(1); - print_dev_ids(); // No device + print_dev_ids(); // No device // Stop all processes stop_dev_handler(); diff --git a/tests/integration/tc_68_6.c b/tests/integration/tc_71_6.c similarity index 74% rename from tests/integration/tc_68_6.c rename to tests/integration/tc_71_6.c index c9543859..74cc73ed 100644 --- a/tests/integration/tc_68_6.c +++ b/tests/integration/tc_71_6.c @@ -20,16 +20,16 @@ int main() { for (int i = 0; i < NUM_TO_CONNECT; i++) { connect_virtual_device("SimpleTestDevice", i); } - sleep(2); // Make sure all devices connect - print_dev_ids(); // Should show MAX_DEVICES + sleep(2); // Make sure all devices connect + print_dev_ids(); // Should show MAX_DEVICES printf("CONNECTED %d DEVICES\n", NUM_TO_CONNECT); printf("Letting devices sit\n"); - sleep(5); // Let devices sit to make sure runtime can handle it + sleep(5); // Let devices sit to make sure runtime can handle it connect_virtual_device("SimpleTestDevice", NUM_TO_CONNECT); - sleep(2); // Let device connect - print_dev_ids(); // Should show MAX_DEVICES (same as last print_dev_ids()) + sleep(2); // Let device connect + print_dev_ids(); // Should show MAX_DEVICES (same as last print_dev_ids()) printf("CONNECTED %d + 1 DEVICES\n", NUM_TO_CONNECT); - sleep(2); // Let last device sit + sleep(2); // Let last device sit // Stop all processes disconnect_all_devices(); @@ -43,7 +43,7 @@ int main() { char expected_output[64]; for (int j = 0; j < 2; j++) { for (int i = 0; i < NUM_TO_CONNECT; i++) { - sprintf(expected_output, "dev_ix = %d", i); // MAX_DEVICES connected + sprintf(expected_output, "dev_ix = %d", i); // MAX_DEVICES connected in_rest_of_output(expected_output); } } diff --git a/tests/integration/tc_68_7.c b/tests/integration/tc_71_7.c similarity index 80% rename from tests/integration/tc_68_7.c rename to tests/integration/tc_71_7.c index 1a852562..1d0e0444 100644 --- a/tests/integration/tc_68_7.c +++ b/tests/integration/tc_71_7.c @@ -17,10 +17,10 @@ int main() { sleep(1); // Connect an UnresponsiveTestDevice - print_dev_ids(); // No device - connect_virtual_device("UnresponsiveTestDevice", 0x123); // Unknown device + print_dev_ids(); // No device + connect_virtual_device("UnresponsiveTestDevice", 0x123); // Unknown device sleep(2); - print_dev_ids(); // No device + print_dev_ids(); // No device // Clean up disconnect_all_devices(); diff --git a/tests/integration/tc_68_8.c b/tests/integration/tc_71_8.c similarity index 81% rename from tests/integration/tc_68_8.c rename to tests/integration/tc_71_8.c index 8f3c8fe6..85308670 100644 --- a/tests/integration/tc_68_8.c +++ b/tests/integration/tc_71_8.c @@ -17,10 +17,10 @@ int main() { sleep(1); // Connect a ForeignTestDevice - print_dev_ids(); // No device - connect_virtual_device("ForeignTestDevice", 0x123); // Unknown device + print_dev_ids(); // No device + connect_virtual_device("ForeignTestDevice", 0x123); // Unknown device sleep(2); - print_dev_ids(); // No device + print_dev_ids(); // No device // Clean up disconnect_all_devices(); diff --git a/tests/integration/tc_68_9.c b/tests/integration/tc_71_9.c similarity index 85% rename from tests/integration/tc_68_9.c rename to tests/integration/tc_71_9.c index d941c6f3..01d0ce0e 100644 --- a/tests/integration/tc_68_9.c +++ b/tests/integration/tc_71_9.c @@ -18,12 +18,12 @@ int main() { sleep(1); // Connect UnstableTestDevice - print_dev_ids(); // No device + print_dev_ids(); // No device connect_virtual_device("UnstableTestDevice", 0x123); sleep(1); - print_dev_ids(); // One device - sleep(5); // UnstableTestDevice will time out - print_dev_ids(); // No device + print_dev_ids(); // One device + sleep(5); // UnstableTestDevice will time out + print_dev_ids(); // No device // Clean up disconnect_all_devices(); diff --git a/tests/test.c b/tests/test.c index 2c5dfe24..2580273b 100644 --- a/tests/test.c +++ b/tests/test.c @@ -5,10 +5,10 @@ pthread_t output_handler_tid; // holds thread ID of output handler thread int save_std_out; // saved standard output file descriptor to return to normal printing after test int pipe_fd[2]; // read and write ends of the pipe created between the parent and child processes -char *test_output = NULL; // holds the contents of temp file -char *rest_of_test_output; // holds the rest of the test output as we're performing checks +char* test_output = NULL; // holds the contents of temp file +char* rest_of_test_output; // holds the rest of the test output as we're performing checks int check_num = 0; // increments to report status each time a check is performed -char *global_test_name = NULL; // name of test +char* global_test_name = NULL; // name of test /** * This thread prints output to terminal and also copies it to standard output @@ -18,25 +18,25 @@ char *global_test_name = NULL; // name of test * args: always NULL * Returns: NULL */ -static void *output_handler(void *args) { +static void* output_handler(void* args) { size_t curr_size = MAX_LOG_LEN; size_t num_total_bytes_read = 0; char nextline[MAX_LOG_LEN]; - char *curr_ptr = malloc(curr_size); + char* curr_ptr = malloc(curr_size); test_output = curr_ptr; - + // loops until it is canceled while (1) { fgets(nextline, MAX_LOG_LEN, stdin); // get the next line from stdin (attached to read end of pipe, which is attached to stdout) fprintf(stderr, "%s", nextline); // print to standard error (attached to terminal) - + // copy the newly read string into curr_ptr strcpy(curr_ptr, nextline); - + // increment both num_total_bytes_read and curr_ptr by how long this last line was num_total_bytes_read += strlen(curr_ptr); curr_ptr += strlen(curr_ptr); - + // double the length of test_output if necessary if (curr_size - num_total_bytes_read <= MAX_LOG_LEN) { test_output = realloc(test_output, curr_size * 2); @@ -44,7 +44,7 @@ static void *output_handler(void *args) { curr_ptr = test_output + num_total_bytes_read; } } - return NULL; // never reached + return NULL; // never reached } /** @@ -56,7 +56,7 @@ static void *output_handler(void *args) { * stream: Where to print (stdout/stderr) * format: String format to put in delimter */ -static void fprintf_delimiter(FILE *stream, char *format, ...) { +static void fprintf_delimiter(FILE* stream, char* format, ...) { // Build string char str[DELIMITER_WIDTH]; va_list args; @@ -76,7 +76,7 @@ static void fprintf_delimiter(FILE *stream, char *format, ...) { // Print string fprintf(stream, " %s ", str); chars_remaining -= strlen(str) + num_spaces; - + // Print stars on right for (int i = 0; i < chars_remaining; i++) { fprintf(stream, "*"); @@ -87,21 +87,21 @@ static void fprintf_delimiter(FILE *stream, char *format, ...) { // ********************************************** PUBLIC TEST FRAMEWORK FUNCTIONS ************************************** // // creates a pipe to route stdout and stdin to for output handling, spawns the output handler thread -void start_test (char *test_description) { +void start_test(char* test_description) { printf("************************************** Starting test: \"%s\" **************************************\n", test_description); fflush(stdout); - + // save the test name global_test_name = malloc(strlen(test_description) + 1); strcpy(global_test_name, test_description); - + // create a pipe if (pipe(pipe_fd) < 0) { printf("pipe: %s\n", strerror(errno)); } // save the standard out attached to the terminal for later save_std_out = dup(fileno(stdout)); - + // route read end of pipe to stdin if (dup2(pipe_fd[0], fileno(stdin)) == -1) { fprintf(stderr, "dup2 stdin to read end of pipe: %s\n", strerror(errno)); @@ -110,7 +110,7 @@ void start_test (char *test_description) { if (dup2(pipe_fd[1], fileno(stdout)) == -1) { fprintf(stderr, "dup2 stdout to write end of pipe: %s\n", strerror(errno)); } - + // create the output handler thread int status; if ((status = pthread_create(&output_handler_tid, NULL, output_handler, NULL)) != 0) { @@ -120,18 +120,18 @@ void start_test (char *test_description) { // this is called when the test has shut down all runtime processes and is ready to compare output // cancels the output handling thread and resets output -void end_test () { +void end_test() { // cancel the output handler thread if (pthread_cancel(output_handler_tid) != 0) { fprintf(stderr, "pthread_cancel: output handler thread\n"); } - + // pull the standard output back to the file descriptor that we saved earlier if (dup2(save_std_out, fileno(stdout)) == -1) { fprintf(stderr, "dup2 stdout back to terminal: %s\n", strerror(errno)); } // now we are back to normal output - + // set the rest_of_test_output to beginning of test_output to be ready for output comparison rest_of_test_output = test_output; // we can use printf now and this will go the terminal @@ -139,7 +139,7 @@ void end_test () { } // Verifies that expected_output is somewhere in the output -void in_output (char *expected_output) { +void in_output(char* expected_output) { check_num++; if (strstr(rest_of_test_output, expected_output) != NULL) { fprintf(stderr, "%s: check %d passed\n", global_test_name, check_num); @@ -155,11 +155,11 @@ void in_output (char *expected_output) { } // Verifies that expected_output is somewhere in the output after the last call to in_rest_of_output -void in_rest_of_output (char *expected_output) { +void in_rest_of_output(char* expected_output) { check_num++; if ((rest_of_test_output = strstr(rest_of_test_output, expected_output)) != NULL) { fprintf(stderr, "%s: check %d passed\n", global_test_name, check_num); - rest_of_test_output += strlen(expected_output); // advance rest_of_test_output past what we were looking for + rest_of_test_output += strlen(expected_output); // advance rest_of_test_output past what we were looking for return; } else { fprintf(stderr, "%s: check %d failed\n", global_test_name, check_num); @@ -172,7 +172,7 @@ void in_rest_of_output (char *expected_output) { } // Verifies that not_expected_output is not anywhere in the output -void not_in_output (char *not_expected_output) { +void not_in_output(char* not_expected_output) { check_num++; if (strstr(test_output, not_expected_output) == NULL) { fprintf(stderr, "%s: check %d passed\n", global_test_name, check_num); @@ -188,7 +188,7 @@ void not_in_output (char *not_expected_output) { } // Verifies that not_expected_output is not anywhere in the output after the last call to in_rest_of_output -void not_in_rest_of_output (char *not_expected_output) { +void not_in_rest_of_output(char* not_expected_output) { check_num++; if (strstr(rest_of_test_output, not_expected_output) == NULL) { fprintf(stderr, "%s: check %d passed\n", global_test_name, check_num); @@ -205,14 +205,14 @@ void not_in_rest_of_output (char *not_expected_output) { // Returns if arrays are the same. Otherwise, exit(1) void same_param_value_array(uint8_t dev_type, param_val_t expected[], param_val_t received[]) { - device_t *dev = get_device(dev_type); + device_t* dev = get_device(dev_type); for (int i = 0; i < dev->num_params; i++) { same_param_value(dev->params[i].name, dev->params[i].type, expected[i], received[i]); } } // Returns if input params are the same. Otherwise, exit(1) -void same_param_value(char *param_name, param_type_t param_type, param_val_t expected, param_val_t received) { +void same_param_value(char* param_name, param_type_t param_type, param_val_t expected, param_val_t received) { check_num++; switch (param_type) { case INT: diff --git a/tests/test.h b/tests/test.h index 2045ef84..7fffa8a6 100644 --- a/tests/test.h +++ b/tests/test.h @@ -1,10 +1,10 @@ #ifndef TEST_H #define TEST_H +#include "client/dev_handler_client.h" +#include "client/executor_client.h" #include "client/net_handler_client.h" #include "client/shm_client.h" -#include "client/executor_client.h" -#include "client/dev_handler_client.h" // ***************************** START/END TEST ***************************** // @@ -15,7 +15,7 @@ * - char *test_description: a short description of what the test is testing * No return value. */ -void start_test(char *test_name); +void start_test(char* test_name); /** * Takes care of resetting the plumbing of the outputs at the end of the test, and @@ -32,7 +32,7 @@ void end_test(); * expected_output: string that should be in the output of the test * No return value. (Will exit with status code 1 if not in output). */ -void in_output(char *expected_output); +void in_output(char* expected_output); /** * Verifies that expected output is somewhere in the output after most recent call to this function @@ -40,7 +40,7 @@ void in_output(char *expected_output); * expected_output: string that should be in the output of the test AFTER most recent call to this function * No return value. (Will exit with status code 1 if not in rest of output). */ -void in_rest_of_output(char *expected_output); +void in_rest_of_output(char* expected_output); /** * Verifies that not_expected_output is not in the output of the test @@ -48,7 +48,7 @@ void in_rest_of_output(char *expected_output); * not_expected_output: string that should NOT be anywhere in the output of the test * No return value. (Will exit with status code 1 if it found the string in the output). */ -void not_in_output(char *not_expected_output); +void not_in_output(char* not_expected_output); /** * Verifies that not_expected_output is not in the output of the test after most recent call to in_rest_of_output @@ -56,7 +56,7 @@ void not_in_output(char *not_expected_output); * not_expected_output: string that should NOT be anywhere in the output after most recent call to in_rest_of_output * No return value. (Will exit with status code 1 if it found the string in the rest of the output). */ -void not_in_rest_of_output(char *not_expected_output); +void not_in_rest_of_output(char* not_expected_output); /** * Verifies that two input arrays of parameters are the same @@ -79,6 +79,6 @@ void same_param_value_array(uint8_t dev_type, param_val_t expected[], param_val_ * Returns nothing if they're the same. * Exits with status code 1 if they're different */ -void same_param_value(char *param_name, param_type_t param_type, param_val_t expected, param_val_t received); +void same_param_value(char* param_name, param_type_t param_type, param_val_t expected, param_val_t received); #endif