in bundles/remote_services/discovery_common/src/endpoint_discovery_server.c [68:204]
celix_status_t endpointDiscoveryServer_create(discovery_t *discovery,
celix_bundle_context_t *context,
const char* defaultServerPath,
const char* defaultServerPort,
const char* defaultServerIp,
endpoint_discovery_server_t **server) {
celix_status_t status;
const char *port = NULL;
const char *ip = NULL;
char *detectedIp = NULL;
const char *path = NULL;
const char *retries = NULL;
int max_ep_num = MAX_NUMBER_OF_RESTARTS;
*server = malloc(sizeof(struct endpoint_discovery_server));
if (!*server) {
return CELIX_ENOMEM;
}
(*server)->loghelper = &discovery->loghelper;
(*server)->entries = hashMap_create(&utils_stringHash, NULL, &utils_stringEquals, NULL);
if (!(*server)->entries) {
return CELIX_ENOMEM;
}
status = celixThreadMutex_create(&(*server)->serverLock, NULL);
if (status != CELIX_SUCCESS) {
return CELIX_BUNDLE_EXCEPTION;
}
bundleContext_getProperty(context, DISCOVERY_SERVER_IP, &ip);
#ifndef ANDROID
if (ip == NULL) {
const char *interface = NULL;
bundleContext_getProperty(context, DISCOVERY_SERVER_INTERFACE, &interface);
if ((interface != NULL) && (endpointDiscoveryServer_getIpAddress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
celix_logHelper_warning(*(*server)->loghelper, "Could not retrieve IP address for interface %s", interface);
}
if (detectedIp == NULL) {
endpointDiscoveryServer_getIpAddress(NULL, &detectedIp);
}
ip = detectedIp;
}
#endif
if (ip != NULL) {
celix_logHelper_info(*(*server)->loghelper, "Using %s for service annunciation", ip);
(*server)->ip = strdup(ip);
}
else {
celix_logHelper_warning(*(*server)->loghelper, "No IP address for service annunciation set. Using %s", defaultServerIp);
(*server)->ip = strdup((char*) defaultServerIp);
}
if (detectedIp != NULL) {
free(detectedIp);
}
bundleContext_getProperty(context, DISCOVERY_SERVER_PORT, &port);
if (port == NULL) {
port = defaultServerPort;
}
bundleContext_getProperty(context, DISCOVERY_SERVER_PATH, &path);
if (path == NULL) {
path = defaultServerPath;
}
bundleContext_getProperty(context, DISCOVERY_SERVER_MAX_EP, &retries);
if (retries != NULL) {
errno=0;
max_ep_num = strtol(retries,NULL,10);
if(errno!=0 || max_ep_num<=0){
max_ep_num=MAX_NUMBER_OF_RESTARTS;
}
}
(*server)->path = format_path(path);
const struct mg_callbacks callbacks = {
.begin_request = endpointDiscoveryServer_callback,
};
unsigned int port_counter = 0;
char newPort[10];
bool bindToAllInterfaces = celix_bundleContext_getPropertyAsBool(context, CELIX_DISCOVERY_BIND_ON_ALL_INTERFACES, CELIX_DISCOVERY_BIND_ON_ALL_INTERFACES_DEFAULT);
do {
char *listeningPorts = NULL;
if (bindToAllInterfaces) {
asprintf(&listeningPorts,"0.0.0.0:%s", port);
} else {
asprintf(&listeningPorts,"%s:%s", (*server)->ip, port);
}
const char *options[] = {
"listening_ports", listeningPorts,
"num_threads", DEFAULT_SERVER_THREADS,
NULL
};
(*server)->ctx = mg_start(&callbacks, (*server), options);
if ((*server)->ctx != NULL)
{
celix_logHelper_info(discovery->loghelper, "Starting discovery server on port %s...", listeningPorts);
}
else {
errno = 0;
char* endptr = (char*)port;
long currentPort = strtol(port, &endptr, 10);
if (*endptr || errno != 0) {
currentPort = strtol(defaultServerPort, NULL, 10);
}
port_counter++;
snprintf(&newPort[0], 10, "%ld", (currentPort+1));
celix_logHelper_warning(discovery->loghelper, "Error while starting discovery server on port %s - retrying on port %s...", port, newPort);
port = newPort;
}
free(listeningPorts);
} while(((*server)->ctx == NULL) && (port_counter < max_ep_num));
(*server)->port = strdup(port);
return status;
}