|
|
#include "app_ble_service.h"
#include "../../ify_hrs_protocol/heart_rate_sensor_protocol.h"
#include "app_event.h"
#include "app_event_distribute.h"
#include "app_scheduler.h"
#include "board/board.h"
#include "board/board_battery_state.h"
#include "device_ctrl_service.h"
#include "heart_wave_sample_service.h"
#include "sample_data_manager_service.h"
#include "zble_module.h"
#include "zdatachannel_service.h"
#include "znordic.h"
#include "znordic_device_info_mgr.h"
static uint8_t rxbufcache[256]; static bool is_rxbufcache_used = false; // ���յ�����Ϣ�Ƿ����ڱ�������
static bool m_realtime_report_state = false; // ʵʱ�ϱ�״̬
static uint8_t m_txbuf[128]; static uint8_t m_reportbuf[128];
static void prvf_process_ble_rx_data(void* p_event_data, uint16_t event_size); static void process_ble_rx_data(void* p_event_data, uint16_t event_size);
/*******************************************************************************
* ��������ע�� * *******************************************************************************/ ZDATACHANNEL_DEF(m_zhrs, 2 /*���ȼ�*/, 1 /*client num*/); /**
* @brief ������Ϣ�ص� */ static void zdatachannel_data_handler(zdatachannel_evt_t* p_evt) { if (p_evt->type != ZDATACHANNEL_EVT_RX_DATA) { return; }
// ��Ϣ���ڱ������У�������������Ϣ
if (is_rxbufcache_used) return; if (p_evt->params.rx_data.length > sizeof(rxbufcache)) return;
memcpy(rxbufcache, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length); uint32_t suc = app_sched_event_put(rxbufcache, p_evt->params.rx_data.length, process_ble_rx_data); if (suc == 0) { is_rxbufcache_used = true; } } /*******************************************************************************
* UTILS * *******************************************************************************/ int ble_start_realtime_report() { m_realtime_report_state = true; return 0; } int ble_stop_realtime_report() { m_realtime_report_state = false; return 0; }
static void send_error_receipt(ify_hrs_packet_t* rxpacket, int32_t errorcode) { ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf; error_receipt_t* receipt = (error_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(error_receipt_t);
txheader->cmd = rxpacket->cmd; txheader->frame_index = rxpacket->frame_index; txheader->frame_type = kifyhrs_pt_error_receipt;
txheader->frame_type = kifyhrs_pt_error_receipt; receipt->errorcode = kifyhrs_ecode_cmd_not_support; zdatachannel_data_send2(m_txbuf, sendlen); }
static void send_success_receipt(ify_hrs_packet_t* rxpacket, int32_t emptydatasize) { ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf; uint16_t sendlen = sizeof(ify_hrs_packet_t) + emptydatasize;
txheader->cmd = rxpacket->cmd; txheader->frame_index = rxpacket->frame_index; txheader->frame_type = kifyhrs_pt_cmd_receipt;
zdatachannel_data_send2(m_txbuf, sendlen); }
static void prvf_try_report_sensor_drop_event(uint8_t dropstate0, uint8_t dropstate1) { sensor_drop_event_report_packet_t* reportpacket = (sensor_drop_event_report_packet_t*)m_reportbuf; reportpacket->cmd = ify_hrs_report_sensor_drop_detect; reportpacket->frame_index = 0; reportpacket->frame_type = kifyhrs_pt_report; reportpacket->drop_state0 = dropstate0; reportpacket->drop_state1 = dropstate1;
uint16_t sendlen = sizeof(sensor_drop_event_report_packet_t); zdatachannel_data_send2(m_reportbuf, sendlen); return; }
static void prvf_try_report_sample_end_event() { ify_hrs_packet_t* reportpacket = (ify_hrs_packet_t*)m_reportbuf; reportpacket->cmd = ify_hrs_report_sample_finish_end; reportpacket->frame_index = 0; reportpacket->frame_type = kifyhrs_pt_report;
uint16_t sendlen = sizeof(ify_hrs_packet_t); zdatachannel_data_send2(m_reportbuf, sendlen); return; }
void prvf_report_sample_data(uint32_t frameIndex, uint32_t data, uint32_t data2, uint32_t data3) { if (!m_realtime_report_state) { return; }
heartrate_report_packet_t* reportpacket = (heartrate_report_packet_t*)m_reportbuf; reportpacket->cmd = ify_hrs_report_heartrate_data; reportpacket->frame_index = 0; reportpacket->frame_type = kifyhrs_pt_report; reportpacket->sample_data_index = frameIndex;
/**
* @brief ��һ�������� */ reportpacket->data[0] = (data >> 0) & 0xFF; reportpacket->data[1] = (data >> 8) & 0xFF; reportpacket->data[2] = (data >> 16) & 0xFF; reportpacket->data[3] = 0;
/**
* @brief �ڶ��������� */ reportpacket->data[4] = (data2 >> 0) & 0xFF; reportpacket->data[5] = (data2 >> 8) & 0xFF; reportpacket->data[6] = (data2 >> 16) & 0xFF; reportpacket->data[7] = 0;
/**
* @brief ������������ */ reportpacket->data[8] = (data3 >> 0) & 0xFF; reportpacket->data[9] = (data3 >> 8) & 0xFF; reportpacket->data[10] = (data3 >> 16) & 0xFF; reportpacket->data[11] = 0;
uint16_t sendlen = sizeof(heartrate_report_packet_t) + 4 * 3; zdatachannel_data_send2(m_reportbuf, sendlen); return; }
/*******************************************************************************
* ��Ϣ���� * *******************************************************************************/ static void process_ble_rx_data(void* p_event_data, uint16_t event_size) { //
prvf_process_ble_rx_data(p_event_data, event_size); is_rxbufcache_used = false; }
static void prvf_process_ble_rx_data(void* p_event_data, uint16_t len) { ify_hrs_packet_t* rxheader = (ify_hrs_packet_t*)p_event_data; ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf; ify_hrs_cmd_t cmd = (ify_hrs_cmd_t)rxheader->cmd; memset(m_txbuf, 0, sizeof(m_txbuf));
ZLOGI("rx:"); NRF_LOG_HEXDUMP_INFO(p_event_data, len); ZLOGI("rx cmd:%d index:%d datalen:%d", cmd, rxheader->frame_index, len - sizeof(ify_hrs_packet_t));
txheader->cmd = rxheader->cmd; txheader->frame_index = rxheader->frame_index; txheader->frame_type = kifyhrs_pt_cmd_receipt;
NRF_LOG_HEXDUMP_INFO(rxheader->data, len - sizeof(ify_hrs_packet_t));
if (cmd == ify_hrs_cmd_read_device_version) { device_version_info_receipt_t* receipt = (device_version_info_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_version_info_receipt_t);
receipt->blestack_version = device_info_read_blestack_version(); receipt->bootloader_version = device_info_read_bootloader_version(); receipt->firmware_version = device_info_read_firmware_version(); receipt->hardware_version = device_info_read_hardware_version(); zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_read_sensor_info) { sensor_info_receipt_t* receipt = (sensor_info_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(sensor_info_receipt_t);
receipt->sensor_num = 1; receipt->sensor_precision = SAMPLE_PRECISION; receipt->sensor_sample_rate = SAMPLE_RATE / 10; receipt->sensor0_pos = kifyhrs_sensor_pos_II; receipt->sensor1_pos = kifyhrs_sensor_pos_V1; receipt->sensor2_pos = kifyhrs_sensor_pos_V5;
zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_read_device_state) { device_state_receipt_t* receipt = (device_state_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_state_receipt_t);
receipt->drop_state0 = hwss_get_drop_state0(); receipt->drop_state1 = hwss_get_drop_state1();
receipt->drop_state1 = 0x00; receipt->device_state0.sampling_state = (DeviceCtrl_now_state() == kdevice_state_sampling); receipt->device_state0.report_state = m_realtime_report_state; receipt->device_state0.low_battery = (BoardBattery_get_battery_level() < 20); receipt->device_state0.full_storge = (SampleDataMgr_storageIsFull());
receipt->device_state1 = 0; receipt->powerlevel = BoardBattery_get_battery_level(); receipt->storage_item_num = SampleDataMgr_getFileNum();
zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_read_time) { read_time_receipt_t* receipt = (read_time_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_time_receipt_t); static ztm_t ztm; znordic_rtc_gettime(&ztm);
receipt->year = (ztm.tm_year + 1900 - 2000); receipt->month = ztm.tm_mon + 1; receipt->day = ztm.tm_mday; receipt->hour = ztm.tm_hour; receipt->minute = ztm.tm_min; receipt->second = ztm.tm_sec; zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_sync_time) { sync_time_cmd_t* cmd = (sync_time_cmd_t*)rxheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t);
znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second); zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_start_capture) { hwss_start_capture(); send_success_receipt(rxheader, 0); }
else if (cmd == ify_hrs_cmd_stop_capture) { hwss_stop_capture(); send_success_receipt(rxheader, 0); }
else if (cmd == ify_hrs_cmd_start_realtime_report) { // unsupport cmd
int ecode = ble_start_realtime_report(); if (ecode == 0) { send_success_receipt(rxheader, 8); // ��8���ֽڣ�ʹ������ִ���ֽڳ���ͬ�ϱ�������һ�£���������
} else { send_error_receipt(rxheader, ecode); } }
else if (cmd == ify_hrs_cmd_stop_realtime_report) { int ecode = ble_stop_realtime_report(); if (ecode == 0) { send_success_receipt(rxheader, 0); } else { send_error_receipt(rxheader, ecode); } }
else if (cmd == ify_hrs_cmd_read_records_info) { // ָ�� 10-��ȡ������¼ͷ����Ϣ
read_record_info_cmd_t* cmd = (read_record_info_cmd_t*)rxheader->data; read_record_info_receipt_t* receipt = (read_record_info_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_record_info_receipt_t);
uint8_t recordoff = cmd->record_index;
// ����ʱ��֧��
if (hwss_is_capturing()) { send_error_receipt(rxheader, kifyhrs_ecode_device_busy); return; }
sample_data_fileinfo_list_t* recordlist = SampleDataMgr_getFileinfoList(); if (recordoff >= recordlist->count) { send_error_receipt(rxheader, kifyhrs_ecode_no_record_find); return; }
sample_data_fileinfo_t* fileinfo = recordlist->fileinfo[recordoff]; memcpy(receipt->record_id, fileinfo->filename, 6); receipt->frameNum = fileinfo->size / 2; // 2byte per frame
receipt->dataSize = fileinfo->size; receipt->sensorNum = 1; receipt->captureRate = SAMPLE_RATE / 10; receipt->capturePrecision = SAMPLE_PRECISION; receipt->compressAlgorithm = 0;
zdatachannel_data_send2(m_txbuf, sendlen);
}
else if (cmd == ify_hrs_cmd_del_record) { // ָ�� 11-ɾ��������¼
del_record_cmd_t* cmd = (del_record_cmd_t*)rxheader->data;
static sample_data_filename_t filename; memset(&filename, 0, sizeof(filename)); memcpy(&filename, cmd->record_id, sizeof(cmd->record_id));
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); }
else if (cmd == ify_hrs_cmd_start_upload_record) { // ָ�� 12-�ϴ��ɼ���¼
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); }
else if (cmd == ify_hrs_cmd_enter_ota) { send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); }
else if (cmd == ify_hrs_cmd_read_sn) { read_sn_receipt_t* receipt = (read_sn_receipt_t*)txheader->data; uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_sn_receipt_t); device_info_read_sn((sn_t*)&receipt->sn); zdatachannel_data_send2(m_txbuf, sendlen); }
else if (cmd == ify_hrs_cmd_reset) { NVIC_SystemReset(); } //
else { send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); } }
void AppBleService_onServiceInitCB() { ZLOGI("init zdatachannel service"); static zdatachannel_init_t zdatachannle_init; memset(&zdatachannle_init, 0, sizeof(zdatachannle_init)); zdatachannle_init.data_handler = zdatachannel_data_handler; ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init)); }
static void app_event_listener(void* p_event_data, uint16_t event_size) { //
app_event_t* event = (app_event_t*)p_event_data; if (event->eventType == kevent_sensor_drop) { prvf_try_report_sensor_drop_event(event->val.sensor_drop.drop0, event->val.sensor_drop.drop1); } else if (event->eventType == kevent_sample_stop_event) { prvf_try_report_sample_end_event(); } else if (event->eventType == kevent_capture_little_data_block_event) { // �ϱ���������
if (m_realtime_report_state) { // �ϱ���������
prvf_report_sample_data(event->val.little_data_block.frameIndex, //
event->val.little_data_block.data[0].data0, //
event->val.little_data_block.data[0].data1, //
event->val.little_data_block.data[0].data2); } } }
void AppBleService_init() { AppEvent_regListener(app_event_listener); }
|