OneNET定位为PaaS服务,即在物联网应用和真实设备之间搭建高效、稳定、安全的应用平台:面向设备,适配多种网络环境和常见传输协议,提供各类硬件终端的快速接入方案和设备管理服务;面向应用层,提供丰富的API和数据分发能力以满足各类行业应用系统的开发需求,使物联网企业可以更加专注于自身应用的开发,而不用将工作重心放在设备接入层的环境搭建上,从而缩短物联网系统的形成周期,降低企业研发、运营和运维成本。 物联网是把生活中各种物品通过各种元器件,传感器等连接在一起的网络。这个网络具备观察性和可控性,我们可以通过这个网络知道其中各个物品的状态,同时可以控制他们。 物联网可以分为三层,感知层、网络层、应用层。其中感知层可以通过传感器,执行器等元器件与环境进行互动。网络层指起到数据存储于管理功能的那一部分,其可以把各种数据按照特定标准进行存储,便于应用层调取。应用层是用户与网络层的接口,一方面把数据以特定形式展现给用户,一方面存储用户的指令,以备感知层调用。 OneNET平台具备网络层和应用层的功能,它可以把Arduino传感器采集的数据存储在自己的服务器上,同时可以在设计应用的时候调用这些数据。 OneNET平台是中国移动开发的物联网平台,稳定性非常好,上手容易。 1)进入OneNET官网(“https://open.iot.10086.cn/”)注册账号 2)注册完成后在首页右上角点击「开发者中心」进入产品开发界面 2.1 创建产品 进入产品开发界面后,选择左侧菜单栏中【全部产品】-【基础服务】。基础服务中有: 【多协议接入】-【HTTP】-【添加产品】 2.2 创建设备 创建产品后,点击左上角 【OneNet】 回到首页,单击进入产品 【HTTP】 OneNet上在项目下还有设备的概念,一个设备就相当于一块Arduino板。单击【设备列表】-【添加备】,在弹出的设备信息里可以随便填,对后面没有影响,唯一需要注意的是数据保密性这里,建议选择私有,如果选择公开,那后面你把这个项目发布的时候别人就能看的你的数据了。填完后单击添加即可完成创建。 选择【设备列表】-【添加设备】 Arduino发送给OneNET平台的数据可能有很多种,比如温度,湿度,光照强度等等。我们需要在OneNET上建立「变量」来存储这些数据,在OneNET上我们把这种变量叫做“ 数据流 ”。单击【数据流模板】-【添加数据流模板】,填入数据流名称即可得到一个存储数据的数据流。 2.4 创建应用 有了数据之后,我们需要把数据以一种特定形式呈现出来,比如用一个温度计显示实时温度,以一个折线图显示一段时间的温度趋势。肩负展示数据功能的是“应用”,就像我们平时在手机的“应用商店”里下载的那种应用一样,上面会有图标,图片等等。我们依次单击选择【应用管理】-【添加应用】 添加应用后,进入编辑应用界面如下: 参考资料 1.1 硬件 1.2 软件 Arduino 通过 ESP8266-01S 发送数据给 OneNet 平台的数据。ESP8266-01S 属于 安信可公司的产品,我们需要下载官网的安信可串口调试助手 查看返回的数据。 1.3 平台 OneNet服务器里有很多项目很多设备,具体把数据发到拿呢? 在正式开始前,我们需要记录设备的ID和密匙。设备ID可通过单击【设备列表】可在设备前面看到设备ID、密匙,在APIKey这一列的就是密匙。 另外,还需要自家的WiFi账号与密码接入网络。 2.1 ESP8266-01S AT指令手动联网 2.2 自动联网及接入设备 把AT指令写进程序让程序自动帮我们发送,并且链接到云平台,还要再实现设备和脚本的关联。 程序讲解参考一下视频连接,代码见文末附录。 安信可串口调试助手 OneNet 移动终端「设备云」效果界面展示,实现温湿度显示、开关控件控制pin13 板载 LED 的亮灭。 参考资料 附代码 ESP8266_EDP.ino EHT11.cpp EHT11.h edp.c
一、初识OneNet
1. 物联网与OneNet
使用方法:
小提示:零基础入,建议先别去网络上找找乱七八糟的文章学习,直接参考官方文档一步一步走就没那么多问题了。遇到实际问题后首先根据官方文档以及网上资料去解决。官方文档:【首页】-【服务与支持】- 【开发文档】- 【快速入门】2. OneNet快速入门
添加产品时,填写产品相关信息
【添加新设备】 – 设置设备名称、设备编号后,点击确认即可。
2.3 新建数据流
设置应用相关信息:名称、logo等。
设置应用界面组件以及组件的属性:
查看应用有两种方法:
二、Arduino + ESP8266 接入 OneNet
1.准备工作
ESP8266-01S
Arduno Uno
VCC&EN
3.3V
GND
GND
RX
TX (D1)
TX
RX(D0)
DHT11
Arduno Uno
VCC
3.3V /5V
GND
GND
OUT
D3
实际上OneNet平台对于发送过来的Json数据是有一定格式要求的,其中除了要传输的数据,还包含了设备ID、密匙,这样就可以保证数据发送到正确的设备。
597420765
vutzlt=cl9B99vnsozQcKSRSkNs=
(进入【设备列表】- 【设备详情】路径添加APIKey)
补充:按照前文的方法对 OneNet平台设置:创建产品(多协议接入 – edp)、创建设备、新建数据流(数据流的名称要与程序中的一致)、添加应用(注意开关控件的属性设置”switch:{V}“)
2.程序设计
/*************************************************** * * 名称:ESP8266 01S AT指令手动联网 * 作者:Naiva * 日期:2020/05/17 * 接线: * Arduino nano ESP8266 01S * D2(RX) ——— TX * D3(TX) ——— RX * VCC(3.3) ——— VCC(&EN) * GND ——— GND * ****************************************************/ #include<SoftwareSerial.h> SoftwareSerial mySerial(2,3);//RX ,TX wifiSerial void setup() { // put your setup code here, to run once: Serial.begin(115200); while (!Serial) { ; } Serial.println("ok"); mySerial.begin(115200); mySerial.println("ready"); } void loop() { // put your main code here, to run repeatedly: if(mySerial.available()) Serial.write(mySerial.read()); if(Serial.available()) mySerial.write(Serial.read()); }
while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式 while (!doCmdOk("AT+CWJAP="CMCC-R6Qs","qmt2fx3q"", "OK"));//WiFi账号与WiFi密码 while (!doCmdOk("AT+CIPSTART="TCP","jjfaedp.hedevice.com",876", "OK"));//链接到云平台,三个参数分别是接入协议,服务器地址和端口号 while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式 while (!doCmdOk("AT+CIPSEND", ">")); //开始发送
https://www.bilibili.com/video/BV1CE411h7hP?p=43.效果展示
实验过程中,一开始用的Arduino Nano 开发板,但后来可能因为开发板质量或接线的把板子烧坏了,电脑识别不了设备,于是我换了一块官网的Arduino Uno 正版开发板!
/*********************************************************** File name: ESP8266_EDP.ino Description: ESP8266 realizes remote control via ONENet Author: Naiva Date: 2020/05/17 ***********************************************************/ #include "edp.c" #include "DHT11.h" DHT11 dht11; #define DHT11PIN 3 //pin3 #define KEY "24eV33JUKr8dj=XGpckVygdFyJQ=" //APIkey #define ID "598229651" //设备ID //#define PUSH_ID "680788" #define PUSH_ID NULL String comdata = ""; // 串口 #define _baudrate 115200 #define WIFI_UART Serial int DHT11 = 0; const int stbPin = 7; //the segment display module STB pin connected to digital pin 7 const int clkPin = 9; //the segment display module CLK pin connected to digital pin 9 const int dioPin = 8; //the segment display module DIO pin connected to digital pin 8 uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; edp_pkt *pkt; /* * doCmdOk * 发送命令至模块,从回复中获取期待的关键字 * keyword: 所期待的关键字 * 成功找到关键字返回true,否则返回false */ bool doCmdOk(String data, char *keyword) { bool result = false; if (data != "") //对于tcp连接命令,直接等待第二次回复 { WIFI_UART.println(data); //发送AT指令 } if (data == "AT") //检查模块存在 delay(2000); else while (!WIFI_UART.available()); // 等待模块回复 delay(200); if (WIFI_UART.find(keyword)) //返回值判断 { result = true; } else { result = false; } while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存 delay(500); //指令时间间隔 return result; } void sendCommand(uint8_t value) { digitalWrite(stbPin, LOW); //pin low. To begin receiving data shiftOut(dioPin, clkPin, LSBFIRST, value); //send data(value) to the segment display module digitalWrite(stbPin, HIGH); //pin high. Stop receiving data } void setup() { char buf[100] = {0}; int tmp; pinMode(13, OUTPUT); //WIFI模块指示灯 pinMode(8, OUTPUT); //用于连接EDP控制的发光二极管 WIFI_UART.begin( _baudrate ); pinMode(stbPin, OUTPUT); //initialize the stbPin as an output 数码管 pinMode(clkPin, OUTPUT); //initialize the clkPin as an output pinMode(dioPin, OUTPUT); //initialize the dioPin as an output sendCommand(0x8f); //activate WIFI_UART.setTimeout(3000); //设置find超时时间 delay(3000); Serial.setTimeout(100); delay(2000); while (!doCmdOk("AT", "OK")); digitalWrite(13, HIGH); // 使Led亮 while (!doCmdOk("AT+CWMODE=3", "OK")); //工作模式 while (!doCmdOk("AT+CWJAP="CMCC-R6Qs","qmt2fx3q"", "OK"));//WiFi账号与WiFi密码 while (!doCmdOk("AT+CIPSTART="TCP","jjfaedp.hedevice.com",876", "OK")); while (!doCmdOk("AT+CIPMODE=1", "OK")); //透传模式 while (!doCmdOk("AT+CIPSEND", ">")); //开始发送 } int dht_flag = 1; void loop() { static int edp_connect = 0; bool trigger = false; edp_pkt rcv_pkt; unsigned char pkt_type; int i = 0, tmp; char num[10]; int wd,sd; char wd1[20],sd1[20]; /* EDP 连接 */ if (!edp_connect) { while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存 packetSend(packetConnect(ID, KEY)); //发送EPD连接包 while (!WIFI_UART.available()); //等待EDP连接应答 if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 ) { rcvDebug(rcv_pkt.data, tmp); if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00) { edp_connect = 1; digitalWrite(13, LOW); // 使Led灭 } else ; } packetClear(&rcv_pkt); } if(dht_flag == 1) { dht_flag = 0; dht11.read(DHT11PIN);//温湿度 wd = dht11.temperature; sd = dht11.humidity; sprintf(wd1,"%d",wd); //int型转换char型 sprintf(sd1,"%d",sd); //int型转换char型 DHT11 = 0; delay(500); packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流 WD是上传的地方 wd1是上传的数据 delay(500); packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流 delay(500); } DHT11++; if(DHT11 > 150&&edp_connect) { dht11.read(DHT11PIN); wd = dht11.temperature; sd = dht11.humidity; sprintf(wd1,"%d",wd); //int型转换char型 sprintf(sd1,"%d",sd); //int型转换char型 DHT11 = 0; delay(500); packetSend(packetDataSaveTrans(NULL, "WD", wd1)); //将新数据值上传至数据流 delay(500); packetSend(packetDataSaveTrans(NULL, "SD", sd1)); //将新数据值上传至数据流 delay(500); } while (WIFI_UART.available()) { readEdpPkt(&rcv_pkt); if (isEdpPkt(&rcv_pkt)) { pkt_type = rcv_pkt.data[0]; switch (pkt_type) { case CMDREQ: char edp_command[50]; char edp_cmd_id[40]; long id_len, cmd_len, rm_len; char datastr[20]; char val[10]; memset(edp_command, 0, sizeof(edp_command)); memset(edp_cmd_id, 0, sizeof(edp_cmd_id)); edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len); //数据处理与应用中EDP命令内容对应 //本例中格式为 datastream:[1/0] sscanf(edp_command, "%[^:]:%s", datastr, val); if (atoi(val) == 1) // 使Led亮 digitalWrite(13, HIGH); //digitalWrite(8, HIGH); else digitalWrite(13, LOW); // 使Led灭 //digitalWrite(8, HIGH); if(atoi(val) > 1) { sendCommand(0x40); //setting the Write Data Command,using automatic address genuine. digitalWrite(stbPin, LOW); //pin low. To begin receiving data shiftOut(dioPin, clkPin, LSBFIRST, 0xc0); //Set the start address 0C0H if(atoi(val) >= 100 && atoi(val) <=1000) { shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/100%10]); //hundred data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data } else if(atoi(val) >= 10 && atoi(val) <=100) { shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)/10%10]); //ten data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data } else if(atoi(val) > 0 && atoi(val) <=10) { shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //ten data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data shiftOut(dioPin, clkPin, LSBFIRST, digits[atoi(val)%10]); //bit data shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data } digitalWrite(stbPin, HIGH); delay(500); } //pin high. Stop receiving data packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流 break; default: ; break; } } //delay(4); } if (rcv_pkt.len > 0) packetClear(&rcv_pkt); delay(150); } /* * readEdpPkt * 从串口缓存中读数据到接收缓存 */ bool readEdpPkt(edp_pkt *p) { int tmp; if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 ) { rcvDebug(p->data + p->len, tmp); p->len += tmp; } return true; } /* * packetSend * 将待发数据发送至串口,并释放到动态分配的内存 */ void packetSend(edp_pkt* pkt) { if (pkt != NULL) { WIFI_UART.write(pkt->data, pkt->len); //串口发送 WIFI_UART.flush(); free(pkt); //回收内存 } } void rcvDebug(unsigned char *rcv, int len) { int i; }
/* File name: EHT11.cpp */ #include "DHT11.h" // Return values: // DHTLIB_OK // DHTLIB_ERROR_CHECKSUM // DHTLIB_ERROR_TIMEOUT int DHT11::read(int pin) { // BUFFER TO RECEIVE uint8_t bits[5]; uint8_t cnt = 7; uint8_t idx = 0; // EMPTY BUFFER for (int i=0; i< 5; i++) bits[i] = 0; // REQUEST SAMPLE pinMode(pin, OUTPUT); digitalWrite(pin, LOW); delay(18); digitalWrite(pin, HIGH); delayMicroseconds(40); pinMode(pin, INPUT); // ACKNOWLEDGE or TIMEOUT unsigned int loopCnt = 10000; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; loopCnt = 10000; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT for (int i=0; i<40; i++) { loopCnt = 10000; while(digitalRead(pin) == LOW) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; unsigned long t = micros(); loopCnt = 10000; while(digitalRead(pin) == HIGH) if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT; if ((micros() - t) > 40) bits[idx] |= (1 << cnt); if (cnt == 0) // next byte? { cnt = 7; // restart at MSB idx++; // next byte! } else cnt--; } // WRITE TO RIGHT VARS // as bits[1] and bits[3] are allways zero they are omitted in formulas. humidity = bits[0]; temperature = bits[2]; uint8_t sum = bits[0] + bits[2]; if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM; return DHTLIB_OK; }
/* /* File name: EHT11.h */ */ #ifndef DHT11_H #define DHT11_H #if defined(ARDUINO) && (ARDUINO >= 100) #include <Arduino.h> #else #include <WProgram.h> #endif #define DHT11LIB_VERSION "V1.0" #define DHTLIB_OK 0 #define DHTLIB_ERROR_CHECKSUM -1 #define DHTLIB_ERROR_TIMEOUT -2 class DHT11 { public: int read(int pin); int humidity; int temperature; }; #endif
/* File name: edp.c */ #include <string.h> #include <stdio.h> #include <stdlib.h> #define CONNREQ 0x10 #define CONNRESP 0x20 #define PUSHDATA 0x30 #define SAVEDATA 0x80 #define SAVEACK 0x90 #define CMDREQ 0xA0 #define CMDRESP 0xB0 #define PINGREQ 0xC0 #define PINGRESP 0xD0 #define ENCRYPTREQ 0xE0 #define ENCRYPTRESP 0xF0 #define MAX_LEN 200 #define PROTOCOL_NAME "EDP" #define PROTOCOL_VERSION 1 typedef unsigned char uint8; typedef char int8; typedef unsigned int uint16; typedef int int16; typedef unsigned long uint32; typedef long int32; typedef struct { uint8 data[MAX_LEN]; int16 len; int16 read_p; } edp_pkt; /* * packetCreate * 创建一个EDP包缓存空间 */ edp_pkt *packetCreate(void) { edp_pkt *p; if((p = (edp_pkt *)malloc(sizeof(edp_pkt))) != NULL) memset(p, 0, sizeof(edp_pkt)); return p; } /* * writeRemainlen * 向EDP包中写入剩余长度字段 * len_val: 剩余长度的值 */ int8 writeRemainlen(edp_pkt* pkt, int16 len_val) { int8 remaining_count = 0; int8 tmp = 0; do { tmp = len_val % 128; len_val = len_val / 128; /* If there are more digits to encode, set the top bit of this digit */ if (len_val > 0) { tmp = tmp | 0x80; } pkt->data[pkt->len++] = tmp; remaining_count++; } while (len_val > 0 && remaining_count < 5); return remaining_count; } /* * writeByte * 向EDP包中写入一个字节 */ int16 writeByte(edp_pkt* pkt, int8 byte) { pkt->data[pkt->len++] = byte; return 0; } /* * writeBytes * 向EDP包中写入多个字节 */ int16 writeBytes(edp_pkt* pkt, const void* bytes, int16 count) { memcpy(pkt->data + pkt->len, bytes, count); pkt->len += count; return 0; } /* * writeStr * 向EDP包中写入字符串字段 * 首先写入两个字节的长度,随后紧跟字符串内容 */ int16 writeStr(edp_pkt* pkt, const int8* str) { short len = strlen(str); writeByte(pkt, len >> 8); writeByte(pkt, len & 0x00ff); memcpy(pkt->data + pkt->len, str, len); pkt->len += len; return 0; } /*---------------------------------------------------------------------------*/ /* * readUint8 * 从EDP包中读出一个字节 */ uint8 readUint8(edp_pkt* pkt) { return pkt->data[pkt->read_p++]; } /* * readUint16 * 从EDP包中读出16bit的字段 */ uint16 readUint16(edp_pkt* pkt) { uint16 tmp; uint8 msb, lsb; msb = readUint8(pkt); lsb = readUint8(pkt); tmp = (msb<<8) | lsb; return tmp; } /* * readUint32 * 从EDP包中读出4个字节的字段 */ uint32 readUint32(edp_pkt* pkt) { uint32 tmp = 0; int i = 4; while (--i >= 0) { tmp <<= 8; tmp |= readUint8(pkt); } return tmp; } /* * readStr * 根据长度,从EDP包中读出字符串数据 * len : 字符串的长度 */ void readStr(edp_pkt* pkt, char* str, uint16 len) { memcpy(str, pkt->data + pkt->read_p, len); pkt->read_p += len; } /* * readRemainlen * 从EDP包中读出剩余长度 */ int32 readRemainlen(edp_pkt* pkt) { uint32 multiplier = 1; uint32 len_len = 0; uint8 onebyte = 0; int32 len_val = 0; do { onebyte = readUint8(pkt); len_val += (onebyte & 0x7f) * multiplier; multiplier *= 0x80; len_len++; if (len_len > 4) { return -1; /*len of len more than 4;*/ } } while((onebyte & 0x80) != 0); return len_val; } /* * packetConnect:组EDP连接包 * 首先创建EDP缓存空间,按照EDP协议组EDP连接包 * 分配的内存需要在发送之后free掉 * devid: 设备id * key:APIKey */ edp_pkt *packetConnect(const int8* devid, const int8* key) { int32 remainlen; edp_pkt* pkt; if((pkt = packetCreate()) == NULL) return NULL; /* msg type */ writeByte(pkt, CONNREQ); /* remain len */ remainlen = (2 + 3) + 1 + 1 + 2 + (2 + strlen(devid)) + (2 + strlen(key)); writeRemainlen(pkt, remainlen); /* protocol desc */ writeStr(pkt, PROTOCOL_NAME); /* protocol version */ writeByte(pkt, PROTOCOL_VERSION); /* connect flag */ writeByte(pkt, 0x40); /* keep time */ writeByte(pkt, 0); writeByte(pkt, 0x80); /* DEVID */ writeStr(pkt, devid); /* auth key */ writeStr(pkt, key); return pkt; } /* * packetDataSaveTrans:组EDP数据存储转发包 * 首先创建EDP缓存空间,按照EDP协议组EDP数据存储转发包 * 分配的内存需要在发送之后free掉 * devid: 设备id * streamId:数据流ID,即数据流名 * val: 字符串形式的数据值 */ edp_pkt *packetDataSaveTrans(const int8* destId, const int8* streamId, const int8 *val) { int32 remainlen; int8 tmp[200]; int16 str_len; edp_pkt *pkt; if((pkt = packetCreate()) == NULL) return pkt; /* 生成数据类型格式5的数据类型 */ sprintf(tmp, ",;%s,%s", streamId, val); str_len = strlen(tmp); /* msg type */ writeByte(pkt, SAVEDATA); if (destId != NULL) { /* remain len */ remainlen = 1 + (2 + strlen(destId)) + 1 + (2 + str_len); writeRemainlen(pkt, remainlen); /* translate address flag */ writeByte(pkt, 0x80); /* dst devid */ writeStr(pkt, destId); } else { /* remain len */ remainlen = 1 + 1 + (2 + str_len); writeRemainlen(pkt, remainlen); /* translate address flag */ writeByte(pkt, 0x00); } /* json flag */ writeByte(pkt, 5); /* json */ writeStr(pkt, tmp); return pkt; } void packetClear(edp_pkt* pkt) { memset(pkt, 0, sizeof(edp_pkt)); } /* * isEdpPkt * 按照EDP数据格式,判断是否是完整数据包 */ int16 isEdpPkt(edp_pkt* pkt) { uint32 data_len = 0; uint32 multiplier = 1; uint32 len_val = 0; uint32 len_len = 1; uint32 pkt_total_len = 0; uint8* pdigit; pdigit = pkt->data; data_len = pkt->len; if (data_len <= 1) { return 0; /* continue receive */ } do { if (len_len > 4) { return -1; /* protocol error; */ } if (len_len > data_len - 1) { return 0; /* continue receive */ } len_len++; pdigit++; len_val += ((*pdigit) & 0x7f) * multiplier; multiplier *= 0x80; } while (((*pdigit) & 0x80) != 0); pkt_total_len = len_len + len_val; /* receive payload */ if (pkt_total_len == data_len) { return 1; /* all data for this pkt is read */ } else { return 0; /* continue receive */ } } /* * edpCommandReqParse * 按照EDP命令请求协议,解析数据 */ int edpCommandReqParse(edp_pkt* pkt, char *id, char *cmd, int32 *rmlen, int32 *id_len, int32 *cmd_len) { readUint8(pkt); /* 包类型 */ *rmlen = readRemainlen(pkt); /* 剩余长度 */ *id_len = readUint16(pkt); /* ID长度 */ readStr(pkt, id, *id_len); /* 命令ID */ *cmd_len = readUint32(pkt); /* 命令长度 */ readStr(pkt, cmd, *cmd_len); /* 命令内容 */ } /* * edpPushDataParse * 按照EDP透传数据格式,解析数据 */ int edpPushDataParse(edp_pkt* pkt, char *srcId, char *data) { uint32 remain_len; uint16 id_len; readUint8(pkt); /* 包类型 */ remain_len = readRemainlen(pkt); /* 剩余长度 */ id_len = readUint16(pkt); /* 源ID长度 */ readStr(pkt, srcId, id_len); /* 源ID */ readStr(pkt, data, remain_len - 2 - id_len); /* 数据内容 */ }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算