THB2/bthome_phy6222/source/thb2_main.c
2024-12-13 18:19:29 +03:00

991 lines
28 KiB
C

/*******************************************************************************
Filename: simpleBLEPeripheral.c
Revised:
Revision:
Description: This file contains the Simple BLE Peripheral sample application
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "bcomdef.h"
#include "config.h"
#include "rf_phy_driver.h"
//#include "bus_dev.h"
#include "global_config.h"
#include "OSAL.h"
#include "OSAL_PwrMgr.h"
#include "gatt.h"
#include "hci.h"
#include "buzzer.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "devinfoservice.h"
#include "thb2_peripheral.h"
#include "gapbondmgr.h"
#include "pwrmgr.h"
#include "gpio.h"
#include "thb2_main.h"
#include "ll.h"
#include "ll_hw_drv.h"
#include "ll_def.h"
#include "hci_tl.h"
#include "flash.h"
//#include "fs.h"
#include "flash_eep.h"
#include "battservice.h"
#include "thservice.h"
#include "thb2_peripheral.h"
#include "bthome_beacon.h"
#include "sensors.h"
#include "battery.h"
#include "sbp_profile.h"
#include "ble_ota.h"
#include "lcd.h"
#include "logger.h"
#include "trigger.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#define INVALID_CONNHANDLE 0xFFFF
// Default passcode
#define DEFAULT_PASSCODE 0 //19655
// Length of bd addr as a string
#define B_ADDR_STR_LEN 15
#define RESOLVING_LIST_ENTRY_NUM 10
// Offset of advertData&scanRspData
#define RSP_OFFSET_MAC 4
/*********************************************************************
* build define
*/
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
perStatsByChan_t g_perStatsByChanTest;
/*********************************************************************
* EXTERNAL VARIABLES
*/
//volatile uint8_t g_current_advType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT;
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
uint8_t simpleBLEPeripheral_TaskID; // Task ID for internal task/event processing
static gaprole_States_t gapProfileState = GAPROLE_INIT;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg );
static void peripheralStateNotificationCB( gaprole_States_t newState );
//static void simpleProfileChangeCB( uint8_t paramID );
static void peripheralStateReadRssiCB( int8_t rssi );
const char* hex_ascii = { "0123456789ABCDEF" };
uint8_t * str_bin2hex(uint8_t *d, uint8_t *s, int len) {
while(len--) {
*d++ = hex_ascii[(*s >> 4) & 0xf];
*d++ = hex_ascii[(*s++ >> 0) & 0xf];
}
return d;
}
// GAP - SCAN RSP data (max size = 31 bytes)
void set_def_name(void)
{
uint8_t * pmac = ownPublicAddr;
uint8_t * p = gapRole_ScanRspData;
gapRole_ScanRspDataLen = sizeof(DEF_MODEL_NUMBER_STR) + 8;
*p++ = sizeof(DEF_MODEL_NUMBER_STR) + 7;
*p++ = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
memcpy(p, devInfoModelNumber, sizeof(DEF_MODEL_NUMBER_STR) - 1);
p += sizeof(DEF_MODEL_NUMBER_STR) - 1;
*p++ = '-';
p = str_bin2hex(p, pmac+2, 1);
p = str_bin2hex(p, pmac+1, 1);
p = str_bin2hex(p, pmac, 1);
*p++ = 0;
flash_write_cfg(NULL, EEP_ID_DVN, 0);
}
void set_dev_name(void)
{
uint8_t * p = gapRole_ScanRspData;
int len = flash_read_cfg(&p[2], EEP_ID_DVN, GAP_DEVICE_NAME_LEN - 1);
if(len > 0 && len < GAP_DEVICE_NAME_LEN && p[2] != 0) {
p[0] = (uint8_t)len + 1;
p[1] = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
p[len + 2] = 0;
} else
set_def_name();
gapRole_ScanRspDataLen = p[0] + 1;
HCI_LE_SetScanRspDataCmd(gapRole_ScanRspDataLen, p);
GGS_SetParameter( GGS_DEVICE_NAME_ATT, p[0] - 1, (void *)&p[2] ); // GAP_DEVICE_NAME_LEN, attDeviceName );
}
void swap_mac(uint8_t * d, uint8_t * s)
{
uint8_t buf[6];
buf[0] = s[5];
buf[1] = s[4];
buf[2] = s[3];
buf[3] = s[2];
buf[4] = s[1];
buf[5] = s[0];
memcpy(d, buf, 6);
}
static void set_mac(void)
{
//extern uint8_t ownPublicAddr[LL_DEVICE_ADDR_LEN];
if(flash_read_cfg(ownPublicAddr, EEP_ID_MAC, MAC_LEN) != MAC_LEN) {
if (read_chip_mAddr(ownPublicAddr) != CHIP_ID_VALID) {
LL_Rand(ownPublicAddr,3);
// Tuya mac[0:3]
ownPublicAddr[3] = 0x8d;
ownPublicAddr[4] = 0x1f;
ownPublicAddr[5] = 0x38;
}
flash_write_cfg(ownPublicAddr, EEP_ID_MAC, MAC_LEN);
}
pGlobal_config[MAC_ADDRESS_LOC] = (uint32_t)ownPublicAddr;
// device name
set_dev_name();
#if (DEV_SERVICES & SERVICE_BINDKEY)
bthome_beacon_init();
#endif
}
static void set_serial_number(void)
{
hal_get_flash_info();
uint8_t *p = str_bin2hex(devInfoSerialNumber, (uint8_t *)&phy_flash.IdentificationID, 3);
*p++ = '-';
#if (DEV_SERVICES & SERVICE_THS)
p = str_bin2hex(p, (uint8_t *)&thsensor_cfg.mid, 4);
#else
p = str_bin2hex(p, (uint8_t *)FLASH_BASE_ADDR, 4);
#endif
*p++ = '-';
#if (DEV_SERVICES & SERVICE_LCD)
p = str_bin2hex(p, (uint8_t *)&lcd_i2c_addr, 1);
#else
*p++ = '0';
*p = '0';
#endif
}
extern gapPeriConnectParams_t periConnParameters;
extern uint16_t gapParameters[];
static void set_adv_interval(uint16_t advInt);
// Set new advertising interval
static void set_new_adv_interval(uint16_t advInt)
{
set_adv_interval(advInt);
GAP_EndDiscoverable( gapRole_TaskID );
gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
// Turn advertising back on.
osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
}
// Set advertising interval
static void set_adv_interval(uint16_t advInt)
{
#ifdef __GCC
gapParameters[TGAP_LIM_DISC_ADV_INT_MIN] = advInt;
gapParameters[TGAP_LIM_DISC_ADV_INT_MAX] = advInt + 10;
gapParameters[TGAP_GEN_DISC_ADV_INT_MIN] = advInt;
gapParameters[TGAP_GEN_DISC_ADV_INT_MAX] = advInt + 10;
#else
GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt + 10);
GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt + 10);
#endif
}
//extern void start_measure(void);
static void adv_measure(void) {
if(gapRole_AdvEnabled) {
get_utc_time_sec(); // счет UTC timestamp
#if (DEV_SERVICES & SERVICE_RDS)
if(!adv_wrk.adv_event) {
if(clkt.utc_time_tik - adv_wrk.rds_timer_tik >= (RDS_EVENT_STEP_SEC << 15)) { // шаг дублирования передачи 30 минут
adv_wrk.rds_timer_tik = clkt.utc_time_tik;
adv_wrk.adv_event = 1;
adv_wrk.adv_reload_count = cfg.adv_event_cnt; // 16
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
set_new_adv_interval(DEF_EVENT_ADV_INERVAL); // 50 ms (in 625us)
return;
}
#endif
if(clkt.utc_time_tik - adv_wrk.measure_batt_tik >= ((uint32_t)cfg.batt_interval << 15)) {
adv_wrk.measure_batt_tik = clkt.utc_time_tik;
batt_start_measure();
#if ((DEV_SERVICES & SERVICE_THS) == 0)
} else {
if(adv_wrk.new_battery) {
adv_wrk.new_battery = 0;
check_battery();
#if (DEV_SERVICES & SERVICE_THS) == 0
measured_data.count++;
#endif
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_lcd(1);
#endif
#if (DEV_SERVICES & SERVICE_HISTORY)
if (cfg.averaging_measurements != 0)
write_memo();
#endif
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
#if (DEV_SERVICES & SERVICE_SCREEN)
} else {
chow_lcd(0);
#endif
}
#endif
}
#if (DEV_SERVICES & SERVICE_THS)
if(adv_wrk.meas_count == (uint8_t)(cfg.measure_interval - 1)) {
start_measure();
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_lcd(0);
#endif
} else {
if(adv_wrk.meas_count >= cfg.measure_interval) {
adv_wrk.meas_count = 0;
read_sensors(); // measured_data.count++
if(adv_wrk.new_battery) {
adv_wrk.new_battery = 0;
check_battery();
}
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_lcd(1);
#endif
#if (DEV_SERVICES & SERVICE_HISTORY)
if (cfg.averaging_measurements != 0)
write_memo();
#endif
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
#if (DEV_SERVICES & SERVICE_SCREEN)
} else {
chow_lcd(0);
#endif
}
}
#endif // (DEV_SERVICES & SERVICE_THS)
#if (DEV_SERVICES & SERVICE_RDS)
}
#endif
if(adv_wrk.adv_reload_count) {
if(--adv_wrk.adv_reload_count == 0) {
// восстановление/переключение типа и интервалов рекламы
#if defined(OTA_TYPE) && OTA_TYPE == OTA_TYPE_BOOT
if (wrk.boot_flg == BOOT_FLG_OTA) {
hal_system_soft_reset();
}
#endif
#if (DEV_SERVICES & SERVICE_BUTTON)
if(adv_wrk.adv_event) { // передавались event ?
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_OFF);
#endif
adv_wrk.adv_reload_count = cfg.adv_event_cnt;
if(!measured_data.button) {
if(adv_wrk.new_battery) {
adv_wrk.new_battery = 0;
check_battery();
}
#if defined(GPIO_BUZZER) && (!defined(PWM_CHL_BUZZER))
hal_gpio_write(GPIO_BUZZER, BUZZER_ON);
#endif
measured_data.count++;
#if defined(GPIO_BUZZER) && (!defined(PWM_CHL_BUZZER))
hal_gpio_write(GPIO_BUZZER, BUZZER_OFF);
#endif
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
#if defined(GPIO_BUZZER) && (!defined(PWM_CHL_BUZZER))
hal_gpio_write(GPIO_BUZZER, BUZZER_ON);
#endif
adv_wrk.adv_event = 0;
#if defined(GPIO_BUZZER) && (!defined(PWM_CHL_BUZZER))
hal_gpio_write(GPIO_BUZZER, BUZZER_OFF);
#endif
set_new_adv_interval(DEF_EVENT_ADV_INERVAL);
}
} else {
// восстановление пользовательского (основного) интервала передачи рекламы
if(adv_wrk.new_battery) {
adv_wrk.new_battery = 0;
check_battery();
}
measured_data.count++;
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
set_new_adv_interval(cfg.advertising_interval * 100);
}
#else
if(adv_wrk.adv_event) { // передавались event ?
// восстановление пользовательского (основного) интервала передачи рекламы после цикла передач event
adv_wrk.adv_event = 0;
if(adv_wrk.new_battery) {
adv_wrk.new_battery = 0;
check_battery();
}
measured_data.count++;
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
}
// восстановление пользовательского (основного) интервала передачи рекламы
set_new_adv_interval(cfg.advertising_interval * 100);
#endif
}
}
adv_wrk.meas_count++;
}
}
#if (DEV_SERVICES & (SERVICE_KEY | SERVICE_RDS | SERVICE_BUTTON))
/*********************************************************************
* LED and Key
*/
static void posedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
{
(void) pin;
if(type == POSEDGE)
{
LOG("int or wakeup(pos):gpio:%d type:%d\n", pin, type);
#if (DEV_SERVICES & (SERVICE_KEY | SERVICE_BUTTON))
if(pin == GPIO_KEY) {
#ifdef GPIO_LED
#if KEY_PRESSED
hal_gpio_write(GPIO_LED, LED_ON);
#else
hal_gpio_write(GPIO_LED, LED_OFF);
#endif
#endif
#if (DEV_SERVICES & SERVICE_KEY) && KEY_PRESSED
if(gapRole_AdvEnabled) {
adv_wrk.adv_reload_count = 60000/DEF_CON_ADV_INERVAL_MS; // 60 sec
set_new_adv_interval(DEF_CON_ADV_INERVAL); // actual time * 625us
}
#endif
#if (DEV_SERVICES & SERVICE_BUTTON)
osal_set_event(simpleBLEPeripheral_TaskID, PIN_INPUT_EVT);
#endif
}
#endif
#if (DEV_SERVICES & SERVICE_RDS)
if(pin == GPIO_INP) {
osal_set_event(simpleBLEPeripheral_TaskID, PIN_INPUT_EVT);
}
#endif
}
else
{
LOG("error\n");
}
}
static void negedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
{
(void) pin;
if(type == NEGEDGE)
{
LOG("int or wakeup(neg):gpio:%d type:%d\n", pin, type);
#if (DEV_SERVICES & (SERVICE_KEY | SERVICE_BUTTON))
if(pin == GPIO_KEY) {
#ifdef GPIO_LED
#if KEY_PRESSED
hal_gpio_write(GPIO_LED, LED_OFF);
#else
hal_gpio_write(GPIO_LED, LED_ON);
#endif // KEY_PRESSED
#endif // GPIO_LED
#if (DEV_SERVICES & SERVICE_KEY) && (KEY_PRESSED == 0)
if(gapRole_AdvEnabled) {
adv_wrk.adv_reload_count = 60000/DEF_CON_ADV_INERVAL_MS; // 60 sec
set_new_adv_interval(DEF_CON_ADV_INERVAL); // actual time * 625us
}
#endif // (DEV_SERVICES & SERVICE_KEY)
#if (DEV_SERVICES & SERVICE_BUTTON)
osal_set_event(simpleBLEPeripheral_TaskID, PIN_INPUT_EVT);
#endif
}
#endif // (DEV_SERVICES & (SERVICE_KEY | SERVICE_BUTTON))
#if (DEV_SERVICES & SERVICE_RDS)
if(pin == GPIO_INP) {
osal_set_event(simpleBLEPeripheral_TaskID, PIN_INPUT_EVT);
}
#endif
}
else
{
LOG("error\n");
}
}
#endif // (DEV_SERVICES & (SERVICE_KEY | SERVICE_RDS | SERVICE_BUTTON))
static void init_app_gpio(void)
{
#if (DEV_SERVICES & (SERVICE_KEY | SERVICE_BUTTON))
hal_gpioin_register(GPIO_KEY, posedge_int_wakeup_cb, negedge_int_wakeup_cb);
#endif
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_ON);
hal_gpioretention_register(GPIO_LED);//enable this pin retention
#endif
#if (DEV_SERVICES & SERVICE_RDS)
hal_gpioin_register(GPIO_INP, posedge_int_wakeup_cb, negedge_int_wakeup_cb);
#endif
#ifdef GPIO_LPWR // питание LCD драйвера
hal_gpio_write(GPIO_LPWR, 1);
hal_gpioretention_register(GPIO_LPWR);//enable this pin retention
#endif
#ifdef GPIO_SPWR // питание сенсора CHT8305_VDD
hal_gpio_write(GPIO_SPWR, 1);
hal_gpioretention_register(GPIO_SPWR);//enable this pin retention
#endif
#if (DEV_SERVICES & SERVICE_TH_TRG)
#ifdef GPIO_TRG
hal_gpio_write(GPIO_TRG, (trg.cfg & TRG_CFG_OUT_INV) != 0);
hal_gpioretention_register(GPIO_TRG);//enable this pin retention
#endif
#endif
}
/*********************************************************************
* GAPROLE ADVERTISING
*/
void gatrole_advert_enable(bool enable) {
uint8_t oldAdvEnabled = gapRole_AdvEnabled;
gapRole_AdvEnabled = enable;
if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) )
{
// Turn off Advertising
if ( ( gapRole_state == GAPROLE_ADVERTISING )
|| ( gapRole_state == GAPROLE_CONNECTED_ADV )
|| ( gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT ) )
{
GAP_EndDiscoverable( gapRole_TaskID );
}
}
else if ( (oldAdvEnabled == FALSE) && (gapRole_AdvEnabled) )
{
// Turn on Advertising
if ( (gapRole_state == GAPROLE_STARTED)
|| (gapRole_state == GAPROLE_WAITING)
|| (gapRole_state == GAPROLE_CONNECTED)
|| (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT) )
{
osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
}
}
}
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =
{
peripheralStateNotificationCB, // Profile State Change Callbacks
peripheralStateReadRssiCB // When a valid RSSI is read from controller (not used by application)
};
#if (DEF_GAPBOND_MGR_ENABLE==1)
// GAP Bond Manager Callbacks, add 2017-11-15
static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
NULL, // Passcode callback (not used by application)
NULL // Pairing / Bonding state Callback (not used by application)
};
#endif
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn SimpleBLEPeripheral_Init
*
* @brief Initialization function for the Simple BLE Peripheral App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by OSAL. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void SimpleBLEPeripheral_Init( uint8_t task_id )
{
simpleBLEPeripheral_TaskID = task_id;
init_app_gpio();
#if (DEV_SERVICES & SERVICE_SCREEN)
init_lcd();
#endif
#if (DEV_SERVICES & SERVICE_THS)
init_sensor();
#endif
set_serial_number();
// Setup the GAP
#ifdef __GCC
gapParameters[TGAP_CONN_PAUSE_PERIPHERAL] = DEFAULT_CONN_PAUSE_PERIPHERAL;
#else
GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
#endif
// Setup the GAP Peripheral Role Profile
{
set_mac();
// gapRole_AdvEventType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT; // already set default
// gapRole_AdvDirectAddr[B_ADDR_LEN] = {1,2,3,4,5,6}; // already set default
// gapRole_AdvChanMap = GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39; // already set default
// Set the GAP Role Parameters
// device starts advertising upon initialization
gatrole_advert_enable(FALSE);
#if (DEV_SERVICES & SERVICE_FINDMY)
if (cfg.flg & FLG_FINDMY) {
extern uint8_t findmy_beacon(void * padbuf);
gapRole_AdvEventType = LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT;
gapRole_AdvertDataLen = findmy_beacon((void *)gapRole_AdvertData);
} else {
gapRole_AdvEventType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT;
}
#endif
// gapRole_AdvertOffTime = 0; // already set default
GAP_UpdateAdvertisingData( gapRole_TaskID, TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
GAP_UpdateAdvertisingData( gapRole_TaskID, FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
gapRole_ParamUpdateEnable = DEFAULT_ENABLE_UPDATE_REQUEST;
/* already set default -> config.h
// extern gapPeriConnectParams_t periConnParameters;
gapRole_MinConnInterval = periConnParameters.intervalMin;
gapRole_MaxConnInterval = periConnParameters.intervalMax;
gapRole_SlaveLatency = periConnParameters.latency;
gapRole_TimeoutMultiplier = periConnParameters.timeout;
*/
}
// Set the GAP Characteristics
// GGS_SetParameter( GGS_DEVICE_NAME_ATT, gapRole_ScanRspData[0] - 1, (void *)&gapRole_ScanRspData[2] ); // GAP_DEVICE_NAME_LEN, attDeviceName );
// Set advertising interval
#if defined(OTA_TYPE) && OTA_TYPE == OTA_TYPE_BOOT
if (wrk.boot_flg == BOOT_FLG_OTA) {
adv_wrk.adv_reload_count = 60000/DEF_OTA_ADV_INERVAL_MS; // 60 sec
set_adv_interval(DEF_CON_ADV_INERVAL); // actual time = advInt * 625us
} else
#endif
set_adv_interval(cfg.advertising_interval * 100); // actual time = advInt * 625us
HCI_PPLUS_AdvEventDoneNoticeCmd(simpleBLEPeripheral_TaskID, ADV_BROADCAST_EVT);
#if (DEF_GAPBOND_MGR_ENABLE==1)
// Setup the GAP Bond Manager, add 2017-11-15
{
uint32_t passkey = DEFAULT_PASSCODE;
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8_t mitm = TRUE;
uint8_t ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT;
uint8_t bonding = TRUE;
GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32_t ), &passkey );
GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8_t ), &pairMode );
GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8_t ), &mitm );
GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8_t ), &ioCap );
GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8_t ), &bonding );
}
#endif
// Initialize GATT attributes
GGS_AddService( GATT_ALL_SERVICES ); // GAP
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
DevInfo_AddService(); // Device Information Service
Batt_AddService();
#if (DEV_SERVICES & SERVICE_THS)
TH_AddService();
#endif
SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile
#if (1)
#if 0 // CODED PHY not work?
deviceFeatureSet.featureSet[1] |= (uint8_t)(
LL_FEATURE_2M_PHY
| LL_FEATURE_CODED_PHY
| LL_FEATURE_CSA2);
// CSA2 feature setting
pGlobal_config[LL_SWITCH] |= CONN_CSA2_ALLOW;
llInitFeatureSetCodedPHY(TRUE);
#endif
//llInitFeatureSet2MPHY(TRUE);
llInitFeatureSetDLE(TRUE);
#else
llInitFeatureSet2MPHY(FALSE);
llInitFeatureSetDLE(FALSE);
#endif
// HCI_LE_SetDefaultPhyMode(0,0xff,0x01,0x01);
#ifdef MTU_SIZE
#if MTU_SIZE > ATT_MAX_MTU_SIZE
#error "MTU_SIZE > 517"
#endif
ATT_SetMTUSizeMax(MTU_SIZE);
#else
ATT_SetMTUSizeMax(ATT_MTU_SIZE_MIN);
#endif
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
// for receive HCI complete message
GAP_RegisterForHCIMsgs(simpleBLEPeripheral_TaskID);
LL_PLUS_PerStats_Init(&g_perStatsByChanTest);
batt_start_measure();
#if (DEV_SERVICES & (SERVICE_RDS | SERVICE_BUTTON))
adv_wrk.rds_timer_tik = clkt.utc_time_tik - (RDS_EVENT_START_SEC << 15);
#endif
LOG("=====SimpleBLEPeripheral_Init Done=======\n");
}
/*********************************************************************
* @fn BLEPeripheral_ProcessEvent
*
* @brief Simple BLE Peripheral Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
*
* @param task_id - The OSAL assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/
uint16_t BLEPeripheral_ProcessEvent( uint8_t task_id, uint16_t events )
{
VOID task_id; // OSAL required parameter that isn't used in this function
if ( events & ADV_BROADCAST_EVT) {
adv_measure();
LOG("advN%u\n", adv_wrk.meas_count);
// return unprocessed events
return (events ^ ADV_BROADCAST_EVT);
}
if ( events & SYS_EVENT_MSG ) {
uint8_t *pMsg;
if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
{
simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
// Release the OSAL message
VOID osal_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
// enable adv (from gaprole start)
if ( events & SBP_RESET_ADV_EVT ) {
LOG("SBP_RESET_ADV_EVT\n");
adv_wrk.meas_count = 0;
// set_new_adv_interval(DEF_ADV_INERVAL); // actual time = advInt * 625us
gatrole_advert_enable(TRUE);
return ( events ^ SBP_RESET_ADV_EVT );
}
#if defined(GPIO_BUZZER) && defined(PWM_CHL_BUZZER)
if( events & BUZZER_TONE_EVT) {
pwm_buzzer_event();
return ( events ^ BUZZER_TONE_EVT);
}
#endif
if( events & TIMER_BATT_EVT) {
LOG("TIMER_EVT\n");
get_utc_time_sec(); // счет UTC timestamp
#if (DEV_SERVICES & SERVICE_THS)
if(clkt.utc_time_tik - adv_wrk.measure_batt_tik >= ((uint32_t)cfg.batt_interval << 15)) {
adv_wrk.measure_batt_tik = clkt.utc_time_tik;
batt_start_measure();
}
read_sensors(); // measured_data.count++;
start_measure();
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_lcd(1);
#endif
#if (DEV_SERVICES & SERVICE_HISTORY)
if (cfg.averaging_measurements != 0)
write_memo();
#endif
// TH Notify
TH_NotifyLevel();
if(cfg.flg & FLG_MEAS_NOTIFY)
measure_notify();
#else // no SERVICE_THS
batt_start_measure();
#endif // (DEV_SERVICES & SERVICE_THS)
// return unprocessed events
return ( events ^ TIMER_BATT_EVT);
}
if( events & BATT_VALUE_EVT) {
LOG("Vbat: %d mV, %d %%\n", measured_data.battery_mv, measured_data.battery);
// Batt Notify
check_battery();
if(!gapRole_AdvEnabled) {
BattNotifyLevel();
#if ((DEV_SERVICES & SERVICE_THS)==0)
if(cfg.flg & FLG_MEAS_NOTIFY)
measure_notify();
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_lcd(1);
#endif
#endif
}
// return unprocessed events
return ( events ^ BATT_VALUE_EVT);
}
if ( events & SBP_START_DEVICE_EVT ) {
// Start the Device
VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
#if (DEF_GAPBOND_MGR_ENABLE==1)
// Start Bond Manager, 2017-11-15
VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
#endif
HCI_LE_ReadResolvingListSizeCmd();
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_OFF);
#endif
//adv_wrk.meas_count = 0;
#if (DEV_SERVICES & SERVICE_SCREEN)
lcd_show_version();
#endif
// return unprocessed events
return ( events ^ SBP_START_DEVICE_EVT );
}
#if (DEV_SERVICES & (SERVICE_RDS | SERVICE_BUTTON))
if(events & PIN_INPUT_EVT) {
int ev = 0;
#if (DEV_SERVICES & SERVICE_BUTTON)
if(hal_gpio_read(GPIO_KEY) == KEY_PRESSED) {
if(!measured_data.flg.pin_input) {
adv_wrk.rds_count++;
measured_data.button = 1; // press
ev = 1;
}
measured_data.flg.pin_input = 1;
} else {
#if defined(GPIO_BUZZER) && defined(PWM_CHL_BUZZER)
pwm_buzzer_stop();
#endif
// if(measured_data.flg.pin_input)
// ev = 1;
measured_data.flg.pin_input = 0;
measured_data.button = 0; // None
}
#else
if(hal_gpio_read(GPIO_INP)) {
if(!measured_data.flg.pin_input) {
adv_wrk.rds_count++;
ev = 1;
}
measured_data.flg.pin_input = 1;
} else {
if(measured_data.flg.pin_input)
ev = 1;
measured_data.flg.pin_input = 0;
}
#endif
if(ev) {
if(gapRole_AdvEnabled) {
measured_data.count++;
adv_wrk.adv_event = 1;
adv_wrk.adv_reload_count = cfg.adv_event_cnt;
adv_wrk.rds_timer_tik = clkt.utc_time_tik - (RDS_EVENT_DOUBLE_SEC << 15);
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
set_new_adv_interval(DEF_EVENT_ADV_INERVAL); // 50ms, actual time * 625us
} else if(cfg.flg & FLG_MEAS_NOTIFY) {
get_utc_time_sec(); // счет UTC timestamp
measure_notify();
}
}
return(events ^ PIN_INPUT_EVT);
}
#endif
#if (DEV_SERVICES & SERVICE_HISTORY)
if(events & WRK_NOTIFY_EVT) {
LOG("Wrk notify events\n");
wrk_notify();
return(events ^ WRK_NOTIFY_EVT);
}
#endif
if(events & SBP_CMDDATA) {
LOG("CMD data events\n");
new_cmd_data();
// return unprocessed events
return(events ^ SBP_CMDDATA);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn simpleBLEPeripheral_ProcessOSALMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
#if DEBUG_INFO
hciEvt_CmdComplete_t *pHciMsg;
#endif
switch ( pMsg->event ){
case HCI_GAP_EVENT_EVENT:{
switch( pMsg->status ){
case HCI_COMMAND_COMPLETE_EVENT_CODE:
#if DEBUG_INFO
pHciMsg = (hciEvt_CmdComplete_t *)pMsg;
LOG("==> HCI_COMMAND_COMPLETE_EVENT_CODE: %x\n", pHciMsg->cmdOpcode);
//safeToDealloc = gapProcessHCICmdCompleteEvt( (hciEvt_CmdComplete_t *)pMsg );
#endif
break;
default:
//safeToDealloc = FALSE; // Send to app
break;
}
}
}
}
/*********************************************************************
* @fn peripheralStateReadRssiCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateReadRssiCB( int8_t rssi )
{
(void)rssi;
}
/*********************************************************************
* @fn peripheralStateNotificationCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateNotificationCB( gaprole_States_t newState )
{
switch ( newState )
{
case GAPROLE_STARTED:
{
LOG("Gaprole_start\n");
osal_set_event(simpleBLEPeripheral_TaskID, SBP_RESET_ADV_EVT);
}
break;
case GAPROLE_ADVERTISING:
{
LOG("Gaprole_adversting\n");
osal_stop_timerEx(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT);
adv_wrk.meas_count = 0;
}
break;
case GAPROLE_CONNECTED:
adv_wrk.adv_event = 0;
adv_wrk.meas_count = 0;
adv_wrk.adv_reload_count = 1;
#if (DEV_SERVICES & SERVICE_THS)
osal_start_reload_timer(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT, adv_wrk.measure_interval_ms); // 10000 ms
#else
osal_start_reload_timer(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT, cfg.batt_interval*1000);
#endif
HCI_PPLUS_ConnEventDoneNoticeCmd(simpleBLEPeripheral_TaskID, 0);
LOG("Gaprole_Connected\n");
#if (DEV_SERVICES & SERVICE_SCREEN)
show_ble_symbol(1);
update_lcd();
#endif
break;
case GAPROLE_CONNECTED_ADV:
break;
case GAPROLE_WAITING:
LOG("Gaprole_Disconnection\n");
osal_stop_timerEx(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT);
bthome_data_beacon((void *) gapRole_AdvertData);
#if 1 //FIX_CONN_INTERVAL
gapRole_SlaveLatency = periConnParameters.latency = cfg.connect_latency;
#else
gapRole_SlaveLatency = cfg.connect_latency;
#endif
adv_wrk.adv_event = 0;
adv_wrk.meas_count = 0;
adv_wrk.adv_reload_count = 1;
#if (DEV_SERVICES & SERVICE_SCREEN)
show_ble_symbol(0);
update_lcd();
#endif
if(wrk.reboot) {
write_reg(OTA_MODE_SELECT_REG, wrk.reboot);
hal_system_soft_reset();
}
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
LOG("Gaprole_waitting_after_timerout\n");
break;
case GAPROLE_ERROR:
LOG("Gaprole error!\n");
break;
default:
break;
}
gapProfileState = newState;
LOG("[GAP ROLE %d]\n",newState);
// VOID gapProfileState;
}