libcoap(三) struct coap_context_t

coap_context_t中第二个成员变量
struct coap_resource_t *resources;

/** The CoAP stack's global state is stored in a coap_context_t object */
typedef struct coap_context_t {
  coap_opt_filter_t known_options;
#ifndef WITH_CONTIKI
  struct coap_resource_t *resources; /**< hash table or list of known resources */
#endif /* WITH_CONTIKI */
typedef struct coap_resource_t {
  unsigned int dirty:1;       /**< set to 1 if resource has changed */
  unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet been notified of the last change */
  unsigned int observable:1; /**< can be observed */
  unsigned int cacheable:1;   /**< can be cached */

  /** 
   * Used to store handlers for the four coap methods @c GET, @c POST,
   * @c PUT, and @c DELETE. coap_dispatch() will pass incoming
   * requests to the handler that corresponds to its request method or
   * generate a 4.05 response if no handler is available.
   */
  coap_method_handler_t handler[4];

  coap_key_t key;   /**< the actual key bytes for this resource */
#ifndef WITH_CONTIKI
#ifdef COAP_RESOURCES_NOHASH
  struct coap_resource_t *next;
#else
  UT_hash_handle hh;
#endif
#endif /* WITH_CONTIKI */

#ifndef WITH_CONTIKI
  coap_attr_t *link_attr; /**< attributes to be included with the link format */
#else /* WITH_CONTIKI */
  LIST_STRUCT(link_attr); /**< attributes to be included with the link format */
#endif /* WITH_CONTIKI */
  LIST_STRUCT(subscribers); /**< list of observers for this resource */


  /**
   * Request URI for this resource. This field will point into the
   * static memory. */
  str uri;
  int flags;

} coap_resource_t;
  unsigned int dirty:1;       /**< set to 1 if resource has changed */
  unsigned int partiallydirty:1; /**< set to 1 if some subscribers have not yet been notified of the last change */
  unsigned int observable:1; /**< can be observed */
  unsigned int cacheable:1;   /**< can be cached */

这四个位与不懂,先不看

  /** 
   * Used to store handlers for the four coap methods @c GET, @c POST,
   * @c PUT, and @c DELETE. coap_dispatch() will pass incoming
   * requests to the handler that corresponds to its request method or
   * generate a 4.05 response if no handler is available.
   */
  coap_method_handler_t handler[4];

这个注释写的很清楚,针对GET POST PUT DELETE的四个handler,每个resource都可以有自己的4个handler

coap_key_t key; /**< the actual key bytes for this resource */

看下这个类型

typedef unsigned char coap_key_t[4];

是个含有4个unsigned char的数组,这个里面保存的是hash key,后续查找resource的时候是根据key来查询。来看下什么时候生成这个hash key

r = coap_resource_init((unsigned char *)"time", 4, 0);
coap_resource_t *
coap_resource_init(const unsigned char *uri, size_t len, int flags) {
  coap_resource_t *r;

#ifdef WITH_POSIX
  r = (coap_resource_t *)coap_malloc(sizeof(coap_resource_t));
#endif
#ifdef WITH_LWIP
  r = (coap_resource_t *)memp_malloc(MEMP_COAP_RESOURCE);
#endif
#ifdef WITH_CONTIKI
  r = (coap_resource_t *)memb_alloc(&resource_storage);
#endif
  if (r) {
    memset(r, 0, sizeof(coap_resource_t));

#ifdef WITH_CONTIKI
    LIST_STRUCT_INIT(r, link_attr);
#endif /* WITH_CONTIKI */
    LIST_STRUCT_INIT(r, subscribers);

    r->uri.s = (unsigned char *)uri;
    r->uri.length = len;

    coap_hash_path(r->uri.s, r->uri.length, r->key);

    r->flags = flags;
  } else {
    debug("coap_resource_init: no memory left\n");
  }

  return r;
}
int
coap_hash_path(const unsigned char *path, size_t len, coap_key_t key) {
  coap_parse_iterator_t pi;

  if (!path)
    return 0;

  memset(key, 0, sizeof(coap_key_t));

  coap_parse_iterator_init((unsigned char *)path, len, 
               '/', (unsigned char *)"?#", 2, &pi);
  coap_split_path_impl(&pi, hash_segment, key);

  return 1;
}
/** 
 * Splits the given string into segments. You should call one of the
 * macros coap_split_path() or coap_split_query() instead.
 * 
 * @param parse_iter The iterator used for tokenizing.
 * @param h      A handler that is called with every token.
 * @param data   Opaque data that is passed to @p h when called.
 * 
 * @return The number of characters that have been parsed from @p s.
 */
size_t
coap_split_path_impl(coap_parse_iterator_t *parse_iter,
             segment_handler_t h, void *data) {
  unsigned char *seg;
  size_t length;

  assert(parse_iter);
  assert(h);

  length = parse_iter->n;

  while ( (seg = coap_parse_next(parse_iter)) ) {

    /* any valid path segment is handled here: */
    h(seg, parse_iter->segment_length, data);
  }

  return length - (parse_iter->n - parse_iter->segment_length);
}
/* hash URI path segments */

/* The function signature of coap_hash() is different from
 * segment_handler_t hence we use this wrapper as safe typecast. */
static inline void
hash_segment(unsigned char *s, size_t len, void *data) {
  coap_hash(s, len, data);
}
/** 
 * Calculates a fast hash over the given string @p s of length @p len
 * and stores the result into @p h. Depending on the exact
 * implementation, this function cannot be used as one-way function to
 * check message integrity or simlar.
 * 
 * @param s   The string used for hash calculation.
 * @param len The length of @p s.
 * @param h   The result buffer to store the calculated hash key.
 */
void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h);

#define coap_hash(String,Length,Result) \
  coap_hash_impl((String),(Length),(Result))
/* Caution: When changing this, update COAP_DEFAULT_WKC_HASHKEY
 * accordingly (see int coap_hash_path());
 */
void
coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h) {
  size_t j;

  while (len--) {
    j = sizeof(coap_key_t)-1;

    while (j) {
      h[j] = ((h[j] << 7) | (h[j-1] >> 1)) + h[j];
      --j;
    }

    h[0] = (h[0] << 7) + h[0] + *s++;
  }
}

coap_hash_impl这个函数就是实现hask key的生成
具体hash key的算法后面再单独开一个主题说一下。

UT_hash_handle hh;

这个就是构造hash的数据结构。

#ifndef WITH_CONTIKI
  coap_attr_t *link_attr; /**< attributes to be included with the link format */
#else /* WITH_CONTIKI */
  LIST_STRUCT(link_attr); /**< attributes to be included with the link format */
#endif /* WITH_CONTIKI */

WITH_CONTIKI没有定义,所以这里直接是一个指针变量,看下这个结构体

typedef struct coap_attr_t {
  struct coap_attr_t *next;
  str name;
  str value;
  int flags;
} coap_attr_t;

里面有自身的指针,一看就是会用链表

看下它是怎么初始化的

  coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0);
  coap_add_attr(r, (unsigned char *)"title", 5, (unsigned char *)"\"General Info\"", 14, 0);
coap_attr_t *
coap_add_attr(coap_resource_t *resource, 
          const unsigned char *name, size_t nlen,
          const unsigned char *val, size_t vlen,
              int flags) {
  coap_attr_t *attr;

  if (!resource || !name)
    return NULL;

#ifdef WITH_POSIX
  attr = (coap_attr_t *)coap_malloc(sizeof(coap_attr_t));
#endif
#ifdef WITH_LWIP
  attr = (coap_attr_t *)memp_malloc(MEMP_COAP_RESOURCEATTR);
#endif
#ifdef WITH_CONTIKI
  attr = (coap_attr_t *)memb_alloc(&attribute_storage);
#endif

  if (attr) {
    attr->name.length = nlen;
    attr->value.length = val ? vlen : 0;

    attr->name.s = (unsigned char *)name;
    attr->value.s = (unsigned char *)val;

    attr->flags = flags;

    /* add attribute to resource list */
#ifndef WITH_CONTIKI
    LL_PREPEND(resource->link_attr, attr);
#else /* WITH_CONTIKI */
    list_add(resource->link_attr, attr);
#endif /* WITH_CONTIKI */
  } else {
    debug("coap_add_attr: no memory left\n");
  }

  return attr;
}
/******************************************************************************
 * singly linked list macros (non-circular)                                   *
 *****************************************************************************/
#define LL_PREPEND(head,add)                                                                   \
do {                                                                                           \
  (add)->next = head;                                                                          \
  head = add;                                                                                  \
} while (0)
LL_PREPEND(resource->link_attr, attr);

可以看出都会”链入“resource的link_attr,目前还不理解这里的coap_attr_t有什么作用。Qustion????????

  /**
   * Request URI for this resource. This field will point into the
   * static memory. */
  str uri;
  int flags;
typedef struct {
  size_t length;        /* length of string */
  unsigned char *s;     /* string data */
} str;

uri就是resource的标示,unsigned char * 型
flags目前这里没有用到。
好了,这个结构体介绍完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值