Skip to content

Commit

Permalink
Merge pull request #963 from cyberbotics/sync-master-3485871c10f5f5ae…
Browse files Browse the repository at this point in the history
…e8b99b49d27624ba98885380

Sync libcontroller master
  • Loading branch information
omichel authored Aug 26, 2024
2 parents f8e1f1e + 9fb41b1 commit 6e1c743
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions webots_ros2_driver/webots/src/controller/c/robot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1081,21 +1081,33 @@ static void wb_robot_cleanup_devices() {
}
}

static char *encode_robot_name(const char *robot_name) {
static char *encode_robot_name(const char *robot_name, int chars_used) {
if (!robot_name)
return NULL;

char *encoded_name = percent_encode(robot_name);
int length = strlen(encoded_name);
// the robot name is used to connect to the libController and in this process there are indirect
// limitations such as QLocalServer only accepting strings up to 106 characters for server names,
// for these reasons if the robot name is bigger than an arbitrary length, a hashed version is used instead
if (length > 70) { // note: this threshold should be the same as in WbRobot.cpp
// limitations such as QLocalServer only accepting strings up to 91 characters long for server names
// on some platforms.
// Since the server name also contains the tmp path and that includes the user's username and,
// in the case of a Snap, the user's home directory, we need to limit the length of the encoded
// robot name based on the tmp path. If it is longer than that, then we compute a hashed version
// of the name and use as much of it as we can. If that would be less than 4 chars, we try to use
// 4 chars and hope we are on a platform where QLocalServer accepts longer names. 4 chars makes the
// chance of a name collision 1/65536.
// Note: It is critical that the same logic is used in WbRobot.cpp
int max_name_length = 91 - chars_used;
if (max_name_length < 4)
max_name_length = 4;
// Round down to the next multiple of 2 because it makes the code easier.
max_name_length = max_name_length / 2 * 2;
if (length > max_name_length) {
char hash[21];
char *output = malloc(41);
char *output = malloc(max_name_length + 1);
SHA1(hash, encoded_name, length);
free(encoded_name);
for (size_t i = 0; i < 20; i++)
for (size_t i = 0; i < max_name_length / 2 && i < 20; i++)
sprintf((output + (2 * i)), "%02x", hash[i] & 0xff);
return output;
}
Expand All @@ -1104,10 +1116,12 @@ static char *encode_robot_name(const char *robot_name) {
}

static char *compute_socket_filename(char *error_buffer) {
char *robot_name = encode_robot_name(wbu_system_getenv("WEBOTS_ROBOT_NAME"));
const char *WEBOTS_INSTANCE_PATH = wbu_system_webots_instance_path(true);
char *robot_name = NULL;
const char *WEBOTS_ROBOT_NAME = wbu_system_getenv("WEBOTS_ROBOT_NAME");
char *socket_filename;
if (robot_name && robot_name[0] && WEBOTS_INSTANCE_PATH && WEBOTS_INSTANCE_PATH[0]) {
if (WEBOTS_ROBOT_NAME && WEBOTS_ROBOT_NAME[0] && WEBOTS_INSTANCE_PATH && WEBOTS_INSTANCE_PATH[0]) {
robot_name = encode_robot_name(WEBOTS_ROBOT_NAME, strlen(WEBOTS_INSTANCE_PATH) + strlen("ipc//intern"));
#ifndef _WIN32
const int length = strlen(WEBOTS_INSTANCE_PATH) + strlen(robot_name) + 15; // "%sintern/%s/socket"
socket_filename = malloc(length);
Expand Down Expand Up @@ -1267,7 +1281,7 @@ static char *compute_socket_filename(char *error_buffer) {

free(robot_name);
const char *sub_string = strstr(&WEBOTS_CONTROLLER_URL[6], "/");
robot_name = encode_robot_name(sub_string ? sub_string + 1 : NULL);
robot_name = encode_robot_name(sub_string ? sub_string + 1 : NULL, strlen(ipc_folder) + strlen("//extern"));
if (robot_name) {
#ifndef _WIN32
// socket file name is like: folder + robot_name + "/extern"
Expand Down Expand Up @@ -1370,7 +1384,7 @@ static void compute_remote_info(char **host, int *port, char **robot_name) {
snprintf(*host, host_length, "%s", &WEBOTS_CONTROLLER_URL[6]);
sscanf(url_suffix, ":%d", port);
const char *rn = strstr(url_suffix, "/");
*robot_name = rn != NULL ? encode_robot_name(rn + 1) : NULL;
*robot_name = rn != NULL ? encode_robot_name(rn + 1, 0) : NULL;
}

int wb_robot_init() { // API initialization
Expand Down Expand Up @@ -1462,11 +1476,11 @@ int wb_robot_init() { // API initialization
retry -= 5;
fprintf(stderr, "%s, pending until loading is done...\n", error_message);
} else if (socket_filename) {
fprintf(stderr,
"The specified robot (at %s) is not in the list of robots with <extern> controllers, retrying for another %d "
"seconds...\n",
socket_filename, 50 - retry);
free(socket_filename);
fprintf(
stderr,
"The specified robot is not in the list of robots with <extern> controllers, retrying for another %d seconds...\n",
50 - retry);
} else
fprintf(stderr, "%s, retrying for another %d seconds...\n", error_message, 50 - retry);
}
Expand Down

0 comments on commit 6e1c743

Please sign in to comment.