1010 lines
30 KiB
Plaintext
1010 lines
30 KiB
Plaintext
![]() |
#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 "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;
|
|||
|
|
|||
|
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
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 0x1:请求包,都需要回复
|
|||
|
0x2:响应包,回复执行结果
|
|||
|
0x3:回执包,仅通知收到(高 4BIT)
|
|||
|
*/
|
|||
|
#define CMD_TYPE_REQ 0x01
|
|||
|
#define CMD_TYPE_RET 0x02
|
|||
|
#define CMD_TYPE_REC 0x03//receipt
|
|||
|
|
|||
|
|
|||
|
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_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(){
|
|||
|
//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};
|
|||
|
|
|||
|
BK_LOGE(TAG, "ilock_open_lock");
|
|||
|
ilock_send_package(CMD_TYPE_REQ,0x40,(uint8_t*)&data,sizeof(data));
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
int ilock_open_lock_sos(){
|
|||
|
BK_LOGE(TAG, "ilock_open_lock_sos");
|
|||
|
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
|
|||
|
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(){
|
|||
|
BK_LOGE(TAG, "ilock_close_lock");
|
|||
|
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
|
|||
|
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:{
|
|||
|
|
|||
|
|
|||
|
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 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])
|
|||
|
{
|
|||
|
//获取版本号回复
|
|||
|
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;
|
|||
|
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;
|
|||
|
//printf("CRC1 %02X \r\n", crc1);
|
|||
|
//printf("CRC2 %02X \r\n", crc2);
|
|||
|
//printf("crcData %d \r\n", crcData);
|
|||
|
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;
|
|||
|
}
|
|||
|
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 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();
|
|||
|
}
|