上手:CoAP server and Copper

导语 本文基于contiki3.0系统,翻译自iot in five days,使用的节点是avr-atmega128rfa1

Copper是一个基于CoAP的IOT通用浏览器,它可以和当前存在的CoAP设备直观的交互和调试。More Information

  • 2.在本次试验中使用两个节点:一个Border Router和一个CoAP server
      注:要确保节点在之前的sessions已经写入了Node ID,以便产生MAC/IPv6地址
      注:在atmega128rfa1平台上EUI即IEEE地址位于platform/avr-atmega128rfa1/params.h,在本次试验中,我将border-router的IEEE地址设置为{0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x02},CoAP server节点设为{0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01}
      另,发现以下错误,修改examples/er-rest-example/project-conf.h中的UIP_CONF_BUFFER_SIZE为240,同时为了使LED可用,在该文件中添加以下代码:
#define PLATFORM_HAS_LEDS 1
  • 3.在Makefile(examples/er-rest-example/)中有两件事要注意:

  • 1.resource文件夹被包含作为项目文件夹,所有的resource文件都被加入编译


  • 2.包含了er-coap和rest-engine应用



      注:如果我们想尽可能避免冲突,移除下面代码:

    #undef NETSTACK_CONF_MAC
    #define NETSTACK_CONF_MAC nullmac_driver
    

* 4.接下来检查**project-conf.h**中的相关配置,首先确保TCP被禁用,因为CoAP是基于UDP的
![](http://upload-images.jianshu.io/upload_images/1245901-aec86e78e6cf255d.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 5.**REST_MAX_CHUNK_SIZE**是提供给资源响应的最大缓冲区大小,更大的数据要通过resource处理并被发送给CoAP blocks.**COAP_MAX_OPEN_TRANSACTION**是节点能够处理的最大开放传输数量
![](http://upload-images.jianshu.io/upload_images/1245901-d57dfc2fa23f6e32.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#CoAP Server
  通过测试er-example-server.c(examples/er-rest-example)这个例子理解它的实现。首先要注意一个叫resources的文件夹:各种resources被不同的文件实现,易于调试。
  在CoAP中要被包含的resources定义如下:
    /*
     * Resources to be activated need to be imported through the extern keyword.
     * The build system automatically compiles the resources in the corresponding sub-directory.
     */
    extern resource_t
      res_hello,
      res_mirror,
      res_chunks,
      res_separate,
      res_push,
      res_event,
      res_sub,
      res_b1_sep_b2;
    #if PLATFORM_HAS_LEDS
    extern resource_t res_leds, res_toggle;
    #endif
    #if PLATFORM_HAS_LIGHT
    #include "dev/light-sensor.h"
    extern resource_t res_light;
    #endif
    /*
    #if PLATFORM_HAS_BATTERY
    #include "dev/battery-sensor.h"
    extern resource_t res_battery;
    #endif
    #if PLATFORM_HAS_RADIO
    #include "dev/radio-sensor.h"
    extern resource_t res_radio;
    #endif
    #if PLATFORM_HAS_SHT11
    #include "dev/sht11/sht11-sensor.h"
    extern resource_t res_sht11;
    #endif
    */
  包含在**PLATFORM_HAS_X**的resources宏定义是独立于目标平台的,如果平台被选定,资源也就确定了。
  REST engine通过调用*rest_init_engine()*初始化,这样开启的resources就被绑定了。
    

      rest_init_engine();
      /*
       * Bind the resources to their Uri-Path.
       * WARNING: Activating twice only means alternate path, not two instances!
       * All static variables are the same for each URI path.
       */
      rest_activate_resource(&res_hello, "test/hello");
    /*  rest_activate_resource(&res_mirror, "debug/mirror"); */
    /*  rest_activate_resource(&res_chunks, "test/chunks"); */
    /*  rest_activate_resource(&res_separate, "test/separate"); */
      rest_activate_resource(&res_push, "test/push");
    /*  rest_activate_resource(&res_event, "sensors/button"); */
    /*  rest_activate_resource(&res_sub, "test/sub"); */
    /*  rest_activate_resource(&res_b1_sep_b2, "test/b1sepb2"); */
    #if PLATFORM_HAS_LEDS
    /*  rest_activate_resource(&res_leds, "actuators/leds"); */
      rest_activate_resource(&res_toggle, "actuators/toggle");
    #endif
    #if PLATFORM_HAS_LIGHT
      rest_activate_resource(&res_light, "sensors/light"); 
      SENSORS_ACTIVATE(light_sensor);  
    #endif    
  现在看看res-hello.c,它实现了一个“hello world” resource 用于测试
  如前所示资源已经在**RESOURCE**宏中定义了,对于这个特定的实现,我们规定资源名为res-hello,也规定了link-formatted属性和**GET**回调handler。**POST,PUT,DELETE**方法在本resource中不被支持,就传入**NULL**作为参数。

![](http://upload-images.jianshu.io/upload_images/1245901-8975a78e8b536c35.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

  **res_get_handler**是**GET** request的回调函数,其实现:
    
        static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
        {
        const char *len = NULL;
        /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */
        char const *const message = "Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy";
        int length = 12; /*           |<-------->| */ //默认
    长度的回复,在本例中整个字符串只有Hello World!会被发送
      /* The query string can be retrieved by rest_get_query() or parsed for its key-value pairs. */
      if(REST.get_query_variable(request, "len", &len)) {//如果len被设定了就发送len长度字节的信息
        length = atoi(len);
        if(length < 0) {//如果为负,发送空字符串
          length = 0;
        }
        if(length > REST_MAX_CHUNK_SIZE) {//如果len比最大允许值还大就值发送最大允许值的字符串
          length = REST_MAX_CHUNK_SIZE;
        }
        memcpy(buffer, message, length); //copy the default
      } else {
        memcpy(buffer, message, length);
      } 
    //设置response内容类型为 Content-Type:text/plain
    REST.set_header_content_type(response, REST.type.TEXT_PLAIN); /*     text/plain is the default, hence this option could be omitted. */

      REST.set_header_etag(response, (uint8_t *)&length, 1);//在response前加入header,设置负荷长度字段
      REST.set_response_payload(response, buffer, length);//把负荷加入response
    }
![](http://upload-images.jianshu.io/upload_images/1245901-4e4b9ba76ef75c36.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  在**project-conf.h**中加入以下代码用于测试
    #undef NETSTACK_CONF_RDC
    #define NETSTACK_CONF_RDC nullrdc_driver
  然后编译并上载(这里为了方便就直接借书上的图了,具体操作可以看我的这篇博客[Contiki边界路由](http://www.jianshu.com/p/8d54bc801271):
![](http://upload-images.jianshu.io/upload_images/1245901-a732a8a8676815a8.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  在串口打印中也可以看到IPv6服务器地址,断开节点连上另一个作为客户端
#Border-Router:
######此部分和我的[Contiki边界路由](http://www.jianshu.com/p/8d54bc801271)博客差不多。。。不好意思这篇博客是先写的
![](http://upload-images.jianshu.io/upload_images/1245901-164137d73e763599.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  不要关闭窗口,让节点连接,就可以看见类似于如下的信息:
![
![](http://upload-images.jianshu.io/upload_images/1245901-6cb368f954af8b69.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
](http://upload-images.jianshu.io/upload_images/1245901-84d37dc1158c1c59.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  可以ping border-router:
![](http://upload-images.jianshu.io/upload_images/1245901-9b5a1edb4fc94d6a.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  连接上服务器节点,也可以ping:

![](http://upload-images.jianshu.io/upload_images/1245901-52925ff581c938b7.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这样就可以发现服务器资源了。打开firfox,输入服务器地址:
    coap://[aaaa::c30c:0000:0000:0001]:5683/
![](http://upload-images.jianshu.io/upload_images/1245901-9c63b98fdf3bbf89.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  点击**DISCOVER**,在左侧网页你就可以:
  如果你选择**toggle**资源,使用**POST**你可以看见服务器节点的红灯会翻转;
  如果选择**Hello**资源,服务器会回应你一个Hello World!
  如果你通过选择并点击**OBSERVE**,观察**Sensors->BUTTON**事件,每当你按一次用户按钮,一个事件就会被触发并被回报。
  最后,如果你去**er-example-server.c**文件,并打开下面的宏定义,可以看到更多可用的宏定义。

![](http://upload-images.jianshu.io/upload_images/1245901-265dfef0468f3684.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  获得当前收发器的RSSI值:
![](http://upload-images.jianshu.io/upload_images/1245901-8e9eaa3e873609ce.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  获取电池电量:

![](http://upload-images.jianshu.io/upload_images/1245901-9e6fb0c09ca9e19e.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  当节点连接到USB,获取ADC单元的值,实际值将为:
             v[mV]=(units*5000)/4096
  如果想让绿灯亮:

![](http://upload-images.jianshu.io/upload_images/1245901-21bec7552c85bee7.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  然后在payload(the ongoing tab)上写:
             mode="on"
  并按下**POST**或**PUT**


  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,406评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,976评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,302评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,366评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,372评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,457评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,872评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,521评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,717评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,523评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,590评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,299评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,859评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,883评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,127评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,760评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,290评论 2 342

推荐阅读更多精彩内容