上手:CoAP server and Copper

導(dǎo)語 本文基于contiki3.0系統(tǒng),翻譯自iot in five days,使用的節(jié)點(diǎn)是avr-atmega128rfa1

Copper是一個(gè)基于CoAP的IOT通用瀏覽器,它可以和當(dāng)前存在的CoAP設(shè)備直觀的交互和調(diào)試。More Information

  • 2.在本次試驗(yàn)中使用兩個(gè)節(jié)點(diǎn):一個(gè)Border Router和一個(gè)CoAP server
      注:要確保節(jié)點(diǎn)在之前的sessions已經(jīng)寫入了Node ID,以便產(chǎn)生MAC/IPv6地址
      注:在atmega128rfa1平臺上EUI即IEEE地址位于platform/avr-atmega128rfa1/params.h,在本次試驗(yàn)中,我將border-router的IEEE地址設(shè)置為{0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x02},CoAP server節(jié)點(diǎn)設(shè)為{0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01}
      另,發(fā)現(xiàn)以下錯(cuò)誤,修改examples/er-rest-example/project-conf.h中的UIP_CONF_BUFFER_SIZE為240,同時(shí)為了使LED可用,在該文件中添加以下代碼:
#define PLATFORM_HAS_LEDS 1
  • 3.在Makefile(examples/er-rest-example/)中有兩件事要注意:

  • 1.resource文件夾被包含作為項(xiàng)目文件夾,所有的resource文件都被加入編譯


  • 2.包含了er-coap和rest-engine應(yīng)用



      注:如果我們想盡可能避免沖突,移除下面代碼:

    #undef NETSTACK_CONF_MAC
    #define NETSTACK_CONF_MAC nullmac_driver
    

* 4.接下來檢查**project-conf.h**中的相關(guān)配置,首先確保TCP被禁用,因?yàn)镃oAP是基于UDP的
![](http://upload-images.jianshu.io/upload_images/1245901-aec86e78e6cf255d.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 5.**REST_MAX_CHUNK_SIZE**是提供給資源響應(yīng)的最大緩沖區(qū)大小,更大的數(shù)據(jù)要通過resource處理并被發(fā)送給CoAP blocks.**COAP_MAX_OPEN_TRANSACTION**是節(jié)點(diǎn)能夠處理的最大開放傳輸數(shù)量
![](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)這個(gè)例子理解它的實(shí)現(xiàn)。首先要注意一個(gè)叫resources的文件夾:各種resources被不同的文件實(shí)現(xiàn),易于調(diào)試。
  在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宏定義是獨(dú)立于目標(biāo)平臺的,如果平臺被選定,資源也就確定了。
  REST engine通過調(diào)用*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    
  現(xiàn)在看看res-hello.c,它實(shí)現(xiàn)了一個(gè)“hello world” resource 用于測試
  如前所示資源已經(jīng)在**RESOURCE**宏中定義了,對于這個(gè)特定的實(shí)現(xiàn),我們規(guī)定資源名為res-hello,也規(guī)定了link-formatted屬性和**GET**回調(diào)handler。**POST,PUT,DELETE**方法在本resource中不被支持,就傳入**NULL**作為參數(shù)。

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

  **res_get_handler**是**GET** request的回調(diào)函數(shù),其實(shí)現(xiàn):
    
        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; /*           |<-------->| */ //默認(rèn)
    長度的回復(fù),在本例中整個(gè)字符串只有Hello World!會被發(fā)送
      /* 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被設(shè)定了就發(fā)送len長度字節(jié)的信息
        length = atoi(len);
        if(length < 0) {//如果為負(fù),發(fā)送空字符串
          length = 0;
        }
        if(length > REST_MAX_CHUNK_SIZE) {//如果len比最大允許值還大就值發(fā)送最大允許值的字符串
          length = REST_MAX_CHUNK_SIZE;
        }
        memcpy(buffer, message, length); //copy the default
      } else {
        memcpy(buffer, message, length);
      } 
    //設(shè)置response內(nèi)容類型為 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,設(shè)置負(fù)荷長度字段
      REST.set_response_payload(response, buffer, length);//把負(fù)荷加入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.itdecent.cn/p/8d54bc801271):
![](http://upload-images.jianshu.io/upload_images/1245901-a732a8a8676815a8.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  在串口打印中也可以看到IPv6服務(wù)器地址,斷開節(jié)點(diǎn)連上另一個(gè)作為客戶端
#Border-Router:
######此部分和我的[Contiki邊界路由](http://www.itdecent.cn/p/8d54bc801271)博客差不多。。。不好意思這篇博客是先寫的
![](http://upload-images.jianshu.io/upload_images/1245901-164137d73e763599.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  不要關(guān)閉窗口,讓節(jié)點(diǎn)連接,就可以看見類似于如下的信息:
![
![](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)
  連接上服務(wù)器節(jié)點(diǎn),也可以ping:

![](http://upload-images.jianshu.io/upload_images/1245901-52925ff581c938b7.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這樣就可以發(fā)現(xiàn)服務(wù)器資源了。打開firfox,輸入服務(wù)器地址:
    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)
  點(diǎn)擊**DISCOVER**,在左側(cè)網(wǎng)頁你就可以:
  如果你選擇**toggle**資源,使用**POST**你可以看見服務(wù)器節(jié)點(diǎn)的紅燈會翻轉(zhuǎn);
  如果選擇**Hello**資源,服務(wù)器會回應(yīng)你一個(gè)Hello World!
  如果你通過選擇并點(diǎn)擊**OBSERVE**,觀察**Sensors->BUTTON**事件,每當(dāng)你按一次用戶按鈕,一個(gè)事件就會被觸發(fā)并被回報(bào)。
  最后,如果你去**er-example-server.c**文件,并打開下面的宏定義,可以看到更多可用的宏定義。

![](http://upload-images.jianshu.io/upload_images/1245901-265dfef0468f3684.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  獲得當(dāng)前收發(fā)器的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)
  當(dāng)節(jié)點(diǎn)連接到USB,獲取ADC單元的值,實(shí)際值將為:
             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**


  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容