5.1.1 CoAP 的 API

contiki的COAP在apps/er-coap中实现。Erbium REST引擎在apps/rest-engine中实现
COAP引擎(当前版本COAP-18)在由er-coap-engine.c实现。
引擎接口由以下结构提供:

  1. const struct rest_implementation coap_rest_implementation = {
  2. coap_init_engine,
  3. coap_set_service_callback,
  4. coap_get_header_uri_path,
  5. (...)
  6. }

再次调用CoAP引擎:

  1. REST.get_query_variable();

Web服务抽象为资源,并且可以通过它们的URL唯一地识别。

REST基本设计采用HTTP或COAP协议的典型CRUD操作(创建,读取,更新,删除):

  • POST:创建资源
  • GET:获取资源
  • PUT:更新资源
  • 删除:删除资源

服务器上有很多可用的资源。服务器的每个资源都具有可供REST层调用响应客户端请求的处理函数。服务器向客户端发送所请求资源内容作为响应。

apps/rest-engine中定义有相关宏,可用于创建新的COAP资源。

正常资源(normal resource)可由关联资源储量函数的静态Uri路径定义,这也是其他资源类型的基础。

父资源通过评估Uri路径管理若干子资源,子资源可能比父资源路径长

  1. #define PARENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler,
  2. delete_handler) \
  3. resource_t name = { NULL, NULL, HAS_SUB_RESOURCES, attributes, get_handler,
  4. post_handler, put_handler, delete_handler, { NULL } }

如果服务器不能立即响应CON请求,服务器将发送ACK空消息简单响应,这样客户端就停止重发请求。当服务器准备好响应后,它发送CON消息响应。

下面的宏允许创建独立响应的COAP资源:

  1. #define SEPARATE_RESOURCE(name, attributes, get_handler, post_handler, put_handler,
  2. delete_handler, resume_handler) \
  3. resource_t name = { NULL, NULL, IS_SEPARATE, attributes, get_handler,
  4. post_handler, put_handler, delete_handler, { .resume = resume_handler } }

事件资源与周期资源类似,但对于非周期性事件如按下按钮,可调用event_handler处理。

  1. #define EVENT_RESOURCE(name, attributes, get_handler, post_handler, put_handler,
  2. delete_handler, event_handler) \
  3. resource_t name = { NULL, NULL, IS_OBSERVABLE, attributes, get_handler,
  4. post_handler, put_handler, delete_handler, { .trigger = event_handler } }

如果我们需要声明周期资源,例如轮询传感器和发布变量到订阅客户端,那么我们应该使用:

  1. #define PERIODIC_RESOURCE(name, attributes, get_handler, post_handler, put_handler,
  2. delete_handler, period, periodic_handler) \
  3. periodic_resource_t periodic_##name; \
  4. resource_t name = { NULL, NULL, IS_OBSERVABLE | IS_PERIODIC, attributes,
  5. get_handler, post_handler, put_handler, delete_handler, { .periodic =
  6. &periodic_##name } }; \
  7. periodic_resource_t periodic_##name = { NULL, &name, period, { { 0 } },
  8. periodic_handler };

注意,PERIODIC_RESOURCE和EVENT_RESOURCE可可观察,意味着指定资源变化将通知客户端。

一旦我们声明并实现了资源,我们需要初始化REST框架,并启动HTTP或COAP进程。
可以调用以下函数实现:

  1. void rest_init_engine(void);

如果想要访问的已声明资源,我们需要还调用以下函数注册(激活)资源。

  1. void rest_activate_resource(resource_t *resource, char *path);

假定在res-hello.c中创建了hello-world资源,声明如下

  1. "title=\"Hello world: ?len=0..\";rt=\"Text\"",
  2. res_get_handler,
  3. NULL,
  4. NULL,
  5. NULL);

为了使能(激活)资源,调用函数:

  1. rest_activate_resource(&res_hello, "test/hello");

这样将可以在test/hello URI路径下访问到hello-world资源。

rest_activate_resource()函数将资源存储到列表。当要列出可用的资源时,可调用rest_get_resources函数,返回资源列表。

rest_get_resources();

注意,COAP默认端口是5683。

下面进入实践环节,演示如何使用Coap。