diff --git a/PlayerTracker b/PlayerTracker index 5e98092..f844999 100755 Binary files a/PlayerTracker and b/PlayerTracker differ diff --git a/include/server_structs.h b/include/server_structs.h index e766687..8e80b35 100644 --- a/include/server_structs.h +++ b/include/server_structs.h @@ -6,149 +6,153 @@ #include #include struct handshake { - // [not used in the current Remote Telemtry version by AC] - // In future versions it will identify the platform type of the client. - // This will be used to adjust a specific behaviour for each platform. (eIPadDevice for now (1)) - int32_t identifier; + // [not used in the current Remote Telemtry version by AC] + // In future versions it will identify the platform type of the client. + // This will be used to adjust a specific behaviour for each platform. (eIPadDevice for now (1)) + int32_t identifier; - // [not used in the current Remote Telemtry version by AC] - // In future version this field will identify the AC Remote Telemetry version that the device expects to speak with. - int32_t version; + // [not used in the current Remote Telemtry version by AC] + // In future version this field will identify the AC Remote Telemetry version that the device expects to speak with. + int32_t version; - // This is the type of operation required by the client. - // The following operations are now available: - // ---------------------------------------------------------------- - // HANDSHAKE = 0 : - // This operation identifier must be set when the client wants to start the comunication. - // - // SUBSCRIBE_UPDATE = 1 : - // This operation identifier must be set when the client wants to be updated from the specific ACServer. - // - // SUBSCRIBE_SPOT = 2 : - // This operation identifier must be set when the client wants to be updated from the specific ACServer just for SPOT Events (e.g.: the end of a lap). - // - // DISMISS = 3 : - // This operation identifier must be set when the client wants to leave the comunication with ACServer. - int32_t operationId; + // This is the type of operation required by the client. + // The following operations are now available: + // ---------------------------------------------------------------- + // HANDSHAKE = 0 : + // This operation identifier must be set when the client wants to start the comunication. + // + // SUBSCRIBE_UPDATE = 1 : + // This operation identifier must be set when the client wants to be updated from the specific ACServer. + // + // SUBSCRIBE_SPOT = 2 : + // This operation identifier must be set when the client wants to be updated from the specific ACServer just for SPOT Events (e.g.: the end of a lap). + // + // DISMISS = 3 : + // This operation identifier must be set when the client wants to leave the comunication with ACServer. + int32_t operationId; } __attribute__((packed)); -struct handshackerResponse{ - // is the name of the car that the player is driving on the AC Server - char carName[50]; +struct handshackerResponse { + // is the name of the car that the player is driving on the AC Server + char carName[50]; - // is the name of the driver running on the AC Server - char driverName[50]; + // is the name of the driver running on the AC Server + char driverName[50]; - // for now is just 4242, this code will identify different status, - // as “NOT AVAILABLE” for connection - int32_t identifier; + // for now is just 4242, this code will identify different status, + // as “NOT AVAILABLE” for connection + int32_t identifier; - // for now is set to 1, this will identify the version running on the AC Server - int32_t version; + // for now is set to 1, this will identify the version running on the AC Server + int32_t version; - // is the name of the track on the AC Server - char trackName[50]; + // is the name of the track on the AC Server + char trackName[50]; - // is the track configuration on the AC Server - char trackConfig[50]; + // is the track configuration on the AC Server + char trackConfig[50]; } __attribute__((packed)); struct postion { - float x; - float y; - float z; + float x; + float y; + float z; } __attribute__((packed)); struct carAtributes { - // Related to ACSP_CAR_INFO - u_char isConnected; // 1 = connected, 0 = disconnected - char *carModel; - char *carSkin; - char *driver_name; - char *driver_team; - char *driver_GUID; + // Related to ACSP_CAR_INFO + u_char isConnected; // 1 = connected, 0 = disconnected + char *car_model; + char *car_skin; + char *driver_name; + char *driver_team; + char *driver_GUID; - // Related to ACSP_CAR_UPDATE - u_int8_t carID; - postion position; - postion velocity; - u_int8_t carGear; - u_int16_t carRPM; - float_t normalizedSplinePos; + // Related to ACSP_CAR_UPDATE + u_int8_t carID; + postion position; + postion velocity; + u_int8_t carGear; + u_int16_t carRPM; + float_t normalizedSplinePos; } __attribute__((packed)); - -struct trackAtributes { - u_int8_t protocol_version; - u_int8_t session_index; - u_int8_t current_session_index; - u_int8_t session_count; - - char *server_name; - char *track; - char *track_config; - char *session_name; - - u_int8_t typ; - u_int16_t time; - u_int16_t laps; - u_int16_t wait_time; - u_int8_t ambient_temp; - u_int8_t road_temp; - - char *weather_graphics; - int32_t elapsed_ms; -} __attribute__((packed)); - - -enum ACSP_MessageType { - // ============================ - // PROTOCOL VERSION - // ============================ - PROTOCOL_VERSION = 4, - - // ============================ - // SERVER → CLIENT MESSAGES - // ============================ - ACSP_NEW_SESSION = 50, - ACSP_NEW_CONNECTION = 51, - ACSP_CONNECTION_CLOSED = 52, - ACSP_CAR_UPDATE = 53, - ACSP_CAR_INFO = 54, // Response to ACSP_GET_CAR_INFO - ACSP_END_SESSION = 55, - ACSP_VERSION = 56, - ACSP_CHAT = 57, - ACSP_CLIENT_LOADED = 58, - ACSP_SESSION_INFO = 59, - ACSP_ERROR = 60, - ACSP_LAP_COMPLETED = 73, - - // ============================ - // EVENTS - // ============================ - ACSP_CLIENT_EVENT = 130, - - // ============================ - // EVENT TYPES - // ============================ - ACSP_CE_COLLISION_WITH_CAR = 10, - ACSP_CE_COLLISION_WITH_ENV = 11, - - // ============================ - // CLIENT → SERVER COMMANDS - // ============================ - ACSP_REALTIMEPOS_INTERVAL = 200, - ACSP_GET_CAR_INFO = 201, - ACSP_SEND_CHAT = 202, // Sends chat to one car - ACSP_BROADCAST_CHAT = 203, // Sends chat to everybody - ACSP_GET_SESSION_INFO = 204, - ACSP_SET_SESSION_INFO = 205, - ACSP_KICK_USER = 206, - ACSP_NEXT_SESSION = 207, - ACSP_RESTART_SESSION = 208, - ACSP_ADMIN_COMMAND = 209 // Send message plus a string +enum SessionType { + PRACTICE = 0, + RACE = 1, + QUALIFYING = 2, }; +struct trackAtributes { + u_int8_t protocol_version; + u_int8_t session_index; + u_int8_t current_session_index; + u_int8_t session_count; + SessionType session_type; + + char *server_name; + char *track; + char *track_config; + char *session_name; + + u_int8_t typ; + u_int16_t time; + u_int16_t laps; + u_int16_t wait_time; + u_int8_t ambient_temp; + u_int8_t road_temp; + + char *weather_graphics; + int32_t elapsed_ms; +} __attribute__((packed)); + +enum ACSP_MessageType { + // ============================ + // PROTOCOL VERSION + // ============================ + PROTOCOL_VERSION = 4, + + // ============================ + // SERVER → CLIENT MESSAGES + // ============================ + ACSP_NEW_SESSION = 50, + ACSP_NEW_CONNECTION = 51, + ACSP_CONNECTION_CLOSED = 52, + ACSP_CAR_UPDATE = 53, + ACSP_CAR_INFO = 54, // Response to ACSP_GET_CAR_INFO + ACSP_END_SESSION = 55, + ACSP_VERSION = 56, + ACSP_CHAT = 57, + ACSP_CLIENT_LOADED = 58, + ACSP_SESSION_INFO = 59, + ACSP_ERROR = 60, + ACSP_LAP_COMPLETED = 73, + + // ============================ + // EVENTS + // ============================ + ACSP_CLIENT_EVENT = 130, + + // ============================ + // EVENT TYPES + // ============================ + ACSP_CE_COLLISION_WITH_CAR = 10, + ACSP_CE_COLLISION_WITH_ENV = 11, + + // ============================ + // CLIENT → SERVER COMMANDS + // ============================ + ACSP_REALTIMEPOS_INTERVAL = 200, + ACSP_GET_CAR_INFO = 201, + ACSP_SEND_CHAT = 202, // Sends chat to one car + ACSP_BROADCAST_CHAT = 203, // Sends chat to everybody + ACSP_GET_SESSION_INFO = 204, + ACSP_SET_SESSION_INFO = 205, + ACSP_KICK_USER = 206, + ACSP_NEXT_SESSION = 207, + ACSP_RESTART_SESSION = 208, + ACSP_ADMIN_COMMAND = 209 // Send message plus a string +}; #endif // SERVER_STRUCTS_H diff --git a/source/main.cpp b/source/main.cpp index cf538ca..18ea833 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -15,6 +16,34 @@ const int SERVER_OUT_PORT = 12000; const int SERVER_IN_PORT = 11000; const char *SERVER_OUT_IP = "127.0.0.1"; +const int MAX_PLAYERS = 64; + +void init_carupdate(carAtributes *car) { + car->carID = 0; + car->position.x = 0.0f; + car->position.y = 0.0f; + car->position.z = 0.0f; + car->velocity.x = 0.0f; + car->velocity.y = 0.0f; + car->velocity.z = 0.0f; + car->carGear = 0; + car->carRPM = 0; + car->normalizedSplinePos = 0.0f; + car->isConnected = 0; + + car->car_model = (char *)malloc(64); + car->driver_GUID = (char *)malloc(64); + car->car_skin = (char *)malloc(64); + car->driver_name = (char *)malloc(64); + car->driver_team = (char *)malloc(64); + + strcpy(car->car_model, ""); + strcpy(car->driver_GUID, ""); + strcpy(car->car_skin, ""); + strcpy(car->driver_name, ""); + strcpy(car->driver_team, ""); +} + int main(void) { printf("[+] Starting server...\n"); @@ -34,15 +63,23 @@ int main(void) { char buffer[1024]; trackAtributes trackInfo; + carAtributes players[MAX_PLAYERS]; + carAtributes update; + // Basically a contrutor for carAtributes (because all strings in carAtributes are pointers) + for (int i = 0; i < MAX_PLAYERS; i++) { + init_carupdate(&players[i]); + } + init_carupdate(&update); + trackInfo.server_name = (char *)malloc(128); trackInfo.track = (char *)malloc(128); trackInfo.track_config = (char *)malloc(64); trackInfo.weather_graphics = (char *)malloc(64); trackInfo.session_name = (char *)malloc(64); - char message[124] = {0}; // just a place to put info messages from the server itself + char message[124] = {0}; // just a place to put info messages from the server itself while (1) { offset = 0; @@ -65,8 +102,7 @@ int main(void) { // ============================ // SERVER → CLIENT MESSAGES // ============================ - - case ACSP_NEW_SESSION: + case ACSP_NEW_SESSION: // DONE printf("[+] Message Type: ACSP_NEW_SESSION\n"); offset = 1; // Reset offset to 1 to read after message types @@ -75,30 +111,31 @@ int main(void) { trackInfo.current_session_index = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); trackInfo.session_count = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.session_type = (SessionType)trackInfo.session_index; // FOR BACKWARD COMPATIBILITY + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.server_name, str_len_8, &ok); str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.track, str_len_8, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.track, str_len_8, &ok); - str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.track_config, str_len_8, &ok); - str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.session_name, str_len_8, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.session_name, str_len_8, &ok); - trackInfo.typ = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - trackInfo.time = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - trackInfo.laps = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - trackInfo.wait_time = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - trackInfo.ambient_temp = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - trackInfo.road_temp = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.typ = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.time = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.laps = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.wait_time = read_uint16((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.ambient_temp = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + trackInfo.road_temp = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); - read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.weather_graphics, str_len_8, &ok); - - trackInfo.elapsed_ms = read_int32((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, trackInfo.weather_graphics, str_len_8, &ok); + trackInfo.elapsed_ms = read_int32((const u_int8_t *)buffer, recv_bytes, &offset, &ok); if (!ok) { fprintf(stderr, "[-] Error parsing NEW_SESSION packet (offset=%zu)\n", offset); @@ -108,27 +145,95 @@ int main(void) { printf("\tServer Name: \"%s\"\n", trackInfo.server_name); printf("\tTrack: \"%s\"\n", trackInfo.track); printf("\tTrack Config: \"%s\"\n", trackInfo.track_config); - printf("\tSession Name: \"%s\"\n", trackInfo.session_name); + printf("\tSession Name: \"%s\"\n", trackInfo.session_name); printf("\tProtocol Version: %d\tSession Index: %d/%d\tCurrent Session Index: %d\n", trackInfo.protocol_version, trackInfo.session_index, trackInfo.session_count, trackInfo.current_session_index); - printf("\tType: %d\tTime: %d mins\tLaps: %d\tWait Time: %d secs\n", trackInfo.typ, trackInfo.time, trackInfo.laps, trackInfo.wait_time); - printf("\tAmbient Temp: %d C\tRoad Temp: %d C\n", trackInfo.ambient_temp, trackInfo.road_temp); - printf("\tWeather Graphics: %s\n", trackInfo.weather_graphics); - printf("\tElapsed Time: %d ms\n", trackInfo.elapsed_ms); + printf("\tType: %d\tTime: %d mins\tLaps: %d\tWait Time: %d secs\n", trackInfo.typ, trackInfo.time, trackInfo.laps, trackInfo.wait_time); + printf("\tAmbient Temp: %d C\tRoad Temp: %d C\n", trackInfo.ambient_temp, trackInfo.road_temp); + printf("\tWeather Graphics: %s\n", trackInfo.weather_graphics); + printf("\tElapsed Time: %d ms\n", trackInfo.elapsed_ms); break; - case ACSP_NEW_CONNECTION: + case ACSP_NEW_CONNECTION: //DONE printf("[+] Message Type: ACSP_NEW_CONNECTION\n"); + offset = 1; // Reset offset to 1 to read after message types + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_name, str_len_8, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_GUID, str_len_8, &ok); + + update.carID = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_model, str_len_8, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_skin, str_len_8, &ok); + + if (!ok) { + fprintf(stderr, "[-] Error parsing NEW_CONNECTION packet (offset=%zu)\n", offset); + break; + } + + update.isConnected = 1; // Mark as connected + + printf("\tDriver Name: \"%s\"\n", update.driver_name); + printf("\tDriver GUID: \"%s\"\n", update.driver_GUID); + printf("\tCar ID: %d\n", update.carID); + printf("\tCar Model: \"%s\"\n", update.car_model); + printf("\tCar Skin: \"%s\"\n", update.car_skin); + + // Store player player into the respective Index + if (update.carID < MAX_PLAYERS) { + memcpy(&players[update.carID], &update, sizeof(carAtributes)); + } + break; - case ACSP_CONNECTION_CLOSED: + case ACSP_CONNECTION_CLOSED: // DONE printf("[+] Message Type: ACSP_CONNECTION_CLOSED\n"); + offset = 1; // Reset offset to 1 to read after message types + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_name, str_len_8, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_GUID, str_len_8, &ok); + + update.carID = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_model, str_len_8, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_skin, str_len_8, &ok); + + if (!ok) { + fprintf(stderr, "[-] Error parsing NEW_CONNECTION packet (offset=%zu)\n", offset); + break; + } + + update.isConnected = 0; // Mark as disconnected + + printf("\tDriver Name: \"%s\"\n", update.driver_name); + printf("\tDriver GUID: \"%s\"\n", update.driver_GUID); + printf("\tCar ID: %d\n", update.carID); + printf("\tCar Model: \"%s\"\n", update.car_model); + printf("\tCar Skin: \"%s\"\n", update.car_skin); + + // Store player player into the respective Index + if (update.carID < MAX_PLAYERS) { + memcpy(&players[update.carID], &update, sizeof(carAtributes)); + } + break; - case ACSP_CAR_UPDATE: + case ACSP_CAR_UPDATE: // DONE printf("[+] Message Type: ACSP_CAR_UPDATE\n"); memcpy(&update.carID, buffer + 1, sizeof(uint8_t)); @@ -146,43 +251,99 @@ int main(void) { printf("\tCar %d Position: X: %.2f Y: %.2f Z: %.2f ", update.carID, update.position.x, update.position.y, update.position.z); printf("Gear: %d RPM: %d\n", update.carGear, update.carRPM); + + // Store player player into the respective index + if (update.carID < MAX_PLAYERS) { + memcpy(&players[update.carID].position, &update.position, sizeof(postion)); + memcpy(&players[update.carID].velocity, &update.velocity, sizeof(postion)); + players[update.carID].carGear = update.carGear; + players[update.carID].carRPM = update.carRPM; + players[update.carID].normalizedSplinePos = update.normalizedSplinePos; + } + break; - case ACSP_CAR_INFO: + case ACSP_CAR_INFO: // DONE printf("[+] Message Type: ACSP_CAR_INFO\n"); + offset = 1; // Reset offset to 1 to read after message types; + // + // is_connected = self.br.read_byte() != 0 + // car_model = self.br.read_utf_string() + // car_skin = self.br.read_utf_string() + // driver_name = self.br.read_utf_string() + // driver_team = self.br.read_utf_string() + // driver_guid = self.br.read_utf_string() + + update.carID = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + update.isConnected = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_model, str_len_8, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.car_skin, str_len_8, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_name, str_len_8, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_team, str_len_8, &ok); + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); + read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, update.driver_GUID, str_len_8, &ok); + + if (!ok) { + fprintf(stderr, "[-] Error parsing CAR_INFO packet (offset=%zu)\n", offset); + } + + printf("\tCar ID: %d\n", update.carID); + printf("\tIs Connected: %d\n", update.isConnected); + printf("\tCar Model: \"%s\"\n", update.car_model); + printf("\tCar Skin: \"%s\"\n", update.car_skin); + printf("\tDriver Name: \"%s\"\n", update.driver_name); + printf("\tDriver Team: \"%s\"\n", update.driver_team); + printf("\tDriver GUID: \"%s\"\n", update.driver_GUID); + + // Store player player into the respective Index + if (update.carID < MAX_PLAYERS) { + memcpy(&players[update.carID], &update, sizeof(carAtributes)); + } + break; - case ACSP_END_SESSION: + case ACSP_END_SESSION: // DONE-ish (only session type cycling) printf("[+] Message Type: ACSP_END_SESSION\n"); + // Advance session_type to the next in the enum; + + trackInfo.session_type = (SessionType)((trackInfo.session_type + 1) % 3); + + printf("\tNext Session Type: %d\n", trackInfo.session_type); + break; - case ACSP_VERSION: + case ACSP_VERSION: // TODO printf("[+] Message Type: ACSP_VERSION\n"); break; - case ACSP_CHAT: + case ACSP_CHAT: // TODO printf("[+] Message Type: ACSP_CHAT\n"); break; - case ACSP_CLIENT_LOADED: + case ACSP_CLIENT_LOADED: // TODO printf("[+] Message Type: ACSP_CLIENT_LOADED\n"); break; - case ACSP_SESSION_INFO: + case ACSP_SESSION_INFO: // TODO printf("[+] Message Type: ACSP_SESSION_INFO\n"); break; - case ACSP_ERROR: + case ACSP_ERROR: // DONE printf("[+] Message Type: ACSP_ERROR\n"); - offset = 1; // Reset offset to 1 to read after message types - + offset = 1; // Reset offset to 1 to read after message types + str_len_8 = read_uint8((const u_int8_t *)buffer, recv_bytes, &offset, &ok); read_utf32le_string((const u_int8_t *)buffer, recv_bytes, &offset, message, str_len_8, &ok); - printf("\tServer Message: \"%s\"\n", message); + printf("\tServer Message: \"%s\"\n", message); break; - case ACSP_LAP_COMPLETED: + case ACSP_LAP_COMPLETED: // TODO printf("[+] Message Type: ACSP_LAP_COMPLETED\n"); break; @@ -264,6 +425,6 @@ int main(void) { free(trackInfo.track); free(trackInfo.track_config); free(trackInfo.weather_graphics); - free(trackInfo.session_name); + free(trackInfo.session_name); return 0; }