Files
ch32v20x-examples/EVT/EXAM/BLE/Observer/APP/observer.c
T
2023-12-01 10:33:09 +08:00

303 lines
8.7 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : observer.c
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : Observer application, initialize scan parameters,
* then scan regularly, if the scan result is not empty,
* print the scanned broadcast address
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "CONFIG.h"
#include "observer.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// Maximum number of scan responses
#define DEFAULT_MAX_SCAN_RES 50
// Scan duration in (625us)
#define DEFAULT_SCAN_DURATION 4800
// Discovey mode (limited, general, all)
#define DEFAULT_DISCOVERY_MODE DEVDISC_MODE_ALL
// TRUE to use active scan
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE
// TRUE to use white list during discovery
#define DEFAULT_DISCOVERY_WHITE_LIST FALSE
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
uint8_t gStatus;
// Task ID for internal task/event processing
static uint8_t ObserverTaskId;
// Number of scan results and scan result index
static uint8_t ObserverScanRes;
// Scan result list
static gapDevRec_t ObserverDevList[DEFAULT_MAX_SCAN_RES];
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void ObserverEventCB(gapRoleEvent_t *pEvent);
static void Observer_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void ObserverAddDeviceInfo(uint8_t *pAddr, uint8_t addrType);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static const gapRoleObserverCB_t ObserverRoleCB = {
ObserverEventCB // Event callback
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Observer_Init
*
* @brief Initialization function for the Simple BLE Observer App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notification).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void Observer_Init()
{
ObserverTaskId = TMOS_ProcessEventRegister(Observer_ProcessEvent);
// Setup Observer Profile
{
uint8_t scanRes = DEFAULT_MAX_SCAN_RES;
GAPRole_SetParameter(GAPROLE_MAX_SCAN_RES, sizeof(uint8_t), &scanRes);
}
// Setup GAP
GAP_SetParamValue(TGAP_DISC_SCAN, DEFAULT_SCAN_DURATION);
// Setup a delayed profile startup
tmos_set_event(ObserverTaskId, START_DEVICE_EVT);
}
/*********************************************************************
* @fn Observer_ProcessEvent
*
* @brief Simple BLE Observer 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 TMOS 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 Observer_ProcessEvent(uint8_t task_id, uint16_t events)
{
// VOID task_id; // TMOS required parameter that isn't used in this function
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(ObserverTaskId)) != NULL)
{
Observer_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & START_DEVICE_EVT)
{
// Start the Device
GAPRole_ObserverStartDevice((gapRoleObserverCB_t *)&ObserverRoleCB);
return (events ^ START_DEVICE_EVT);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn Observer_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Observer_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
case GATT_MSG_EVENT:
break;
default:
break;
}
}
/*********************************************************************
* @fn ObserverEventCB
*
* @brief Observer event callback function.
*
* @param pEvent - pointer to event structure
*
* @return none
*/
static void ObserverEventCB(gapRoleEvent_t *pEvent)
{
switch(pEvent->gap.opcode)
{
case GAP_DEVICE_INIT_DONE_EVENT:
{
GAPRole_ObserverStartDiscovery(DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST);
PRINT("Discovering...\n");
}
break;
case GAP_DEVICE_INFO_EVENT:
{
ObserverAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);
}
break;
case GAP_DEVICE_DISCOVERY_EVENT:
{
PRINT("Discovery over...\n");
// Display discovery results
if(pEvent->discCmpl.numDevs > 0)
{
int i, j;
// Increment index of current result (with wraparound)
for(j = 0; j < pEvent->discCmpl.numDevs; j++)
{
PRINT("Device %d : ", j);
for(i = 0; i < 6; i++)
{
PRINT("%x ", pEvent->discCmpl.pDevList[j].addr[i]);
}
PRINT("\n");
}
}
GAPRole_ObserverStartDiscovery(DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST);
PRINT("Discovering...\n ");
}
break;
case GAP_EXT_ADV_DEVICE_INFO_EVENT:
{
// Display device addr
PRINT("Recv ext adv \n");
// Add device to list
ObserverAddDeviceInfo(pEvent->deviceExtAdvInfo.addr, pEvent->deviceExtAdvInfo.addrType);
}
break;
case GAP_DIRECT_DEVICE_INFO_EVENT:
{
// Display device addr
PRINT("Recv direct adv \n");
// Add device to list
ObserverAddDeviceInfo(pEvent->deviceDirectInfo.addr, pEvent->deviceDirectInfo.addrType);
}
break;
default:
break;
}
}
/*********************************************************************
* @fn ObserverAddDeviceInfo
*
* @brief Add a device to the device discovery result list
*
* @return none
*/
static void ObserverAddDeviceInfo(uint8_t *pAddr, uint8_t addrType)
{
uint8_t i;
// If result count not at max
if(ObserverScanRes < DEFAULT_MAX_SCAN_RES)
{
// Check if device is already in scan results
for(i = 0; i < ObserverScanRes; i++)
{
if(tmos_memcmp(pAddr, ObserverDevList[i].addr, B_ADDR_LEN))
{
return;
}
}
// Add addr to scan result list
tmos_memcpy(ObserverDevList[ObserverScanRes].addr, pAddr, B_ADDR_LEN);
ObserverDevList[ObserverScanRes].addrType = addrType;
// Increment scan result count
ObserverScanRes++;
}
}
/*********************************************************************
*********************************************************************/