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;
}
Esempio n. 17
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;
}