边缘计算开源框架EdgeXFoundry的部署应用开发(二)源码调整
边缘计算开源框架EdgeXFoundry的部署应用开发(二)源码调整
- http 服务启动问题
-
- 修改的原因
- 修改SDK源码
- 内存释放问题,导致的段错误
- 优化调试打印信息输出
- 重新编译
- 边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发
http 服务启动问题
修改的原因
启动设备服务出现:Unable to start HTTP server
问题影响:设备服务启动失败,控制台无法get、set设备数据
检查发现源码未启用支持microhttpd IPV6
修改后:修改microhttpd参考
- 开启httpd的调试打印
- 使用
MHD_USE_EPOLL_INTERNAL_THREAD
- 启用
MHD_USE_IPv6|MHD_USE_DUAL_STACK
修改SDK源码
本次修改文件为rest-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; }}
内存释放问题,导致的段错误
代码位于sdk中src/c/device.c
get请求
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);
sdk对发出的请求无差别释放,请求了几个资源就释放几个
- 1、编写代码时注意对请求不到的资源也要申请内存(给默认值)
- 2、修改释放处的代码,进行判断是否NULL,才进行释放,不过赋值需要初始化为NULL
优化调试打印信息输出
修改源码目录下:src/c/iot/logger.c
增加色彩输出
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);}
重新编译
进入sdk根目录
make