新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于STM32平臺的CoAP Server方案

        基于STM32平臺的CoAP Server方案

        作者: 時間:2016-11-13 來源:網絡 收藏
        0.前言

        CoAP是受限制的應用協議(Constrained Application Protocol)的代名詞。在當前由PC機組成的世界,信息交換是通過TCP和應用層協議HTTP實現的。但是對于小型設備而言,實現TCP和HTTP協議顯然是一個過分的要求。為了讓小設備可以接入互聯網,CoAP協議被設計出來。CoAP是一種應用層協議,它運行于UDP協議之上而不是像HTTP那樣運行于TCP之上。CoAP協議非常小巧,最小的數據包僅為4字節。
        本文將使用STM32平臺實現一個CoAP Server Demo。本文將詳細說明如何使用STM32這樣的低成本MCU實現CoAP Server的步驟,本文試圖說明CoAP協議雖然很“年輕”,但是有用、好用且易用。
        【代碼倉庫】
        如果想獲得本文的示例代碼請點擊——【bitbucket】,示例代碼中的doc目錄有本文所使用開發板的原理圖和相關說明。
        【相關博文】
        物聯網學習筆記——索引博文】
        【CoAP學習筆記——nodeJS node-coap安裝和使用(windows平臺)】

        本文引用地址:http://www.104case.com/article/201611/316106.htm

        1.使用LwIP處理CoAP數據包
        新建一個套接字,綁定UDP 5683端口,偵聽該端口數據使用microcoap響應函數解析,最后獲得返回結果即可。示例中使用了RT Thread中移植好的LwIP協議棧,網卡驅動為ENC28J60。

        1. voidcoap_server(void*para)
        2. {
        3. intfd;
        4. structsockaddr_inservaddr,cliaddr;
        5. coap_rw_buffer_tscratch_buf={scratch_raw,sizeof(scratch_raw)};
        6. if((fd=socket(AF_INET,SOCK_DGRAM,0))==-1)
        7. {
        8. printf("SocketErrorrn");
        9. return;
        10. }
        11. servaddr.sin_family=AF_INET;
        12. servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        13. servaddr.sin_port=htons(PORT);
        14. rt_memset(&(servaddr.sin_zero),0,sizeof(servaddr.sin_zero));
        15. if((bind(fd,(structsockaddr*)&servaddr,sizeof(servaddr)))==-1)
        16. {
        17. printf("Binderrorrn");
        18. return;
        19. }
        20. endpoint_setup();
        21. rt_kprintf("CoapServerStart!rn");
        22. while(1)
        23. {
        24. intn,rc;
        25. socklen_tlen=sizeof(cliaddr);
        26. coap_packet_tpkt;
        27. n=recvfrom(fd,buf,sizeof(buf),0,(structsockaddr*)&cliaddr,&len);
        28. #ifdefMICROCOAP_DEBUG
        29. printf("rn--------------------rn");
        30. printf("ReceivedBuffer:rn");
        31. coap_dump(buf,n,true);
        32. printf("rn");
        33. #endif
        34. if(0!=(rc=coap_parse(&pkt,buf,n)))
        35. {
        36. printf("Badpacketrc=%drn",rc);
        37. }
        38. else
        39. {
        40. size_trsplen=sizeof(buf);
        41. coap_packet_trsppkt;
        42. #ifdefMICROCOAP_DEBUG
        43. printf("DumpPacket:rn");
        44. coap_dumpPacket(&pkt);
        45. #endif
        46. coap_handle_req(&scratch_buf,&pkt,&rsppkt);
        47. if(0!=(rc=coap_build(buf,&rsplen,&rsppkt)))
        48. {
        49. printf("coap_buildfailedrc=%dn",rc);
        50. }
        51. else
        52. {
        53. #ifdefMICROCOAP_DEBUG
        54. printf("--------------------rn");
        55. printf("SendingBuffer:rn");
        56. coap_dump(buf,rsplen,true);
        57. printf("rn");
        58. #endif
        59. #ifdefMICROCOAP_DEBUG
        60. coap_dumpPacket(&rsppkt);
        61. #endif
        62. sendto(fd,buf,rsplen,0,(structsockaddr*)&cliaddr,sizeof(cliaddr));
        63. }
        64. }
        65. }
        66. }


        代碼中使用了多個LwIP Socket部分的函數,例如socket, bind, recvfrom, sendto等。
        其中coap_parse函數把從UDP獲得的payload轉化為符合CoAP規范的結構體,coap_handle_req函數根據CoAP請求中的URI,調用響應的處理函數。最后由coap_build函數把處理的結果系列化為UDP負載。

        2.終端描述
        所有的終端信息均保存在endpoints全局數組中,該全局數組位于endpoints.c文件中。

        1. constcoap_endpoint_tendpoints[]=
        2. {
        3. {COAP_METHOD_GET,handle_get_well_known_core,&path_well_known_core,"ct=40"},
        4. {COAP_METHOD_GET,handle_get_light,&path_light,"ct=0"},
        5. {COAP_METHOD_PUT,handle_put_light,&path_light,NULL},
        6. {COAP_METHOD_GET,handle_get_test_json,&path_test_json,"ct=50"},
        7. {(coap_method_t)0,NULL,NULL,NULL}
        8. };


        【1】每個endpoint需要CoAP訪問方法,相應的處理函數,URI路徑描述,資源描述方法等。
        【2】CoAP協議中定義了多種訪問方法,GET、PUT、POST和DELETE等方法。
        【3】handle_get_light等函數主要用于處理CoAP請求,根據不同的請求調用不同的處理方法。
        【4】ct=xx指定資源描述方法,例如ct=0表示字符串形式描述,ct=50表示JSON形式描述。

        URI采用以下方式描述:

        1. staticinthandle_get_light(coap_rw_buffer_t*scratch,
        2. constcoap_packet_t*inpkt,
        3. coap_packet_t*outpkt,
        4. uint8_tid_hi,uint8_tid_lo)
        5. {
        6. returncoap_make_response(scratch,
        7. outpkt,
        8. (constuint8_t*)&light,1,
        9. id_hi,id_lo,
        10. &inpkt->tok,
        11. COAP_RSPCODE_CONTENT,
        12. COAP_CONTENTTYPE_TEXT_PLAIN);
        13. }

        除了指定返回內容之外,可通過COAP_RSPCODE_CONTENT指定返回是否成功,也可以通過COAP_CONTENTTYPE_TEXT_PLAIN指定返回內容的格式。更多的定義請查看microcoap的源代碼。

        3.簡單測試
        可使用CoAP命令行工具測試CoAP Server工作是否正常,或者使用火狐瀏覽器的coap插件。
        使用CoAP命令行測試工具——coap-cli,詳細的安裝步驟請參考【CoAP學習筆記——nodeJS node-coap安裝和使用(windows平臺)】第2部分
        3.1 light Demo
        輸入指令,嘗試修改light狀態
        coap put -p 1 coap://10.13.11.116/light
        返回
        (2.05) 1
        說明
        -p參數可用于指定coap的負載,此處1表示打開light,0表示關閉light。


        圖3.1 light PUT方法輸出
        輸入指令,嘗試獲得light狀態
        coap get coap://10.13.11.116/light
        返回
        (2.05) 1
        控制臺輸出


        圖3.2 light GET方法輸出

        3.2 JSON格式Demo
        指令
        coap get coap://10.13.11.116/test_json
        返回
        (2.05)
        {
        "value": 12
        }
        控制臺輸出


        圖3.3 JSON格式測試輸出

        4.CoAP格式分析
        通過示例代碼并借助wireshark可分析CoAP數據包的各個部分,可加上CoAP協議的理解。wireshark中已經支持CoAP協議,在過濾窗口中輸入coap便可抓取所有coap數據包。
        CoAP協議的分析請參考——【CoAP學習筆記——CoAP格式詳解】

        圖4.1 wireshark分析CoAP

        5. 總結
        microcoap正如它的名稱一樣,簡單好用,函數不多但是可以實現最基本的功能。(by xukai871105)



        關鍵詞: STM32平臺CoAPServe

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 宁晋县| 旬阳县| 田林县| 富阳市| 怀来县| 河北区| 襄樊市| 大城县| 石景山区| 甘泉县| 桦南县| 渝北区| 那坡县| 安多县| 九龙城区| 广平县| 密云县| 卓资县| 大连市| 龙岩市| 根河市| 马公市| 原平市| 保定市| 通海县| 宁阳县| 土默特右旗| 邵阳市| 普陀区| 庆阳市| 新宁县| 洮南市| 玉溪市| 阿鲁科尔沁旗| 鸡泽县| 吉安县| 英德市| 镇坪县| 宁武县| 晋城| 铁岭县|