全部产品
弹性计算 会员服务 网络 安全 移动云 数加·大数据分析及展现 数加·大数据应用 管理与监控 云通信 阿里云办公 培训与认证 更多
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 智能硬件
阿里云物联网套件

CoAP连接通信

更新时间:2018-04-02 21:19:41

CoAP协议适用在资源受限的低功耗设备上,尤其是NB-IoT的设备使用,下图讲述如果基于CoAP协议将NB-IoT设备接入物联网套件。NB-IoT

大体流程如下:

  • 设备端NB-IoT模块中集成阿里云 IoT SDK,厂商在IoT套件控制台申请设备证书(ProductKey/DeviceName/DeviceSecret)并烧录到设备中;
  • NB-IoT设备通过运营商的蜂窝网络进行入网,可能需要联系当地运营商,确保设备所属地区已经覆盖NB网络,并已具备NB-IoT入网能力;
  • 设备入网成功后,NB设备产生的流量数据及产生的费用数据,将由运营商的M2M平台管理,此部分平台能力由运营商提供;
  • 设备开发者可通过 CoAP/UDP 协议,将设备采集的实时数据上报到阿里云IoT套件,借助IoT套件实现海量亿级设备的安全连接和数据管理能力,并可通过规则引擎,与阿里云的各类大数据产品、云数据库和报表系统打通,快速实现从连接到智能的跨越;
  • IoT套件提供相关的数据开放接口和消息推送服务,可将数据转发到业务服务器中,实现设备资产与实际应用的快速集成。

接下来就重点讲解如何基于CoAP协议接入IoT套件。

1、使用SDK接入

我们提供了C版本SDK示例,可以参考DEMO

2、使用CoAP协议自主接入

使用CoAP自主接入流程:

  • CoAP服务器地址endpoint = ${productKey}.iot-as-coap.cn-shanghai.aliyuncs.com:5684, 其中productKey请替换为您申请的产品Key。
  • 目前只支持DTLS,必须走安全通道,根证书
  • 设备在发送数据前,首先发起认证,获取设备的token。
  • 每次上报数据时,都需要携带token信息,如果token失效需要重新认证获取token,token可以缓存本地,有效期48小时。

2.1 设备认证(${endpoint}/auth)

  1. 此接口用于传输数据前获取token,只需要请求一次:
  2. POST /auth
  3. Host: ${productKey}.iot-as-coap.cn-shanghai.aliyuncs.com
  4. Port: 5684
  5. Accept: application/json or application/cbor
  6. Content-Format: application/json or application/cbor
  7. payload: {"productKey":"ZG1EvTEa7NN","deviceName":"NlwaSPXsCpTQuh8FxBGH","clientId":"mylight1000002","sign":"bccb3d2618afe74b3eab12b94042f87b"}

参数说明:

  1. * Method: POST,只支持POST方法
  2. * URL: /authurl地址
  3. * Accept:接收的数据编码方式,目前支持 application/json application/cbor
  4. * Content-Format 上行数据的编码格式,目前支持 application/json application/cbor
payload内容:

JSON数据格式,具体属性值如下:

字段名称 是否必选 说明
productKey 必选 productKey,从iot套件控制台获取
deviceName 必选 deviceName,从iot套件控制台获取
sign 必选 签名,hmacmd5(deviceSecret,content), content = 将所有提交给服务器的参数(version,sign,resources,signmethod除外), 按照字母顺序排序, 然后将参数值依次拼接,无拼接符号
signmethod 可选 算法类型,hmacmd5或hmacsha1
clientId 必选 客户端自表示Id,64字符内
timestamp 可选 时间戳,目前时间戳并不做窗口校验,只起到加盐的作用
返回:
  1. response:{"token":"eyJ0b2tlbiI6IjBkNGUyNjkyZTNjZDQxOGU5MTA4Njg4ZDdhNWI3MjUxIiwiZXhwIjoxNDk4OTg1MTk1fQ.DeQLSwVX8iBjdazjzNHG5zcRECWcL49UoQfq1lXrJvI"}
返回码(CoAP返回码)说明:
Code 描述 Payload 备注
2.05 Content 认证通过:Token对象 正确请求
4.00 Bad Request 返回错误信息 请求发送的Payload非法
4.04 Not Found 404 Not found 请求的路径不存在
4.05 Method Not Allowed 支持的方法 请求方法不是指定值
4.06 Not Acceptable 要求的Accept Accept不是指定的类型
4.15 Unsupported Content-Format 支持的content信息 请求的content不是指定类型
5.00 Internal Server Error 返回错误信息 auth服务器超时或错误
C版本SDK
  • SDK中使用IOT_CoAP_Init 和 IOT_CoAP_DeviceNameAuth与云端建立CoAP认证。

示例代码

  1. iotx_coap_context_t *p_ctx = NULL;
  2. p_ctx = IOT_CoAP_Init(&config);
  3. if (NULL != p_ctx) {
  4. IOT_CoAP_DeviceNameAuth(p_ctx);
  5. do {
  6. count ++;
  7. if (count == 11) {
  8. count = 1;
  9. }
  10. IOT_CoAP_Yield(p_ctx);
  11. } while (m_coap_client_running);
  12. IOT_CoAP_Deinit(&p_ctx);
  13. } else {
  14. HAL_Printf("IoTx CoAP init failed\r\n");
  15. }
  1. /**
  2. * @brief Initialize the CoAP client.
  3. * This function initialize the data structures and network,
  4. * and create the DTLS session.
  5. *
  6. * @param [in] p_config: Specify the CoAP client parameter.
  7. *
  8. * @retval NULL : Initialize failed.
  9. * @retval NOT_NULL : The contex of CoAP client.
  10. * @see None.
  11. */
  12. iotx_coap_context_t *IOT_CoAP_Init(iotx_coap_config_t *p_config);
  13. /**
  14. * @brief Handle device name authentication with remote server.
  15. *
  16. * @param [in] p_context: Pointer of contex, specify the CoAP client.
  17. *
  18. * @retval IOTX_SUCCESS : Authenticate success.
  19. * @retval IOTX_ERR_SEND_MSG_FAILED : Send authentication message failed.
  20. * @retval IOTX_ERR_AUTH_FAILED : Authenticate failed or timeout.
  21. * @see iotx_ret_code_t.
  22. */
  23. int IOT_CoAP_DeviceNameAuth(iotx_coap_context_t *p_context);

2.2 上行数据(${endpoint}/topic/${topic})

发送数据到某个topic,${topic}可以在控制台产品管理->消息通信进行设置,比如对于topic /productkey/${deviceName}/pub, 如果当前设备名称=device,那么您可以调用 ${productKey}.iot-as-coap.cn-shanghai.aliyuncs.com:5684/topic/productkey/device/pub 这个地址来上报数据,目前只支持pub权限的topic用于数据上报,示例:

  1. POST /topic/${topic}
  2. Host: ${productKey}.iot-as-coap.cn-shanghai.aliyuncs.com
  3. Port: 5683
  4. Accept: application/json or application/cbor
  5. Content-Format: application/json or application/cbor
  6. payload: ${your_data}
  7. CustomOptions: number:61(标识token)

参数说明

  1. * Method: POST,支持POST方法
  2. * URL: /topic/${topic},${topic}替换为当前设备对应的topic
  3. * Accept:接收的数据编码方式,目前只支持 application/json application/cbor
  4. * Content-Format 上行数据的编码格式,服务端不做校验
  5. * CustomOptions 设备认证(Auth)获取到token值,Option Number 使用61
payload内容:
  1. 发往${topic}的内容,由业务方自定义,套件不会解析,只进行透传
返回值:
  1. response: byte[]
  2. 由业务客户端按照和业务服务端约定的数据格式进行解析。由于payload是二进制数据,限定 content-formate 使用 application/octet-stream
返回码(CoAP返回码)说明:
Code 描述 Payload 备注
2.05 Content 发送结果 正确请求
4.00 Bad Request 请求错误说明
4.01 Unauthorized 返回错误信息 token非法或者过期,需求重新认证获取token
4.02 Bad Option 返回错误信息 token不存在或者长度非法
4.04 Not Found 返回错误信息 请求的路径不存在
4.05 Method Not Allowed 返回错误信息 请求的方法错误,非post
4.06 Not Acceptable 要求的Accept Accept不是指定的类型
4.14 Request-url Too Long 返回错误信息 topic 设置过长,超过128
4.29 Too Many Requests 返回错误信息
5.00 Internal Server Error 返回错误信息 一般是认证或者流转服务超时
C版本SDK
  • SDK使用接口IOT_CoAP_SendMessage来发送数据,使用IOT_CoAP_GetMessagePayload和IOT_CoAP_GetMessageCode来接收数据。

示例代码

  1. /* send data */
  2. static void iotx_post_data_to_server(void *param)
  3. {
  4. char path[IOTX_URI_MAX_LEN + 1] = {0};
  5. iotx_message_t message;
  6. iotx_deviceinfo_t devinfo;
  7. message.p_payload = (unsigned char *)"{\"name\":\"hello world\"}";
  8. message.payload_len = strlen("{\"name\":\"hello world\"}");
  9. message.resp_callback = iotx_response_handler;
  10. message.msg_type = IOTX_MESSAGE_CON;
  11. message.content_type = IOTX_CONTENT_TYPE_JSON;
  12. iotx_coap_context_t *p_ctx = (iotx_coap_context_t *)param;
  13. iotx_set_devinfo(&devinfo);
  14. snprintf(path, IOTX_URI_MAX_LEN, "/topic/%s/%s/update/", (char *)devinfo.product_key,
  15. (char *)devinfo.device_name);
  16. IOT_CoAP_SendMessage(p_ctx, path, &message);
  17. }
  18. /* receive data */
  19. static void iotx_response_handler(void *arg, void *p_response)
  20. {
  21. int len = 0;
  22. unsigned char *p_payload = NULL;
  23. iotx_coap_resp_code_t resp_code;
  24. IOT_CoAP_GetMessageCode(p_response, &resp_code);
  25. IOT_CoAP_GetMessagePayload(p_response, &p_payload, &len);
  26. HAL_Printf("[APPL]: Message response code: 0x%x\r\n", resp_code);
  27. HAL_Printf("[APPL]: Len: %d, Payload: %s, \r\n", len, p_payload);
  28. }
  1. /**
  2. * @brief Send a message with specific path to server.
  3. * Client must authentication with server before send message.
  4. *
  5. * @param [in] p_context : Pointer of contex, specify the CoAP client.
  6. * @param [in] p_path: Specify the path name.
  7. * @param [in] p_message: Message to be sent.
  8. *
  9. * @retval IOTX_SUCCESS : Send the message success.
  10. * @retval IOTX_ERR_MSG_TOO_LOOG : The message length is too long.
  11. * @retval IOTX_ERR_NOT_AUTHED : The client hasn't authenticated with server
  12. * @see iotx_ret_code_t.
  13. */
  14. int IOT_CoAP_SendMessage(iotx_coap_context_t *p_context, char *p_path, iotx_message_t *p_message);
  15. /**
  16. * @brief Retrieves the length and payload pointer of specified message.
  17. *
  18. * @param [in] p_message: Pointer to the message to get the payload. Should not be NULL.
  19. * @param [out] pp_payload: Pointer to the payload.
  20. * @param [out] p_len: Size of the payload.
  21. *
  22. * @retval IOTX_SUCCESS : Get the payload success.
  23. * @retval IOTX_ERR_INVALID_PARAM : Can't get the payload due to invalid parameter.
  24. * @see iotx_ret_code_t.
  25. **/
  26. int IOT_CoAP_GetMessagePayload(void *p_message, unsigned char **pp_payload, int *p_len);
  27. /**
  28. * @brief Get the response code from a CoAP message.
  29. *
  30. * @param [in] p_message: Pointer to the message to add the address information to.
  31. * Should not be NULL.
  32. * @param [out] p_resp_code: The response code.
  33. *
  34. * @retval IOTX_SUCCESS : When get the response code to message success.
  35. * @retval IOTX_ERR_INVALID_PARAM : Pointer to the message is NULL.
  36. * @see iotx_ret_code_t.
  37. **/
  38. int IOT_CoAP_GetMessageCode(void *p_message, iotx_coap_resp_code_t *p_resp_code);

限制条件及注意事项

  1. * TOPIC规范和MQTTTOPIC一致,CoAP协议内 coap://host:port/topic/${topic},这个接口对于所有${topic}和MQTT topic是可以复用的,不支持`?query_String=xxx`形式传参。
  2. * 客户端缓存认证返回的token是请求的令牌,通过DTLS传输。
  3. * 传输的数据大小依赖于MTU的大小,最好在1K以内

C版本SDK其他接口介绍

  • IOT_CoAP_Yield 接口接收数据。请在任何需要接收数据的地方调用这个API。如果系统允许,请起一个单独的线程,执行该接口。
    1. /**
    2. * @brief Handle CoAP response packet from remote server,
    3. * and process timeout request etc..
    4. *
    5. * @param [in] p_context : Pointer of contex, specify the CoAP client.
    6. *
    7. * @return status.
    8. * @see iotx_ret_code_t.
    9. */
    10. int IOT_CoAP_Yield(iotx_coap_context_t *p_context);
  • IOT_CoAP_Deinit 接口释放内存。
    1. /**
    2. * @brief De-initialize the CoAP client.
    3. * This function release CoAP DTLS session.
    4. * and release the related resource. *
    5. * @param [in] p_context: Pointer of contex, specify the CoAP client.
    6. *
    7. * @return None.
    8. * @see None.
    9. */
    10. void IOT_CoAP_Deinit(iotx_coap_context_t **p_context);

    C版本SDK具体使用请参考\sample\coap\coap-example.c的实现

本文导读目录