| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- #include "stm32f10x.h"
- #include <string.h>
- #include "CoAP_Util.h"
- static uint16_t CoAP_Length;
- static uint16_t Current_Option_Number;
- static uint8_t * CoAP_Message;
- void Insert(uint8_t * dest, uint16_t dest_start, uint8_t * source, uint16_t source_start, uint16_t len)
- {
- uint16_t i = 0;
- while(i < len)
- {
- dest[dest_start + i] = source[source_start + i];
- i++;
- }
- }
- void insert(uint16_t start, uint8_t * source, uint16_t len)
- {
- Insert(CoAP_Message, start, source, 0, len);
- }
- uint16_t CoAP_Get_Length()
- {
- return CoAP_Length;
- }
- void CoAP_Init(uint8_t * coap_message)
- {
- CoAP_Message = coap_message;
- CoAP_Length = 4;
- Current_Option_Number = 0;
- CoAP_Message[0] |= 0x01 << 6; // 协议版本,固定为1
- }
- // 报文类型,00CON,01NON,10ACK,11Rest
- void CoAP_Set_T(uint8_t t)
- {
- CoAP_Message[0] |= t << 4;
- }
- // 请求类型
- void CoAP_Set_Code(uint8_t code)
- {
- CoAP_Message[1] = code;
- }
- // messageID
- void CoAP_Set_MessageID(uint16_t messageID)
- {
- uint8_t message_id[2];
- message_id[0] = (messageID >> 8) & 0xFF;
- message_id[1] = messageID & 0xFF;
- insert(2, message_id, sizeof(message_id));
- }
- // token len不能大于8
- void CoAP_Set_Token(uint8_t * token, uint8_t len)
- {
- if(len > 8)
- {
- len = 8;
- }
- CoAP_Message[0] |= len & 0xFF;
- insert(CoAP_Length, token, len);
- CoAP_Length += len;
- }
- // 设置option
- void CoAP_Set_Option(uint16_t number, uint16_t length, uint8_t * value)
- {
- uint16_t pos_start = CoAP_Length, opt_length = 1;
- int32_t delta = number - Current_Option_Number;
-
- if (delta < 0){
- return;
- } else if (delta < 13){
- CoAP_Message[pos_start] |= (delta & 0xFF) << 4;
- }else if (delta < 255+13){
- CoAP_Message[pos_start] |= (0x0D & 0xFF) << 4;
- uint8_t ext = delta - 0x0D;
- CoAP_Message[pos_start + opt_length++] = ext;
- }else if (delta < 65535){
- CoAP_Message[pos_start] |= (0x0E & 0xFF) << 4;
- uint16_t ext = (delta - 0x0E - 0xFF);
- CoAP_Message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
- CoAP_Message[pos_start + opt_length++] = ext & 0xFF;
- }
- // length
- if (length < 1){
- return;
- }else if (length < 13){
- CoAP_Message[pos_start] |= (length & 0xFF);
- }else if (length < 255+13){
- CoAP_Message[pos_start] |= (0x0D & 0xFF);
- uint8_t ext = length - 0x0D;
- CoAP_Message[pos_start + opt_length++] = ext;
- }else if (length < 65535){
- CoAP_Message[pos_start] |= (0x0E & 0xFF);
- uint16_t ext = (length - 0x0E - 0xFF);
- CoAP_Message[pos_start + opt_length++] = (ext >> 8) & 0xFF;
- CoAP_Message[pos_start + opt_length++] = ext & 0xFF;
- }
-
- insert(pos_start + opt_length, value, length);
- opt_length += length;
- CoAP_Length += opt_length;
- Current_Option_Number = number;
- }
- // 设置字符串类型的option
- void CoAP_Set_Option_Str(uint16_t number, char * message)
- {
- uint16_t len = strlen(message);
- uint8_t value[len];
- for(uint16_t i = 0; i < len; i++)
- {
- value[i] = message[i];
- }
- CoAP_Set_Option(number, len, value);
- }
- // 设置short类型的option
- void CoAP_Set_Option_Short(uint16_t number, uint16_t num)
- {
- if(num < 256)
- {
- uint8_t value[1];
- value[0] = num;
- CoAP_Set_Option(number, sizeof(value), value);
- }
- else
- {
- uint8_t value[2];
- value[0] = (num >> 8) & 0xFF;
- value[1] = num & 0xFF;
- CoAP_Set_Option(number, sizeof(value), value);
- }
- }
- // 设置payload
- void CoAP_Set_Payload(uint8_t * payload, uint16_t length)
- {
- uint16_t pos = CoAP_Length;
- CoAP_Message[pos] = 0xFF;
- insert(pos + 1, payload, length);
- CoAP_Length += length + 1;
- }
- void CoAP_Set_Payload_Str(char * payload)
- {
- uint16_t len = strlen(payload);
- uint8_t value[len];
- for(uint16_t i = 0; i < len; i++)
- {
- value[i] = payload[i];
- }
- CoAP_Set_Payload(value, len);
- }
- // 报文解析
- // 获取版本号
- uint8_t CoAP_Get_Ver(uint8_t * coap_message)
- {
- uint8_t ver = (coap_message[0] & 0xC0) >> 6;
- return ver;
- }
- // 获取报文类型
- uint8_t CoAP_Get_T(uint8_t * coap_message)
- {
- uint8_t t = (coap_message[0] & 0x30) >> 4;
- return t;
- }
- // 获取tkl
- uint8_t CoAP_Get_Tkl(uint8_t * coap_message)
- {
- uint8_t tkl = coap_message[0] & 0x0F;
- return tkl;
- }
- // 获取请求方式
- uint8_t CoAP_Get_Code(uint8_t * coap_message)
- {
- uint8_t code = coap_message[1];
- return code;
- }
- // 获取messageID
- uint16_t CoAP_Get_MessageID(uint8_t * coap_message)
- {
- uint16_t messageID = 0;
- messageID = (messageID | coap_message[2]) << 8;
- messageID = messageID | coap_message[3];
- return messageID;
- }
- // 获取token
- uint8_t * CoAP_Get_Token(uint8_t * coap_message, uint8_t * token)
- {
- uint8_t tkl = CoAP_Get_Tkl(coap_message);
- for(uint8_t i = 0; i < tkl; i++)
- {
- token[i] = coap_message[4 + i];
- }
- return token;
- }
- struct Option_Struct
- {
- uint8_t valid; // 是否合法
- uint16_t number; // 编号
- uint16_t length; // 长度
- uint16_t pos; // 位置
- uint8_t delta_ext; // 编号扩展,字节
- uint8_t length_ext; // 长度扩展,字节
- };
- struct Option_Struct Get_Option(uint8_t * coap_message, uint16_t pos, uint16_t number)
- {
- struct Option_Struct option_struct = {
- .valid = 1,
- .number = number,
- .length = coap_message[pos] & 0x0F,
- .pos = pos,
- .delta_ext = 0,
- .length_ext = 0,
- };
- uint8_t delta = (coap_message[pos] & 0xF0) >> 4;
- if(delta < 0x0D)
- {
- option_struct.delta_ext = 0;
- option_struct.number += delta;
- }
- else if(delta == 0x0D)
- {
- option_struct.delta_ext = 1;
- uint8_t num = coap_message[pos + 1];
- option_struct.number += (0x0D + num);
- }
- else if(delta == 0x0E)
- {
- option_struct.delta_ext = 2;
- uint16_t num = 0;
- num = (num | coap_message[pos + 1]) << 8;
- num = num | coap_message[pos + 2];
- option_struct.number += (0x0E + 0xFF + num);
- }
- else
- {
- option_struct.valid = 0;
- return option_struct;
- }
-
- if(option_struct.length < 0x0D)
- {
- option_struct.length_ext = 0;
- }
- else if(option_struct.length == 0x0D)
- {
- option_struct.length_ext = 1;
- uint8_t num = coap_message[pos + option_struct.delta_ext + 1];
- option_struct.length = (0x0D + num);
- }
- else if(option_struct.length == 0x0E)
- {
- option_struct.length_ext = 2;
- uint16_t num = 0;
- num = (num | coap_message[pos + option_struct.delta_ext + 1]) << 8;
- num = num | coap_message[pos + option_struct.delta_ext + 2];
- option_struct.length = (0x0E + 0xFF + num);
- }
- else
- {
- option_struct.valid = 0;
- return option_struct;
- }
- return option_struct;
- }
- // 获取option长度
- struct Option_Struct CoAP_Get_Option(uint8_t * coap_message, uint16_t coap_length, uint16_t number)
- {
- uint8_t tkl = CoAP_Get_Tkl(coap_message);
- uint16_t pos = 4 + tkl;
- uint16_t current_number = 0;
- struct Option_Struct option_struct;
-
- while(pos < coap_length)
- {
- option_struct = Get_Option(coap_message, pos, current_number);
- if(option_struct.valid == 0 || option_struct.number == number)
- {
- break;
- }
- else
- {
- current_number = option_struct.number;
- pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
- }
- }
- return option_struct;
- }
- // 获取option长度
- uint16_t CoAP_Get_Option_Length(uint8_t * coap_message, uint16_t coap_length, uint16_t number)
- {
- uint16_t length = 0;
- struct Option_Struct option_struct = CoAP_Get_Option(coap_message, coap_length, number);
- if(option_struct.valid)
- {
- length = option_struct.length;
- }
- return length;
- }
- // 获取option value
- uint8_t * CoAP_Get_Option_Value(uint8_t * coap_message, uint16_t coap_length, uint16_t number, uint8_t * value)
- {
- struct Option_Struct option_struct = CoAP_Get_Option(coap_message, coap_length, number);
- if(option_struct.valid)
- {
- for(uint8_t i = 0; i < option_struct.length; i++)
- {
- value[i] = coap_message[option_struct.pos + option_struct.delta_ext + option_struct.length_ext + 1 + i];
- }
- }
- else
- {
- // value[0] = 0x99;
- }
- return value;
- }
- struct Payload_Struct
- {
- uint8_t valid;
- uint16_t pos;
- uint16_t length;
- };
- // 获取payload
- struct Payload_Struct Get_Payload(uint8_t * coap_message, uint16_t coap_length)
- {
- uint8_t tkl = CoAP_Get_Tkl(coap_message);
- uint16_t pos = 4 + tkl;
- uint16_t current_number = 0;
- struct Option_Struct option_struct;
- struct Payload_Struct payload_struct = {
- .valid = 1,
- .pos = 0,
- .length = 0
- };
-
- while(pos < coap_length)
- {
- if(coap_message[pos] == 0xFF)
- {
- payload_struct.valid = 1;
- payload_struct.pos = pos + 1;
- payload_struct.length = coap_length - pos - 1;
- break;
- }
- option_struct = Get_Option(coap_message, pos, current_number);
- if(option_struct.valid == 0)
- {
- payload_struct.valid = 0;
- payload_struct.length = 0;
- payload_struct.pos = 0;
- break;
- }
- else
- {
- current_number = option_struct.number;
- pos = option_struct.pos + option_struct.delta_ext + option_struct.length_ext + option_struct.length + 1; // 下一个循环的位置起点
- }
- }
- return payload_struct;
- }
- // 获取payload长度
- uint16_t CoAP_Get_Payload_Length(uint8_t * coap_message, uint16_t coap_length)
- {
- struct Payload_Struct payload_struct = Get_Payload(coap_message, coap_length);
- return payload_struct.length;
- }
- // 获取payload值
- uint16_t CoAP_Get_Payload(uint8_t * coap_message, uint16_t coap_length, uint8_t * payload)
- {
- struct Payload_Struct payload_struct = Get_Payload(coap_message, coap_length);
- if(payload_struct.valid)
- {
- for(uint8_t i = 0; i < payload_struct.length; i++)
- {
- payload[i] = coap_message[payload_struct.pos + i];
- }
- }
- else
- {
-
- }
- return payload_struct.length;
- }
|