#include #include #include #include #include #include "gpio_map.h" #include "gpio_driver.h" #include #include //#include "bk_wifi_netif.h" #include "bk_wifi.h" #include #include "bk_uart.h" #include #include #include #include //#include "wlan_ui_pub.h" //#include #include #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 %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 %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(); }