边缘计算开源框架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的部署应用开发(三)设备服务开发

猜你喜欢

转载自blog.csdn.net/weixin_42892101/article/details/110298580