/******************************************************************** * @fn GAPRole_SendUpdateParam * * @brief Update the parameters of an existing connection * * @param minConnInterval - the new min connection interval * @param maxConnInterval - the new max connection interval * @param latency - the new slave latency * @param connTimeout - the new timeout value * @param handleFailure - what to do if the update does not occur. * Method may choose to terminate connection, try again, or take no action * * @return SUCCESS, bleNotConnected, or bleInvalidRange */ bStatus_t GAPRole_SendUpdateParam( uint16 minConnInterval, uint16 maxConnInterval, uint16 latency, uint16 connTimeout, uint8 handleFailure ) { // If there is no existing connection no update need be sent if ( gapRole_state != GAPROLE_CONNECTED ) { return ( bleNotConnected ); } // Check that all parameters are in range before sending request if ( ( minConnInterval >= DEFAULT_MIN_CONN_INTERVAL ) && ( minConnInterval < DEFAULT_MAX_CONN_INTERVAL ) && ( maxConnInterval >= DEFAULT_MIN_CONN_INTERVAL ) && ( maxConnInterval < DEFAULT_MAX_CONN_INTERVAL ) && ( latency < MAX_SLAVE_LATENCY ) && ( connTimeout >= MIN_TIMEOUT_MULTIPLIER ) && ( connTimeout < MAX_TIMEOUT_MULTIPLIER ) ) { gapRole_MinConnInterval = minConnInterval; gapRole_MaxConnInterval = maxConnInterval; gapRole_SlaveLatency = latency; gapRole_TimeoutMultiplier = connTimeout; // Start connection update procedure gapRole_startConnUpdate( handleFailure ); // Connection update requested by app, cancel such pending procedure (if active) VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT ); return ( SUCCESS ); } return ( bleInvalidRange ); }
/******************************************************************** * @fn GAPRole_SendUpdateParam * * @brief Update the parameters of an existing connection * * @param minConnInterval - the new min connection interval * @param maxConnInterval - the new max connection interval * @param latency - the new slave latency * @param connTimeout - the new timeout value * @param handleFailure - what to do if the update does not occur. * Method may choose to terminate connection, try again, * or take no action * * @return SUCCESS, bleNotConnected, or bleInvalidRange */ bStatus_t GAPRole_SendUpdateParam(uint16_t minConnInterval, uint16_t maxConnInterval, uint16_t latency, uint16_t connTimeout, uint8_t handleFailure, uint16_t connHandle) { uint8 connHandleIndex = gapRoleInfo_Find(connHandle); // If there is no existing connection no update need be sent if (multiConnInfo[connHandleIndex].gapRole_ConnectionHandle == GAPROLE_CONN_JUST_TERMINATED || multiConnInfo[connHandleIndex].gapRole_ConnectionHandle == INVALID_CONNHANDLE) { return (bleNotConnected); } if (multiConnInfo[connHandleIndex].gapRole_ConnRole != GAP_PROFILE_PERIPHERAL) { return (bleNotConnected); } // If there is no existing connection no update need be sent if (gapRole_peripheralState != GAPROLE_CONNECTED) { return (bleNotConnected); } // Check that all parameters are in range before sending request if ((minConnInterval >= DEFAULT_MIN_CONN_INTERVAL) && (minConnInterval < DEFAULT_MAX_CONN_INTERVAL) && (maxConnInterval >= DEFAULT_MIN_CONN_INTERVAL) && (maxConnInterval < DEFAULT_MAX_CONN_INTERVAL) && (latency < MAX_SLAVE_LATENCY) && (connTimeout >= MIN_TIMEOUT_MULTIPLIER) && (connTimeout < MAX_TIMEOUT_MULTIPLIER)) { gapRole_MinConnInterval = minConnInterval; gapRole_MaxConnInterval = maxConnInterval; gapRole_SlaveLatency = latency; gapRole_TimeoutMultiplier = connTimeout; // Start connection update procedure VOID gapRole_startConnUpdate(handleFailure, multiConnInfo[connHandleIndex].gapRole_ConnectionHandle); // Connection update requested by app, cancel such pending procedure (if active) Util_stopClock(&startUpdateClock); return (SUCCESS); } return (bleInvalidRange); }
/********************************************************************* * @brief Task Event Processor function. * * Internal function defined in peripheral.h. */ uint16 GAPRole_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( gapRole_TaskID )) != NULL ) { gapRole_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 & GAP_EVENT_SIGN_COUNTER_CHANGED ) { // Sign counter changed, save it to NV VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter ); return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED ); } if ( events & START_ADVERTISING_EVT ) { if ( gapRole_AdvEnabled ) { gapAdvertisingParams_t params; // Setup advertisement parameters params.eventType = gapRole_AdvEventType; params.initiatorAddrType = gapRole_AdvDirectType; VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN ); params.channelMap = gapRole_AdvChanMap; params.filterPolicy = gapRole_AdvFilterPolicy; if ( GAP_MakeDiscoverable( gapRole_TaskID, ¶ms ) != SUCCESS ) { gapRole_state = GAPROLE_ERROR; // Notify the application with the new state change if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange ) { pGapRoles_AppCGs->pfnStateChange( gapRole_state ); } } } return ( events ^ START_ADVERTISING_EVT ); } if ( events & RSSI_READ_EVT ) { // Only get RSSI when in a connection if ( gapRole_state == GAPROLE_CONNECTED ) { // Ask for RSSI VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle ); // Setup next event if ( gapRole_RSSIReadRate ) { VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate ); } } return ( events ^ RSSI_READ_EVT ); } if ( events & START_CONN_UPDATE_EVT ) { // Start connection update procedure gapRole_startConnUpdate( GAPROLE_NO_ACTION ); return ( events ^ START_CONN_UPDATE_EVT ); } if ( events & CONN_PARAM_TIMEOUT_EVT ) { // Unsuccessful in updating connection parameters gapRole_HandleParamUpdateNoSuccess(); return ( events ^ CONN_PARAM_TIMEOUT_EVT ); } // Discard unknown events return 0; }
/********************************************************************* * @brief Set a GAP Role parameter. * * Public function defined in peripheral.h. */ bStatus_t GAPRole_SetParameter( uint16 param, uint8 len, void *pValue ) { bStatus_t ret = SUCCESS; switch ( param ) { case GAPROLE_IRK: if ( len == KEYLEN ) { VOID osal_memcpy( gapRole_IRK, pValue, KEYLEN ) ; } else { ret = bleInvalidRange; } break; case GAPROLE_SRK: if ( len == KEYLEN ) { VOID osal_memcpy( gapRole_SRK, pValue, KEYLEN ) ; } else { ret = bleInvalidRange; } break; case GAPROLE_SIGNCOUNTER: if ( len == sizeof ( uint32 ) ) { gapRole_signCounter = *((uint32*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_ENABLED: if ( len == sizeof( uint8 ) ) { uint8 oldAdvEnabled = gapRole_AdvEnabled; gapRole_AdvEnabled = *((uint8*)pValue); if ( (oldAdvEnabled) && (gapRole_AdvEnabled == FALSE) ) { // Turn off Advertising if ( gapRole_state == GAPROLE_ADVERTISING ) { VOID 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_WAITING_AFTER_TIMEOUT) ) { VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT ); } } } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_OFF_TIME: if ( len == sizeof ( uint16 ) ) { gapRole_AdvertOffTime = *((uint16*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_DATA: if ( len <= B_MAX_ADV_LEN ) { VOID osal_memset( gapRole_AdvertData, 0, B_MAX_ADV_LEN ); VOID osal_memcpy( gapRole_AdvertData, pValue, len ); gapRole_AdvertDataLen = len; } else { ret = bleInvalidRange; } break; case GAPROLE_SCAN_RSP_DATA: if ( len <= B_MAX_ADV_LEN ) { VOID osal_memset( gapRole_ScanRspData, 0, B_MAX_ADV_LEN ); VOID osal_memcpy( gapRole_ScanRspData, pValue, len ); gapRole_ScanRspDataLen = len; } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_EVENT_TYPE: if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_ADTYPE_ADV_NONCONN_IND) ) { gapRole_AdvEventType = *((uint8*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_DIRECT_TYPE: if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= ADDRTYPE_PRIVATE_RESOLVE) ) { gapRole_AdvDirectType = *((uint8*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_DIRECT_ADDR: if ( len == B_ADDR_LEN ) { VOID osal_memcpy( gapRole_AdvDirectAddr, pValue, B_ADDR_LEN ) ; } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_CHANNEL_MAP: if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= 0x07) ) { gapRole_AdvChanMap = *((uint8*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_FILTER_POLICY: if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_FILTER_POLICY_WHITE) ) { gapRole_AdvFilterPolicy = *((uint8*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_RSSI_READ_RATE: if ( len == sizeof ( uint16 ) ) { gapRole_RSSIReadRate = *((uint16*)pValue); if ( (gapRole_RSSIReadRate) && (gapRole_state == GAPROLE_CONNECTED) ) { // Start the RSSI Reads VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate ); } } else { ret = bleInvalidRange; } break; case GAPROLE_PARAM_UPDATE_ENABLE: if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= TRUE) ) { gapRole_ParamUpdateEnable = *((uint8*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_MIN_CONN_INTERVAL: { uint16 newInterval = *((uint16*)pValue); if ( len == sizeof ( uint16 ) && ( newInterval >= MIN_CONN_INTERVAL ) && ( newInterval <= MAX_CONN_INTERVAL ) ) { gapRole_MinConnInterval = newInterval; } else { ret = bleInvalidRange; } } break; case GAPROLE_MAX_CONN_INTERVAL: { uint16 newInterval = *((uint16*)pValue); if ( len == sizeof ( uint16 ) && ( newInterval >= MIN_CONN_INTERVAL) && ( newInterval <= MAX_CONN_INTERVAL) ) { gapRole_MaxConnInterval = newInterval; } else { ret = bleInvalidRange; } } break; case GAPROLE_SLAVE_LATENCY: { uint16 latency = *((uint16*)pValue); if ( len == sizeof ( uint16 ) && (latency < MAX_SLAVE_LATENCY) ) { gapRole_SlaveLatency = latency; } else { ret = bleInvalidRange; } } break; case GAPROLE_TIMEOUT_MULTIPLIER: { uint16 newTimeout = *((uint16*)pValue); if ( len == sizeof ( uint16 ) && (newTimeout >= MIN_TIMEOUT_MULTIPLIER) && (newTimeout <= MAX_TIMEOUT_MULTIPLIER) ) { gapRole_TimeoutMultiplier = newTimeout; } else { ret = bleInvalidRange; } } break; case GAPROLE_PARAM_UPDATE_REQ: { uint8 req = *((uint8*)pValue); if ( len == sizeof ( uint8 ) && (req == TRUE) ) { // Make sure we don't send an L2CAP Connection Parameter Update Request // command within TGAP(conn_param_timeout) of an L2CAP Connection Parameter // Update Response being received. if ( osal_get_timeoutEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT ) == 0 ) { // Start connection update procedure gapRole_startConnUpdate( GAPROLE_NO_ACTION ); // Connection update requested by app, cancel such pending procedure (if active) VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT ); } else { ret = blePending; } } else { ret = bleInvalidRange; } } break; default: // The param value isn't part of this profile, try the GAP. if ( (param < TGAP_PARAMID_MAX) && (len == sizeof ( uint16 )) ) { ret = GAP_SetParamValue( param, *((uint16*)pValue) ); } else { ret = INVALIDPARAMETER; } break; } return ( ret ); }
/********************************************************************* * @fn gapRole_taskFxn * * @brief Task entry point for the GAP Peripheral Role. * * @param a0 - first argument * @param a1 - second argument * * @return none */ static void gapRole_taskFxn(UArg a0, UArg a1) { // Initialize profile gapRole_init(); // Profile main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) == ICALL_ERRNO_SUCCESS) { if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { ICall_Event *pEvt = (ICall_Event *)pMsg; // Check for BLE stack events first if (pEvt->signature == 0xffff) { if (pEvt->event_flag & GAP_EVENT_SIGN_COUNTER_CHANGED) { // Sign counter changed, save it to NV VOID osal_snv_write(BLE_NVID_SIGNCOUNTER, sizeof(uint32_t), &gapRole_signCounter); } } else { // Process inter-task message gapRole_processStackMsg((ICall_Hdr *)pMsg); } } if (pMsg) { ICall_freeMsg(pMsg); } } } if (events & START_ADVERTISING_EVT) { events &= ~START_ADVERTISING_EVT; if (gapRole_AdvEnabled || gapRole_AdvNonConnEnabled) { gapAdvertisingParams_t params; // Setup advertisement parameters if (gapRole_AdvNonConnEnabled) { // Only advertise non-connectable undirected. params.eventType = GAP_ADTYPE_ADV_NONCONN_IND; } else { params.eventType = gapRole_AdvEventType; params.initiatorAddrType = gapRole_AdvDirectType; VOID memcpy(params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN); } params.channelMap = gapRole_AdvChanMap; params.filterPolicy = gapRole_AdvFilterPolicy; if (GAP_MakeDiscoverable(selfEntity, ¶ms) != SUCCESS) { gapRole_state = GAPROLE_ERROR; // Notify the application with the new state change if (pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange) { pGapRoles_AppCGs->pfnStateChange(gapRole_state); } } } } if (events & START_CONN_UPDATE_EVT) { events &= ~START_CONN_UPDATE_EVT; // Start connection update procedure gapRole_startConnUpdate(GAPROLE_NO_ACTION); } if (events & CONN_PARAM_TIMEOUT_EVT) { events &= ~CONN_PARAM_TIMEOUT_EVT; // Unsuccessful in updating connection parameters gapRole_HandleParamUpdateNoSuccess(); } } // for }
/********************************************************************* * @brief Set a GAP Role parameter. * * Public function defined in peripheral.h. */ bStatus_t GAPRole_SetParameter(uint16_t param, uint8_t len, void *pValue) { bStatus_t ret = SUCCESS; switch (param) { case GAPROLE_IRK: if (len == KEYLEN) { VOID memcpy(gapRole_IRK, pValue, KEYLEN) ; } else { ret = bleInvalidRange; } break; case GAPROLE_SRK: if (len == KEYLEN) { VOID memcpy(gapRole_SRK, pValue, KEYLEN) ; } else { ret = bleInvalidRange; } break; case GAPROLE_SIGNCOUNTER: if (len == sizeof (uint32_t)) { gapRole_signCounter = *((uint32_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_ENABLED: if (len == sizeof(uint8_t)) { // Non-connectable advertising must be disabled. if (gapRole_AdvNonConnEnabled != TRUE) { uint8_t oldAdvEnabled = gapRole_AdvEnabled; gapRole_AdvEnabled = *((uint8_t*)pValue); if ((oldAdvEnabled) && (gapRole_AdvEnabled == FALSE)) { // Turn off advertising. if ((gapRole_state == GAPROLE_ADVERTISING) || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT)) { VOID GAP_EndDiscoverable(selfEntity); } } else if ((oldAdvEnabled == FALSE) && (gapRole_AdvEnabled)) { // Turn on advertising. if ((gapRole_state == GAPROLE_STARTED) || (gapRole_state == GAPROLE_WAITING) || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT)) { gapRole_setEvent(START_ADVERTISING_EVT); } } } else { ret = bleIncorrectMode; } } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_NONCONN_ENABLED: if (len == sizeof(uint8_t)) { // Connectable advertising must be disabled. if (gapRole_AdvEnabled != TRUE) { uint8_t oldAdvEnabled = gapRole_AdvNonConnEnabled; gapRole_AdvNonConnEnabled = *((uint8_t*)pValue); if ((oldAdvEnabled) && (gapRole_AdvNonConnEnabled == FALSE)) { if ((gapRole_state == GAPROLE_ADVERTISING_NONCONN) || (gapRole_state == GAPROLE_CONNECTED_ADV) || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT)) { VOID GAP_EndDiscoverable(selfEntity); } } else if ((oldAdvEnabled == FALSE) && (gapRole_AdvNonConnEnabled)) { // Turn on advertising. if ((gapRole_state == GAPROLE_STARTED) || (gapRole_state == GAPROLE_WAITING) || (gapRole_state == GAPROLE_CONNECTED) || (gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT)) { gapRole_setEvent(START_ADVERTISING_EVT); } } } else { ret = bleIncorrectMode; } } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_OFF_TIME: if (len == sizeof (uint16_t)) { gapRole_AdvertOffTime = *((uint16_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADVERT_DATA: if (len <= B_MAX_ADV_LEN) { VOID memset(gapRole_AdvertData, 0, B_MAX_ADV_LEN); VOID memcpy(gapRole_AdvertData, pValue, len); gapRole_AdvertDataLen = len; // Update the advertising data ret = GAP_UpdateAdvertisingData(selfEntity, TRUE, gapRole_AdvertDataLen, gapRole_AdvertData); } else { ret = bleInvalidRange; } break; case GAPROLE_SCAN_RSP_DATA: if (len <= B_MAX_ADV_LEN) { VOID memset(gapRole_ScanRspData, 0, B_MAX_ADV_LEN); VOID memcpy(gapRole_ScanRspData, pValue, len); gapRole_ScanRspDataLen = len; // Update the Response Data ret = GAP_UpdateAdvertisingData(selfEntity, FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_EVENT_TYPE: if ((len == sizeof (uint8_t)) && (*((uint8_t*)pValue) <= GAP_ADTYPE_ADV_LDC_DIRECT_IND)) { gapRole_AdvEventType = *((uint8_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_DIRECT_TYPE: if ((len == sizeof (uint8_t)) && (*((uint8_t*)pValue) <= ADDRTYPE_PRIVATE_RESOLVE)) { gapRole_AdvDirectType = *((uint8_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_DIRECT_ADDR: if (len == B_ADDR_LEN) { VOID memcpy(gapRole_AdvDirectAddr, pValue, B_ADDR_LEN) ; } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_CHANNEL_MAP: if ((len == sizeof (uint8_t)) && (*((uint8_t*)pValue) <= 0x07)) { gapRole_AdvChanMap = *((uint8_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_ADV_FILTER_POLICY: if ((len == sizeof (uint8_t)) && (*((uint8_t*)pValue) <= GAP_FILTER_POLICY_WHITE)) { gapRole_AdvFilterPolicy = *((uint8_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_PARAM_UPDATE_ENABLE: if ((len == sizeof (uint8_t)) && (*((uint8_t*)pValue) <= TRUE)) { gapRole_ParamUpdateEnable = *((uint8_t*)pValue); } else { ret = bleInvalidRange; } break; case GAPROLE_MIN_CONN_INTERVAL: { uint16_t newInterval = *((uint16_t*)pValue); if ( len == sizeof (uint16_t) && (newInterval >= MIN_CONN_INTERVAL) && (newInterval <= MAX_CONN_INTERVAL)) { gapRole_MinConnInterval = newInterval; } else { ret = bleInvalidRange; } } break; case GAPROLE_MAX_CONN_INTERVAL: { uint16_t newInterval = *((uint16_t*)pValue); if ( len == sizeof (uint16_t) && (newInterval >= MIN_CONN_INTERVAL) && (newInterval <= MAX_CONN_INTERVAL)) { gapRole_MaxConnInterval = newInterval; } else { ret = bleInvalidRange; } } break; case GAPROLE_SLAVE_LATENCY: { uint16_t latency = *((uint16_t*)pValue); if (len == sizeof (uint16_t) && (latency < MAX_SLAVE_LATENCY)) { gapRole_SlaveLatency = latency; } else { ret = bleInvalidRange; } } break; case GAPROLE_TIMEOUT_MULTIPLIER: { uint16_t newTimeout = *((uint16_t*)pValue); if (len == sizeof (uint16_t) && (newTimeout >= MIN_TIMEOUT_MULTIPLIER) && (newTimeout <= MAX_TIMEOUT_MULTIPLIER)) { gapRole_TimeoutMultiplier = newTimeout; } else { ret = bleInvalidRange; } } break; case GAPROLE_PARAM_UPDATE_REQ: { uint8_t req = *((uint8_t*)pValue); if (len == sizeof (uint8_t) && (req == TRUE)) { // Make sure we don't send an L2CAP Connection Parameter Update Request // command within TGAP(conn_param_timeout) of an L2CAP Connection Parameter // Update Response being received. if (Util_isActive(&updateTimeoutClock) == FALSE) { // Start connection update procedure ret = gapRole_startConnUpdate(GAPROLE_NO_ACTION); if (ret == SUCCESS) { // Connection update requested by app, cancel such pending procedure (if active) Util_stopClock(&startUpdateClock); } } else { ret = blePending; } } else { ret = bleInvalidRange; } } break; default: // The param value isn't part of this profile, try the GAP. if ((param < TGAP_PARAMID_MAX) && (len == sizeof (uint16_t))) { ret = GAP_SetParamValue(param, *((uint16_t*)pValue)); } else { ret = INVALIDPARAMETER; } break; } return (ret); }
/********************************************************************* * @fn gapRole_taskFxn * * @brief Task entry point for the GAP Peripheral Role. * * @param a0 - first argument * @param a1 - second argument * * @return none */ static void gapRole_taskFxn(UArg a0, UArg a1) { // Initialize profile gapRole_init(); // Profile main loop for (;;) { // Waits for a signal to the semaphore associated with the calling thread. // Note that the semaphore associated with a thread is signaled when a // message is queued to the message receive queue of the thread or when // ICall_signal() function is called onto the semaphore. ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); if (errno == ICALL_ERRNO_SUCCESS) { ICall_EntityID dest; ICall_ServiceEnum src; ICall_HciExtEvt *pMsg = NULL; if (ICall_fetchServiceMsg(&src, &dest, (void **) &pMsg) == ICALL_ERRNO_SUCCESS) { uint8_t safeToDealloc = TRUE; if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { ICall_Stack_Event *pEvt = (ICall_Stack_Event *) pMsg; // Check for BLE stack events first if (pEvt->signature == 0xffff) { if (pEvt->event_flag & GAP_EVENT_SIGN_COUNTER_CHANGED) { // Sign counter changed, save it to NV VOID osal_snv_write(BLE_NVID_SIGNCOUNTER, sizeof(uint32_t), &gapRole_signCounter); } } else { // Process inter-task message safeToDealloc = gapRole_processStackMsg((ICall_Hdr *) pMsg); } } if (pMsg && safeToDealloc) { ICall_freeMsg(pMsg); } } } if (events & START_ADVERTISING_EVT) { events &= ~START_ADVERTISING_EVT; if (gapRole_AdvEnabled || gapRole_AdvNonConnEnabled) { gapAdvertisingParams_t params; // Setup advertisement parameters if (gapRole_AdvNonConnEnabled) { // Only advertise non-connectable undirected. params.eventType = GAP_ADTYPE_ADV_NONCONN_IND; } else { params.eventType = gapRole_AdvEventType; params.initiatorAddrType = gapRole_AdvDirectType; VOID memcpy(params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN); } params.channelMap = gapRole_AdvChanMap; params.filterPolicy = gapRole_AdvFilterPolicy; if (GAP_MakeDiscoverable(selfEntity, ¶ms) != SUCCESS) { gapRole_peripheralState = GAPROLE_ERROR; gapRole_peripheralStateChangeHandler(gapRole_peripheralState); //gapRole_abort(); } } } if (events & START_CONN_UPDATE_EVT) { events &= ~START_CONN_UPDATE_EVT; // Start connection update procedure uint8 index = 0; while (index < MAX_NUM_BLE_CONNS && multiConnInfo[index].gapRole_ConnRole != GAP_PROFILE_PERIPHERAL && multiConnInfo[index].gapRole_ConnectionHandle != GAPROLE_CONN_JUST_TERMINATED) { index++; } if (index >= MAX_NUM_BLE_CONNS) { //no connection as peripheral found //INVALIDPARAMETER; //Util_stopClock(&startUpdateClock); } else { gapRole_startConnUpdate(GAPROLE_NO_ACTION, multiConnInfo[index].gapRole_ConnectionHandle); } } if (events & CONN_PARAM_TIMEOUT_EVT) { events &= ~CONN_PARAM_TIMEOUT_EVT; // Unsuccessful in updating connection parameters gapRole_HandleParamUpdateNoSuccess(); } } // for }