/********************************************************************* * @fn processGapStateChange * * @brief Change the GAP state. * 1. Connected -> disconnect and start advertising * 2. Advertising -> stop advertising * 3. Disconnected/not advertising -> start advertising * * @param none * * @return none */ static void processGapStateChange(void) { if (gapProfileState != GAPROLE_CONNECTED) { uint8_t current_adv_enabled_status; uint8_t new_adv_enabled_status; // Find the current GAP advertising status GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status); if (current_adv_enabled_status == FALSE) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } // Change the GAP advertisement status to opposite of current status GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &new_adv_enabled_status); } if (gapProfileState == GAPROLE_CONNECTED) { uint8_t adv_enabled = TRUE; // Disconnect GAPRole_TerminateConnection(); // Start advertising GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &adv_enabled); } }
/********************************************************************* * @fn simpleBLEBroadcaster_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void simpleBLEBroadcaster_HandleKeys( uint8 shift, uint8 keys ) { VOID shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_1 ) { advertData[6]++; GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); } if ( keys & HAL_KEY_SW_2 ) { // ressing the right key should toggle advertising on and off uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; //Find the current GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status ); if( current_adv_enabled_status == FALSE ) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } //change the GAP advertisement status to opposite of current status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); } }
/********************************************************************* * @fn simpleTopology_init * * @brief Called during initialization and contains application * specific initialization (ie. hardware initialization/setup, * table initialization, power up notification, etc), and * profile initialization/setup. * * @param None. * * @return None. */ static void simpleTopology_init(void) { // ****************************************************************** // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp // ****************************************************************** // Register the current thread as an ICall dispatcher application // so that the application can send and receive messages. ICall_registerApp(&selfEntity, &sem); // Create an RTOS queue for message from profile to be sent to app. appMsgQueue = Util_constructQueue(&appMsg); Util_constructClock(&scanClock, SensorTagMultiRoleTest_scanStartHandler, SCAN_EVENT_PERIOD, SCAN_EVENT_PERIOD, TRUE, SCAN_EVENT); // Setup the GAP { /*-------------------PERIPHERAL-------------------*/ uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL; GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt); GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt); GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt); GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt); GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT, ADV_DURATION); /*-------------------CENTRAL-------------------*/ GAP_SetParamValue(TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION); GAP_SetParamValue(TGAP_GEN_DISC_SCAN_INT, DEFAULT_SCAN_INT); GAP_SetParamValue(TGAP_GEN_DISC_SCAN_WIND, DEFAULT_SCAN_WIND); GAP_SetParamValue(TGAP_LIM_DISC_SCAN_INT, DEFAULT_SCAN_INT); GAP_SetParamValue(TGAP_LIM_DISC_SCAN_WIND, DEFAULT_SCAN_WIND); } // Setup the GAP Role Profile { /*--------PERIPHERAL-------------*/ // For all hardware platforms, device starts advertising upon initialization uint8_t initialAdvertEnable = FALSE; // By setting this to zero, the device will go into the waiting state after // being discoverable for 30.72 second, and will not being advertising again // until the enabler is set back to TRUE uint16_t advertOffTime = 0; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable, NULL); GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t), &advertOffTime, NULL); GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData, NULL); // Register with GAP for HCI/Host messages GAP_RegisterForMsgs(selfEntity); } VOID GAPRole_StartDevice(&simpleTopology_gapRoleCBs); }
/** * @fn SNP_stopAdv * */ uint8_t SNP_stopAdv(void) { //Disable Advertising. uint8_t start = FALSE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &start); GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), &start); return SNP_SUCCESS; }
/********************************************************************* * @fn CyclingSensor_handleResetEvt * * @brief "soft" resets the device. This puts the device into a waiting * state, clears all white list, bonding and GATT service handle * information about previously previously connected devices. * * @param none * * @return none */ static void CyclingSensor_handleResetEvt(void) { static uint8_t isWLClear = FALSE; if (gapProfileState == GAPROLE_CONNECTED) { // Exit the connection. GAPRole_TerminateConnection(); } else if (gapProfileState == GAPROLE_ADVERTISING) { uint8_t value = FALSE; // Turn off advertising. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &value); } else if (USING_WHITE_LIST == TRUE && isWLClear == FALSE) { // Set internal white list flag to true. isWLClear = TRUE; // Disable white list use with advertising. sensorUsingWhiteList = FALSE; // Temporary variable. uint8_t value = GAP_FILTER_POLICY_ALL; // Turn off white list filter policy. GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(uint8_t), &value); // Clear the white list. HCI_LE_ClearWhiteListCmd(); } else if ((gapProfileState == GAPROLE_STARTED) || (gapProfileState == GAPROLE_WAITING) || (gapProfileState == GAPROLE_WAITING_AFTER_TIMEOUT)) { uint8_t eraseBonds = TRUE; // Stop the periodic expirations of the reset clock. Util_stopClock(&resetClock); // Set internal white list flag to false for next reset event. isWLClear = FALSE; // Erase all bonds. GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS, 0, &eraseBonds); // Turn on GREEN LED for set time. //HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); } }
static void FanPeripheralStateNotificationCallBack(gaprole_States_t newState) { switch (newState) { case GAPROLE_STARTED: { uint8 ownAddress[B_ADDR_LEN]; uint8 systemId[DEVINFO_SYSTEM_ID_LEN]; GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); // use 6 bytes of device address for 8 bytes of system ID value systemId[0] = ownAddress[0]; systemId[1] = ownAddress[1]; systemId[2] = ownAddress[2]; // set middle bytes to zero systemId[4] = 0x00; systemId[3] = 0x00; // shift three bytes up systemId[7] = ownAddress[5]; systemId[6] = ownAddress[4]; systemId[5] = ownAddress[3]; DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId); } break; case GAPROLE_ADVERTISING: break; case GAPROLE_CONNECTED: FanConnected(fanTaskId); break; case GAPROLE_WAITING: { FanDisConnected(); uint8 advertEnabled = FALSE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &advertEnabled); GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanResponseData), scanResponseData); GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, scanResponseData + 2); advertEnabled = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &advertEnabled); } break; case GAPROLE_WAITING_AFTER_TIMEOUT: break; case GAPROLE_ERROR: break; default: break; } };
/** * SNP_setAdvData * */ uint8_t SNP_setAdvData(snpSetAdvDataReq_t *pReq, uint8_t len) { uint8_t status = 0; uint8_t *pDataPtr; //Device must be started, or the set adv command will failed. VOID GAPRole_StartDevice(&SNP_gapRoleCBs); if(pReq->type < SNP_ADV_DATA_MAX_IDX) { pDataPtr = advPtrTable[pReq->type].pData; if(pDataPtr) { ICall_free(advPtrTable[pReq->type].pData); } advPtrTable[pReq->type].pData = pDataPtr = ICall_malloc(len); if(pDataPtr) { advPtrTable[pReq->type].length = len; memcpy(pDataPtr, pReq->pData, len); if(pReq->type == SNP_ADV_DATA_SCAN_RSP_IDX) { status = GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, len, pDataPtr); } else if(pReq->type == SNP_ADV_DATA_NON_CONN_IDX) { status = GAPRole_SetParameter(GAPROLE_ADVERT_DATA, len, pDataPtr); } else if(pReq->type == SNP_ADV_DATA_CONN_IDX) { uint8_t value; GAPRole_GetParameter(GAPROLE_STATE, &value); if(value == GAPROLE_CONNECTED_ADV) { status = GAPRole_SetParameter(GAPROLE_ADVERT_DATA, len, pDataPtr); } } } else { status = SNP_OUT_OF_RESOURCES; } } else { //Error, bad type status = SNP_INVALID_PARAMS; } return status; }
/********************************************************************* * @fn hidDevInitialAdvertising * * @brief Start advertising for initial connection * * @return None. */ static void hidDevInitialAdvertising( void ) { uint8 param; VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, HID_INITIAL_ADV_INT_MIN ); VOID GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, HID_INITIAL_ADV_INT_MAX ); VOID GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, HID_INITIAL_ADV_TIMEOUT ); // Setup adverstising filter policy first param = GAP_FILTER_POLICY_ALL; VOID GAPRole_SetParameter( GAPROLE_ADV_FILTER_POLICY, sizeof( uint8 ), ¶m ); param = TRUE; VOID GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m ); }
void MysensorTag_updateAdvertisingData(void) { uint16_t RawTemperature, RawHumidity; bStatus_t st1,st2,st3, st4; uint8_t period, config, HumiditySensorON=1; uint8_t HumRawData[4]; // humidity sensor raw data float temperature,humidity; // temperature and humidity measurements in Celcius and % // set parameter st1 = Humidity_setParameter(SENSOR_CONF,1,&HumiditySensorON); // turn on //SensorTagHum_processCharChangeEvt(SENSOR_CONF); // enable humidity sensing // SensorTag_enqueueMsg(ST_CHAR_CHANGE_EVT, SERVICE_ID_HUM, SENOSR_CONF); // get parameter st2 = Humidity_getParameter(SENSOR_PERI, &period); st3 = Humidity_getParameter(SENSOR_CONF, &config); st4 = Humidity_getParameter(SENSOR_DATA, &HumRawData); // raw temperature and humidity RawTemperature = HumRawData[0] | (HumRawData[1]<<8); RawHumidity = HumRawData[2] | (HumRawData[3]<<8); sensorHdc1000Convert(RawTemperature, RawHumidity,&temperature, &humidity); // update advertisement data advertData[KEY_STATE_OFFSET+1] = (uint8_t)temperature; advertData[KEY_STATE_OFFSET+2] = (uint8_t)humidity; GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData); }
/********************************************************************* * @fn softCmd_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void softCmd_HandleKeys( uint8 shift, uint8 keys ) { if ( keys & HAL_KEY_SW_1 ) { // if in a connection send a soft key if ( softCmdGapState == GAPROLE_CONNECTED ) { softCmdSend( CMD_ENUM_SOFT_CMD_0 ); } } if ( keys & HAL_KEY_SW_2 ) { // if not in a connection, toggle advertising on and off if( softCmdGapState != GAPROLE_CONNECTED ) { uint8 status; // toggle GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &status ); status = !status; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &status ); } // if in a connection send a soft key else { softCmdSend( CMD_ENUM_SOFT_CMD_1 ); } } }
/********************************************************************* * @fn timeAppDisconnected * * @brief Handle disconnect. * * @return none */ static void timeAppDisconnected( void ) { // Initialize state variables timeAppDiscState = DISC_IDLE; timeAppPairingStarted = FALSE; timeAppDiscPostponed = FALSE; // stop periodic measurement osal_stop_timerEx( bloodPressureTaskId, BP_TIMER_CUFF_EVT ); // reset bloodPressure measurement client configuration uint16 param = 0; BloodPressure_SetParameter(BLOODPRESSURE_MEAS_CHAR_CFG, sizeof(uint16), (uint8 *) ¶m); // reset bloodPressure intermediate measurement client configuration BloodPressure_SetParameter(BLOODPRESSURE_IMEAS_CHAR_CFG, sizeof(uint16), (uint8 *) ¶m); uint8 advEnable = FALSE; //disable advertising on disconnect GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advEnable ); }
/*--------------------------------------------------------------------------- * Add the set the last part of hte device name to the final bytes of the * device address. Useful when mane demo devices are located in the same room. *-------------------------------------------------------------------------*/ void updateNameWithAddressInfo(void) { //uint8 status; uint8 numberString[4]; uint8 address[6]; uint8 value; //status = GAPRole_GetParameter(GAPROLE_BD_ADDR, address); GAPRole_GetParameter(GAPROLE_BD_ADDR, address); value = (address[1] & 0xF0) >> 4; numberString[0] = getAscii(value); value = address[1] & 0x0F; numberString[1] = getAscii(value); value = (address[0] & 0xF0) >> 4; numberString[2] = getAscii(value); value = address[0] & 0x0F; numberString[3] = getAscii(value); // Replace "0000" part of "OLP425-0000" osal_memcpy(&attDeviceName[7], numberString, 4); osal_memcpy(&deviceName[9], numberString, 4); osal_memcpy(&attDeviceNameNew[7], numberString, 4); osal_memcpy(&deviceNameNew[9], numberString, 4); // status = GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( deviceName ), deviceName ); // status = GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN - 1, attDeviceName ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( deviceName ), deviceName ); GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN - 1, attDeviceName ); }
/********************************************************************* * @fn SimpleBLEPeripheral_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 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events ) { VOID task_id; // OSAL required parameter that isn't used in this function if ( events & SYS_EVENT_MSG ) { uint8 *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); } if ( events & SBP_START_DEVICE_EVT ) { P0_7 = 0; //防止继电器跳变,初始化为高 P0DIR |= BV(7); //设置为输出 P0SEL &=~BV(7); //设置该脚为普通GPIO //HCI_EXT_SetTxPowerCmd (HCI_EXT_TX_POWER_MINUS_23_DBM); // Start the Device VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs ); // Start Bond Manager VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs ); return ( events ^ SBP_START_DEVICE_EVT ); } if ( events & SBP_PERIODIC_EVT ) { //成功写入后,重启从机 HAL_SYSTEM_RESET(); return (events ^ SBP_PERIODIC_EVT); } #if defined ( PLUS_BROADCASTER ) if ( events & SBP_ADV_IN_CONNECTION_EVT ) { uint8 turnOnAdv = TRUE; // Turn on advertising while in a connection GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv ); return (events ^ SBP_ADV_IN_CONNECTION_EVT); } #endif // PLUS_BROADCASTER // Discard unknown events return 0; }
/*--------------------------------------------------------------------------- * Initialization of GAP properties. *-------------------------------------------------------------------------*/ static void gapApplicationInit(void) { // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed uint8 initial_advertising_enable = TRUE; // By setting this to zero, the device will go into the waiting state after // being discoverable for 30.72 second, and will not being advertising again // until the enabler is set back to TRUE uint16 gapRole_AdvertOffTime = 0; uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; // Set the GAP Role Parameters GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( deviceName ), deviceName ); GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); // Set the GAP Attributes GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName ); // Setup the GAP Bond Manager { uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = TRUE; uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; uint8 bonding = TRUE; GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding ); } // Set max output power and reciever gain HCI_EXT_SetTxPowerCmd(HCI_EXT_TX_POWER_4_DBM); HCI_EXT_SetRxGainCmd(HCI_EXT_RX_GAIN_HIGH); }
/********************************************************************* * @fn SimplePropBeacon_startRegularAdv * * @brief Start regular advertise. * If configuration mode was on going, stop it. * * @param none * * @return none */ static void SimplePropBeacon_startRegularAdv(void) { uint8 advertEnabled = FALSE; uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND; // Stop connectable advertising GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled); advertEnabled = TRUE; GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(uint8_t), &advType); GAPRole_SetParameter(GAPROLE_ADVERT_DATA, PROPBEACON_PACKET_SIZE, &propBeaconAdv); GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t), &advertEnabled); }
/********************************************************************* * @fn performPeriodicTask * * @brief Perform a periodic application task. This function gets * called every five seconds as a result of the SBP_PERIODIC_EVT * OSAL event. In this example, the value of the third * characteristic in the SimpleGATTProfile service is retrieved * from the profile, and then copied into the value of the * the fourth characteristic. * * @param none * * @return none */ static void performPeriodicTask( void ) { uint8 pos = FALSE, txpwr = 0; Batt_MeasLevel( ); GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &pos); advertData[11] = Battery2Asc(battLevel); advertData[12] = (P0 & 1<<4) ? 0x31 : 0x30; advertData[13] = (P0 & 1<<5) ? 0x31 : 0x30; advertData[14] = (P0 & 1<<6) ? 0x31 : 0x30; advertData[15] = '0' + advert_internal/100; advertData[16] = '0' + (advert_internal/10)%10; advertData[17] = '0' + advert_internal%10; ProxReporter_GetParameter(PP_TX_POWER_LEVEL, &txpwr); advertData[18] = txpwr + '0'; HCI_LE_SetAdvDataCmd( sizeof( advertData ), advertData ); pos = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8), &pos); }
/********************************************************************* * @fn simpleBLEPeripheral_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys ) { uint8 SK_Keys = 0; VOID shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_1 ) { SK_Keys |= SK_KEY_LEFT; } if ( keys & HAL_KEY_SW_2 ) { SK_Keys |= SK_KEY_RIGHT; // if device is not in a connection, pressing the right key should toggle // advertising on and off // Note: If PLUS_BROADCASTER is define this condition is ignored and // Device may advertise during connections as well. #ifndef PLUS_BROADCASTER if( gapProfileState != GAPROLE_CONNECTED ) { #endif // PLUS_BROADCASTER uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; //Find the current GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status ); if( current_adv_enabled_status == FALSE ) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } //change the GAP advertisement status to opposite of current status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); #ifndef PLUS_BROADCASTER } #endif // PLUS_BROADCASTER } // Set the value of the keys state to the Simple Keys Profile; // This will send out a notification of the keys state if enabled SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys ); }
/*--------------------------------------------------------------------------- * Add the set the last part of hte device name to the final bytes of the * device address. Useful when mane demo devices are located in the same room. *-------------------------------------------------------------------------*/ void Rename_Device(uint8 *name) { //uint8 status; osal_memcpy(&attDeviceName[0], name, 21); osal_memcpy(&deviceName[0], name, 21); //status = GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof (deviceName), deviceName); //status = GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN - 1, attDeviceName ); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof (deviceName), deviceName); GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN - 1, attDeviceName ); }
/********************************************************************* * @fn HidDev_Close * * @brief Close the connection or stop advertising. * * @return None. */ void HidDev_Close( void ) { uint8 param; // if connected then disconnect if ( hidDevGapState == GAPROLE_CONNECTED ) { GAPRole_TerminateConnection(); } // else stop advertising else { param = FALSE; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m ); } }
/********************************************************************* * @fn HeartRate_toggleAdvertising * * @brief Toggle advertising state. * * @param none * * @return status - TRUE if advertising, FALSE otherwise. */ static bool HeartRate_toggleAdvertising(void) { uint8_t advState; // Find the current GAP advertisement status. GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &advState); // Get the opposite state. advState = !advState; // Change the GAP advertisement status to opposite of current status. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advState); return advState; }
/********************************************************************* * @fn heartRate_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void heartRate_HandleKeys( uint8 shift, uint8 keys ) { if ( keys & HAL_KEY_SW_1 ) { // set simulated measurement flag index if (++heartRateFlagsIdx == FLAGS_IDX_MAX) { heartRateFlagsIdx = 0; } } if ( keys & HAL_KEY_SW_2 ) { // if not in a connection, toggle advertising on and off if( gapProfileState != GAPROLE_CONNECTED ) { uint8 status; // Set fast advertising interval for user-initiated connections GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION ); // toggle GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &status ); status = !status; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &status ); // Set state variable if (status == FALSE) { heartRateAdvCancelled = TRUE; } } // if in a connection toggle some the battery state bits for test purposes else { uint8 state; Batt_GetParameter( BATT_PARAM_STATE, &state ); state ^= BATT_FLAGS_CR_CRIT; Batt_SetParameter( BATT_PARAM_STATE, sizeof( uint8 ), &state ); } } }
/********************************************************************* * @fn bloodPressure_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ static void bloodPressure_HandleKeys( uint8 shift, uint8 keys ) { if ( keys & HAL_KEY_SW_1 ) { // set simulated measurement flag index if (++bloodPressureFlagsIdx == FLAGS_IDX_MAX) { bloodPressureFlagsIdx = 0; } } if ( keys & HAL_KEY_SW_2 ) { // if device is not in a connection, pressing the right key should toggle // advertising on and off and start a measurement if( gapProfileState != GAPROLE_CONNECTED ) { uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; //Find the current GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status ); if( current_adv_enabled_status == FALSE ) new_adv_enabled_status = TRUE; else new_adv_enabled_status = FALSE; //change the GAP advertisement status to opposite of current status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); //start simulation timer (start --> cuff -->measurement ready) osal_start_timerEx( bloodPressureTaskId, BP_TIMER_CUFF_EVT, TIMER_CUFF_PERIOD ); //reset cuff count cuffCount = 0; } else //connected mode, simulate some measurements { simulateMeas(); } } }
/********************************************************************* * @fn simpleTopology_processRoleEvent * * @brief Multi role event processing function. * * @param pEvent - pointer to event structure * * @return none */ static void simpleTopology_processRoleEvent(gapMultiRoleEvent_t *pEvent) { switch (pEvent->gap.opcode) { /*case GAP_MAKE_DISCOVERABLE_DONE_EVENT: { if (gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) > 0) { LCD_WRITE_STRING("Advertising", LCD_PAGE2); } else { LCD_WRITE_STRING("Advertising", LCD_PAGE2); } } break;*/ case GAP_END_DISCOVERABLE_DONE_EVENT: { if (gapRoleNumLinks(GAPROLE_AVAILABLE_LINKS) > 0) { LCD_WRITE_STRING("Ready to Advertise", LCD_PAGE2); } else { LCD_WRITE_STRING("Can't Adv : No links", LCD_PAGE2); } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete scanningStarted = FALSE; advertising_enabled = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enabled, NULL); } break; default: break; } }
uint8 Application_StopAdvertise() { if( gapProfileState != GAPROLE_CONNECTED ) { uint8 astatus; // toggle GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &astatus ); if (astatus == TRUE) { astatus = FALSE; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &astatus ); return SUCCESS; } } return FAILURE; }
/********************************************************************* * @fn hidDevGapStateCB * * @brief Notification from the profile of a state change. * * @param newState - new state * * @return none */ static void hidDevGapStateCB( gaprole_States_t newState ) { // if connected if ( newState == GAPROLE_CONNECTED ) { // get connection handle GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle ); // connection not secure yet hidDevConnSecure = FALSE; // don't start advertising when connection is closed uint8 param = FALSE; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), ¶m ); // start idle timer hidDevStartIdleTimer(); } // if disconnected else if ( hidDevGapState == GAPROLE_CONNECTED && newState != GAPROLE_CONNECTED ) { hidDevDisconnected(); updateConnParams = TRUE; if ( pairingStatus == SMP_PAIRING_FAILED_CONFIRM_VALUE ) { // bonding failed due to mismatched confirm values hidDevInitialAdvertising(); pairingStatus = SUCCESS; } } // if started else if ( newState == GAPROLE_STARTED ) { // nothing to do for now! } hidDevGapState = newState; }
uint8 Application_StartAdvertise(uint16 duration, uint16 interval) { if( gapProfileState != GAPROLE_CONNECTED ) { uint8 astatus; // toggle GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &astatus ); if (astatus == FALSE) { //Set fast advertising interval for user-initiated connections GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, interval ); GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, interval ); GAP_SetParamValue( TGAP_LIM_ADV_TIMEOUT, duration ); astatus = TRUE; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &astatus ); return SUCCESS; } } return FAILURE; }
/********************************************************************* * @fn thermometer_Advertise * * @brief Start advertisemement when measurement is ready * * * @return none */ static void thermometer_Advertise( void ) { // Advertise if not connected if( gapProfileState != GAPROLE_CONNECTED ) { uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; //Find the current GAP advertisement status GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status ); if( current_adv_enabled_status == FALSE ) { new_adv_enabled_status = TRUE; } //change the GAP advertisement status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); } }
/********************************************************************* * @fn Thermometer_advertise * * @brief Start advertisement when measurement is ready. * * @param none * * @return none */ static void Thermometer_advertise(void) { // If not connected, toggle advertising. if (gapProfileState != GAPROLE_CONNECTED) { uint8_t current_adv_enabled_status; uint8_t new_adv_enabled_status; // Find the current GAP advertisement status. GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status); if(current_adv_enabled_status == FALSE) { new_adv_enabled_status = TRUE; } // Change the GAP advertisement status . GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &new_adv_enabled_status); } }
/********************************************************************* * @fn BlueBasic_Init * * @brief Initialization function for the Blue Basic 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 BlueBasic_Init( uint8 task_id ) { blueBasic_TaskID = task_id; #ifdef ENABLE_BLE_CONSOLE GAPRole_SetParameter( GAPROLE_ADVERT_DATA, 0, sizeof(consoleAdvert), (void*)consoleAdvert ); #endif // Set advertising interval GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, DEFAULT_ADVERTISING_INTERVAL ); GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, DEFAULT_ADVERTISING_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_ADVERTISING_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_ADVERTISING_INTERVAL ); // Initialize GATT attributes GGS_AddService( GATT_ALL_SERVICES ); // GAP GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes #ifdef ENABLE_FAKE_OAD_PROFILE GATTServApp_RegisterService(oadProfile, GATT_NUM_ATTRS(oadProfile), NULL); #endif DevInfo_AddService(); // Device Information Service #if defined FEATURE_OAD VOID OADTarget_AddService(); // OAD Profile #endif // Enable clock divide on halt // This reduces active current while radio is active and CC254x MCU // is halted #ifdef ENABLE_BLE_CONSOLE // See: http://e2e.ti.com/support/wireless_connectivity/f/538/p/169944/668822.aspx#664740 HCI_EXT_ClkDivOnHaltCmd(HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT); #endif // Overlap enabled HCI_EXT_OverlappedProcessingCmd(HCI_EXT_ENABLE_OVERLAPPED_PROCESSING); // Setup a delayed profile startup osal_set_event( blueBasic_TaskID, BLUEBASIC_START_DEVICE_EVT ); }
/********************************************************************* * @fn hidDevSendReport * * @brief Send a HID report. * * @param id - HID report ID. * @param type - HID report type. * @param len - Length of report. * @param pData - Report data. * * @return None. */ static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8 *pData ) { hidRptMap_t *pRpt; gattAttribute_t *pAttr; uint16 retHandle; // get att handle for report if ( (pRpt = hidDevRptById(id, type)) != NULL ) { // if notifications are enabled if ( (pAttr = GATT_FindHandle(pRpt->cccdHandle, &retHandle)) != NULL ) { uint16 value; value = GATTServApp_ReadCharCfg( gapConnHandle, (gattCharCfg_t *) pAttr->pValue ); if ( value & GATT_CLIENT_CFG_NOTIFY ) { // After service discovery and encryption, the HID Device should request to // change to the preferred connection parameters that best suit its use case. if ( updateConnParams ) { GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &updateConnParams ); updateConnParams = FALSE; } // send notification lastNoti.handle = pRpt->handle; lastNoti.len = len; osal_memcpy(lastNoti.value, pData, len); GATT_Notification( gapConnHandle, &lastNoti, FALSE ); // start idle timer hidDevStartIdleTimer(); } } } }