> 文档中心 > 边缘计算开源框架EdgeXFoundry的部署应用开发(二)源码调整

边缘计算开源框架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.cget请求

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

边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发