uint16_t FUNCTION_ATTRIBUTE get_tlv_len(struct TLV *params_in) { uint8_t need_length; uint16_t type = 0; uint16_t length = 0; void *value_pos = NULL; if (params_in == NULL) { return -1; } pd_memcpy(&type, &(params_in->type), sizeof(params_in->type)); type = net16_to_host(type); need_length = is_tlv_need_length(type); if (need_length == 1) { pd_memcpy(&length, &(params_in->length), sizeof(params_in->length)); length = net16_to_host(length); } else { length = get_type_length(type); } return length; }
int FUNCTION_ATTRIBUTE pando_protocol_encode(struct pando_buffer *pdbuf, uint16_t *payload_type) { uint8_t *position = pdbuf->buffer + pdbuf->offset; uint8_t *buffer_end = pdbuf->buffer + pdbuf->buff_len; struct mqtt_bin_header m_header; struct device_header sub_device_header; struct device_header *header = (struct device_header*)position; if ((position += DEV_HEADER_LEN) > buffer_end) { pd_printf("Incorrect encode buffer length.\n"); return -1; } pd_memcpy(&payload_type, &(header->payload_type), sizeof(header->payload_type)); *payload_type = net16_to_host(*payload_type); pd_memcpy(&(sub_device_header.flags), &(header->flags), sizeof(header->flags)); sub_device_header.flags = net16_to_host(sub_device_header.flags); if (init_pdbin_header(&m_header, &sub_device_header)) { pd_printf("Init pdbin header failed.\n"); return -1; } position -= GATE_HEADER_LEN; pd_memcpy(position, &m_header, GATE_HEADER_LEN); pdbuf->offset = pdbuf->offset + DEV_HEADER_LEN - GATE_HEADER_LEN; return 0; }
char *pando_protocol_get_uri(struct pando_buffer *pdbuf) { if (pdbuf == NULL) { return NULL; } struct sub_device_buffer device_buffer; device_buffer.buffer_length = pdbuf->buff_len - pdbuf->offset; device_buffer.buffer = pdbuf->buffer + pdbuf->offset; struct pando_command cmd_body; struct TLV *cmd_param = get_sub_device_command(&device_buffer, &cmd_body); int i = 0; uint16_t tlv_type, tlv_length; for (i = 0; i < cmd_body.params->count; i++) { pd_memcpy(&tlv_type, &(cmd_param->type), sizeof(tlv_type)); tlv_type = net16_to_host(tlv_type); pd_memcpy(&tlv_length, &(cmd_param->length), sizeof(tlv_length)); tlv_length = net16_to_host(tlv_length); if (tlv_type == TLV_TYPE_URI) { return (char *)cmd_param->value; } cmd_param = (struct TLV *)((uint8_t *)cmd_param + sizeof(struct TLV) + tlv_length); } return NULL; }
struct TLV *get_next_property(struct pando_property *next_property, struct pando_property *property_body) { property_body->sub_device_id = net16_to_host(next_property->sub_device_id); property_body->property_num = net16_to_host(next_property->property_num); property_body->params->count = net16_to_host(next_property->params->count); return (struct TLV *)(next_property + sizeof(struct pando_property)); }
struct TLV * FUNCTION_ATTRIBUTE get_tlv_value(struct TLV *params_in, void *value) { uint8_t need_length; void *value_pos = NULL; uint16_t type_p; uint16_t length_p; uint16_t *type = &type_p; uint16_t *length = &length_p; pd_memcpy(type, &(params_in->type), sizeof(params_in->type)); *type = net16_to_host(*type); need_length = is_tlv_need_length(*type); if (need_length == 1) { pd_memcpy(length, &(params_in->length), sizeof(params_in->length)); *length = net16_to_host(*length); pd_memcpy(value, params_in->value, *length); } else { *length = get_type_length(*type); value_pos = (uint8_t *)params_in + sizeof(params_in->type); pd_memcpy(value, value_pos, *length); switch (*type) { case TLV_TYPE_FLOAT64: net64f_to_host(*(double *)value); break; case TLV_TYPE_UINT64: case TLV_TYPE_INT64: net64_to_host(*(uint64_t *)value); break; case TLV_TYPE_FLOAT32: net32f_to_host(*(float *)value); break; case TLV_TYPE_UINT32: case TLV_TYPE_INT32: net32_to_host(*(uint32_t *)value); break; case TLV_TYPE_INT8: case TLV_TYPE_UINT8: case TLV_TYPE_BOOL: break; case TLV_TYPE_INT16: case TLV_TYPE_UINT16: net16_to_host(*(uint16_t *)value); break; default: break; }//switch }//need_length == 0 return (struct TLV *)((uint8_t *)params_in + *length + sizeof(struct TLV) - (!need_length) * sizeof(*length)); }
struct TLVs * FUNCTION_ATTRIBUTE get_next_property( struct pando_property *next_property, struct pando_property *property_body) { property_body->sub_device_id = net16_to_host(next_property->sub_device_id); property_body->property_num = net16_to_host(next_property->property_num); property_body->params->count = net16_to_host(next_property->params->count); return (struct TLVs *)((uint8_t *)next_property + sizeof(struct pando_property) - sizeof(struct TLVs)); }
struct TLV *get_tlv_param(struct TLV *params_in, uint16_t *type, uint16_t *length, void *value) { uint8_t need_length; pd_memcpy(type, &(params_in->type), sizeof(params_in->type)); pd_memcpy(length, &(params_in->length), sizeof(params_in->type)); *type = net16_to_host(*type); *length = net16_to_host(*length); need_length = is_tlv_need_length(*type); if (need_length == 1) { value = params_in->value; } else { pd_memcpy(value, params_in->value, *length); switch (*type) { case TLV_TYPE_FLOAT64: net64f_to_host(*(double *)value); break; case TLV_TYPE_UINT64: case TLV_TYPE_INT64: net64_to_host(*(uint64_t *)value); break; case TLV_TYPE_FLOAT32: net32f_to_host(*(float *)value); break; case TLV_TYPE_UINT32: case TLV_TYPE_INT32: net32_to_host(*(uint32_t *)value); break; case TLV_TYPE_INT8: case TLV_TYPE_UINT8: case TLV_TYPE_BOOL: break; case TLV_TYPE_INT16: case TLV_TYPE_UINT16: net16_to_host(*(uint16_t *)value); break; default: break; }//switch }//need_length == 0 return (params_in + *length + sizeof(struct TLV) - need_length * sizeof(*length)); }
struct TLV * FUNCTION_ATTRIBUTE get_sub_device_property(struct sub_device_buffer *device_buffer, struct pando_property *property_body) { struct pando_property *tmp_body = (struct pando_property *)(device_buffer->buffer + DEV_HEADER_LEN); struct device_header *head = (struct device_header *)device_buffer->buffer; base_params.command_sequence = net32_to_host(head->frame_seq); property_body->sub_device_id = net16_to_host(tmp_body->sub_device_id); property_body->property_num = net16_to_host(tmp_body->property_num); property_body->params->count = net16_to_host(tmp_body->params->count); return (struct TLV *)(device_buffer->buffer + DEV_HEADER_LEN + sizeof(struct pando_property)); }
uint16_t FUNCTION_ATTRIBUTE get_tlv_type(struct TLV *params_in) { uint16_t type = 0; pd_memcpy(&type, &(params_in->type), sizeof(params_in->type)); type = net16_to_host(type); return type; }
struct TLVs * FUNCTION_ATTRIBUTE get_sub_device_command( struct sub_device_buffer *device_buffer, struct pando_command *command_body) { struct pando_command *tmp_body = (struct pando_command *)(device_buffer->buffer + DEV_HEADER_LEN); //需要对包头进行校验,尚未编写 struct device_header *head = (struct device_header *)device_buffer->buffer; base_params.command_sequence = net32_to_host(head->frame_seq); command_body->sub_device_id = net16_to_host(tmp_body->sub_device_id); command_body->command_num = net16_to_host(tmp_body->command_num); command_body->priority = net16_to_host(tmp_body->priority); command_body->params->count = net16_to_host(tmp_body->params->count); return (struct TLVs *)(device_buffer->buffer + DEV_HEADER_LEN + sizeof(struct pando_command) - sizeof(struct TLVs)); }
//pdbuf points to the buffer contains command from server ,it's big endian. uint16_t pando_protocol_get_payload_type(struct pando_buffer *pdbuf) { if (pdbuf == NULL) { return -1; } struct device_header *gateway_header = (struct device_header *)(pdbuf->buffer + pdbuf->offset); return net16_to_host(gateway_header->payload_type); }
static struct TLV FUNCTION_ATTRIBUTE *get_current_tlv(struct TLVs *params) { if (s_current_param.handled_length == 0) //first tlv { s_current_param.tlv_count = net16_to_host(params->count); } return (struct TLV *)((uint8_t *)params + sizeof(struct TLVs) + s_current_param.handled_length); }
struct TLV * FUNCTION_ATTRIBUTE get_sub_device_command(struct sub_device_buffer *device_buffer, struct pando_command *command_body) { struct pando_command *tmp_body = (struct pando_command *)(device_buffer->buffer + DEV_HEADER_LEN); //需要对包头进行校验,尚未编写 struct device_header *head = (struct device_header *)device_buffer->buffer; base_params.command_sequence = net32_to_host(head->frame_seq); command_body->sub_device_id = net16_to_host(tmp_body->sub_device_id); /* if ((command_body->sub_device_id = net16_to_host(tmp_body->sub_device_id)) != base_params.sub_device_id) { pd_printf("Local sub device id: %d, receive a command to id : %d.\n", base_params.sub_device_id, command_body->sub_device_id); return -1; }*/ command_body->command_id = net16_to_host(tmp_body->command_id); command_body->priority = net16_to_host(tmp_body->priority); command_body->params->count = net16_to_host(tmp_body->params->count); return (struct TLV *)(device_buffer->buffer + DEV_HEADER_LEN + sizeof(struct pando_command)); }
uint16_t FUNCTION_ATTRIBUTE get_sub_device_payloadtype(struct sub_device_buffer *package) { struct device_header *head; if (package == NULL) { return -1; } head = (struct device_header *)package->buffer; return net16_to_host(head->payload_type); }
int pando_protocol_get_sub_device_id(struct pando_buffer *buf, uint16_t *sub_device_id) { uint8_t *pos = buf->buffer + GATE_HEADER_LEN + buf->offset; if (pos == NULL) { pd_printf("subdevice null\n"); return -1; } else { pd_memcpy(sub_device_id, pos, sizeof(*sub_device_id)); *sub_device_id = net16_to_host(*sub_device_id); return 0; } }
int add_next_property(struct sub_device_buffer *data_package, uint16_t property_num, struct TLVs *next_data_params) { uint8_t *new_buffer = NULL; uint8_t *position = NULL; struct device_header *hdr = (struct device_header *)data_package->buffer; uint16_t payload_len = 0; uint16_t append_len = sizeof(struct pando_property) + current_tlv_block_size - sizeof(struct TLVs); if (data_package == NULL) { return -1; } /* append payload length */ payload_len = net16_to_host(hdr->payload_len); data_package->buffer_length += append_len; payload_len += append_len; hdr->payload_len = host16_to_net(payload_len); new_buffer = (uint8_t *)pd_malloc(data_package->buffer_length); pd_memset(new_buffer, 0, data_package->buffer_length); /* copy buffer content, skip subdev id, copy property num and tlv params */ position = new_buffer + data_package->buffer_length - append_len; pd_memcpy(new_buffer, data_package->buffer, data_package->buffer_length); position += 2; //sub device id property_num = host16_to_net(property_num); pd_memcpy(position, &property_num, sizeof(property_num)); position += sizeof(property_num); pd_memcpy(position, next_data_params, current_tlv_block_size); pd_free(data_package->buffer); data_package->buffer = new_buffer; return 0; }
void ICACHE_FLASH_ATTR weektask_set(struct weektask* value) { // TODO: implement object set function here. // the set function read value and operate the hardware. int len1 = os_strlen(value->weekday); int len2 = os_strlen(value->time); uint8 temp[5]; uint16 delay = net16_to_host(value->delay); //minute int8 repeat = value->repeat; //1:repeat, 0: not repeat int8 enable = value->enable; //1: enable, 0: disable int i,j=0; uint16 id = 0; for(i=0; i<2*TASK_BUF_MAX_LENGTH; i++) { task_buf[i] = 0; } PRINTF("\nweektask_set weekday:%s, time:%s, len1:%d,len2:%d,delay:%d,repeat:%d, enable:%d\n", value->weekday, value->time,len1, len2, delay, repeat, enable); if((len1 <= 0) || (len1 > 7)) { PRINTF("\nlen1:%d\n",len1); return; } PRINTF("\npass len1:%d\n",len1); if(len2 != 5) { PRINTF("\nlen2:%d\n",len2); return; } if((repeat != 0) && (repeat != 1)) { PRINTF("\nrepeat:%d\n",repeat); return; } if((enable != 0) && (enable != 1)) { PRINTF("\nenable:%d\n",enable); return; } spi_flash_read((PRIV_PARAM_START_SEC + WEEKTASK_FLASH_SECTOR_NO) * SPI_FLASH_SEC_SIZE, (uint32 *)task_buf, TASK_BUF_MAX_LENGTH); for(i=0; i<4; i++) { temp[i] = task_buf[i]; } temp[i] = '\0'; id = (uint16)strtol(temp, NULL, 16); if(id >= 0xFFFD) { id = 0; } id++; os_sprintf(&task_buf[0], "%04X", id); j=4; for(i=0; i < len1; i++) { if((value->weekday[i]> '0') && (value->weekday[i] <= '7')) task_buf[j++] = value->weekday[i]; } if(j<11) { for(i=j; i<11; i++) task_buf[i] = '0'; } for(i=0,j=11; i<len2; i++) { if((i == 2) && (value->time[i] != ':')) { PRINTF("\nquit i:%d\n",i); return; } else if((i!=2) && ((value->time[i] < '0') || (value->time[i] > '9'))) { PRINTF("\nvalue->time[%d]:%X\n",i, value->time[i]); return; } task_buf[j++] = value->time[i]; } os_sprintf(&task_buf[j], "%04X%X%X", delay, repeat, enable); PRINTF("\n Get weektask:%s\n", task_buf); for(i=0, j=TASK_BUF_MAX_LENGTH; i<TASK_BUF_MAX_LENGTH; i++,j++) { task_buf[j] = task_buf[i]; } spi_flash_erase_sector(PRIV_PARAM_START_SEC + WEEKTASK_FLASH_SECTOR_NO); spi_flash_write((PRIV_PARAM_START_SEC + WEEKTASK_FLASH_SECTOR_NO) * SPI_FLASH_SEC_SIZE, (uint32 *)task_buf, 2*TASK_BUF_MAX_LENGTH); }
int FUNCTION_ATTRIBUTE add_next_param(struct TLVs *params_block, uint16_t next_type, uint16_t next_length, void *next_value) { uint16_t type; uint16_t conver_length; uint8_t need_length; uint8_t tlv_length; uint8_t tmp_value[8]; uint8_t *tlv_position; struct TLVs *new_property_block = NULL; uint16_t current_count = net16_to_host(params_block->count); //由于create的时候就对该值进行了端转换,因此需要回转 need_length = is_tlv_need_length(next_type); if (1 == need_length) { } else if (0 == need_length) { if(next_length != get_type_length(next_type)) { printf("Param type dismatch with the input length\n"); return -1; } } else { return -1; } //信息区扩容 if (current_tlv_block_size + next_length + sizeof(struct TLV) - (!need_length) * sizeof(next_length) > tlv_block_buffer_size) { tlv_block_buffer_size = tlv_block_buffer_size + DEFAULT_TLV_BLOCK_SIZE + next_length; new_property_block = (struct TLVs *)pd_malloc(tlv_block_buffer_size); pd_memcpy(new_property_block, params_block, current_tlv_block_size); pd_free(params_block); params_block = new_property_block; } current_count++; tlv_position = (uint8_t *)params_block + current_tlv_block_size; //将count保存为网络字节序,便于创建事件或数据包时直接赋值 params_block->count = host16_to_net(current_count); //复制tlv内容,并大小端转换,修正tlv长度和type的设置方式,解决跨字错误 type = host16_to_net(next_type); pd_memcpy(tlv_position, &type, sizeof(type)); tlv_position += sizeof(type); if (need_length) { conver_length = host16_to_net(next_length); pd_memcpy(tlv_position, &conver_length, sizeof(conver_length)); tlv_position += sizeof(conver_length); } switch(next_type) { case TLV_TYPE_FLOAT64 : *((double *)tmp_value) = host64f_to_net(*((uint64_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_FLOAT32 : *((float *)tmp_value) = host32f_to_net(*((float *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_INT16: *((int16_t *)tmp_value) = host16_to_net(*((int16_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_UINT16: *((uint16_t *)tmp_value) = host16_to_net(*((uint16_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_INT32: *((int32_t *)tmp_value) = host32_to_net(*((int32_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_UINT32: *((uint32_t *)tmp_value) = host32_to_net(*((uint32_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_UINT64: *((uint64_t *)tmp_value) = host64_to_net(*((uint64_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; case TLV_TYPE_INT64: *((int64_t *)tmp_value) = host64_to_net(*((int64_t *)next_value)); pd_memcpy(tlv_position, tmp_value, next_length); break; default: pd_memcpy(tlv_position, next_value, next_length); break; } current_tlv_block_size = current_tlv_block_size + next_length + sizeof(struct TLV) - (!need_length) * sizeof(next_length); return 0; }