helloyifa 31f179cb76 init
2025-05-15 14:19:56 +08:00

1383 lines
42 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <components/log.h>
#include <components/system.h>
#include <os/os.h>
#include <components/shell_task.h>
#include <common/bk_include.h>
#include "gpio_map.h"
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <common/bk_kernel_err.h>
//#include "bk_wifi_netif.h"
#include "bk_wifi.h"
#include <os/str.h>
#include "bk_uart.h"
#include <os/mem.h>
#include <os/os.h>
#include <common/bk_kernel_err.h>
#include <string.h>
//#include "wlan_ui_pub.h"
//#include <lwip/inet.h>
#include <driver/uart.h>
#include "common.h"
#include "ilock_client.h"
#define TAG "iLock"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define SET_BIT(x, bit) (x |= (1 << bit)) /* 置1第bit位 */
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) /* 获取第bit位 */
#define CLEAR_BIT(x, bit) (x &= ~(1 << bit)) /* 清零第bit位 */
static const int RX_BUF_SIZE = 128;
//static const char *ILOCK_TAG = "ILOCK_CLIENT";
static uart_id_t uart_id = UART_ID_1;
//static uart_id_t uart_id = UART_ID_2;
static beken_thread_t ilock_thread_hdl = NULL;
ilock_dev dev_info_lasted;
static int serial_num = 0;
static char ilock_device_id[32] = {0};
static beken_queue_t uart1_msg_q = NULL;
static beken_queue_t lock_command_q = NULL;
//static lock_package_t lock_pack;
static lock_command_t lock_command;
static beken_semaphore_t uart_rx_semaphore = NULL;
static int rx_start = 0;
static int is_ota = 0;
typedef enum
{
NULL_MSG = 0,
UART_TX_MSG,
UART_RX_MSG,
} UartMessageType;
typedef struct
{
UartMessageType type;
int len;
uint8_t *msg;
} UartMessage;
#define CMD_LOCK_START 0xAA
#define CMD_LOCK_END 0xAA
#define CMD_PACKAGE_LEN_MAX 128
#define UART_BAUDRATE 9600
#define ILOCK_CHECK_CRC 0
//######### OTA ##########
int ota_start_result = 0;
int ota_sdata_result = 0;
int ota_end_result = 0;
#define OTA_NEED_WAIT_RESP 1
typedef enum
{
STATUS_IDLE =0,
STATUS_HEAD,/*获取标志头*/
STATUS_LEN, /*获取长度*/
STATUS_DATA,/*获取数据*/
STATUS_CRC1,/*获取CRC1*/
STATUS_CRC2,/*获取CRC2*/
} ilock_recv_t;
static unsigned char recv_buff[CMD_PACKAGE_LEN_MAX];
static int data_len;
static int recv_len;
static ilock_recv_t recv_state = STATUS_IDLE;
static ilock_client_cb_ops_t *event_cb;
void ilock_set_callback(ilock_client_cb_ops_t *cb_ops){
event_cb = cb_ops;
}
static void uart_example_rx_isr(uart_id_t id, void *param)
{
BK_LOGE(TAG, "uart(%d) enter uart_example_rx_isr\r\n", id);
int ret;
ret = rtos_set_semaphore(&uart_rx_semaphore);
if(kNoErr !=ret){
os_printf("rx_isr: set sema failed\r\n");
}
}
void ilock_uart_init(void) {
uart_config_t config = {0};
os_memset(&config, 0, sizeof(uart_config_t));
config.baud_rate = UART_BAUDRATE; //115200 8130 38400
config.data_bits = UART_DATA_8_BITS;
config.parity = UART_PARITY_NONE;
config.stop_bits = UART_STOP_BITS_1;
config.flow_ctrl = UART_FLOWCTRL_DISABLE;
//config.src_clk = UART_SCLK_XTAL_26M;
int ret = bk_uart_is_in_used(uart_id);
warning_prf("bk_uart_is_in_used : %d \r\n",ret);
BK_LOG_ON_ERR(bk_uart_init(uart_id, &config));
//CLI_LOGI("uart init, uart_id=%d\n", uart_id);
BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, UART_BAUDRATE));
//bk_uart_disable_sw_fifo(uart_id);
//bk_uart_register_rx_isr(uart_id, (uart_isr_t)uart_example_rx_isr, NULL);
bk_uart_enable_rx_interrupt(uart_id);
//BK_LOG_ON_ERR(bk_uart_enable_rx_interrupt(uart_id));
//BK_LOG_ON_ERR(bk_uart_register_rx_isr(uart_id, uart_example_rx_isr, NULL));
}
void ilock_uart_deinit(){
bk_uart_deinit(uart_id);
}
char * ilock_client_get_device_id(){
return ilock_device_id;
}
int ilock_crc16_modbus(uint8_t *CRC_buf, int len)
{ // x16+x15+x2+1
int CRC_ReturnValue = 0xffff;
int i, j, temp;
for (i = 0; i < len; i++)
{
//BK_LOGE(TAG, "+++%02x\r\n", CRC_buf[i]);
temp = CRC_buf[i] & 0xff;
CRC_ReturnValue ^= temp;
j = 8;
while (j != 0)
{
if ((CRC_ReturnValue & 0x01) != 0)
CRC_ReturnValue = (CRC_ReturnValue >> 1) ^ 0xA001;
else
CRC_ReturnValue = CRC_ReturnValue >> 1;
j--;
}
}
return CRC_ReturnValue;
}
int ilock_sendData(char* data,int len)
{
bk_uart_write_bytes(uart_id, data, len);
return -1;
}
int ilock_gen_package( lock_command_t *command,uint8_t cmd_type,uint8_t cmd,uint8_t*cmd_data,int data_len){
//AA packlen 0x01(4bit-serial 4bit-cmdtype) cmd body 0x010x02(crc)
command->cmd_len = data_len+6;
command->cmds[0] = 0xAA;
command->cmds[1] = (data_len+4)&0xFF;
//serial
if(serial_num > 0xF){
serial_num = 0;
}else{
serial_num++;
}
//cmd_type
switch (cmd_type)
{
case CMD_TYPE_REQ:
command->cmds[2]= 0x11;
break;
case CMD_TYPE_RET:
command->cmds[2]= 0xD2;
break;
case CMD_TYPE_REC:
command->cmds[2]= 0xD3;
break;
default:
break;
}
command->cmds[2] = command->cmds[2]&0xF;// 0000xyzu 高位0000
//serialno
int bit0 = GET_BIT(serial_num,0);
int bit1 = GET_BIT(serial_num,1);
int bit2 = GET_BIT(serial_num,2);
int bit3 = GET_BIT(serial_num,3);
if(bit0){
SET_BIT(command->cmds[2],4);
}
if(bit1){
SET_BIT(command->cmds[2],5);
}
if(bit2){
SET_BIT(command->cmds[2],6);
}
if(bit3){
SET_BIT(command->cmds[2],7);
}
command->serial_no = command->cmds[2]>>4;
//BK_LOGE(TAG, "serial-->%d\r\n", cmds[2]>>4 );
command->cmds[3]= cmd;
if(cmd_data!=NULL && data_len != 0){
os_memcpy(&command->cmds[4], cmd_data, data_len);
}
int crc = ilock_crc16_modbus(&command->cmds[2],data_len+2);
int cmd_len = sizeof(command->cmds);
command->cmds[cmd_len-2] = (crc >> 8);
command->cmds[cmd_len-1] = (crc & 0xff);
//BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, UART_BAUDRATE));
//bk_uart_write_bytes(uart_id, command->cmds, cmd_len);
return command->cmd_len;
}
int ilock_ol(char *message_id,int uid){
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
if(uid != -1){
data[1] = (uid >> 24) &0xff;
data[2] = (uid >> 16) &0xff;
data[3] = (uid >> 8) &0xff;
data[4] = uid&0xff;
}
BK_LOGE(TAG, "ilock_open_lock");
BK_LOGE(TAG, "open_lock:%02X%02X%02X%02X\n",data[1],data[2],data[3],data[4]);
lock_command_t command;
command.cmd_type = 0x40;
memset(command.message_id,0,sizeof(command.message_id));
strcpy((char *)command.message_id,message_id);
ilock_gen_package(&command,CMD_TYPE_REQ,0x40,(uint8_t*)&data,sizeof(data));
BK_LOGE(TAG, "ilock_send_lock_commond:%s",command.message_id);
rtos_push_to_queue(&lock_command_q, &command, BEKEN_NEVER_TIMEOUT);
return 1;
}
int ilock_send_package(uint8_t cmd_type,uint8_t cmd,uint8_t*cmd_data,int data_len){
//AA packlen 0x01(4bit-serial 4bit-cmdtype) cmd body 0x010x02(crc)
uint8_t cmds[data_len+6];
os_memset(&cmds, 0, sizeof(cmds));
cmds[0] = 0xAA;
cmds[1] = (data_len+4)&0xFF;
//serial
if(serial_num > 0xF){
serial_num = 0;
}else{
serial_num++;
}
//cmd_type
switch (cmd_type)
{
case CMD_TYPE_REQ:
cmds[2]= 0x11;
break;
case CMD_TYPE_RET:
cmds[2]= 0xD2;
break;
case CMD_TYPE_REC:
cmds[2]= 0xD3;
break;
default:
break;
}
cmds[2] = cmds[2]&0xF;// 0000xyzu 高位0000
//serialno
int bit0 = GET_BIT(serial_num,0);
int bit1 = GET_BIT(serial_num,1);
int bit2 = GET_BIT(serial_num,2);
int bit3 = GET_BIT(serial_num,3);
if(bit0){
SET_BIT(cmds[2],4);
}
if(bit1){
SET_BIT(cmds[2],5);
}
if(bit2){
SET_BIT(cmds[2],6);
}
if(bit3){
SET_BIT(cmds[2],7);
}
//BK_LOGE(TAG, "serial-->%d\r\n", cmds[2]>>4 );
cmds[3]= cmd;
if(cmd_data!=NULL && data_len != 0){
os_memcpy(&cmds[4], cmd_data, data_len);
}
int crc = ilock_crc16_modbus(&cmds[2],data_len+2);
int cmd_len = sizeof(cmds);
cmds[cmd_len-2] = (crc >> 8);
cmds[cmd_len-1] = (crc & 0xff);
BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, UART_BAUDRATE));
bk_uart_write_bytes(uart_id, cmds, cmd_len);
#if 0
//lock_command
int count = 0;
while(1){
rtos_delay_milliseconds(300);
if(count>10){
BK_LOGE(TAG, "cmd-->FAILED!!!\r\n", cmds[2]>>4 );
break;
}
if(lock_command.cmd_type == cmd_type ){
BK_LOGE(TAG, "$$$$$$$$$$$$$\r\n");
break;
}else{
BK_LOGE(TAG, "@@@@@@@@@@@@@ type:%02X resp_state:%02X \r\n",lock_command.cmd_type ,lock_command.resp_state);
}
count++;
}
BK_LOGE(TAG, "FINISH!!!!!!!!!\r\n");
for (int i = 0; i < sizeof(cmds); i++) {
BK_LOGE(TAG, "-->%02x\r\n", cmds[i]);
}
#endif
return 1;
}
int ilock_cmds(char*cmds,int cmd, char* playload,int playload_len){
//char cmds[10] = {0xAA, 0x08, 0x11, 0x41, 0x0B, 0x00, 0x00, 0x00, 0xB1, 0x00};
//bk_uart_write_bytes(uart_id, cmds, sizeof(cmds));
return 1;
}
int ilock_read_state(){
BK_LOGE(TAG, "ilock_read_state\n");
ilock_send_package(CMD_TYPE_REQ,0x44,NULL,0);
return 1;
}
int ilock_set_utc(long utc){
BK_LOGE(TAG, "ilock_set_utc:%lld\n",utc);
uint8_t data[4] = {0x00};
data[0] = (utc >> 24) &0xff;
data[1] = (utc >> 16) &0xff;
data[2] = (utc >> 8) &0xff;
data[3] = utc&0xff;
//BK_LOGE(TAG, "utc:%02X%02X%02X%02X\n",data[0],data[2],data[2],data[3]);
ilock_send_package(CMD_TYPE_REQ,0x12,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_ping(){
BK_LOGE(TAG, "ilock_ping");
//ilock_send_package(CMD_TYPE_REQ,0xE4,NULL,0);
uint8_t data[1] = {0x01};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_read_version(){
ilock_send_package(CMD_TYPE_REQ,0x21,NULL,0);
return 1;
}
int ilock_read_serialno(){
ilock_send_package(CMD_TYPE_REQ,0x20,NULL,0);
return 1;
}
//*
//1 or 3
int ilock_play_voice(int voice_index){
uint8_t data[1] = {voice_index};
ilock_send_package(CMD_TYPE_REQ,0x48,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_factory_reset(){
BK_LOGE(TAG, "ilock_factory_reset");
uint8_t data[5] = {0};
ilock_send_package(CMD_TYPE_REQ,0x24,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_open_lock(int uid){
//aa 0b 81 40 06 43 bb 8b a6 1f 03 88 6d
//bk_uart_set_baud_rate(uart_id, 8130);
//unsigned char wakeup[4] = {0x0F,0xF0,0xFF,0xFF};
//bk_uart_write_bytes(uart_id, wakeup, sizeof(wakeup));
//rtos_delay_milliseconds(50);
//unsigned char cmds[6] = {0xAA,0x04,0xD1,0x44,0xD0,0x9D};
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
if(uid != -1){
data[1] = (uid >> 24) &0xff;
data[2] = (uid >> 16) &0xff;
data[3] = (uid >> 8) &0xff;
data[4] = uid&0xff;
}
BK_LOGE(TAG, "ilock_open_lock");
ilock_send_package(CMD_TYPE_REQ,0x40,(uint8_t*)&data,sizeof(data));
BK_LOGE(TAG, "open_lock:%02X%02X%02X%02X\n",data[1],data[2],data[3],data[4]);
return 0;
}
int ilock_open_lock_sos(int uid){
BK_LOGE(TAG, "ilock_open_lock_sos");
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
if(uid != -1){
data[1] = (uid >> 24) &0xff;
data[2] = (uid >> 16) &0xff;
data[3] = (uid >> 8) &0xff;
data[4] = uid&0xff;
}
ilock_send_package(CMD_TYPE_REQ,0x4A,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_open_camera(){
BK_LOGE(TAG, "ilock_open_camera");
uint8_t data[1] = {0x01};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_close_camera(){
BK_LOGE(TAG, "\n\nilock_close_camera\n\n");
uint8_t data[1] = {0x00};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_close_lock(int uid){
BK_LOGE(TAG, "ilock_close_lock");
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
if(uid != -1){
data[1] = (uid >> 24) &0xff;
data[2] = (uid >> 16) &0xff;
data[3] = (uid >> 8) &0xff;
data[4] = uid&0xff;
}
ilock_send_package(CMD_TYPE_REQ,0x41,(uint8_t*)&data,sizeof(data));
return 0;
}
/*
*获取锁体参数
*/
int ilock_read_lock_params(){
ilock_send_package(CMD_TYPE_REQ,0x23,NULL,0);
return 0;
}
static void ilock_parser_data(uint8_t *recv, int len){
if(recv == NULL || len == 0) return;
if(recv[0]!= 0xAA && len < 2) return;
uint8_t data_len = recv[1];
//LOGE("data len: %d \n", data_len);
LOGE("\n");
LOGE("data len: %d \n", data_len);
//命令序号
uint8_t serial_no = (recv[2]&0xF0)>>4;
LOGE("serial_no: %d \n", serial_no);
//判断数据类型
uint8_t type = (recv[2]&0xF);
switch (type)
{
case 1://req
LOGE("data type: req\n");
break;
case 2://resp
LOGE("data type: resp\n");
break;
case 3://receipt
LOGE("data type: receipt\n");
break;
default:
break;
}
LOGE("cmd: %2x\n", recv[3]);
if(type == 1){
switch (recv[3])
{
case 0x47:{
uint8_t event = recv[4];
char str_state[32] = {0};
sprintf(str_state,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",recv[0],recv[1],recv[2],recv[3],recv[4],recv[5],recv[6],recv[7],recv[8],
recv[9],recv[10],recv[11],recv[12],recv[13],recv[14],recv[15],recv[16],recv[17],recv[18]);
LOGE("state: %s\n",str_state);
//char str_state[32] = {0};
//sprintf(str_state,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",recv[5],recv[6],recv[7],recv[8],
//recv[9],recv[10],recv[11],recv[12],recv[13],recv[14],recv[15],recv[16],recv[17],recv[18]);
//LOGE("state: %s\n",str_state);
//获取状态数据体长度(去标志头尾等)
int status_len = data_len - 5 -2 ;
//循环判断key 和 value
ilock_dev dev_info;
dev_info.event_code = event;
for(int i = 0 ;i<status_len ;i++){
int index = 5+i;
int key = recv[index];
//LOGE("key: %02X\n",key);
switch(key){
case 0x01:
dev_info.lock_lock_state= recv[index+1];
i++;
break;
case 0x02:
dev_info.lock_door_state = recv[index+1];
i++;
break;
case 0x03:
dev_info.lock_lockedin_state = recv[index+1];
i++;
break;
case 0x04:
dev_info.lock_power_supply = recv[index+1];
i++;
break;
case 0x05:
dev_info.lock_batt_value = recv[index+1];
i++;
break;
case 0x06:
dev_info.lock_batt_state = recv[index+1];
i++;
break;
case 0x07:
dev_info.lock_disable_lock_state = recv[index+1];
i++;
break;
case 0xF0:
i = i+2; //F0 的值为2个字节
break;
case 0xF1:
i = i+4; //F1 的值为4个字节
break;
}
//LOGE("value: %02X\n",recv[5+i+1]);
//i++;
}
//LOGE(" batt_value> %d \r\n,",dev_info.lock_batt_value);
//LOGE(" lock_door_state> %d \r\n,",dev_info.lock_door_state);
//LOGE(" lock_lock_state> %d \r\n,",dev_info.lock_lock_state);
if (event_cb != NULL)
event_cb->event_lock_state(&dev_info);
break;
}
case 0x48:
if (event_cb != NULL)
event_cb->event_doorbell(0,0);
break;
case 0x49:
if (event_cb != NULL)
event_cb->event_network_boarding();
break;
}
}
if(type == 2){ //resp
switch (recv[3])
{
//OTA START 回复
case 0x70:
ota_start_result = 1;
break;
//OTA DATA 回复
case 0x71:
ota_sdata_result = 1;
break;
//OTA END 回复
case 0x72:
ota_end_result = 1;
break;
//获取版本号回复
case 0x21:
if(recv[4] == 0){
LOGE("read version: succ\n");
LOGE("%02X%02X%02X%02X\n",recv[5],recv[6],recv[7],recv[8]);
char str_version[8] = {0};
sprintf(str_version,"%02X%02x%02X%02X",recv[5],recv[6],recv[7],recv[8]);
if (event_cb != NULL)
event_cb->event_lock_version(str_version,strlen(str_version));
}
break;
//获取锁体状态回复
case 0x23:
if(recv[4] == 0){
LOGE("read param: succ\n");
int body_len = data_len - 3 - 2;
LOGE("body_len: %d\n",body_len);
char str_params[body_len];
os_memcpy(&str_params[0], &recv[5], body_len);
#if 0
for (int i = 0; i < body_len; i++) {
BK_LOGE(TAG, "%02X\r\n", str_params[i]);
}
#endif
if (event_cb != NULL)
event_cb->event_lock_params(str_params,body_len);
}
else{
LOGE("read param: fail\n");
}
break;
case 0x40:
if(recv[4] == 0){
LOGE("unlock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_unlock(1);
}
else{
LOGE("unlock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_unlock(0);
}
break;
case 0x4A:
LOGE("sos unlock: succ lock_command.cmd_type%02X\n",lock_command.cmd_type);
if(recv[4] == 0){
if(lock_command.cmd_type == 0x4A){
lock_command.resp_state=1;
lock_command.cmd_result = 1;
}
LOGE("sos unlock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_unlock_sos(1);
}
else{
if(lock_command.cmd_type == 0x4A){
lock_command.resp_state=1;
lock_command.cmd_result = 0;
}
LOGE("sos unlock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_unlock_sos(0);
}
break;
case 0x41:
if(recv[4] == 0){
LOGE("lock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_lock(1);
}
else{
LOGE("lock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_lock(0);
}
break;
case 0x44:{
LOGE("event: %d\n",recv[4]);
char str_state[32] = {0};
sprintf(str_state,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",recv[5],recv[6],recv[7],recv[8],
recv[9],recv[10],recv[11],recv[12],recv[13],recv[14],recv[15],recv[16],recv[17],recv[18]);
LOGE("state: %s\n",str_state);
//获取状态数据体长度(去标志头尾等)
int status_len = data_len - 5 -2 ;
//循环判断key 和 value
ilock_dev dev_info;
for(int i = 0 ;i<status_len ;i++){
int index = 5+i;
int key = recv[index];
//LOGE("key: %02X\n",key);
switch(key){
case 0x01:
dev_info.lock_lock_state= recv[index+1];
i++;
break;
case 0x02:
dev_info.lock_door_state = recv[index+1];
i++;
break;
case 0x03:
dev_info.lock_lockedin_state = recv[index+1];
i++;
break;
case 0x04:
dev_info.lock_power_supply = recv[index+1];
i++;
break;
case 0x05:
dev_info.lock_batt_value = recv[index+1];
i++;
break;
case 0x06:
dev_info.lock_batt_state = recv[index+1];
i++;
break;
case 0x07:
dev_info.lock_disable_lock_state = recv[index+1];
i++;
break;
case 0xF0:
i = i+2; //F0 的值为2个字节
break;
case 0xF1:
i = i+4; //F1 的值为4个字节
break;
}
//LOGE("value: %02X\n",recv[5+i+1]);
//i++;
}
//LOGE(" batt_value> %d \r\n,",dev_info.lock_batt_value);
//LOGE(" lock_door_state> %d \r\n,",dev_info.lock_door_state);
//LOGE(" lock_lock_state> %d \r\n,",dev_info.lock_lock_state);
if (event_cb != NULL)
event_cb->event_lock_state(&dev_info);
break;
}
case 0x47:
break;
default:
break;
}
}
LOGE("\n");
if (event_cb != NULL)
event_cb->event_lock_recv_data(recv,len);
}
static void ilock_rx_task(void *arg)
{
uint8_t *data = (uint8_t *)os_malloc(RX_BUF_SIZE+1);
#if 0
//char *msg = NULL;
int ret = -1;
int cnt = 0;
uint8_t rx_data;
while (1) {
ret = rtos_get_semaphore(&uart_rx_semaphore, BEKEN_WAIT_FOREVER);
if(kNoErr == ret) {
while(1) /* read all data from rx-FIFO. */
{
ret = uart_read_byte_ex(uart_id, &rx_data);
if (ret == -1)
break;
data[cnt] = (char)rx_data;
cnt++;
if(cnt >= RX_BUF_SIZE)
break;
}
//bkreg_run_command1(data, cnt);
if(cnt > 0){
uint8_t *buff = (uint8_t *)os_malloc(cnt);
if(buff)
{
os_memcpy(buff, data, cnt);
UartMessage uMsg;
uMsg.len = cnt;
uMsg.msg = buff;
uMsg.type = UART_RX_MSG;
bk_err_t ret = rtos_push_to_queue(&uart1_msg_q, &uMsg, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
os_free(buff);
}
}
memset(data,0,RX_BUF_SIZE+1);
cnt = 0;
}
}
}
#else
while (rx_start) {
//ilock_sendData("hello world!!",3);
int rxBytes = bk_uart_read_bytes(uart_id, data, RX_BUF_SIZE, BEKEN_WAIT_FOREVER);//ms BEKEN_WAIT_FOREVER 200
if (rxBytes > 0) {
data[rxBytes] = 0;
uint8_t *buff = (uint8_t *)os_malloc(rxBytes);
if(buff)
{
os_memcpy(buff, data, rxBytes);
UartMessage uMsg;
uMsg.len = rxBytes;
uMsg.msg = buff;
uMsg.type = UART_RX_MSG;
bk_err_t ret = rtos_push_to_queue(&uart1_msg_q, &uMsg, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
os_free(buff);
}
}
//BK_LOGE(TAG, "uart recv data:\r\n");
//bk_uart_write_bytes(uart_id, data, rxBytes);
//for (int i = 0; i < rxBytes; i++) {
// BK_LOGE(TAG, "%02X\r\n", data[i]);
//}
//warning_prf("Read %d bytes: %s \r\n",rxBytes,data);
}else{
//warning_prf("Read ..\r\n");
}
}
#endif
if(data) {
os_free(data);
}
data = NULL;
BK_LOGE(TAG, "lock_rx_task finish \r\n");
}
/**
* 处理命令
* 1.判断命令类型
* 2.组装命令
* 3.发送命令
* 4.while命令结果
* 5.命令是否超时 重复一次
* 6.回调结果
*/
void lock_command_handle_thread( beken_thread_arg_t arg )
{
while(1)
{
bk_err_t ret = rtos_pop_from_queue(&lock_command_q, &lock_command, BEKEN_WAIT_FOREVER);
if(kNoErr != ret)
{
}
BK_LOGE(TAG, "handle_thread:%02X\r\n",lock_command.cmd_type);
//rtos_delay_milliseconds(1000);
switch(lock_command.cmd_type)
{
case CMD_OPEN_LOCK:
break;
case CMD_OPEN_LOCK_SOS:
BK_LOGE(TAG, "lock_command_q -> CMD_OPEN_LOCK_SOS\r\n");
//ilock_open_lock_sos();
break;
case CMD_CLOSE_LOCK:
break;
default:
os_printf("unknown msg\r\n");
break;
}
}
}
int ilock_send_lock_commond(char *message_id,int cmd_type,int param){
BK_LOGE(TAG, "ilock_send_lock_commond:%02x",cmd_type);
lock_command_t command;
command.cmd_type = cmd_type;
memset(command.message_id,0,sizeof(command.message_id));
strcpy((char *)command.message_id,message_id);
BK_LOGE(TAG, "ilock_send_lock_commond:%s",command.message_id);
bk_err_t ret = rtos_push_to_queue(&lock_command_q, &command, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
}
BK_LOGE(TAG, "ilock_send_lock_commond: succ");
return 1;
}
/**
* 对接收到的串口数据进行分包解析处理
*/
static ilock_recv_t parser_data(unsigned char data){
//BK_LOGE(TAG,"%02X ", data&0xFF);
if(recv_len == CMD_PACKAGE_LEN_MAX){
recv_len = 0;
recv_state = STATUS_IDLE;
}
switch(recv_state){
case STATUS_IDLE:
case STATUS_HEAD://接收0xAA头
if(data == CMD_LOCK_START){
recv_len = 0;
recv_buff[recv_len++] = data;
recv_state = STATUS_LEN;
}
break;
case STATUS_LEN://接收LEN
data_len = data;
recv_buff[recv_len++] = data;
recv_state = STATUS_DATA;
break;
case STATUS_DATA://接收DATA
recv_buff[recv_len++] = data;
if(recv_len== data_len) {
//DATA接收到缓冲区完成
recv_state = STATUS_CRC1;
}
break;
case STATUS_CRC1://接收CRC1
recv_buff[recv_len++] = data;
recv_state = STATUS_CRC2;
break;
case STATUS_CRC2://接收CRC2
recv_buff[recv_len++] = data;
if(ILOCK_CHECK_CRC){
int crc = ilock_crc16_modbus(&recv_buff[2],recv_len-4);
unsigned char crc1 = recv_buff[recv_len-2]&0xFF;
unsigned char crc2 = recv_buff[recv_len-1]&0xFF;
int crcData =crc1 << 8|crc2;
if(crcData != crc) {
BK_LOGE(TAG,"CRC ERROR!\r\n");
recv_len = 0;
recv_state = STATUS_IDLE;
}else {
BK_LOGE(TAG,"CRC OK!\r\n");
//处理一包完整的数据包
ilock_parser_data(recv_buff,recv_len);
recv_len = 0;
data_len = 0;
}
}else{
//处理一包完整的数据包
ilock_parser_data(recv_buff,recv_len);
recv_len = 0;
data_len = 0;
}
recv_state = STATUS_IDLE;
break;
default: break;;
}
return recv_state;
}
void uart_tx_rx_handle_thread( beken_thread_arg_t arg )
{
UartMessage uMsg;
while(1)
{
bk_err_t ret = rtos_pop_from_queue(&uart1_msg_q, &uMsg, BEKEN_WAIT_FOREVER);
if(kNoErr != ret)
{
}
switch(uMsg.type)
{
case UART_RX_MSG:
os_printf("UART_RX_MSG \r\n");
//对接收到的数据逐个传入解析器 解析出完整的通信协议包
for(int i = 0; i< uMsg.len; i++){
parser_data(uMsg.msg[i]);
}
if(uMsg.msg)
{
os_free(uMsg.msg);
}
break;
case UART_TX_MSG:
//uart1_txdata_handler(u1msg);
os_printf("UART_TX_MSG \r\n");
break;
default:
os_printf("unknown msg\r\n");
break;
}
}
}
void clear_buffer(){
uint8_t *recv_data = (uint8_t *)os_malloc(256);
if (recv_data == NULL) {
return;
}
bk_uart_read_bytes(uart_id, recv_data, 128, 100);
if (recv_data) {
os_free(recv_data);
}
recv_data = NULL;
}
uint8_t recvResp( uint8_t respCmd, uint32_t time_out, uint8_t send_num)
{
uint8_t i = 0;
for(i = 0; i < send_num; i++)
{
uint8_t *recv_data = (uint8_t *)os_malloc(128);
if (recv_data == NULL) {
return -1;
}
int data_len = bk_uart_read_bytes(uart_id, recv_data, 128, time_out);
BK_LOGE(TAG, "recvResp len: %d \n",data_len);
if(recv_data[0]== 0xAA && data_len > 2){
//判断数据类型
//uint8_t type = (recv[2]&0xF);
uint8_t cmd = recv_data[3]&0xFF;
if(cmd == respCmd){
return 1;
}
}
if (recv_data) {
os_free(recv_data);
}
recv_data = NULL;
}
return 0;
}
uint8_t ilock_client_recvResp( uint8_t step, uint32_t time_out)
{
int check_delay = 10;//ms
int check_times = time_out/10;
while(check_times){
rtos_delay_milliseconds(check_delay);
//start
if(step == 1){
if(ota_start_result){
BK_LOGE(TAG, "ota_start success\n");
return 1;
}
}
else if(step == 2){
if(ota_sdata_result){
BK_LOGE(TAG, "ota_data success\n");
return 1;
}
}
else if(step == 3){
if(ota_end_result){
BK_LOGE(TAG, "ota_end success\n");
return 1;
}
}
check_times --;
}
return 0;
}
int ilock_client_is_ota_mode(){
return is_ota;
}
/**
* return: 0 成功 -1 启动失败 -2 传输失败 -3 校验失败
*
*/
int ilock_client_ota_start(int target,uint8_t* data, int data_len){
//1.停止异步接收
//2.发送开始指令 同步接收结果
// {
// 循环发送数据
// }
//发送结束
//重启
//bk_uart_disable_rx_interrupt(uart_id);
//ilock_rx_stop();
//rtos_delay_milliseconds(1000);
int mcu_target = 0x11;
//int total_len = 0;
int send_delay = 10;
int indexSize = 1 * 128;
//CMD START
is_ota = 1;
BK_LOGE(TAG, "data_len:%d \n",data_len);
uint8_t cmd_start[7] = {0x00};
cmd_start[0] = mcu_target & 0xff;
cmd_start[1] = (data_len >> 24) &0xff;
cmd_start[2] = (data_len >> 16) &0xff;
cmd_start[3] = (data_len >> 8) &0xff;
cmd_start[4] = data_len &0xff;
BK_LOGE(TAG, "indexSize:%d \n",indexSize);
int total_pack_size = data_len % indexSize == 0 ? data_len / indexSize : data_len / indexSize + 1;
BK_LOGE(TAG, "total_pack_size:%d \n",total_pack_size);
cmd_start[5] = (total_pack_size >> 8) &0xff;
cmd_start[6] = total_pack_size &0xff;
//clear_buffer();
ilock_send_package(CMD_TYPE_REQ,0x70,(uint8_t*)&cmd_start,sizeof(cmd_start));
rtos_delay_milliseconds(send_delay);
#ifdef OTA_NEED_WAIT_RESP
ota_start_result = 0;
int resp = ilock_client_recvResp(1,5000);
BK_LOGE(TAG, "OTA START Resp :%d \n",resp);
if(!resp){
BK_LOGE(TAG, "OTA START fail! \n");
is_ota = 0;
return -1;
}
#endif
//CMD DATA
int send_pos = 0;
for (int i = 0; i <= total_pack_size; i++) {
if (i == total_pack_size -1) {
BK_LOGE(TAG, "last one:%d \n", i);
int last_len = data_len - (i*indexSize);
BK_LOGE(TAG, "last len:%d \n", last_len);
uint8_t cmd_data[last_len+4];
cmd_data[0] = mcu_target;
//pack num
cmd_data[1] = (i >> 8) &0xff;
cmd_data[2] = i &0xff;
//data size
cmd_data[3] = last_len &0xff;
//unsigned char out [128] = {0};
//hex_to_asciistring(data+send_pos,last_len,out);
//BK_LOGE(TAG, "!EE: %s\n",out);
memcpy(&cmd_data[4], data+send_pos, last_len);
send_pos = send_pos+last_len;
BK_LOGE(TAG, "total_pack: %d send pack: %d\n",total_pack_size ,i);
//unsigned char out2 [128] = {0};
//hex_to_asciistring(cmd_data,sizeof(cmd_data),out2);
//BK_LOGE(TAG, "send data: %s\n",out);
ilock_send_package(CMD_TYPE_REQ,0x71,(uint8_t*)&cmd_data,sizeof(cmd_data));
rtos_delay_milliseconds(send_delay);
#ifdef OTA_NEED_WAIT_RESP
ota_sdata_result = 0;
int resp = ilock_client_recvResp(2,5000);
BK_LOGE(TAG, "OTA DATA Resp :%d \n",resp);
if(!resp){
BK_LOGE(TAG, "OTA DATA fail! \n");
is_ota = 0;
return -2;
}
#endif
//CMD END
int sum = checksum(data,data_len);
BK_LOGE(TAG, "check sum: %d\n",sum);
uint8_t cmd_end[11];
cmd_end[0] = mcu_target;
cmd_end[1] = (data_len >> 24) &0xff;
cmd_end[2] = (data_len >> 16) &0xff;
cmd_end[3] = (data_len >> 8) &0xff;
cmd_end[4] = data_len &0xff;
//pack num
cmd_end[5] = (total_pack_size >> 8) &0xff;
cmd_end[6] = total_pack_size &0xff;
//check sum
cmd_end[7] = (sum >> 24) &0xff;
cmd_end[8] = (sum >> 16) &0xff;
cmd_end[9] = (sum >> 8) &0xff;
cmd_end[10] = sum &0xff;
ilock_send_package(CMD_TYPE_REQ,0x72,(uint8_t*)&cmd_end,sizeof(cmd_end));
#ifdef OTA_NEED_WAIT_RESP
resp = ilock_client_recvResp(3,5000);
BK_LOGE(TAG, "OTA END Resp :%d \n",resp);
if(!resp){
BK_LOGE(TAG, "OTA END fail! \n");
is_ota = 0;
return -3;
}
#endif
BK_LOGE(TAG, "OTA finish !!\n");
break;
}
//unsigned char out [128] = {0};
//hex_to_asciistring(data+send_pos,indexSize,out);
//BK_LOGE(TAG, "SEND: %s\n",out);
//send_pos = send_pos+indexSize;
#if 1
uint8_t cmd_data[indexSize+4];
cmd_data[0] = mcu_target;
//pack num
cmd_data[1] = (i >> 8) &0xff;
cmd_data[2] = i &0xff;
//data size
cmd_data[3] = indexSize &0xff;
os_memcpy(&cmd_data[4], data+send_pos, indexSize);
//hex_to_asciistring(data+send_pos,indexSize,out);
//BK_LOGE(TAG, "!S: %s\n",out);
//os_memcpy(&cmd_data[3], data+send_pos, indexSize);
ilock_send_package(CMD_TYPE_REQ,0x71,(uint8_t*)&cmd_data,sizeof(cmd_data));
#ifdef OTA_NEED_WAIT_RESP
ota_sdata_result = 0;
int resp = ilock_client_recvResp(2,5000);
BK_LOGE(TAG, "OTA DATA Resp :%d \n",resp);
if(!resp){
BK_LOGE(TAG, "OTA DATA fail! \n");
is_ota = 0;
return -2;
}
#endif
send_pos = send_pos+indexSize;
BK_LOGE(TAG, "total_pack: %d send pack: %d\n",total_pack_size ,i);
//unsigned char out [128] = {0};
//hex_to_asciistring(cmd_data,sizeof(cmd_data),out);
//BK_LOGE(TAG, "CMD: %s\n",out);
#endif
rtos_delay_milliseconds(send_delay);
}
return 0;
}
void ilock_init(void)
{
bk_uart_driver_init();
ilock_uart_init();
bk_err_t ret = BK_OK;
if(NULL == uart_rx_semaphore)
{
ret = rtos_init_semaphore(&uart_rx_semaphore, 1);
if (kNoErr != ret)
os_printf("ilock_init: create background sema failed\r\n");
}
ret = rtos_init_queue(&uart1_msg_q,
"UartQueue",
sizeof(UartMessage),
12);
ret = rtos_init_queue(&lock_command_q,
"LockCommand",
sizeof(lock_command_t),
5);
ret = rtos_create_thread( NULL, BEKEN_APPLICATION_PRIORITY,
"UART1_TxRx_Handle",
uart_tx_rx_handle_thread,
0x2048,
0 );
ret = rtos_create_thread( NULL, BEKEN_APPLICATION_PRIORITY,
"LockCommand_Handle ",
lock_command_handle_thread,
0x2048,
0 );
if (ret != kNoErr) {
warning_prf("ilock_init fail \r\n");
ilock_thread_hdl = NULL;
}
}
void ilock_rx_start(){
bk_err_t ret = BK_OK;
rx_start = 1;
ret = rtos_create_thread(&ilock_thread_hdl,
BEKEN_APPLICATION_PRIORITY,
"ilock",
(beken_thread_function_t)ilock_rx_task,
1024*2,
NULL);
if (ret != kNoErr) {
warning_prf("create ilock_rx_task fail \r\n");
ilock_thread_hdl = NULL;
}
}
void ilock_rx_stop(){
rx_start = 0;
}
void ilock_deinit(void){
rtos_deinit_queue(&uart1_msg_q);
uart1_msg_q = NULL;
ilock_rx_stop();
bk_uart_driver_deinit();
}