Deployment and application development of EdgeXFoundry, an open source framework for edge computing (2) Source code adjustment
http service startup problem
Reason for modification
Start the device service and appear:Unable to start HTTP server
Impact of the problem: The device service fails to start, and the console cannot get and set device data.
Check that the source code is not enabled to support microhttpd IPV6.
After modification : modify the microhttpd reference
- Enable httpd debug printing
- use
MHD_USE_EPOLL_INTERNAL_THREAD
- Enable
MHD_USE_IPv6|MHD_USE_DUAL_STACK
Modify SDK source code
The revised file isrest-server.c
edgex_rest_server *edgex_rest_server_create
(iot_logger_t *lc, const char *bindaddr, uint16_t port, devsdk_error *err)
{
edgex_rest_server *svr;
uint16_t flags = MHD_USE_EPOLL_INTERNAL_THREAD|MHD_USE_DEBUG;//MHD_USE_THREAD_PER_CONNECTION|MHD_USE_DEBUG;
flags |= MHD_USE_IPv6|MHD_USE_DUAL_STACK;
/* config: flags |= MHD_USE_IPv6 ? */
svr = calloc (1, sizeof (edgex_rest_server));
svr->lc = lc;
pthread_mutex_init (&svr->lock, NULL);
/* Start http server */
if (strcmp (bindaddr, "0.0.0.0"))
{
struct addrinfo *res;
char svc[6];
char resaddr[INET6_ADDRSTRLEN];
sprintf (svc, "%" PRIu16, port);
if (getaddrinfo (bindaddr, svc, NULL, &res) == 0)
{
iot_log_info (lc, "Starting HTTP server on interface %s, port %d", bindaddr, port);
edgex_rest_sa_out (resaddr, res->ai_addr);
// edgex_sa_out2ipv4(resaddr, res);
iot_log_debug (lc, "Resolved interface is %s", resaddr);
// svr->daemon = MHD_start_daemon (flags, port, 0, 0, http_handler, svr, MHD_OPTION_SOCK_ADDR, res->ai_addr, MHD_OPTION_END);
// struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)res->ai_addr;
// struct sockaddr_in *sa4 = (struct sockaddr_in *)res->ai_addr;
// if(res->ai_family == AF_INET6)
// {
// sa6->sin6_port = port;
// svr->daemon = MHD_start_daemon (flags, port, 0, 0, http_handler, NULL, MHD_OPTION_SOCK_ADDR, sa6, MHD_OPTION_END);
// }
// else if(res->ai_family == AF_INET)
// {
// sa4->sin_port = port;
// svr->daemon = MHD_start_daemon (flags, port, 0, 0, http_handler, NULL, MHD_OPTION_SOCK_ADDR, sa4, MHD_OPTION_END);
// }
svr->daemon = MHD_start_daemon (flags, port, 0, 0, http_handler, svr, MHD_OPTION_END);
freeaddrinfo (res);
}
else
{
iot_log_error (lc, "HTTP server: unable to resolve bind address %s", bindaddr);
}
}
else
{
iot_log_info (lc, "Starting HTTP server on port %d (all interfaces)", port);
svr->daemon = MHD_start_daemon (flags, port, 0, 0, http_handler, svr, MHD_OPTION_END);
}
if (svr->daemon == NULL)
{
*err = EDGEX_HTTP_SERVER_FAIL;
iot_log_error (lc, "Unable to start HTTP server");
edgex_rest_server_destroy (svr);
return NULL;
}
else
{
return svr;
}
}
Segmentation fault caused by memory release problem
The code is in the src/c/device.c
get request in the sdk
static int edgex_device_runget
(
devsdk_service_t *svc,
edgex_device *dev,
const edgex_cmdinfo *cmdinfo,
const devsdk_nvpairs *qparams,
edgex_event_cooked **reply,
char **exc
)
{
devsdk_commandresult *results;
int retcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
iot_data_t *e = NULL;
for (int i = 0; i < cmdinfo->nreqs; i++)
{
if (!cmdinfo->pvals[i]->readable)
{
iot_log_error (svc->logger, "Attempt to read unreadable value %s", cmdinfo->reqs[i].resname);
return MHD_HTTP_METHOD_NOT_ALLOWED;
}
}
results = calloc (cmdinfo->nreqs, sizeof (devsdk_commandresult));
if
(
svc->userfns.gethandler (svc->userdata, dev->name, (devsdk_protocols *)dev->protocols, cmdinfo->nreqs, cmdinfo->reqs, results, qparams, &e)
)
{
devsdk_error err = EDGEX_OK;
*reply = edgex_data_process_event (dev->name, cmdinfo, results, svc->config.device.datatransform, "");
if (*reply)
{
retcode = MHD_HTTP_OK;
edgex_event_cooked_add_ref (*reply);
edgex_data_client_add_event_now (svc, *reply);
if (svc->config.device.updatelastconnected)
{
edgex_metadata_client_update_lastconnected (svc->logger, &svc->config.endpoints, dev->name, &err);
}
}
else
{
iot_log_error (svc->logger, "Assertion failed for device %s. Disabling.", dev->name);
edgex_metadata_client_set_device_opstate (svc->logger, &svc->config.endpoints, dev->id, DISABLED, &err);
}
}
else
{
if (e)
{
*exc = iot_data_to_json (e);
}
iot_log_error (svc->logger, "Driver for %s failed on GET%s%s", dev->name, e ? ": " : "", e ? *exc : "");
}
iot_data_free (e);
devsdk_commandresult_free (results, cmdinfo->nreqs);
return retcode;
}
devsdk_commandresult_free (results, cmdinfo->nreqs);
The sdk releases the requests indiscriminately, and releases a few resources after a few requests
- 1. When writing code, pay attention to apply for memory for resources that are not requested (give the default value)
- 2. Modify the code at the release location and judge whether it is NULL before releasing, but the assignment needs to be initialized to NULL
Optimize debugging print information output
Modify the source code directory: src/c/iot/logger.c
add color output
void iot_log__error (iot_logger_t * logger, ...)
{
va_list args;
va_start (args, logger);
printf("\033[31m");
iot_logger_log (logger, IOT_LOG_ERROR, args);
printf("\033[0m\n");
va_end (args);
}
void iot_log__warn (iot_logger_t * logger, ...)
{
va_list args;
va_start (args, logger);
printf("\033[36m");
iot_logger_log (logger, IOT_LOG_WARN, args);
printf("\033[0m\n");
va_end (args);
}
void iot_log__info (iot_logger_t * logger, ...)
{
va_list args;
va_start (args, logger);
iot_logger_log (logger, IOT_LOG_INFO, args);
va_end (args);
}
void iot_log__debug (iot_logger_t * logger, ...)
{
va_list args;
va_start (args, logger);
printf("\033[36m");
iot_logger_log (logger, IOT_LOG_DEBUG, args);
printf("\033[0m\n");
va_end (args);
}
void iot_log__trace (iot_logger_t * logger, ...)
{
va_list args;
va_start (args, logger);
printf("\033[34m");
iot_logger_log (logger, IOT_LOG_TRACE, args);
printf("\033[0m\n");
va_end (args);
}
Recompile
Enter the sdk root directory
make