coap协议说明及函数使用

coap的首部结构

格式

消息头(HEAD)

第一行是消息头,必须有,固定4个byte。

Ver : 2bit, 版本信息,当前是必须写0x01。

T: 2bit, 消息类型,包括 CON, NON. ACK, RST这4种。

TKL: 4bit,token长度, 当前支持0~8B长度,其他长度保留将来扩展用。

Code:8bit,分成前3bit(07)和后5bit(031),前3bit代表类型。 0代表空消息或者请求码, 2开头代表响应码,取值如下:

1 0.00 Indicates an Empty message

2 0.01-0.31 Indicates a request.

3 1.00-1.31 Reserved

4 2.00-5.31 Indicates a response.

5 6.00-7.31 Reserved

Message ID:16bit, 代表消息MID,每个消息都有一个ID ,重发的消息MID不变

token(可选)

用于将响应与请求匹配。 token值为0到8字节的序列。 ( 每条消息必须带有一个标记, 即使它的长度为零)。 每个请求都带有一个客户端生成的token, 服务器在任何结果响应中都必须对其进行回应。token类似消息ID,用以标记消息的唯一性。token还是消息安全性的一个设置,使用全8字节的随机数,使伪造的报文无法获得验证通过。

option(可选,0个或者多个)

请求消息 与回应消息都可以0~多个options。 主要用于描述请求或者响应对应的各个属性,类似参数或者特征描述,比如是否用到代理服务器,目的主机的端口等。

payload(可选)

实际携带数据内容, 若有, 前面加payload标识符“0xFF”,如果没有payload标识符,那么就代表这是一个0长度的payload。如果存在payload标识符但其后跟随的是0长度的payload,那么必须当作消息格式错误处理。

COAP的请求码(requests)和响应码(responses)

【0.01】GET方法——用于获得某资源

【0.02】POST方法——用于创建某资源

【0.03】PUT方法——用于更新某资源

【0.04】DELETE方法——用于删除某资源

函数使用

1.保存将要发送数据的目的地址

int demo_resolve_address(struct incom_addr *addr, coap_address_t *coapaddr) 

参数1: 为目的地址,可以是ipv6或者Ipv4
参数2:为sockaddr的结构体
这个函数要实现的的功能就是吧server的地址,放到dst中,并根据是Ip4和ipv6把dst补充完善。包括端口,地址,协议族

2. 保存路径

static int incom_resolve_path(unsigned char *path, incom_list_t **optlist)

参数1:为访问地址的uri-path 和uri_query组成的字符串
参数2:为一个链表结构体,会通过下面的函数将uri_path和uri_query插入到俩女表结构体t

 coap_insert(optlist, new_option_node(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(b), COAP_OPT_VALUE(b)),order_opts);
 coap_insert(optlist, new_option_node(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(b), COAP_OPT_VALUE(b)),order_opts);

3.生成ctx结构体

static coap_context_t *incom_new_contex(coap_address_t *coapaddr)

参数1:为第一个函数生成的coap的地址
返回值为ctx结构体

该函数的功能
利用出现的函数生成ctx的结构体

static coap_context_t *incom_gen_context(const char *node, const char *port)
引用ctx = incom_gen_context("::","");

然后利用下面的函数将返回函数添加到ctx中去

static int incom_register_handler(coap_context_t *ctx, coap_response_handler_t handler)
ret = incom_register_handler(ctx, incom_response_handler);
typedef struct coap_context_t {
  coap_opt_filter_t known_options;
  struct coap_resource_t *resources; /**< hash table or list of known resources */

#ifndef WITHOUT_ASYNC
  /**
   * list of asynchronous transactions */
  struct coap_async_state_t *async_state;
#endif /* WITHOUT_ASYNC */

  /**
   * The time stamp in the first element of the sendqeue is relative
   * to sendqueue_basetime. */
  coap_tick_t sendqueue_basetime;
  coap_queue_t *sendqueue;
  coap_endpoint_t *endpoint;      /**< the endpoint used for listening  */

#ifdef WITH_POSIX
  int sockfd;                     /**< send/receive socket */
#endif /* WITH_POSIX */

#ifdef WITH_CONTIKI
  struct uip_udp_conn *conn;      /**< uIP connection object */
  struct etimer retransmit_timer; /**< fires when the next packet must be sent */
  struct etimer notify_timer;     /**< used to check resources periodically */
#endif /* WITH_CONTIKI */

#ifdef WITH_LWIP
  uint8_t timer_configured;       /**< Set to 1 when a retransmission is
                                   *   scheduled using lwIP timers for this
                                   *   context, otherwise 0. */
#endif /* WITH_LWIP */

  /**
   * The last message id that was used is stored in this field. The initial
   * value is set by coap_new_context() and is usually a random value. A new
   * message id can be created with coap_new_message_id().
   */
  unsigned short message_id;

  /**
   * The next value to be used for Observe. This field is global for all
   * resources and will be updated when notifications are created.
   */
  unsigned int observe;

  coap_response_handler_t response_handler;

  ssize_t (*network_send)(struct coap_context_t *context,
                          const coap_endpoint_t *local_interface,
                          const coap_address_t *dst,
                          unsigned char *data, size_t datalen);

  ssize_t (*network_read)(coap_endpoint_t *ep, coap_packet_t **packet);

}coap_context_t

4.对监听端点设置优先级

ret = incom_set_message_priority(ctx->endpoint->handle.fd, (unsigned int)para->priority);

参数1:为ctx的套接字fd,
参数2:为优先级

通过下面的函数对fd进行优先级设置

 ret = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void *)&(priority), sizeof(priority));

5. 组成coap的数据包

static coap_pdu_t *incom_new_request(coap_context_t *ctx, unsigned char m, incom_token *token, incom_list_t **opts, unsigned char *data, size_t len)

参数1:为ctx,上面的函数生成
参数2: 是用于coap头部的code的内容
参数3:是用于coap头部的token的值
参数4:适用于coap头部的opt选项
参数5:为负载数据
参数6:为数据的长度

先利用下面的函数产生一个空的pdu

pdu = coap_new_pdu();

再利用下面的函数向pdu中添加值

    pdu->hdr->type = COAP_MESSAGE_CON;
    pdu->hdr->id = coap_new_message_id(ctx);
    pdu->hdr->code = m;
    coap_add_token(pdu, token->len, token->token)
    coap_add_option(pdu, COAP_OPTION_KEY(*o), COAP_OPTION_LENGTH(*o), COAP_OPTION_DATA(*o))
    coap_add_data(pdu, len, data)

结构体coap_pdu_t

typedef struct {
  size_t max_size;          /**< allocated storage for options and data */
  coap_hdr_t *hdr;          /**< Address of the first byte of the CoAP message.
                             *   This may or may not equal (coap_hdr_t*)(pdu+1)
                             *   depending on the memory management
                             *   implementation. */
  unsigned short max_delta; /**< highest option number */
  unsigned short length;    /**< PDU length (including header, options, data) */
  unsigned char *data;      /**< payload */

#ifdef WITH_LWIP
  struct pbuf *pbuf;        /**< lwIP PBUF. The package data will always reside
                             *    inside the pbuf's payload, but this pointer
                             *    has to be kept because no exact offset can be
                             *    given. This field must not be accessed from
                             *    outside, because the pbuf's reference count
                             *    is checked to be 1 when the pbuf is assigned
                             *    to the pdu, and the pbuf stays exclusive to
                             *    this pdu. */
#endif
} coap_pdu_t;

6.发送数据包

static int incom_send_request(coap_context_t *ctx, coap_endpoint_t *loif, coap_address_t *dst, coap_pdu_t *pdu)

参数1:为上面生成的ctx
参数2:为ctx的端点
参数3:为目的地址dst
参数4:为数据包pdu

7.等待发送完成

ret = incom_wait_response(ctx, para->timeout);

参数1,为上面生成的ctx
参数2:为超时时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值