EDP KIT from OneNet
Dependents: 8-0_OneNet_IoT_demo STM32F103C8T6_OneNet_IoT
Revision 0:79de700849c5, committed 2017-03-29
- Comitter:
- TaylorGy
- Date:
- Wed Mar 29 03:07:27 2017 +0000
- Commit message:
- EDP KIT from OneNet
Changed in this revision
EdpKit.cpp | Show annotated file Show diff for this revision Revisions of this file |
EdpKit.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 79de700849c5 EdpKit.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EdpKit.cpp Wed Mar 29 03:07:27 2017 +0000 @@ -0,0 +1,1039 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <assert.h> +#include "EdpKit.h" + +#define MKFUN_PACKET_SAVE_DATA(TYPE, NAME) \ + EdpPacket* PacketSavedata##NAME(SaveDataType type, \ + const char* dst_devid, \ + const char* ds_id, \ + TYPE value, \ + time_t at, \ + const char* token){ \ + EdpPacket* pkg = NULL; \ + switch (type){ \ + case kTypeFullJson: \ + pkg = PacketSavedataType1##NAME(dst_devid, ds_id, \ + value, at, token); \ + break; \ + case kTypeSimpleJsonWithoutTime: \ + pkg = PacketSavedataType2##NAME(dst_devid, ds_id, \ + value, at, token); \ + break; \ + case kTypeSimpleJsonWithTime: \ + pkg = PacketSavedataType3##NAME(dst_devid, ds_id, \ + value, at, token); \ + break; \ + default: \ + break; \ + } \ + \ + return pkg; \ +} + +#define MKFUN_PACKET_SAVE_DATA_TYPE1(TYPE, NAME, MED) \ + static EdpPacket* PacketSavedataType1##NAME(const char* dst_devid, \ + const char* ds_id, \ + TYPE value, \ + time_t at, \ + const char* token){ \ + cJSON* json_obj = NULL; \ + cJSON* ds_array = NULL; \ + cJSON* json_obj_ds = NULL; \ + cJSON* dp_array = NULL; \ + cJSON* dp_item = NULL; \ + char ss[100] = {0}; \ + EdpPacket* pkg = NULL; \ + \ + json_obj = cJSON_CreateObject(); \ + \ + if(token) { \ + cJSON_AddStringToObject(json_obj, "token", token); \ + } \ + \ + ds_array = cJSON_CreateArray(); \ + json_obj_ds = cJSON_CreateObject(); \ + \ + cJSON_AddStringToObject(json_obj_ds, "id", ds_id); \ + \ + dp_array = cJSON_CreateArray(); \ + dp_item = cJSON_CreateObject(); \ + \ + FormatAt(ss, 100, at); \ + cJSON_AddStringToObject(dp_item, "at", ss); \ + cJSON_Add##MED##ToObject(dp_item, "value", value); \ + cJSON_AddItemToArray(dp_array, dp_item); \ + \ + cJSON_AddItemToObject(json_obj_ds, "datapoints", dp_array); \ + cJSON_AddItemToArray(ds_array, json_obj_ds); \ + cJSON_AddItemToObject(json_obj, "datastreams", ds_array); \ + \ + pkg = PacketSavedataJson(dst_devid, json_obj, \ + kTypeFullJson); \ + cJSON_Delete(json_obj); \ + \ + return pkg; \ +} + +#define MKFUN_PACKET_SAVE_DATA_TYPE2(TYPE, NAME, MED) \ + static EdpPacket* PacketSavedataType2##NAME(const char* dst_devid, \ + const char* ds_id, \ + TYPE value, \ + time_t at, \ + const char* token) \ + { \ + cJSON* json_obj = NULL; \ + EdpPacket* pkg = NULL; \ + \ + json_obj = cJSON_CreateObject(); \ + cJSON_Add##MED##ToObject(json_obj, ds_id, value); \ + \ + pkg = PacketSavedataJson(dst_devid, json_obj, \ + kTypeSimpleJsonWithoutTime); \ + cJSON_Delete(json_obj); \ + \ + return pkg; \ +} + + +#define MKFUN_PACKET_SAVE_DATA_TYPE3(TYPE, NAME, MED) \ + static EdpPacket* PacketSavedataType3##NAME(const char* dst_devid, \ + const char* ds_id, \ + TYPE value, \ + time_t at, \ + const char* token){ \ + cJSON* json_obj = NULL; \ + cJSON* json_obj_ds = NULL; \ + char ss[100] = {0}; \ + EdpPacket* pkg = NULL; \ + \ + json_obj = cJSON_CreateObject(); \ + FormatAt(ss, 100, at); \ + json_obj_ds = cJSON_CreateObject(); \ + cJSON_Add##MED##ToObject(json_obj_ds, ss, value); \ + cJSON_AddItemToObject(json_obj, ds_id, json_obj_ds); \ + \ + pkg = PacketSavedataJson(dst_devid, json_obj, \ + kTypeSimpleJsonWithTime); \ + cJSON_Delete(json_obj); \ + \ + return pkg; \ +} + +#define MKFUN_UNPACK_SAVE_DATA(TYPE, NAME) \ + int32 UnpackSavedata##NAME(SaveDataType type, \ + EdpPacket* pkg, \ + char** ds_id, \ + TYPE* value) \ + { \ + int ret = -1; \ + switch (type){ \ + case kTypeFullJson: \ + ret = UnpackSavedataType1##NAME(pkg, ds_id, value); \ + break; \ + case kTypeSimpleJsonWithoutTime: \ + ret = UnpackSavedataType2##NAME(pkg, ds_id, value); \ + break; \ + case kTypeSimpleJsonWithTime: \ + ret = UnpackSavedataType3##NAME(pkg, ds_id, value); \ + break; \ + default: \ + break; \ + } \ + \ + return ret; \ +} + +#define MKFUN_UNPACK_SAVE_DATA_TYPE1(TYPE, NAME, MED) \ + static int32 UnpackSavedataType1##NAME(EdpPacket* pkg, \ + char** ds_id, \ + TYPE* value) \ + { \ + cJSON* json_obj = NULL; \ + cJSON* ds_array = NULL; \ + cJSON* ds_item = NULL; \ + char* id = NULL; \ + cJSON* dp_array = NULL; \ + cJSON* dp_item = NULL; \ + char* valuestring = NULL; \ + \ + if(0 != UnpackSavedataJson(pkg, &json_obj)) \ + return ERR_UNPACK_SAVED_JSON; \ + \ + ds_array = cJSON_GetObjectItem(json_obj, "datastreams"); \ + if((0 == ds_array) || (1 != cJSON_GetArraySize(ds_array))) \ + return ERR_UNPACK_SAVED_JSON; \ + \ + ds_item = cJSON_GetArrayItem(ds_array, 0); \ + if(0 == ds_item) \ + return ERR_UNPACK_SAVED_JSON; \ + \ + id = cJSON_GetObjectItem(ds_item, "id")->valuestring; \ + *ds_id = (char*)malloc(strlen(id)+1); \ + memcpy((char*)(*ds_id), id, strlen(id)+1); \ + \ + dp_array = cJSON_GetObjectItem(ds_item, "datapoints"); \ + if((0 == dp_array) || (1 != cJSON_GetArraySize(dp_array))) \ + return ERR_UNPACK_SAVED_JSON; \ + \ + dp_item = cJSON_GetArrayItem(dp_array, 0); \ + + +#define UNPACK_SAVE_DATA_TYPE1_END_STRING \ + valuestring = cJSON_GetObjectItem(dp_item, "value")->valuestring; \ + *value = (char*)malloc(strlen(valuestring)+1); \ + memcpy((char*)(*value), valuestring, strlen(valuestring)+1); \ + cJSON_Delete(json_obj); \ + return 0; \ +} + +#define UNPACK_SAVE_DATA_TYPE1_END_NUMBER(TYPE) \ + *value = cJSON_GetObjectItem(dp_item, "value")->value##TYPE; \ + cJSON_Delete(json_obj); \ + return 0; \ +} + +#define MKFUN_UNPACK_SAVE_DATA_TYPE2(TYPE, NAME, MED) \ + static int32 UnpackSavedataType2##NAME(EdpPacket* pkg, \ + char** ds_id, \ + TYPE* value) \ + { \ + cJSON* json_obj = NULL; \ + cJSON* json_child = NULL; \ + size_t len = 0; \ + char* valuestring = NULL; \ + \ + if(0 != UnpackSavedataJson(pkg, &json_obj)) \ + return ERR_UNPACK_SAVED_JSON; \ + if (!json_obj->child){ \ + cJSON_Delete(json_obj); \ + return ERR_UNPACK_SAVED_JSON; \ + } \ + json_child = json_obj->child; \ + len = strlen(json_child->string) + 1; \ + *ds_id = (char*)malloc(len); \ + memcpy((char*)(*ds_id), json_child->string, len); \ + +#define UNPACK_SAVE_DATA_TYPE23_END_NUMBER(TYPE) \ + *value = json_child->value##TYPE; \ + cJSON_Delete(json_obj); \ + return 0; \ +} + +#define UNPACK_SAVE_DATA_TYPE23_END_STRING() \ + valuestring = json_child->valuestring; \ + *value = (char*)malloc(strlen(valuestring)+1); \ + memcpy((char*)(*value), valuestring, strlen(valuestring)+1); \ + cJSON_Delete(json_obj); \ + return 0; \ +} + +#define MKFUN_UNPACK_SAVE_DATA_TYPE3(TYPE, NAME, MED) \ + static int32 UnpackSavedataType3##NAME(EdpPacket* pkg, \ + char** ds_id, \ + TYPE* value) \ +{ \ + cJSON* json_obj = NULL; \ + cJSON* json_child = NULL; \ + char* valuestring = NULL; \ + size_t len = 0; \ + \ + if(0 != UnpackSavedataJson(pkg, &json_obj)) \ + return ERR_UNPACK_SAVED_JSON; \ + \ + json_child = json_obj->child; \ + if (!json_child || !json_child->string){ \ + cJSON_Delete(json_obj); \ + return ERR_UNPACK_SAVED_JSON; \ + } \ + \ + len = strlen(json_child->string) + 1; \ + *ds_id = (char*)malloc(len); \ + memcpy(*ds_id, json_child->string, len); \ + \ + json_child = json_child->child; \ + if (!json_child){ \ + cJSON_Delete(json_obj); \ + return ERR_UNPACK_SAVED_JSON; \ + } + + +static void FormatAt(char* buffer, int len, time_t now) +{ + struct tm timinfo; + + if (now == 0){ + now = 0; //time(0); + } + +#if defined(linux) || defined(__linux) || defined(__linux__) + strftime(buffer, len, "%F %T", localtime_r(&now, &timinfo)); +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + localtime_s(&timinfo, &now); + strftime(buffer, len, "%F %T", &timinfo); +#endif +} + +/*---------------------------------------------------------------------------*/ +Buffer* NewBuffer() +{ + Buffer* buf = (Buffer*)malloc(sizeof(Buffer)); + buf->_data = (uint8*)malloc(sizeof(uint8) * BUFFER_SIZE); + buf->_write_pos = 0; + buf->_read_pos = 0; + buf->_capacity = BUFFER_SIZE; + return buf; +} + +void DeleteBuffer(Buffer** buf) +{ + uint8* pdata = (*buf)->_data; + free(pdata); + free(*buf); + *buf = 0; +} + +int32 CheckCapacity(Buffer* buf, uint32 len) +{ + uint32 cap_len = buf->_capacity; + int32 flag = 0; + uint8* pdata = NULL; + + while (cap_len - buf->_write_pos < len) /* remain len < len */ + { + cap_len = cap_len << 1; + if (++flag > 32) + break; /* overflow */ + } + if (flag > 32) + return -1; + if (cap_len > buf->_capacity) + { + pdata = (uint8*)malloc(sizeof(uint8) * cap_len); + memcpy(pdata, buf->_data, buf->_write_pos); + free(buf->_data); + buf->_data = pdata; + buf->_capacity = cap_len; + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +int32 ReadByte(EdpPacket* pkg, uint8* val) +{ + if (pkg->_read_pos+1 > pkg->_write_pos) + return -1; + *val = pkg->_data[pkg->_read_pos]; + pkg->_read_pos += 1; + return 0; +} + +int32 ReadBytes(EdpPacket* pkg, uint8** val, uint32 count) +{ + if (pkg->_read_pos+count > pkg->_write_pos) + return -1; + *val = (uint8*)malloc(sizeof(uint8) * count); + memcpy(*val, pkg->_data + pkg->_read_pos, count); + pkg->_read_pos += count; + return 0; +} + +int32 ReadUint16(EdpPacket* pkg, uint16* val) +{ + uint8 msb, lsb; + if (pkg->_read_pos+2 > pkg->_write_pos) + return -1; + msb = pkg->_data[pkg->_read_pos]; + pkg->_read_pos++; + lsb = pkg->_data[pkg->_read_pos]; + pkg->_read_pos++; + *val = (msb<<8) + lsb; + return 0; +} + +int32 ReadUint32(EdpPacket* pkg, uint32* val) +{ + int32 i = 0; + uint32 tmpval = 0; + if (pkg->_read_pos+4 > pkg->_write_pos) + return -1; + while (i++ < 4) { + tmpval = (tmpval << 8) | (pkg->_data[pkg->_read_pos]); + pkg->_read_pos++; + } + *val = tmpval; + return 0; +} + +int32 ReadStr(EdpPacket* pkg, char** val) +{ + uint16 len = 0; + int rc = 0; + /* read str len */ + rc = ReadUint16(pkg, &len); + if (rc) + return rc; + if (pkg->_read_pos+len > pkg->_write_pos) + return -1; + /* copy str val */ + *val = (char*)malloc(sizeof(char) * (len + 1)); + memset(*val, 0, len+1); + strncpy(*val, (const char *)(pkg->_data + pkg->_read_pos), len); + pkg->_read_pos += len; + return 0; +} + +int32 ReadRemainlen(EdpPacket* pkg, uint32* len_val) +{ + uint32 multiplier = 1; + uint32 len_len = 0; + uint8 onebyte = 0; + int32 rc; + *len_val = 0; + do { + rc = ReadByte(pkg, &onebyte); + if (rc) + return rc; + + *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 0; +} + +/*---------------------------------------------------------------------------*/ +int32 WriteByte(Buffer* buf, uint8 byte) +{ + assert(buf->_read_pos == 0); + if (CheckCapacity(buf, 1)) + return -1; + buf->_data[buf->_write_pos] = byte; + buf->_write_pos++; + return 0; +} + +int32 WriteBytes(Buffer* buf, const void* bytes, uint32 count) +{ + assert(buf->_read_pos == 0); + if (CheckCapacity(buf, count)) + return -1; + memcpy(buf->_data + buf->_write_pos, bytes, count); + buf->_write_pos += count; + return 0; +} + +int32 WriteUint16(Buffer* buf, uint16 val) +{ + assert(buf->_read_pos == 0); + return WriteByte(buf, MOSQ_MSB(val)) + || WriteByte(buf, MOSQ_LSB(val)); +} + +int32 WriteUint32(Buffer* buf, uint32 val) +{ + assert(buf->_read_pos == 0); + return WriteByte(buf, (val >> 24) & 0x00FF) + || WriteByte(buf, (val >> 16) & 0x00FF) + || WriteByte(buf, (val >> 8) & 0x00FF) + || WriteByte(buf, (val) & 0x00FF); +} + +int32 WriteStr(Buffer* buf, const char *str) +{ + uint16 length = 0; + assert(buf->_read_pos == 0); + length = strlen(str); + return WriteUint16(buf, length) + || WriteBytes(buf, str, length); +} + +int32 WriteRemainlen(Buffer* buf, uint32 len_val) +{ + uint32 remaining_length = len_val; + int32 remaining_count = 0; + uint8 byte = 0; + + assert(buf->_read_pos == 0); + + do { + byte = remaining_length % 128; + remaining_length = remaining_length / 128; + /* If there are more digits to encode, set the top bit of this digit */ + if (remaining_length > 0) { + byte = byte | 0x80; + } + buf->_data[buf->_write_pos++] = byte; + remaining_count++; + }while(remaining_length > 0 && remaining_count < 5); + assert(remaining_count != 5); + return 0; +} + +/*---------------------------------------------------------------------------*/ +/* connect1 (C->S): devid + apikey */ +EdpPacket* PacketConnect1(const char* devid, const char* auth_key) +{ + EdpPacket* pkg = NewBuffer(); + uint32 remainlen; + /* msg type */ + WriteByte(pkg, CONNREQ); + /* remain len */ + remainlen = (2+3)+1+1+2+(2+strlen(devid))+(2+strlen(auth_key)); + WriteRemainlen(pkg, remainlen); + /* protocol desc */ + WriteStr(pkg, PROTOCOL_NAME); + /* protocol version */ + WriteByte(pkg, PROTOCOL_VERSION); + /* connect flag */ + WriteByte(pkg, 0x40); + /* keep time */ + WriteUint16(pkg, 0x0080); + /* DEVID */ + WriteStr(pkg, devid); + /* auth key */ + WriteStr(pkg, auth_key); + return pkg; +} + +/* connect2 (C->S): userid + auth_info */ +EdpPacket* PacketConnect2(const char* userid, const char* auth_info) +{ + EdpPacket* pkg = NULL; + uint32 remainlen; + + pkg = NewBuffer(); + /* msg type */ + WriteByte(pkg, CONNREQ); + /* remain len */ + remainlen = (2+3)+1+1+2+2+(2+strlen(userid))+(2+strlen(auth_info)); + WriteRemainlen(pkg, remainlen); + /* protocol desc */ + WriteStr(pkg, PROTOCOL_NAME); + /* protocol version */ + WriteByte(pkg, PROTOCOL_VERSION); + /* connect flag */ + WriteByte(pkg, 0xC0); + /* keep time */ + WriteUint16(pkg, 0x0080); + /* devid */ + WriteByte(pkg, 0x00); + WriteByte(pkg, 0x00); + /* USERID */ + WriteStr(pkg, userid); + /* auth info */ + WriteStr(pkg, auth_info); + return pkg; +} + +/* push_data (C->S) */ +EdpPacket* PacketPushdata(const char* dst_devid, const char* data, uint32 data_len) +{ + EdpPacket* pkg = NULL; + uint32 remainlen; + + pkg = NewBuffer(); + /* msg type */ + WriteByte(pkg, PUSHDATA); + /* remain len */ + remainlen = (2+strlen(dst_devid))+data_len; + WriteRemainlen(pkg, remainlen); + /* dst devid */ + WriteStr(pkg, dst_devid); + /* data */ + WriteBytes(pkg, data, data_len); + return pkg; +} + +/* sava_data (C->S) */ +EdpPacket* PacketSavedataJson(const char* dst_devid, cJSON* json_obj, int type) +{ + EdpPacket* pkg = NULL; + uint32 remainlen = 0; + char* json_out = NULL; + uint32 json_len = 0; + + pkg = NewBuffer(); + remainlen; + json_out = cJSON_Print(json_obj); + json_len = strlen(json_out); + + /* msg type */ + WriteByte(pkg, SAVEDATA); + if (dst_devid) + { + /* remain len */ + remainlen = 1+(2+strlen(dst_devid))+1+(2+json_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x80); + /* dst devid */ + WriteStr(pkg, dst_devid); + } + else + { + /* remain len */ + remainlen = 1+1+(2+json_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x00); + } + /* json flag */ + WriteByte(pkg, type); + /* json */ + WriteStr(pkg, json_out); + free(json_out); + return pkg; +} + +/* + * 定义3种JSON格式的打包和解包函数, + * 每种格式都支持int,double和char*三种类型 + */ +MKFUN_PACKET_SAVE_DATA_TYPE1(int, Int, Number) +MKFUN_PACKET_SAVE_DATA_TYPE1(double, Double, Number) +MKFUN_PACKET_SAVE_DATA_TYPE1(const char*, String, String) + +MKFUN_PACKET_SAVE_DATA_TYPE2(int, Int, Number) +MKFUN_PACKET_SAVE_DATA_TYPE2(double, Double, Number) +MKFUN_PACKET_SAVE_DATA_TYPE2(const char*, String, String) + +MKFUN_PACKET_SAVE_DATA_TYPE3(int, Int, Number) +MKFUN_PACKET_SAVE_DATA_TYPE3(double, Double, Number) +MKFUN_PACKET_SAVE_DATA_TYPE3(const char*, String, String) + +MKFUN_PACKET_SAVE_DATA(int, Int) +MKFUN_PACKET_SAVE_DATA(double, Double) +MKFUN_PACKET_SAVE_DATA(const char*, String) + +/* 解包函数 */ +MKFUN_UNPACK_SAVE_DATA_TYPE1(int, Int, Number) +UNPACK_SAVE_DATA_TYPE1_END_NUMBER(int) +MKFUN_UNPACK_SAVE_DATA_TYPE1(double, Double, Number) +UNPACK_SAVE_DATA_TYPE1_END_NUMBER(double) +MKFUN_UNPACK_SAVE_DATA_TYPE1(char*, String, String) +UNPACK_SAVE_DATA_TYPE1_END_STRING + +MKFUN_UNPACK_SAVE_DATA_TYPE2(int, Int, Number) +UNPACK_SAVE_DATA_TYPE23_END_NUMBER(int) +MKFUN_UNPACK_SAVE_DATA_TYPE2(double, Double, Number) +UNPACK_SAVE_DATA_TYPE23_END_NUMBER(double) +MKFUN_UNPACK_SAVE_DATA_TYPE2(char*, String, String) +UNPACK_SAVE_DATA_TYPE23_END_STRING() + +MKFUN_UNPACK_SAVE_DATA_TYPE3(int, Int, Number) +UNPACK_SAVE_DATA_TYPE23_END_NUMBER(int) +MKFUN_UNPACK_SAVE_DATA_TYPE3(double, Double, Number) +UNPACK_SAVE_DATA_TYPE23_END_NUMBER(double) +MKFUN_UNPACK_SAVE_DATA_TYPE3(char*, String, String) +UNPACK_SAVE_DATA_TYPE23_END_STRING() + +MKFUN_UNPACK_SAVE_DATA(int, Int) +MKFUN_UNPACK_SAVE_DATA(double, Double) +MKFUN_UNPACK_SAVE_DATA(char*, String) + +int32 UnpackSavedataAck(EdpPacket* pkg, char** json_ack){ + uint32 remainlen = 0; + uint8 flag = 0; + uint16 json_len = 0; + + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_SAVEDATA_ACK; + + if (ReadByte(pkg, &flag)) + return ERR_UNPACK_SAVEDATA_ACK; + + if (ReadUint16(pkg, &json_len)) + return ERR_UNPACK_SAVEDATA_ACK; + + if (ReadBytes(pkg, (uint8**)(json_ack), json_len)) + return ERR_UNPACK_SAVEDATA_ACK; + + return 0; +} + +/* sava_data bin (C->S) */ +EdpPacket* PacketSavedataBin(const char* dst_devid, + cJSON* desc_obj, const uint8* bin_data, uint32 bin_len) +{ + EdpPacket* pkg = NULL; + uint32 remainlen = 0; + char* desc_out = NULL; + uint32 desc_len = 0; + + /* check arguments */ + desc_out = cJSON_Print(desc_obj); + desc_len = strlen(desc_out); + if (desc_len > (0x01 << 16) || bin_len > (3 * (0x01 << 20)) + /* desc < 2^16 && bin_len < 3M*/ + || cJSON_GetObjectItem(desc_obj, "ds_id") == 0) + /* desc_obj MUST has ds_id */ + { + free(desc_out); + return 0; + } + pkg = NewBuffer(); + /* msg type */ + WriteByte(pkg, SAVEDATA); + if (dst_devid) + { + /* remain len */ + remainlen = 1+(2+strlen(dst_devid))+1+(2+desc_len)+(4+bin_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x80); + /* dst devid */ + WriteStr(pkg, dst_devid); + } + else + { + /* remain len */ + remainlen = 1+1+(2+desc_len)+(4+bin_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x00); + } + /* bin flag */ + WriteByte(pkg, 0x02); + /* desc */ + WriteStr(pkg, desc_out); + free(desc_out); + /* bin data */ + WriteUint32(pkg, bin_len); + WriteBytes(pkg, bin_data, bin_len); + return pkg; +} + +EdpPacket* PacketSavedataBinStr(const char* dst_devid, + const char* desc_str, const uint8* bin_data, uint32 bin_len) +{ + EdpPacket* pkg = NULL; + uint32 remainlen = 0; + uint32 desc_len = 0; + + /* check arguments */ + desc_len = strlen(desc_str); + if (desc_len > (0x01 << 16) || bin_len > (3 * (0x01 << 20))) + { /* desc < 2^16 && bin_len < 3M*/ + return 0; + } + pkg = NewBuffer(); + /* msg type */ + WriteByte(pkg, SAVEDATA); + if (dst_devid) + { + /* remain len */ + remainlen = 1+(2+strlen(dst_devid))+1+(2+desc_len)+(4+bin_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x80); + /* dst devid */ + WriteStr(pkg, dst_devid); + } + else + { + /* remain len */ + remainlen = 1+1+(2+desc_len)+(4+bin_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x00); + } + /* bin flag */ + WriteByte(pkg, 0x02); + /* desc */ + WriteStr(pkg, desc_str); + /* bin data */ + WriteUint32(pkg, bin_len); + WriteBytes(pkg, bin_data, bin_len); + return pkg; +} + +EdpPacket* PacketCmdResp(const char* cmdid, uint16 cmdid_len, + const char* resp, uint32 resp_len) +{ + EdpPacket* send_pkg = NULL; + unsigned remainlen = 0; + + send_pkg = NewBuffer(); + /* 6 = 2 + 4 = len(cmdid_len) + len(resp_len) */ + remainlen = cmdid_len + resp_len + (resp_len ? 6 : 2); + WriteByte(send_pkg, CMDRESP); + WriteRemainlen(send_pkg, remainlen); + WriteUint16(send_pkg, cmdid_len); + WriteBytes(send_pkg, cmdid, cmdid_len); + if (resp_len){ + WriteUint32(send_pkg, resp_len); + WriteBytes(send_pkg, resp, resp_len); + } + return send_pkg; +} + +/* ping (C->S) */ +EdpPacket* PacketPing(void) +{ + EdpPacket* pkg = NULL; + + pkg = NewBuffer(); + /* msg type */ + WriteByte(pkg, PINGREQ); + /* remain len */ + WriteRemainlen(pkg, 0); + return pkg; +} + +/*---------------------------------------------------------------------------*/ +/* recv stream to a edp packet (S->C) */ +EdpPacket* GetEdpPacket(RecvBuffer* buf) +{ + EdpPacket* pkg = NULL; + int32 flag = 0; + + assert(buf->_read_pos == 0); + flag = IsPkgComplete(buf); + if (flag <= 0) + return pkg; + pkg = NewBuffer(); + WriteBytes(pkg, buf->_data, flag); + /* shrink buffer */ + memmove(buf->_data, buf->_data + flag, buf->_write_pos - flag); + buf->_write_pos -= flag; + return pkg; +} + +/* is the recv buffer has a complete edp packet? */ +int32 IsPkgComplete(RecvBuffer* buf) +{ + uint8* data = NULL; + uint32 data_len = 0; + uint32 multiplier = 1; + uint32 len_val = 0; + uint32 len_len = 1; + uint8* pdigit = NULL; + uint32 pkg_total_len = 0; + + data = buf->_data; + data_len = buf->_write_pos; + + if (data_len <= 1) { + return 0; /* continue receive */ + } + /* recevie remaining len */ + pdigit = data; + + 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); + + pkg_total_len = len_len + len_val; + /* receive payload */ + if (pkg_total_len <= (uint32)data_len){ +#ifdef _DEBUG + printf("a complete packet len:%d\n", pkg_total_len); +#endif + return pkg_total_len; /* all data for this pkg is read */ + }else{ + return 0; /* continue receive */ + } +} + +/* get edp packet type, client should use this type to invoke Unpack??? function */ +uint8 EdpPacketType(EdpPacket* pkg) +{ + uint8 mtype = 0x00; + ReadByte(pkg, &mtype); + return mtype; +} + +/* connect_resp (S->C)*/ +int32 UnpackConnectResp(EdpPacket* pkg) +{ + uint8 flag, rtn; + uint32 remainlen; + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_CONNRESP_REMAIN; + if (ReadByte(pkg, &flag)) + return ERR_UNPACK_CONNRESP_FLAG; + if (ReadByte(pkg, &rtn)) + return ERR_UNPACK_CONNRESP_RTN; + assert(pkg->_read_pos == pkg->_write_pos); + return (int32)rtn; +} + +/* push_data (S->C) */ +int32 UnpackPushdata(EdpPacket* pkg, char** src_devid, char** data, uint32* data_len) +{ + uint32 remainlen; + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_PUSHD_REMAIN; + if (ReadStr(pkg, src_devid)) + return ERR_UNPACK_PUSHD_DEVID; + remainlen -= (2 + strlen(*src_devid)); + if (ReadBytes(pkg, (uint8**)data, remainlen)) + return ERR_UNPACK_PUSHD_DATA; + *data_len = remainlen; + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +/* save_data (S->C) */ +int32 UnpackSavedata(EdpPacket* pkg, char** src_devid, uint8* jb_flag) +{ + uint32 remainlen; + uint8 ta_flag; + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_SAVED_REMAIN; + /* translate address flag */ + if (ReadByte(pkg, &ta_flag)) + return ERR_UNPACK_SAVED_TANSFLAG; + if (ta_flag == 0x80) + { + if (ReadStr(pkg, src_devid)) + return ERR_UNPACK_SAVED_DEVID; + } + else + { + *src_devid = 0; + } + /* json or bin */ + if (ReadByte(pkg, jb_flag)) + return ERR_UNPACK_SAVED_DATAFLAG; + return 0; +} + +int32 UnpackSavedataJson(EdpPacket* pkg, cJSON** json_obj) +{ + char* json_str; + if (ReadStr(pkg, &json_str)) + return ERR_UNPACK_SAVED_JSON; + *json_obj = cJSON_Parse(json_str); + free(json_str); + if (*json_obj == 0) + return ERR_UNPACK_SAVED_PARSEJSON; + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +int32 UnpackSavedataBin(EdpPacket* pkg, cJSON** desc_obj, + uint8** bin_data, uint32* bin_len) +{ + char* desc_str; + if (ReadStr(pkg, &desc_str)) + return ERR_UNPACK_SAVED_BIN_DESC; + *desc_obj = cJSON_Parse(desc_str); + free(desc_str); + if (*desc_obj == 0) + return ERR_UNPACK_SAVED_PARSEDESC; + if (ReadUint32(pkg, bin_len)) + return ERR_UNPACK_SAVED_BINLEN; + if (ReadBytes(pkg, bin_data, *bin_len)) + return ERR_UNPACK_SAVED_BINDATA; + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +int32 UnpackSavedataBinStr(EdpPacket* pkg, char** desc_str, + uint8** bin_data, uint32* bin_len) +{ + if (ReadStr(pkg, desc_str)) + return ERR_UNPACK_SAVED_BIN_DESC; + if (ReadUint32(pkg, bin_len)) + return ERR_UNPACK_SAVED_BINLEN; + if (ReadBytes(pkg, bin_data, *bin_len)) + return ERR_UNPACK_SAVED_BINDATA; + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +int32 UnpackCmdReq(EdpPacket* pkg, char** cmdid, uint16* cmdid_len, + char** req, uint32* req_len) +{ + uint32 remainlen; + int rc; + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_CMDREQ; + + rc = ReadUint16(pkg, cmdid_len); + if (rc) + return rc; + if (ReadBytes(pkg, (uint8**)cmdid, *cmdid_len)) + return ERR_UNPACK_CMDREQ; + + rc = ReadUint32(pkg, req_len); + if (rc) + return rc; + if (ReadBytes(pkg, (uint8**)req, *req_len)) + return ERR_UNPACK_CMDREQ; + + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +/* ping_resp (S->C) */ +int32 UnpackPingResp(EdpPacket* pkg) +{ + uint32 remainlen; + if (ReadRemainlen(pkg, &remainlen)) + return ERR_UNPACK_PING_REMAIN; + assert(pkg->_read_pos == pkg->_write_pos); + return 0; +} + +/* sava_data (C->S) */ +EdpPacket* PacketSavedataSimpleString(const char* dst_devid, const char* input) +{ + EdpPacket* pkg = NULL; + uint32 remainlen = 0; + uint32 input_len = 0; + + pkg = NewBuffer(); + input_len = strlen(input); + /* msg type */ + WriteByte(pkg, SAVEDATA); + if (dst_devid) + { + /* remain len */ + remainlen = 1+(2+strlen(dst_devid))+1+(2+input_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x80); + /* dst devid */ + WriteStr(pkg, dst_devid); + } + else + { + /* remain len */ + remainlen = 1+1+(2+input_len); + WriteRemainlen(pkg, remainlen); + /* translate address flag */ + WriteByte(pkg, 0x00); + } + /* json flag */ + WriteByte(pkg, kTypeString); + /* json */ + WriteStr(pkg, input); + + return pkg; +} + +int32 UnpackSavedataSimpleString(EdpPacket* pkg, char** output) +{ + if (ReadStr(pkg, output)) + return ERR_UNPACK_SAVED_JSON; + return 0; +} +
diff -r 000000000000 -r 79de700849c5 EdpKit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EdpKit.h Wed Mar 29 03:07:27 2017 +0000 @@ -0,0 +1,743 @@ +#ifndef __EDP_KIT_H__ +#define __EDP_KIT_H__ + +#ifdef EDPKIT_EXPORTS + #define EDPKIT_DLL __declspec(dllexport) +#else + #define EDPKIT_DLL +#endif + +#include "Common.h" +#include "cJSON.h" +#include "time.h" +/* + * history + * 2015-06-01 v1.0.1 wululu fix bug: malloc for string, MUST memset to 0 + * 2015-07-10 v1.1.0 wusongwei add UnpackCmdReq() and PacketCmdResp() + * 2015-07-13 v1.1.1 wululu 增加封装json的接口, windows版本dll + * 2015-07-13 v1.1.2 wululu 支持double和string类型的打包函数和解包函数 + * 2015-07-15 v1.1.3 wusongwei 添加SAVEACK响应 + * 2015-07-20 v1.1.4 wusongwei 添加/修改SAVEDATA消息的打包/解包函数 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------*/ +#define MOSQ_MSB(A) (uint8)((A & 0xFF00) >> 8) +#define MOSQ_LSB(A) (uint8)(A & 0x00FF) +#define BUFFER_SIZE (0x100) +#define PROTOCOL_NAME "EDP" +#define PROTOCOL_VERSION 1 +/*----------------------------错误码-----------------------------------------*/ +#define ERR_UNPACK_CONNRESP_REMAIN -1000 +#define ERR_UNPACK_CONNRESP_FLAG -1001 +#define ERR_UNPACK_CONNRESP_RTN -1002 +#define ERR_UNPACK_PUSHD_REMAIN -1010 +#define ERR_UNPACK_PUSHD_DEVID -1011 +#define ERR_UNPACK_PUSHD_DATA -1012 +#define ERR_UNPACK_SAVED_REMAIN -1020 +#define ERR_UNPACK_SAVED_TANSFLAG -1021 +#define ERR_UNPACK_SAVED_DEVID -1022 +#define ERR_UNPACK_SAVED_DATAFLAG -1023 +#define ERR_UNPACK_SAVED_JSON -1024 +#define ERR_UNPACK_SAVED_PARSEJSON -1025 +#define ERR_UNPACK_SAVED_BIN_DESC -1026 +#define ERR_UNPACK_SAVED_PARSEDESC -1027 +#define ERR_UNPACK_SAVED_BINLEN -1028 +#define ERR_UNPACK_SAVED_BINDATA -1029 +#define ERR_UNPACK_PING_REMAIN -1030 +#define ERR_UNPACK_CMDREQ -1031 +#define ERR_UNPACK_ENCRYPT_RESP -1032 +#define ERR_UNPACK_SAVEDATA_ACK -1033 + +/*----------------------------消息类型---------------------------------------*/ +/* 连接请求 */ +#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 + +#ifndef NULL +#define NULL (void*)0 +#endif + +/* SAVEDATA消息支持的格式类型 */ +typedef enum { + kTypeFullJson = 0x01, + kTypeBin = 0x02, + kTypeSimpleJsonWithoutTime = 0x03, + kTypeSimpleJsonWithTime = 0x04, + kTypeString = 0x05 +}SaveDataType; + +/*-------------发送buffer, 接收buffer, EDP包结构定义-------------------------*/ +EDPKIT_DLL +typedef struct Buffer +{ + uint8* _data; /* buffer数据 */ + uint32 _write_pos; /* buffer写入位置 */ + uint32 _read_pos; /* buffer读取位置 */ + uint32 _capacity; /* buffer容量 */ +}Buffer, SendBuffer, RecvBuffer, EdpPacket; +/*-----------------------------操作Buffer的接口------------------------------*/ +/* + * 函数名: NewBuffer + * 功能: 生成Buffer + * 说明: 一般情况下, NewBuffer和DeleteBuffer应该成对出现 + * 参数: 无 + * 返回值: 类型 (Buffer*) + * 返回值非空 生成Buffer成功, 返回这个Buffer的指针 + * 返回值为空 生成Buffer失败, 内存不够 + */ +EDPKIT_DLL Buffer* NewBuffer(); +/* + * 函数名: DeleteBuffer + * 功能: 销毁Buffer + * 说明: 一般情况下, NewBuffer和DeleteBuffer应该成对出现 + * 参数: buf 一个Buffer的指针的指针 + * 返回值: 无 + */ +EDPKIT_DLL void DeleteBuffer(Buffer** buf); +/* + * 函数名: CheckCapacity + * 功能: 检查Buffer是否能够写入长度为len的字节流, + * 如果Buffer的容量不够, 自动成倍扩展Buffer的容量(不影响Buffer数据) + * 参数: buf 需要写入Buffer的指针 + * len 期望写入的长度 + * 返回值: 类型 (int32) + * <0 失败, 内存不够 + * =0 成功 + */ +EDPKIT_DLL int32 CheckCapacity(Buffer* buf, uint32 len); + +/*------------------------读取EDP包数据的接口-------------------------------*/ +/* + * 函数名: ReadByte + * 功能: 按EDP协议, 从Buffer(包)中读取一个字节数据 + * 参数: pkg EDP包 + * val 数据(一个字节) + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadByte(EdpPacket* pkg, uint8* val); +/* + * 函数名: ReadBytes + * 功能: 按EDP协议, 从Buffer(包)中读取count个字节数据 + * 说明: val是malloc出来的, 需要客户端自己free + * 参数: pkg EDP包 + * val 数据(count个字节) + * count 字节数 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadBytes(EdpPacket* pkg, uint8** val, uint32 count); +/* + * 函数名: ReadUint16 + * 功能: 按EDP协议, 从Buffer(包)中读取uint16值 + * 参数: pkg EDP包 + * val uint16值 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadUint16(EdpPacket* pkg, uint16* val); +/* + * 函数名: ReadUint32 + * 功能: 按EDP协议, 从Buffer(包)中读取uint32值 + * 参数: pkg EDP包 + * val uint32值 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadUint32(EdpPacket* pkg, uint32* val); +/* + * 函数名: ReadStr + * 功能: 按EDP协议, 从Buffer(包)中读取字符串, 以\0结尾 + * 参数: pkg EDP包 + * val 字符串 + * 说明: val是malloc出来的, 需要客户端自己free + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadStr(EdpPacket* pkg, char** val); +/* + * 函数名: ReadRemainlen + * 功能: 按EDP协议, 从Buffer(包)中remainlen + * 说明: remainlen是EDP协议中的概念, 是一个EDP包身的长度 + * 参数: pkg EDP包 + * len_val remainlen + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 ReadRemainlen(EdpPacket* pkg, uint32* len_val); + +/*------------------------数据写入EDP包的接口-------------------------------*/ +/* + * 说明: 目前不支持一个包即在写入又在读取, 因此, 只有对于_read_pos为0的包才能被写入 + */ +/* + * 函数名: WriteByte + * 功能: 按EDP协议, 将一个字节数据写入Buffer(包)中 + * 参数: pkg EDP包 + * byte 数据(一个字节) + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteByte(Buffer* buf, uint8 byte); +/* + * 函数名: WriteBytes + * 功能: 按EDP协议, 将count个字节数据写入Buffer(包)中 + * 参数: pkg EDP包 + * bytes 数据 + * count 字节数 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteBytes(Buffer* buf, const void* bytes, uint32 count); +/* + * 函数名: WriteUint16 + * 功能: 按EDP协议, 将uint16写入Buffer(包)中 + * 参数: pkg EDP包 + * val uint16数据 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteUint16(Buffer* buf, uint16 val); +/* + * 函数名: WriteUint32 + * 功能: 按EDP协议, 将uint32写入Buffer(包)中 + * 参数: pkg EDP包 + * val uint32数据 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteUint32(Buffer* buf, uint32 val); +/* + * 函数名: WriteStr + * 功能: 按EDP协议, 将字符串写入Buffer(包)中 + * 参数: pkg EDP包 + * val 字符串 + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteStr(Buffer* buf, const char *str); +/* + * 函数名: WriteRemainlen + * 功能: 按EDP协议, 将remainlen写入Buffer(包)中 + * 说明: remainlen是EDP协议中的概念, 是一个EDP包身的长度 + * 参数: pkg EDP包 + * len_val remainlen + * 返回值: 类型 (int32) + * <0 失败, pkg中无数据 + * =0 成功 + */ +EDPKIT_DLL int32 WriteRemainlen(Buffer* buf, uint32 len_val); +/* + * 函数名: IsPkgComplete + * 功能: 判断接收到的Buffer, 是否为一个完整的EDP包 + * 参数: buf 接收到的Buffer(二进制流) + * 返回值: 类型 (int32) + * =0 数据还未收完, 需要继续接收 + * >0 成功 + * <0 数据错误, 不符合EDP协议 + */ +EDPKIT_DLL int32 IsPkgComplete(RecvBuffer* buf); + +/*-----------------------------客户端操作的接口------------------------------*/ +/* + * 函数名: GetEdpPacket + * 功能: 将接收到的二进制流, 分解成一个一个的EDP包 + * 说明: 返回的EDP包使用后, 需要删除 + * 相关函数:EdpPacketType, Unpack***类函数 + * 参数: buf 接收缓存 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 无完整的EDP协议包 + */ +EDPKIT_DLL EdpPacket* GetEdpPacket(RecvBuffer* buf); + +/* + * 函数名: EdpPacketType + * 功能: 获取一个EDP包的消息类型, 客户程序根据消息类型做不同的处理 + * 相关函数:Unpack***类函数 + * 参数: pkg EDP协议包 + * 返回值: 类型 (uint8) + * 值 消息类型(详细参见本h的消息类型定义) + */ +/* 例子: + * ... + * int8 mtype = EdpPacketType(pkg); + * switch(mtype) + * { + * case CONNRESP: + * UnpackConnectResp(pkg); + * break; + * case PUSHDATA: + * UnpackPushdata(pkg, src_devid, data, data_len); + * break; + * case SAVEDATA: + * UnpackSavedata(pkg, src_devid, flag, data); + * break; + * case PINGRESP: + * UnpackPingResp(pkg); + * break; + * ... + * } + */ +EDPKIT_DLL uint8 EdpPacketType(EdpPacket* pkg); + +/* + * 函数名: PacketConnect1 + * 功能: 打包 由设备到设备云的EDP协议包, 连接设备云的请求(登录认证方式1) + * 说明: 返回的EDP包发送给设备云后, 需要客户程序删除该包 + * 设备云会回复连接响应给设备 + * 相关函数:UnpackConnectResp + * 参数: devid 设备ID, 申请设备时平台返回的ID + * auth_key 鉴权信息(api-key), 在平台申请的可以操作该设备的api-key字符串 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketConnect1(const char* devid, const char* auth_key); + +/* + * 函数名: PacketConnect2 + * 功能: 打包 由设备到设备云的EDP协议包, 连接设备云的请求(登录认证方式2) + * 说明: 返回的EDP包发送给设备云后, 需要客户程序删除该包 + * 设备云会回复连接响应给设备 + * 相关函数:UnpackConnectResp + * 参数: userid 用户ID, 在平台注册账号时平台返回的用户ID + * auth_info 鉴权信息, 在平台申请设备时填写设备的auth_info属性 + * (json对象字符串), 该属性需要具备唯一性 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketConnect2(const char* userid, const char* auth_info); + +/* + * 函数名: UnpackConnectResp + * 功能: 解包 由设备云到设备的EDP协议包, 连接响应 + * 说明: 接收设备云发来的数据, 通过函数GetEdpPacket和EdpPacketType判断出是连接响应后, + * 将整个响应EDP包作为参数, 由该函数进行解析 + * 相关函数:PacketConnect1, PacketConnect2, GetEdpPacket, EdpPacketType + * 参数: pkg EDP包, 必须是连接响应包 + * 返回值: 类型 (int32) + * =0 连接成功 + * >0 连接失败, 具体失败原因见<OneNet接入方案与接口.docx> + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackConnectResp(EdpPacket* pkg); + +/* + * 函数名: PacketPushdata + * 功能: 打包 设备到设备云的EDP协议包, 设备与设备之间转发数据 + * 说明: 返回的EDP包发送给设备云后, 需要删除这个包 + * 相关函数:UnpackPushdata + * 参数: dst_devid 目的设备ID + * data 数据 + * data_len 数据长度 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketPushdata(const char* dst_devid, + const char* data, uint32 data_len); + +/* + * 函数名: UnpackPushdata + * 功能: 解包 由设备云到设备的EDP协议包, 设备与设备之间转发数据 + * 说明: 接收设备云发来的数据, 通过函数GetEdpPacket和EdpPacketType判断出是pushdata后, + * 将整个响应EDP包作为参数, 由该函数进行解析 + * 返回的源设备ID(src_devid)和数据(data)都需要客户端释放 + * 相关函数:PacketPushdata, GetEdpPacket, EdpPacketType + * 参数: pkg EDP包, 必须是pushdata包 + * src_devid 源设备ID + * data 数据 + * data_len 数据长度 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackPushdata(EdpPacket* pkg, char** src_devid, + char** data, uint32* data_len); + +/* + * 函数名: PacketSavedataJson + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(json格式数据) + * 说明: 返回的EDP包发送给设备云后, 需要删除这个包 + * 相关函数:UnpackSavedata, UnpackSavedataJson + * 参数: dst_devid 目的设备ID + * json_obj json数据 + * type json的类型 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EdpPacket* PacketSavedataJson(const char* dst_devid, cJSON* json_obj, int type); + +/* + * 函数名: PacketSavedataInt + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(json格式数据) + * 说明: 该函数适用于数据点为int类型的数据流 + * 它把参数封装成EDP协议规定的cJSON对象, + * type类型决定使用哪种JSON格式,具体格式说明见文档《设备终端接入协议2-EDP.docx》 + * 相关函数:UnPacketSavedataInt + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * dst_devid 目的设备ID + * ds_id 数据流ID + * value int型数据点 + * at 如果设置为0,则采用系统当前时间,否则采用给定时间。 + * 如果type选择为kTypeSimpleJsonWithoutTime,由于这种类型的JSON格式不带时间, + * 服务器端统一采用系统时间,此值将被忽略 + * token 当type为kTypeFullJson时,将根据EDP协议封装token字段, + * 为其它类型时将被忽略。 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketSavedataInt(SaveDataType type, const char* dst_devid, + const char* ds_id, int value, + time_t at, const char* token); + +/* + * 函数名: PacketSavedataDouble + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(json格式数据) + * 说明: 该函数适用于数据点为double类型的数据流 + * 它把参数封装成EDP协议规定的cJSON对象, + * type类型决定使用哪种JSON格式,具体格式说明见文档《设备终端接入协议2-EDP.docx》 + * 相关函数:UnPacketSavedataDouble + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * dst_devid 目的设备ID + * ds_id 数据流ID + * value double型数据点 + * at 如果设置为0,则采用系统当前时间,否则采用给定时间。 + * 如果type选择为kTypeSimpleJsonWithoutTime,由于这种类型的JSON格式不带时间, + * 服务器端统一采用系统时间,此值将被忽略 + * token 当type为kTypeFullJson时,将根据EDP协议封装token字段, + * 为其它类型时将被忽略。 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketSavedataDouble(SaveDataType type, const char* dst_devid, + const char* ds_id, double value, + time_t at, const char* token); + +/* + * 函数名: PacketSavedataString + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(json格式数据) + * 说明: 该函数适用于数据点为char*类型的数据流 + * 它把参数封装成EDP协议规定的cJSON对象, + * type类型决定使用哪种JSON格式,具体格式说明见文档《设备终端接入协议2-EDP.docx》 + * 相关函数:UnPacketSavedataString + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * dst_devid 目的设备ID + * ds_id 数据流ID + * value char*型数据点 + * at 如果设置为0,则采用系统当前时间,否则采用给定时间。 + * 如果type选择为kTypeSimpleJsonWithoutTime,由于这种类型的JSON格式不带时间, + * 服务器端统一采用系统时间,此值将被忽略 + * token 当type为kTypeFullJson时,将根据EDP协议封装token字段, + * 为其它类型时将被忽略。 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketSavedataString(SaveDataType type, const char* dst_devid, + const char* ds_id, const char* value, + time_t at, const char* token); + +/* + * 函数名: UnpackSavedataInt + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据 + * 说明: 接收设备云发来的数据,将其中的数据流ID及值解析出来。 + * + * 相关函数:PacketSavedataInt + * + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * pkg EDP包, 必须是savedata包 + * ds_id 获取数据流ID,使用完后必须释放 + * value 数据流对应的值 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, -1 type类型不合法,其它值见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataInt(SaveDataType type, EdpPacket* pkg, + char** ds_id, int* value); + +/* + * 函数名: UnpackSavedataDouble + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据 + * 说明: 接收设备云发来的数据,将其中的数据流ID及值解析出来。 + * + * 相关函数:PacketSavedataDouble + * + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * pkg EDP包, 必须是savedata包 + * ds_id 获取数据流ID,使用完后必须释放 + * value 数据流对应的值 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, -1 type类型不合法,其它值见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataDouble(SaveDataType type, EdpPacket* pkg, + char** ds_id, double* value); + +/* + * 函数名: UnpackSavedataString + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据 + * 说明: 接收设备云发来的数据,将其中的数据流ID及值解析出来。 + * + * 相关函数:PacketSavedataString + * + * 参数: type 采用的JSON数据类型,可选类型为:kTypeFullJson, + * kTypeSimpleJsonWithoutTime, kTypeSimpleJsonWithTime + * pkg EDP包, 必须是savedata包 + * ds_id 获取数据流ID,使用完后需要释放 + * value 数据流对应的值,使用完后需要释放 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, -1 type类型不合法,其它值见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataString(SaveDataType type, EdpPacket* pkg, + char** ds_id, char** value); + + +/* + * 函数名: UnpackSavedataAck + * 功能: 解包 由设备云到设备的EDP协议包, 存贮(转发)消息的响应 + * 说明: 当存贮(转发)消息带token时,平台会响应一个SAVE_ACK消息, + * 用作存储消息的确认。 + * 相关函数: PacketSavedataDoubleWithToken PacketSavedataStringWithToken + * 参数: pkg EDP包, 必须是连接响应包 + * json_ack 获取响应的json字符串,使用完后需要释放 + * 返回值: 类型 (int32) + * =0 心跳成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataAck(EdpPacket* pkg, char** json_ack); + +/* + * 函数名: PacketSavedataSimpleString + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(以分号分隔的简单字符串形式) + * 说明: 返回的EDP包发送给设备云后, 需要删除这个包 + * 相关函数:UnpackSavedataSimpleString + * 参数: dst_devid 目的设备ID + * input 以分号分隔的简单字符串形式, + * 详见《设备终端接入协议2-EDP.docx》 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketSavedataSimpleString(const char* dst_devid, const char* input); + +/* + * 函数名: UnpackSavedataSimpleString + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据 + * 说明: 接收设备云发来的数据, 通过函数GetEdpPacket和EdpPacketType判断出是savedata后, + * 将整个响应EDP包作为参数, 由该函数进行解析, + * 获取源端发送来的以分号作为分隔符的字符串。 + * 相关函数: PacketSavedataSimpleString + * + * 参数: pkg EDP包, 必须是savedata包 + * output 存储发送来的字符串 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataSimpleString(EdpPacket* pkg, char** output); + +/* + * 函数名: PacketSavedataBin + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(bin格式数据) + * 说明: 返回的EDP包发送给设备云后, 需要删除这个包 + * 相关函数:UnpackSavedata, UnpackSavedataBin + * 参数: dst_devid 目的设备ID + * desc_obj 数据描述 json格式 + * bin_data 二进制数据 + * bin_len 二进制数据长度 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EdpPacket* PacketSavedataBin(const char* dst_devid, + cJSON* desc_obj, const uint8* bin_data, uint32 bin_len); +/* + * 函数名: PacketSavedataBinStr + * 功能: 打包 设备到设备云的EDP协议包, 存储数据(bin格式数据) + * 说明: 返回的EDP包发送给设备云后, 需要删除这个包 + * 相关函数:UnpackSavedata, UnpackSavedataBin + * 参数: dst_devid 目的设备ID + * desc_obj 数据描述 字符串格式 + * bin_data 二进制数据 + * bin_len 二进制数据长度 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketSavedataBinStr(const char* dst_devid, + const char* desc_str, const uint8* bin_data, uint32 bin_len); + +/* + * 函数名: UnpackSavedata + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据 + * 说明: 接收设备云发来的数据, 通过函数GetEdpPacket和EdpPacketType判断出是savedata后, + * 将整个响应EDP包作为参数, 由该函数进行解析 + * 然后再根据json和bin的标识(jb_flag), 调用相应的解析函数 + * 返回的源设备ID(src_devid)需要客户端释放 + * 相关函数:PacketSavedataJson, PacketSavedataBin, GetEdpPacket, + * UnpackSavedataJson, UnpackSavedataBin + * 参数: pkg EDP包, 必须是savedata包 + * src_devid 源设备ID + * jb_flag json or bin数据, 1: json, 2: 二进制 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedata(EdpPacket* pkg, char** src_devid, uint8* jb_flag); + +/* + * 函数名: UnpackSavedataJson + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据(json格式数据) + * 说明: 返回的json数据(json_obj)需要客户端释放 + * 相关函数:PacketSavedataJson, GetEdpPacket, EdpPacketType, UnpackSavedata + * 参数: pkg EDP包, 必须是savedata包的json数据包 + * json_obj json数据 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +int32 UnpackSavedataJson(EdpPacket* pkg, cJSON** json_obj); + +/* + * 函数名: UnpackSavedataBin + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据(bin格式数据) + * 说明: 返回的数据描述(desc_obj)和bin数据(bin_data)需要客户端释放 + * 相关函数:PacketSavedataBin, GetEdpPacket, EdpPacketType, UnpackSavedata + * 参数: pkg EDP包, 必须是savedata包的bin数据包 + * desc_obj 数据描述 json格式 + * bin_data 二进制数据 + * bin_len 二进制数据长度 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +int32 UnpackSavedataBin(EdpPacket* pkg, cJSON** desc_obj, + uint8** bin_data, uint32* bin_len); +/* + * 函数名: UnpackSavedataBinStr + * 功能: 解包 由设备云到设备的EDP协议包, 存储数据(bin格式数据) + * 说明: 返回的数据描述(desc_obj)和bin数据(bin_data)需要客户端释放 + * 相关函数:PacketSavedataBin, GetEdpPacket, EdpPacketType, UnpackSavedata + * 参数: pkg EDP包, 必须是savedata包的bin数据包 + * desc_obj 数据描述 string格式 + * bin_data 二进制数据 + * bin_len 二进制数据长度 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackSavedataBinStr(EdpPacket* pkg, char** desc_str, + uint8** bin_data, uint32* bin_len); +/* + * 函数名: PacketCmdResp + * 功能: 向接入机发送命令响应 + * 说明: 返回的EDP包发送给设备云后, 需要客户程序删除该包 + * + * 相关函数:UnpackCmdReq + * 参数: cmdid 命令id + * cmdid_len 命令id长度 + * resp 响应的消息 + * resp_len 响应消息长度 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketCmdResp(const char* cmdid, uint16 cmdid_len, + const char* resp, uint32 resp_len); + +/* + * 函数名: UnpackCmdReq + * 功能: 解包 由设备云到设备的EDP协议包, 命令请求消息 + * 说明: 接收设备云发来的数据, 解析命令请求消息包 + * 获取的cmdid以及req需要在使用后释放。 + * 相关函数:PacketCmdResp + * 参数: pkg EDP包 + * cmdid 获取命令id + * cmdid_len cmdid的长度 + * req 用户命令的起始位置 + * req_len 用户命令的长度 + * 返回值: 类型 (int32) + * =0 解析成功 + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackCmdReq(EdpPacket* pkg, char** cmdid, uint16* cmdid_len, + char** req, uint32* req_len); + +/* + * 函数名: PacketPing + * 功能: 打包 由设备到设备云的EDP协议包, 心跳 + * 说明: 返回的EDP包发送给设备云后, 需要客户程序删除该包 + * 设备云会回复心跳响应给设备 + * 相关函数:UnpackPingResp + * 参数: 无 + * 返回值: 类型 (EdpPacket*) + * 非空 EDP协议包 + * 为空 EDP协议包生成失败 + */ +EDPKIT_DLL EdpPacket* PacketPing(void); + +/* + * 函数名: UnpackPingResp + * 功能: 解包 由设备云到设备的EDP协议包, 心跳响应 + * 说明: 接收设备云发来的数据, 通过函数GetEdpPacket和EdpPacketType判断出是连接响应后, + * 将整个响应EDP包作为参数, 由该函数进行解析 + * 相关函数:PacketPing, GetEdpPacket, EdpPacketType + * 参数: pkg EDP包, 必须是连接响应包 + * 返回值: 类型 (int32) + * =0 心跳成功 + * >0 心跳失败, 具体失败原因见<OneNet接入方案与接口.docx> + * <0 解析失败, 具体失败原因见本h文件的错误码 + */ +EDPKIT_DLL int32 UnpackPingResp(EdpPacket* pkg); + +#ifdef __cplusplus +} +#endif + +#endif /* __EDP_KIT_H__ */