如何在Contiki OS中使用block2实现coap观察器

时间:2019-11-06 13:56:15

标签: rest iot contiki coap

我将首先解释设置;

设置:我有一个微控制器板,运行带有可观察资源的Coap rest服务器(使用Contiki OS),以及一个客户端(使用Coaphon-Coap的python库),观察该资源在Linux SOM上运行。我成功地观察到了从服务器(微控制器)到客户端(Linux SOM)的少量数据(64字节)。描述完所有内容后,我将在最后添加代码。

问题:在从Coap服务器向客户端观察器发送大量数据(假定1024字节)时,我需要帮助。我该怎么做(在此先感谢您提供任何帮助,在此方面我将提供的任何帮助将不胜感激)?

我正在发布Contiki可观察的资源代码和coapthon客户代码(我正在发布不发送大数据的代码)。 验证码:

char * temp_payload = "Behold empty data";

PERIODIC_RESOURCE(res_periodic_ext_temp_data,
         "title=\"Temperature\";rt=\"Temperature\";obs",
         res_get_handler_of_periodic_ext_temp_data,
         NULL,
         NULL,
         res_delete_handler_ext_temp_data,
         (15*CLOCK_SECOND),
         res_periodic_handler_of_ext_temp_data);

static void
res_get_handler_of_periodic_ext_temp_data(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
    /*
     * For minimal complexity, request query and options should be ignored for GET on observable resources.
     * Otherwise the requests must be stored with the observer list and passed by REST.notify_subscribers().
     * This would be a TODO in the corresponding files in contiki/apps/erbium/!
     */
    /* Check the offset for boundaries of the resource data. */
    if(*offset >= 1024) {
        REST.set_response_status(response, REST.status.BAD_OPTION);
        /* A block error message should not exceed the minimum block size (16). */
        const char *error_msg = "BlockOutOfScope";
        REST.set_response_payload(response, error_msg, strlen(error_msg));
        return;
    }
    REST.set_header_content_type(response, REST.type.TEXT_PLAIN);
    REST.set_response_payload(response,(temp_payload + *offset), MIN( (int32_t)strlen(temp_payload) - *offset, preferred_size));
    REST.set_response_status(response, REST.status.OK);
    /* IMPORTANT for chunk-wise resources: Signal chunk awareness to REST engine. */
    *offset += preferred_size;
    /* Signal end of resource representation. */
    if(*offset >= (int32_t)strlen( temp_payload) + 1) {
        *offset = -1;
    }
    REST.set_header_max_age(response, MAX_AGE);
}

我没有为定期处理程序添加代码,定期从定期处理程序通知get处理程序。 Coapthon代码:

def ext_temp_data_callback_observe(response):  
    print response.pretty_print()

def observe_ext_temp_data(host, callback):
    client = HelperClient(server=(host, port))
    request = Request()
    request.code = defines.Codes.GET.number
    request.type = defines.Types["CON"]
    request.destination = (host, port)
    request.uri_path = "data/res_periodic_ext_temp_data"
    request.content_type = defines.Content_types["text/plain"]
    request.observe = 0
    request.block2 = (0, 0, 64)
    try:
        response = client.send_request(request, callback)
        print response.pretty_print()
    except Empty as e:
        print("listener_post_observer_rate_of_change({0}) timed out". format(host))

同样,我需要在coap逐块传输(https://tools.ietf.org/html/rfc7959#page-26)中实现观察者。

2 个答案:

答案 0 :(得分:0)

对于您使用的特定系统,我了解不多,但是一般来说,逐块传输和观察工作的结合是服务器仅发送更新资源的第一块。然后由客户端要求剩余的块,并验证其ETag选项是否匹配。

contiki代码看起来应该足够了,因为它将偏移量设置为-1,这可能会设置块头中的“更多数据”位。

在coapython方面,您可能需要手动重新组装,或者要求coapython自动进行重新组装(其代码并不表示它支持逐块组合和观察,至少一眼不看)

答案 1 :(得分:0)

要“引导”开发,您可以考虑使用Eclipse/Californium。 demo-apps / cf-helloworld-client中的简单客户端需要对观察进行一些更改。如果您需要帮助,请在github中打开一个问题。

我有两年的使用该功能的经验,如果您的数据更改速度超过了“带宽”能够传输的速度(包括考虑的块RTT),您可能会发送很多块徒然。 如果数据更改的速度快于最后一个块的发送速度,则到目前为止,整个传输无效。然后一些人开始发展他们的解决方法,但是从那以后,您就可以轻而易举了:-)。