in src/session.c [1096:1181]
LINK_ENDPOINT_HANDLE session_create_link_endpoint(SESSION_HANDLE session, const char* name)
{
LINK_ENDPOINT_INSTANCE* result;
/* Codes_S_R_S_SESSION_01_044: [If session, name or frame_received_callback is NULL, session_create_link_endpoint shall fail and return NULL.] */
if ((session == NULL) ||
(name == NULL))
{
result = NULL;
}
else
{
/* Codes_S_R_S_SESSION_01_043: [session_create_link_endpoint shall create a link endpoint associated with a given session and return a non-NULL handle to it.] */
SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)session;
result = (LINK_ENDPOINT_INSTANCE*)calloc(1, sizeof(LINK_ENDPOINT_INSTANCE));
/* Codes_S_R_S_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
if (result != NULL)
{
/* Codes_S_R_S_SESSION_01_046: [An unused handle shall be assigned to the link endpoint.] */
handle selected_handle = 0;
size_t i;
size_t name_length;
for (i = 0; i < session_instance->link_endpoint_count; i++)
{
if (session_instance->link_endpoints[i]->output_handle > selected_handle)
{
break;
}
selected_handle++;
}
result->on_session_state_changed = NULL;
result->on_session_flow_on = NULL;
result->frame_received_callback = NULL;
result->callback_context = NULL;
result->output_handle = selected_handle;
result->input_handle = 0xFFFFFFFF;
result->link_endpoint_state = LINK_ENDPOINT_STATE_NOT_ATTACHED;
name_length = strlen(name);
result->name = (char*)malloc(name_length + 1);
result->on_link_endpoint_destroyed_callback = NULL;
result->on_link_endpoint_destroyed_context = NULL;
if (result->name == NULL)
{
/* Codes_S_R_S_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
free(result);
result = NULL;
}
else
{
LINK_ENDPOINT_INSTANCE** new_link_endpoints;
(void)memcpy(result->name, name, name_length + 1);
result->session = session;
size_t realloc_size = safe_add_size_t((size_t)session_instance->link_endpoint_count, 1);
realloc_size = safe_multiply_size_t(realloc_size, sizeof(LINK_ENDPOINT_INSTANCE));
if (realloc_size == SIZE_MAX ||
(new_link_endpoints = (LINK_ENDPOINT_INSTANCE**)realloc(session_instance->link_endpoints, realloc_size)) == NULL)
{
/* Codes_S_R_S_SESSION_01_045: [If allocating memory for the link endpoint fails, session_create_link_endpoint shall fail and return NULL.] */
LogError("Cannot realloc new_link_endpoints, size:%zu", realloc_size);
free(result->name);
free(result);
result = NULL;
}
else
{
session_instance->link_endpoints = new_link_endpoints;
if (session_instance->link_endpoint_count - selected_handle > 0)
{
(void)memmove(&session_instance->link_endpoints[selected_handle + 1], &session_instance->link_endpoints[selected_handle], (session_instance->link_endpoint_count - selected_handle) * sizeof(LINK_ENDPOINT_INSTANCE*));
}
session_instance->link_endpoints[selected_handle] = result;
session_instance->link_endpoint_count++;
}
}
}
}
return result;
}