/********************************************************************* * @fn oadManagerCCCDiscoveryMsg * * @brief Process GATT Client Characteristic Configuration discovery message * * @return none */ static void oadManagerCCCDiscoveryMsg(gattMsgEvent_t *pMsg) { if (oadManagerCCCIdx < OAD_CHAR_CNT) { if ( pMsg->hdr.status == SUCCESS ) // CCCD found, the store handle. { attFindInfoRsp_t *pRsp = &(pMsg->msg.findInfoRsp); if ( ( pRsp->numInfo > 0 ) && ( pRsp->format == ATT_HANDLE_BT_UUID_TYPE ) ) { // for each handle/uuid pair for ( uint8 i = 0; i < pRsp->numInfo; i++ ) { // look for CCCDs if ( ( pRsp->info.btPair[i].uuid[0] == LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID) ) && ( pRsp->info.btPair[i].uuid[1] == HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID) ) ) { // CCCD found oadManagerCCCHandles[oadManagerCCCIdx] = pRsp->info.btPair[i].handle; if (++oadManagerCCCIdx == OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD CCCDs Found!", HAL_LCD_LINE_1); #endif // OAD CCCDs found; enable them for notification oadManagerEnableNoti( oadManagerCCCHandles[OAD_CHAR_IMG_IDENTIFY] ); oadManagerEnableNoti( oadManagerCCCHandles[OAD_CHAR_IMG_BLOCK] ); oadManagerDiscIdx = 0; (void)osal_set_event(oadManagerTaskId, CHAR_DISCOVERY_EVT); break; } } } // for } } else if ( pMsg->hdr.status == bleProcedureComplete ) { if (oadManagerCCCIdx < OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD CCCDNotFound", HAL_LCD_LINE_3); #endif } } } }
/********************************************************************* * @fn pairStateCB * * @brief Pairing state callback. * * @return none */ static void timeAppPairStateCB( uint16 connHandle, uint8 state, uint8 status ) { if ( state == GAPBOND_PAIRING_STATE_STARTED ) { timeAppPairingStarted = TRUE; LCD_WRITE_STRING( "Pairing started", HAL_LCD_LINE_1 ); } else if ( state == GAPBOND_PAIRING_STATE_COMPLETE ) { timeAppPairingStarted = FALSE; if ( status == SUCCESS ) { linkDBItem_t *pItem; if ( (pItem = linkDB_Find( timeAppConnHandle )) != NULL ) { // Store bonding state of pairing timeAppBonded = ( (pItem->stateFlags & LINK_BOUND) == LINK_BOUND ); if ( timeAppBonded ) { osal_memcpy( timeAppBondedAddr, pItem->addr, B_ADDR_LEN ); } } // If discovery was postponed start discovery if ( timeAppDiscPostponed && timeAppDiscoveryCmpl == FALSE ) { timeAppDiscPostponed = FALSE; osal_set_event( timeAppTaskId, START_DISCOVERY_EVT ); } LCD_WRITE_STRING( "Pairing success", HAL_LCD_LINE_1 ); } else { LCD_WRITE_STRING_VALUE( "Pairing fail", status, 10, HAL_LCD_LINE_1 ); } } else if ( state == GAPBOND_PAIRING_STATE_BONDED ) { if ( status == SUCCESS ) { LCD_WRITE_STRING( "Bonding success", HAL_LCD_LINE_1 ); } } }
/********************************************************************* * @fn oadManagerDevDiscovery * * @brief OAD device discovery. * * @return none */ static void oadManagerDevDiscovery(void) { oadManagerScanning = TRUE; oadManagerScanRes = 0; #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_3 ); #endif GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST ); }
/********************************************************************* * @fn Time_clockDisplay() * * @brief Write the clock time to the display. * * @return none */ void Time_clockDisplay(void) { char displayBuf[20]; char *p = displayBuf; UTCTimeStruct time; memset(displayBuf, 0x00, 20); // Get time structure from UTC. UTC_convertUTCTime(&time, UTC_getClock()); // Display is in the format: // HH:MM MmmDD YYYY p = num2Str(p, time.hour); *p++ = ':'; p = num2Str(p, time.minutes); *p++ = ' '; *p++ = timeMonthStr[time.month][0]; *p++ = timeMonthStr[time.month][1]; *p++ = timeMonthStr[time.month][2]; p = num2Str(p, time.day + 1); *p++ = ' '; p = year2Str(p, time.year); LCD_WRITE_STRING(displayBuf, LCD_PAGE2); }
/********************************************************************* * @fn glucoseCtlPntGattMsg() * * @brief Handle GATT messages for control point operations. * * @param pMsg - GATT message. * * @return None. */ void glucoseCtlPntGattMsg( gattMsgEvent_t *pMsg ) { if (pMsg->method == ATT_ERROR_RSP) { glucCollClearPending = false; LCD_WRITE_STRING("Write Error", HAL_LCD_LINE_1); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_3 ); } else if (pMsg->method == ATT_WRITE_RSP) { // start procedure timer osal_start_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT, GLUCOSE_PROCEDURE_TIMEOUT ); } glucCollWritePending = false; }
/********************************************************************* * @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; } }
/********************************************************************* * @fn simpleBLEObserverEventCB * * @brief Observer event callback function. * * @param pEvent - pointer to event structure * * @return none */ static void simpleBLEObserverEventCB( gapObserverRoleEvent_t *pEvent ) { switch ( pEvent->gap.opcode ) { case GAP_DEVICE_INIT_DONE_EVENT: { LCD_WRITE_STRING( "BLE Observer", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 ); } break; case GAP_DEVICE_INFO_EVENT: { simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete simpleBLEScanning = FALSE; // Copy results simpleBLEScanRes = pEvent->discCmpl.numDevs; osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes, 10, HAL_LCD_LINE_1 ); if ( simpleBLEScanRes > 0 ) { LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 ); } // initialize scan index to last device simpleBLEScanIdx = simpleBLEScanRes; } break; default: break; } }
/********************************************************************* * @fn glucCollCentral_processPairState * * @brief Pairing state callback. * * @param connHandle - connection handle * @param state - pairing state * @param status - pairing status * * @return none */ static void glucCollCentral_processPairState(uint16_t connHandle, uint8_t state, uint8_t status) { if (state == GAPBOND_PAIRING_STATE_STARTED) { glucCollPairingStarted = true; LCD_WRITE_STRING("Pairing started", LCD_PAGE0); } else if (state == GAPBOND_PAIRING_STATE_COMPLETE) { glucCollPairingStarted = false; if (status == SUCCESS) { // If discovery was postponed start discovery if (glucCollDiscPostponed && glucCollCharHdls == false) { glucCollDiscPostponed = false; // Set START_DISCOVERY event events |= GLUCOLL_START_DISCOVERY_EVT; // Wake up the application thread when it waits for clock event Semaphore_post(sem); } LCD_WRITE_STRING("Pairing success", LCD_PAGE0); } else { LCD_WRITE_STRING_VALUE("Pairing fail", status, 10, LCD_PAGE0); } } else if (state == GAPBOND_PAIRING_STATE_BONDED) { if (status == SUCCESS) { LCD_WRITE_STRING("Bonding success", LCD_PAGE0); } } }
/********************************************************************* * @fn simpleBLEGATTDiscoveryEvent * * @brief Process GATT discovery event * * @return none */ static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg ) { attReadByTypeReq_t req; if ( simpleBLEDiscState == BLE_DISC_STATE_SVC ) { // Service found, store handles if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0 ) { simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle; simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle; } // If procedure complete if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ) { if ( simpleBLESvcStartHdl != 0 ) { // Discover characteristic simpleBLEDiscState = BLE_DISC_STATE_CHAR; req.startHandle = simpleBLESvcStartHdl; req.endHandle = simpleBLESvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID); GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId ); } } } else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR ) { // Characteristic found, store handle if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 ) { simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0], pMsg->msg.readByTypeRsp.dataList[1] ); LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 ); simpleBLEProcedureInProgress = FALSE; } simpleBLEDiscState = BLE_DISC_STATE_IDLE; } }
/********************************************************************* * @fn oadManagerErrorRsp * * @brief Process GATT Error Response message * * @return none */ static void oadManagerErrorRsp( attErrorRsp_t *pRsp ) { if ( pRsp->errCode == ATT_ERR_ATTR_NOT_FOUND ) { switch ( pRsp->reqOpcode ) { case ATT_FIND_BY_TYPE_VALUE_REQ: if ( oadSvcStartHdl == 0 ) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD SvcNotFound", HAL_LCD_LINE_3); #endif } break; case ATT_FIND_INFO_RSP: if (oadManagerCCCIdx < OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD CCCDNotFound", HAL_LCD_LINE_3); #endif } break; case ATT_READ_BY_TYPE_RSP: if (oadManagerDiscIdx < OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD CharNotFound", HAL_LCD_LINE_3); #endif } break; default: break; } } }
/********************************************************************* * @fn controlBLECentralPasscodeCB * * @brief Passcode callback. * * @return none */ static void controlBLECentralPasscodeCB( uint8 *deviceAddr, uint16 connectionHandle, uint8 uiInputs, uint8 uiOutputs ) { #if (HAL_LCD == TRUE) uint32 passcode; uint8 str[7]; // Create random passcode LL_Rand( ((uint8 *) &passcode), sizeof( uint32 )); passcode %= 1000000; // Display passcode to user if ( uiOutputs != 0 ) { LCD_WRITE_STRING( "Passcode:", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( (char *) _ltoa(passcode, str, 10), HAL_LCD_LINE_2 ); } // Send passcode response GAPBondMgr_PasscodeRsp( connectionHandle, SUCCESS, passcode ); #endif }
/********************************************************************* * @fn pairStateCB * * @brief Pairing state callback. * * @return none */ static void glucCollCentralPairStateCB( uint16 connHandle, uint8 state, uint8 status ) { if ( state == GAPBOND_PAIRING_STATE_STARTED ) { glucCollPairingStarted = true; LCD_WRITE_STRING( "Pairing started", HAL_LCD_LINE_1 ); } else if ( state == GAPBOND_PAIRING_STATE_COMPLETE ) { glucCollPairingStarted = false; if ( status == SUCCESS ) { // If discovery was postponed start discovery if ( glucCollDiscPostponed && glucCollCharHdls == false) { glucCollDiscPostponed = false; osal_set_event( glucCollTaskId, START_DISCOVERY_EVT ); } LCD_WRITE_STRING( "Pairing success", HAL_LCD_LINE_1 ); } else { LCD_WRITE_STRING_VALUE( "Pairing fail", status, 10, HAL_LCD_LINE_1 ); } } else if ( state == GAPBOND_PAIRING_STATE_BONDED ) { if ( status == SUCCESS ) { LCD_WRITE_STRING( "Bonding success", HAL_LCD_LINE_1 ); } } }
/********************************************************************* * @fn oadManagerCharDiscoveryMsg * * @brief Process GATT Characteristic discovery message * * @return none */ static void oadManagerCharDiscoveryMsg(gattMsgEvent_t *pMsg) { if (oadManagerDiscIdx < OAD_CHAR_CNT) { if ( pMsg->hdr.status == SUCCESS ) // Characteristic found, the store handle. { attReadByTypeRsp_t *pRsp = &(pMsg->msg.readByTypeRsp); if (pRsp->numPairs > 0) { oadManagerHandles[oadManagerDiscIdx] = BUILD_UINT16(pRsp->dataList[3], pRsp->dataList[4]); if (++oadManagerDiscIdx == OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD Chars Found!", HAL_LCD_LINE_1); #endif oadManagerSendImgNotify(); return; } } (void)osal_set_event(oadManagerTaskId, CHAR_DISCOVERY_EVT); } else if ( pMsg->hdr.status == bleProcedureComplete ) { if (oadManagerDiscIdx < OAD_CHAR_CNT) { #if (defined HAL_LCD) && (HAL_LCD == TRUE) LCD_WRITE_STRING("OAD CharNotFound", HAL_LCD_LINE_3); #endif } } } }
/********************************************************************* * @fn glucoseCtlPntGattMsg() * * @brief Handle GATT messages for control point operations. * * @param pMsg - GATT message. * * @return None. */ void glucoseCtlPntGattMsg( gattMsgEvent_t *pMsg ) { if (pMsg->method == ATT_ERROR_RSP) { attErrorRsp_t *pRsp = &pMsg->msg.errorRsp; glucCollClearPending = false; LCD_WRITE_STRING("Write Error", HAL_LCD_LINE_1); LCD_WRITE_STRING_VALUE("Handle: ", pRsp->handle, 10, HAL_LCD_LINE_2); LCD_WRITE_STRING_VALUE("errCode: ", pRsp->errCode, 10, HAL_LCD_LINE_3); } else if (pMsg->method == ATT_WRITE_RSP) { // start procedure timer osal_start_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT, GLUCOSE_PROCEDURE_TIMEOUT ); } glucCollWritePending = false; }
/********************************************************************* * @fn timeAppIndGattMsg * * @brief Handle indications and notifications. * * @param pValue - Pointer to buffer containing a new incoming alert * characteristic. * @param len - length of pValue. * * @return none */ static void timeAppDisplayAlert( uint8 *pValue, uint8 len ) { char buf[HAL_LCD_MAX_CHARS + 1]; uint8 buflen; // Verify alert category and length if ( pValue[0] <= ALERT_CAT_ID_MAX && len >= 2 ) { // Write category and number of unread to first line LCD_WRITE_STRING_VALUE( (char *) timeAppAlertCatStr[pValue[0]], pValue[1], 10, HAL_LCD_LINE_1 ); pValue += 2; len -= 2; // Write alert text to second line buflen = MIN( HAL_LCD_MAX_CHARS, len ); memcpy( buf, pValue, buflen ); buf[buflen] = '\0'; LCD_WRITE_STRING( buf, HAL_LCD_LINE_2 ); } }
/********************************************************************* * @fn glucoseCtlPntGattMsg() * * @brief Handle GATT messages for control point operations. * * @param pMsg - GATT message. * * @return None. */ void glucoseCtlPntGattMsg(gattMsgEvent_t *pMsg) { if (pMsg->method == ATT_ERROR_RSP) { attErrorRsp_t *pRsp = &pMsg->msg.errorRsp; glucCollClearPending = false; LCD_WRITE_STRING("Write Error", LCD_PAGE0); LCD_WRITE_STRING_VALUE("Handle: ", pRsp->handle, 10, LCD_PAGE1); LCD_WRITE_STRING_VALUE("errCode: ", pRsp->errCode, 10, LCD_PAGE2); } else if (pMsg->method == ATT_WRITE_RSP) { // start procedure timer Util_stopClock(&procTimeoutClock); Util_startClock(&procTimeoutClock); } glucCollWritePending = false; }
/********************************************************************* * @fn SimpleBLEBroadcaster_processStateChangeEvt * * @brief Notification from the profile of a state change. * * @param newState - new state * * @return none */ static void SimpleBLEBroadcaster_processStateChangeEvt(gaprole_States_t newState) { switch (newState) { case GAPROLE_STARTED: { uint8 ownAddress[B_ADDR_LEN]; GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); // Display device address LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1); LCD_WRITE_STRING("Initialized", LCD_PAGE2); } break; case GAPROLE_ADVERTISING: { LCD_WRITE_STRING("Advertising", LCD_PAGE2); } break; case GAPROLE_WAITING: { LCD_WRITE_STRING("Waiting", LCD_PAGE2); } break; case GAPROLE_ERROR: { LCD_WRITE_STRING("Error", LCD_PAGE2); } break; default: { LCD_WRITE_STRING("", LCD_PAGE2); } break; } }
/********************************************************************* * @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_DEVICE_INIT_DONE_EVENT: { maxPduSize = pEvent->initDone.dataPktLen; LCD_WRITE_STRING("Connected to 0", LCD_PAGE0); LCD_WRITE_STRING(Util_convertBdAddr2Str(pEvent->initDone.devAddr), LCD_PAGE1); LCD_WRITE_STRING("Initialized", LCD_PAGE2); DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, pEvent->initDone.devAddr); } break; 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_INFO_EVENT: { // if filtering device discovery results based on service UUID if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) { if (simpleTopology_findSvcUuid(SIMPLEPROFILE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen)) { simpleTopology_addDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType); } } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete scanningStarted = FALSE; // if not filtering device discovery results based on service UUID if (DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE) { // Copy results scanRes = pEvent->discCmpl.numDevs; memcpy(devList, pEvent->discCmpl.pDevList, (sizeof(gapDevRec_t) * scanRes)); } LCD_WRITE_STRING_VALUE("Devices Found", scanRes, 10, LCD_PAGE3); if (scanRes > 0) { LCD_WRITE_STRING("<- To Select", LCD_PAGE4); } // initialize scan index to last device scanIdx = scanRes; } break; case GAP_LINK_ESTABLISHED_EVENT: { if (pEvent->gap.hdr.status == SUCCESS) { LCD_WRITE_STRING("Connected!", LCD_PAGE3); LCD_WRITE_STRING_VALUE("Connected to ", gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) ,10, LCD_PAGE0); //update state connecting_state = 0; //store connection handle connHandle = pEvent->linkCmpl.connectionHandle; //if we're not advertising, attempt to turn advertising back on uint8_t adv; GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &adv, NULL); if (adv == 1) //connected and advertising { if (gapRoleNumLinks(GAPROLE_AVAILABLE_LINKS) > 0) { LCD_WRITE_STRING("Advertising", LCD_PAGE2); } else //no available links { LCD_WRITE_STRING("Can't adv: no links", LCD_PAGE2); } } else //not currently advertising { LCD_WRITE_STRING("Ready to Advertise", LCD_PAGE2); //attempt to turn advertising back o uint8_t advertEnabled = TRUE; uint8_t stat = GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertEnabled, NULL); if (stat == bleNoResources) //no more links { LCD_WRITE_STRING("Can't adv: no links", LCD_PAGE2); } else if (stat == SUCCESS) //turning advertising back on { LCD_WRITE_STRING("Advertising", LCD_PAGE2); } else { while(1); } } // Print last connected device LCD_WRITE_STRING("", LCD_PAGE4); LCD_WRITE_STRING(Util_convertBdAddr2Str(pEvent->linkCmpl.devAddr), LCD_PAGE5 ); // initiate service discovery Util_startClock(&startDiscClock); } else { connHandle = GAP_CONNHANDLE_INIT; discState = BLE_DISC_STATE_IDLE; LCD_WRITE_STRING("Connect Failed", LCD_PAGE4); LCD_WRITE_STRING_VALUE("Reason:", pEvent->gap.hdr.status, 10, LCD_PAGE3); } } break; case GAP_LINK_TERMINATED_EVENT: { connHandle = GAP_CONNHANDLE_INIT; discState = BLE_DISC_STATE_IDLE; uint8_t i; for (i=0; i < MAX_NUM_BLE_CONNS; i++) { if (multiConnInfo[i].gapRole_ConnectionHandle == GAPROLE_CONN_JUST_TERMINATED) { //clear screen, reset discovery info, and return to main menu multiConnInfo[i].gapRole_ConnectionHandle = INVALID_CONNHANDLE; charHdl[i] = 0; LCD_WRITE_STRING_VALUE("Connected to ", gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) ,10, LCD_PAGE0); LCD_WRITE_STRING("Disconnected!", LCD_PAGE5); LCD_WRITE_STRING("Main Menu", LCD_PAGE3); LCDmenu = MAIN_MENU; } if ((gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) == (MAX_NUM_BLE_CONNS-1))) //now we can advertise again { LCD_WRITE_STRING("Ready to Advertise", LCD_PAGE2); } } } break; case GAP_LINK_PARAM_UPDATE_EVENT: { LCD_WRITE_STRING_VALUE("Param Update:", pEvent->linkUpdate.status, 10, LCD_PAGE2); } break; default: break; } }
/********************************************************************* * @fn simpleTopology_processGATTDiscEvent * * @brief Process GATT discovery event * * @return none */ static void simpleTopology_processGATTDiscEvent(gattMsgEvent_t *pMsg) { if (pMsg->method == ATT_MTU_UPDATED_EVENT) { // MTU size updated LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE4); } else if (discState == BLE_DISC_STATE_MTU) { // MTU size response received, discover simple BLE service if (pMsg->method == ATT_EXCHANGE_MTU_RSP) { uint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID) }; discState = BLE_DISC_STATE_SVC; // Discovery simple BLE service VOID GATT_DiscPrimaryServiceByUUID(connHandle, uuid, ATT_BT_UUID_SIZE, selfEntity); } } else if (discState == BLE_DISC_STATE_SVC) { // Service found, store handles if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0) { svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); } // If procedure complete if (((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP) && (pMsg->hdr.status == bleProcedureComplete)) || (pMsg->method == ATT_ERROR_RSP)) { if (svcStartHdl != 0) { attReadByTypeReq_t req; // Discover characteristic discState = BLE_DISC_STATE_CHAR; req.startHandle = svcStartHdl; req.endHandle = svcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID); VOID GATT_ReadUsingCharUUID(connHandle, &req, selfEntity); } } } else if (discState == BLE_DISC_STATE_CHAR) { // Characteristic found, store handle if ((pMsg->method == ATT_READ_BY_TYPE_RSP) && (pMsg->msg.readByTypeRsp.numPairs > 0)) { //find index to store handle uint8_t connIndex = gapRoleInfo_Find(connHandle); charHdl[connIndex] = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0], pMsg->msg.readByTypeRsp.pDataList[1]); LCD_WRITE_STRING("Simple Svc Found", LCD_PAGE6); } discState = BLE_DISC_STATE_IDLE; } }
/********************************************************************* * @fn simpleTopology_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 simpleTopology_handleKeys(uint8_t shift, uint8_t keys) { (void)shift; // Intentionally unreferenced parameter if (LCDmenu == MAIN_MENU) { if (keys & KEY_LEFT) //show discovery results { selectKey = DISCOVERED_DEVICES; // If discovery has occurred and a device was found if (!scanningStarted && scanRes > 0) { // Increment index of current result (with wraparound) scanIdx++; if (scanIdx >= scanRes) { scanIdx = 0; } LCD_WRITE_STRING_VALUE("Device", (scanIdx + 1), 10, LCD_PAGE3); LCD_WRITE_STRING(Util_convertBdAddr2Str(devList[scanIdx].addr), LCD_PAGE4); } return; } if (keys & KEY_UP) //Scan for devices { // Start or stop discovery if (gapRoleNumLinks(GAPROLE_AVAILABLE_LINKS) > 0) //if we can connect to another device { if (!scanningStarted) //if we're not already scanning { scanningStarted = TRUE; scanRes = 0; LCD_WRITE_STRING("Discovering...", LCD_PAGE3); LCD_WRITE_STRING("", LCD_PAGE4); LCD_WRITE_STRING("", LCD_PAGE6); GAPRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } else //cancel scanning { LCD_WRITE_STRING("Discovery Cancelled", LCD_PAGE3); GAPRole_CancelDiscovery(); scanningStarted = FALSE; } } else // can't add more links at this time { LCD_WRITE_STRING("Can't scan:no links ", LCD_PAGE3); } return; } if (keys & KEY_RIGHT) // turn advertising on / off { uint8_t adv; uint8_t adv_status; GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &adv_status, NULL); if (adv_status) //turn off { adv = FALSE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &adv, NULL); } else //turn on { adv = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &adv, NULL); } return; } if (keys & KEY_SELECT) //connect to a discovered device { if (selectKey == DISCOVERED_DEVICES) // connect to a device { uint8_t addrType; uint8_t *peerAddr; if (connecting_state == 1) // if already attempting to connect, cancel connection { GAPRole_TerminateConnection(0xFFFE); LCD_WRITE_STRING("Connecting stopped.", LCD_PAGE3); connecting_state = 0; } else //establish new connection { // if there is a scan result if (scanRes > 0) { // connect to current device in scan result peerAddr = devList[scanIdx].addr; addrType = devList[scanIdx].addrType; GAPRole_EstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr); connecting_state = 1; LCD_WRITE_STRING("Connecting", LCD_PAGE3); LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddr), LCD_PAGE4); } } } else if (selectKey == CONNECTED_DEVICES) //enter the device menu { if (multiConnInfo[connIdx].gapRole_ConnectionHandle != INVALID_CONNHANDLE) { LCDmenu = DEVICE_MENU; LCD_WRITE_STRING("Device Menu", LCD_PAGE3); LCD_WRITE_STRING(Util_convertBdAddr2Str(multiConnInfo[connIdx].gapRole_devAddr), LCD_PAGE4); if (multiConnInfo[connIdx].gapRole_ConnRole == GAP_PROFILE_CENTRAL) { LCD_WRITE_STRING("Connected as Central", LCD_PAGE5); LCD_WRITE_STRING("", LCD_PAGE6); LCD_WRITE_STRING("", LCD_PAGE7); } else //PERIPHERAL { LCD_WRITE_STRING("Connected as Periph", LCD_PAGE5); LCD_WRITE_STRING("", LCD_PAGE6); LCD_WRITE_STRING("", LCD_PAGE7); } //use this connection for all functionality connHandle = multiConnInfo[connIdx].gapRole_ConnectionHandle; } else // no active connection here LCD_WRITE_STRING("No Connection here.", LCD_PAGE3); } return; } if (keys & KEY_DOWN) //browse connected devices { LCD_WRITE_STRING("Connected Device:", LCD_PAGE3); if (++connIdx >= MAX_NUM_BLE_CONNS) //increment connIdx { connIdx = 0; } if (multiConnInfo[connIdx].gapRole_ConnectionHandle != INVALID_CONNHANDLE) //if there is a connection at this index { LCD_WRITE_STRING(Util_convertBdAddr2Str(multiConnInfo[connIdx].gapRole_devAddr), LCD_PAGE4); } else { LCD_WRITE_STRING("N/A", LCD_PAGE4); } selectKey = CONNECTED_DEVICES; } return; } else if (LCDmenu == DEVICE_MENU) { if (keys & KEY_UP) //read/whrite char { if (charHdl[connIdx] != 0) { uint8_t status; // Do a read or write as long as no other read or write is in progress if (doWrite) { // Do a write attWriteReq_t req; req.pValue = GATT_bm_alloc(connHandle, ATT_WRITE_REQ, 1, NULL); if ( req.pValue != NULL ) { req.handle = charHdl[connIdx]; req.len = 1; req.pValue[0] = charVal; req.sig = 0; req.cmd = 0; status = GATT_WriteCharValue(connHandle, &req, selfEntity); if ( status != SUCCESS ) { GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ); } } } else { // Do a read attReadReq_t req; req.handle = charHdl[connIdx]; status = GATT_ReadCharValue(connHandle, &req, selfEntity); } if (status == SUCCESS) { doWrite = !doWrite; } } return; } if (keys & KEY_RIGHT) //connection update...eventually { asm("NOP"); return; } if (keys & KEY_SELECT) { GAPRole_TerminateConnection(connHandle); LCD_WRITE_STRING("Disconnecting", LCD_PAGE5); LCD_WRITE_STRING("", LCD_PAGE6); return; } if (keys & KEY_DOWN) //back to main menu { LCDmenu = MAIN_MENU; LCD_WRITE_STRING("Main Menu", LCD_PAGE3); //clear screen LCD_WRITE_STRING("", LCD_PAGE4); LCD_WRITE_STRING("", LCD_PAGE5); LCD_WRITE_STRING("", LCD_PAGE6); LCD_WRITE_STRING("", LCD_PAGE7); LCD_WRITE_STRING_VALUE("Connected to ", gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) ,10, LCD_PAGE0); connIdx = 0; return; } } }
/********************************************************************* * @fn controlBLECentralEventCB * * @brief Central event callback function. * * @param pEvent - pointer to event structure * * @return none */ static void controlBLECentralEventCB( gapCentralRoleEvent_t *pEvent ) { switch ( pEvent->gap.opcode ) { case GAP_DEVICE_INIT_DONE_EVENT: { //LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 ); // LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 ); } /***wkxboot***/ app_write_string("hello wkxboot&ble4.0!\r\n"); app_write_string("central role init done. own addr is:"); app_write_string(bdAddr2Str(pEvent->initDone.devAddr)); wkxboot_start_discover(); break; case GAP_DEVICE_INFO_EVENT: { app_write_string("\r\nfind device addr is:"); app_write_string(bdAddr2Str( pEvent->deviceInfo.addr )); // if filtering device discovery results based on service UUID if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE ) { if ( simpleBLEFindSvcUuid( PARAM_BLE_CAR_IN_PROFILE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen ) ) { simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } } /****wkxboot***/ // simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete simpleBLEScanning = FALSE; // if not filtering device discovery results based on service UUID if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE ) { // Copy results simpleBLEScanRes = pEvent->discCmpl.numDevs; osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); } //LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes, // 10, HAL_LCD_LINE_1 ); if ( simpleBLEScanRes > 0 ) { LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 ); } // initialize scan index to last device simpleBLEScanIdx = simpleBLEScanRes; /****wkxboot***/ app_write_string("scan completed!!\r\n"); app_write_string("scan num is:"); app_write_string(uint8_to_string(simpleBLEScanRes)); if(simpleBLEScanIdx--) { wkxboot_start_connect(); } else { wkxboot_start_discover(); } } break; case GAP_LINK_ESTABLISHED_EVENT: { if ( pEvent->gap.hdr.status == SUCCESS ) { simpleBLEState = BLE_STATE_CONNECTED; simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle; simpleBLEProcedureInProgress = TRUE; // If service discovery not performed initiate service discovery if ( simpleBLECharHdl == 0 ) { osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY ); } //LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 ); // LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 ); app_write_string("connected peeraddr is:"); app_write_string(bdAddr2Str(pEvent->linkCmpl.devAddr)); app_write_string("connected connhandle is:"); app_write_string(uint16_to_string(simpleBLEConnHandle)); app_write_string("start to read RSSI!\r\n"); GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD ); app_write_string("start to find services.....\r\n"); } else { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; //LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 ); //LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 ); app_write_string("connect failed!reason is:"); app_write_string(uint8_to_string(pEvent->gap.hdr.status)); } } break; case GAP_LINK_TERMINATED_EVENT: { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; simpleBLECharHdl = 0; simpleBLEProcedureInProgress = FALSE; // LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 ); // LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason, // 10, HAL_LCD_LINE_2 ); app_write_string("disconnected !reason is:"); app_write_string(uint8_to_string(pEvent->gap.hdr.status)); app_write_string("scan again!!\r\n"); wkxboot_start_discover(); } break; case GAP_LINK_PARAM_UPDATE_EVENT: { // LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 ); app_write_string("link param update!\r\n"); } break; default: break; } }
/********************************************************************* * @fn glucCollCentral_processRoleEvent * * @brief Central event callback function. * * @param pEvent - pointer to event structure * * @return TRUE if safe to deallocate event message, FALSE otherwise. */ static uint8_t glucCollCentral_processRoleEvent(gapCentralRoleEvent_t *pEvent) { switch (pEvent->gap.opcode) { case GAP_DEVICE_INIT_DONE_EVENT: { LCD_WRITE_STRING("Gluc. Collector", LCD_PAGE0); LCD_WRITE_STRING(Util_convertBdAddr2Str(pEvent->initDone.devAddr), LCD_PAGE1); } break; case GAP_DEVICE_INFO_EVENT: { // if filtering device discovery results based on service UUID if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) { if (glucCollCentral_findSvcUuid(GLUCOSE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen)) { glucCollCentral_addDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType); } } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete glucCollScanning = FALSE; // if not filtering device discovery results based on service UUID if (DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE) { // Copy results glucCollScanRes = pEvent->discCmpl.numDevs; memcpy(glucCollDevList, pEvent->discCmpl.pDevList, (sizeof(gapDevRec_t) * pEvent->discCmpl.numDevs)); } LCD_WRITE_STRING_VALUE("Devices Found", glucCollScanRes, 10, LCD_PAGE0); if (glucCollScanRes > 0) { LCD_WRITE_STRING("<- To Select", LCD_PAGE1); } // initialize scan index to last device glucCollScanIdx = glucCollScanRes; } break; case GAP_LINK_ESTABLISHED_EVENT: { if (pEvent->gap.hdr.status == SUCCESS) { glucCollState = BLE_STATE_CONNECTED; glucCollConnHandle = pEvent->linkCmpl.connectionHandle; // If service discovery not performed initiate service discovery if (glucCollCharHdls == false) { // start procedure timer Util_stopClock(&discoveryClock); Util_startClock(&discoveryClock); } LCD_WRITE_STRING("Connected", LCD_PAGE0); LCD_WRITE_STRING(Util_convertBdAddr2Str(pEvent->linkCmpl.devAddr), LCD_PAGE1); } else { glucCollState = BLE_STATE_IDLE; glucCollConnHandle = GAP_CONNHANDLE_INIT; glucCollDiscState = DISC_IDLE; LCD_WRITE_STRING("Connect Failed", LCD_PAGE0); LCD_WRITE_STRING_VALUE("Reason:", pEvent->gap.hdr.status, 10, LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } } break; case GAP_LINK_TERMINATED_EVENT: { glucCollState = BLE_STATE_IDLE; glucCollConnHandle = GAP_CONNHANDLE_INIT; glucCollDiscState = DISC_IDLE; glucCollPairingStarted = false; glucCollDiscPostponed = false; glucCollClearPending = false; // stop procedure timer Util_stopClock(&procTimeoutClock); LCD_WRITE_STRING("Disconnected", LCD_PAGE0); LCD_WRITE_STRING_VALUE("Reason:", pEvent->linkTerminate.reason, 10, LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } break; case GAP_LINK_PARAM_UPDATE_EVENT: { LCD_WRITE_STRING("Param Update", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } break; default: break; } return (TRUE); }
/********************************************************************* * @fn glucCollCentral_handleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. * * @return none */ static void glucCollCentral_handleKeys(uint8_t shift, uint8_t keys) { (void)shift; // Intentionally unreferenced parameter if (keys & KEY_UP) { // Start or stop discovery if (glucCollState != BLE_STATE_CONNECTED) { if (!glucCollScanning) { glucCollScanning = TRUE; glucCollScanRes = 0; LCD_WRITE_STRING("Discovering...", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); GAPCentralRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } else { GAPCentralRole_CancelDiscovery(); } } else if (glucCollState == BLE_STATE_CONNECTED && glucCollCharHdls == true && glucCollWritePending == false) { uint8_t status; #if GLUCOSE_FILTER_ENABLED // Request number of records status = glucoseCtlPntWriteFilter(CTL_PNT_OP_GET_NUM, CTL_PNT_OPER_RANGE, DEFAULT_FILTER_TYPE, pFilter1, pFilter2); #else // Request number of records status = glucoseCtlPntWrite(CTL_PNT_OP_GET_NUM, CTL_PNT_OPER_ALL); #endif if(status == 0) { glucCollWritePending = true; } } return; } if (keys & KEY_LEFT) { // Display discovery results if (glucCollState != BLE_STATE_CONNECTED && !glucCollScanning && glucCollScanRes > 0) { // Increment index of current result (with wraparound) glucCollScanIdx++; if (glucCollScanIdx >= glucCollScanRes) { glucCollScanIdx = 0; } LCD_WRITE_STRING_VALUE("Device", glucCollScanIdx + 1, 10, LCD_PAGE0); LCD_WRITE_STRING(Util_convertBdAddr2Str(glucCollDevList[glucCollScanIdx].addr), LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } else if (glucCollState == BLE_STATE_CONNECTED) { if(glucoseCtlPntWrite(CTL_PNT_OP_ABORT, CTL_PNT_OPER_NULL) == 0) { glucCollWritePending = false; } } return; } if (keys & KEY_RIGHT) { // Request all records if (glucCollState == BLE_STATE_CONNECTED && glucCollCharHdls == true && glucCollWritePending == false) { uint8_t status; #if GLUCOSE_FILTER_ENABLED status = glucoseCtlPntWriteFilter(CTL_PNT_OP_REQ, CTL_PNT_OPER_RANGE, DEFAULT_FILTER_TYPE, pFilter1, pFilter2); #else status = glucoseCtlPntWrite(CTL_PNT_OP_REQ, CTL_PNT_OPER_ALL); #endif if(status == SUCCESS) { glucCollWritePending = true; } } return; } if (keys & KEY_SELECT) { uint8_t addrType; uint8_t *peerAddr; // Connect or disconnect if (glucCollState == BLE_STATE_IDLE) { // if there is a scan result if (glucCollScanRes > 0) { // connect to current device in scan result peerAddr = glucCollDevList[glucCollScanIdx].addr; addrType = glucCollDevList[glucCollScanIdx].addrType; glucCollState = BLE_STATE_CONNECTING; GAPCentralRole_EstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr); LCD_WRITE_STRING("Connecting", LCD_PAGE0); LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddr), LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } } else if (glucCollState == BLE_STATE_CONNECTING || glucCollState == BLE_STATE_CONNECTED) { // disconnect glucCollState = BLE_STATE_DISCONNECTING; GAPCentralRole_TerminateLink(glucCollConnHandle); LCD_WRITE_STRING("Disconnecting", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } return; } if (keys & KEY_DOWN) { // Clear stored records if (glucCollState == BLE_STATE_CONNECTED && glucCollCharHdls == true && glucCollWritePending == false) { uint8_t status; #if GLUCOSE_FILTER_ENABLED status = glucoseCtlPntWriteFilter(CTL_PNT_OP_CLR, CTL_PNT_OPER_RANGE, DEFAULT_FILTER_TYPE, pFilter1, pFilter2); #else status = glucoseCtlPntWrite(CTL_PNT_OP_CLR, CTL_PNT_OPER_ALL); #endif if(status == 0) { glucCollWritePending = true; glucCollClearPending = true; } } else if (glucCollState != BLE_STATE_CONNECTED) { // erase all bonds GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS, 0, NULL); LCD_WRITE_STRING("Erasing bonds", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); // initiate service discovery again glucCollCharHdls = false; } } }
/********************************************************************* * @fn glucCollCentral_taskFxn * * @brief Application task entry point for the Glucose collector. * * @param a0, a1 - not used * * @return none */ static void glucCollCentral_taskFxn(UArg a0, UArg a1) { // Initialize application glucCollCentral_Init(); // Application 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)) { // Process inter-task message glucCollCentral_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { glucCollEvt_t *pMsg = (glucCollEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. glucCollCentral_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } if (events) { if (events & GLUCOLL_PROCEDURE_TIMEOUT_EVT) { events &= ~GLUCOLL_PROCEDURE_TIMEOUT_EVT; if (glucCollState == BLE_STATE_CONNECTED) { // disconnect glucCollState = BLE_STATE_DISCONNECTING; GAPCentralRole_TerminateLink(glucCollConnHandle); LCD_WRITE_STRING("Timeout", LCD_PAGE0); LCD_WRITE_STRING("", LCD_PAGE1); LCD_WRITE_STRING("", LCD_PAGE2); } } if (events & GLUCOLL_START_DISCOVERY_EVT) { events &= ~GLUCOLL_START_DISCOVERY_EVT; if (glucCollPairingStarted) { // Postpone discovery until pairing completes glucCollDiscPostponed = TRUE; } else { glucCollCentral_startDiscovery(); } } } } } }
/********************************************************************* * @fn GlucColl_ProcessEvent * * @brief Glucose Collector 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 GlucColl_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( glucCollTaskId )) != NULL ) { glucCollCentral_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 & PROCEDURE_TIMEOUT_EVT ) { if ( glucCollState == BLE_STATE_CONNECTED ) { // disconnect glucCollState = BLE_STATE_DISCONNECTING; GAPCentralRole_TerminateLink( glucCollConnHandle ); LCD_WRITE_STRING( "Timeout", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_3 ); } // return unprocessed events return ( events ^ PROCEDURE_TIMEOUT_EVT ); } if ( events & START_DEVICE_EVT ) { // Start the Device VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &glucCollRoleCB ); // Register with bond manager after starting device GAPBondMgr_Register( (gapBondCBs_t *) &glucCollBondCB ); return ( events ^ START_DEVICE_EVT ); } if ( events & START_DISCOVERY_EVT ) { if ( glucCollPairingStarted ) { // Postpone discovery until pairing completes glucCollDiscPostponed = TRUE; } else { glucCollCentralStartDiscovery( ); } return ( events ^ START_DISCOVERY_EVT ); } // Discard unknown events return 0; }
/********************************************************************* * @fn SimpleBLEBroadcaster_init * * @brief Initialization function for the Simple BLE Broadcaster App * Task. This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notification ...). * * @param none * * @return none */ static void SimpleBLEBroadcaster_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); // Hard code the DB Address till CC2650 board gets its own IEEE address //uint8 bdAddress[B_ADDR_LEN] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33 }; //HCI_EXT_SetBDADDRCmd(bdAddress); // Create an RTOS queue for message from profile to be sent to app. appMsgQueue = Util_constructQueue(&appMsg); #ifdef TI_DRIVERS_LCD_INCLUDED //Enable the 3V3 Domain and open LCD Board_openLCD(); #endif //TI_DRIVERS_LCD_INCLUDED // Setup the GAP Broadcaster Role Profile { // For all hardware platforms, device starts advertising upon initialization uint8_t 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_t gapRole_AdvertOffTime = 0; #ifndef BEACON_FEATURE uint8_t advType = GAP_ADTYPE_ADV_SCAN_IND; // use scannable undirected adv #else uint8_t advType = GAP_ADTYPE_ADV_NONCONN_IND; // use non-connectable adv #endif // !BEACON_FEATURE // Set the GAP Role Parameters GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable); GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t), &gapRole_AdvertOffTime); GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof (scanRspData), scanRspData); GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData); GAPRole_SetParameter(GAPROLE_ADV_EVENT_TYPE, sizeof(uint8_t), &advType); } // Set advertising interval { 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); } // Start the Device VOID GAPRole_StartDevice(&simpleBLEBroadcaster_BroadcasterCBs); LCD_WRITE_STRING("BLE Broadcaster", LCD_PAGE0); }
static void controlBLECentral_HandleKeys( uint8 shift, uint8 keys ) { (void)shift; // Intentionally unreferenced parameter uint8 adc; if(keys & KEY_FUN1) { app_write_string("\r\ngot the KEY_FUN1 V:"); adc=halGetVoltageMonitorInput(); app_write_string( uint8_to_string(adc)); HalLedSet( HAL_LED_1 , HAL_LED_MODE_FLASH ); } if(keys & KEY_FUN2) { app_write_string("\r\ngot the KEY_FUN2"); HalLedSet(HAL_LED_2, HAL_LED_MODE_BLINK); } if ( keys & HAL_KEY_UP ) { // Start or stop discovery if ( simpleBLEState != BLE_STATE_CONNECTED ) { if ( !simpleBLEScanning ) { simpleBLEScanning = TRUE; simpleBLEScanRes = 0; LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST ); } else { GAPCentralRole_CancelDiscovery(); } } else if ( simpleBLEState == BLE_STATE_CONNECTED && simpleBLECharHdl != 0 && simpleBLEProcedureInProgress == FALSE ) { uint8 status; // Do a read or write as long as no other read or write is in progress if ( simpleBLEDoWrite ) { // Do a write attWriteReq_t req; req.handle = simpleBLECharHdl; req.len = 1; req.value[0] = simpleBLECharVal; req.sig = 0; req.cmd = 0; status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); } else { // Do a read attReadReq_t req; req.handle = simpleBLECharHdl; status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId ); } if ( status == SUCCESS ) { simpleBLEProcedureInProgress = TRUE; simpleBLEDoWrite = !simpleBLEDoWrite; } } } if ( keys & HAL_KEY_LEFT ) { // Display discovery results if ( !simpleBLEScanning && simpleBLEScanRes > 0 ) { // Increment index of current result (with wraparound) simpleBLEScanIdx++; if ( simpleBLEScanIdx >= simpleBLEScanRes ) { simpleBLEScanIdx = 0; } LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + 1, 10, HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ), HAL_LCD_LINE_2 ); } } if ( keys & HAL_KEY_RIGHT ) { // Connection update if ( simpleBLEState == BLE_STATE_CONNECTED ) { GAPCentralRole_UpdateLink( simpleBLEConnHandle, DEFAULT_UPDATE_MIN_CONN_INTERVAL, DEFAULT_UPDATE_MAX_CONN_INTERVAL, DEFAULT_UPDATE_SLAVE_LATENCY, DEFAULT_UPDATE_CONN_TIMEOUT ); } } if ( keys & HAL_KEY_CENTER ) { uint8 addrType; uint8 *peerAddr; // Connect or disconnect if ( simpleBLEState == BLE_STATE_IDLE ) { // if there is a scan result if ( simpleBLEScanRes > 0 ) { // connect to current device in scan result peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr; addrType = simpleBLEDevList[simpleBLEScanIdx].addrType; simpleBLEState = BLE_STATE_CONNECTING; GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr ); LCD_WRITE_STRING( "Connecting", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( peerAddr ), HAL_LCD_LINE_2 ); } } else if ( simpleBLEState == BLE_STATE_CONNECTING || simpleBLEState == BLE_STATE_CONNECTED ) { // disconnect simpleBLEState = BLE_STATE_DISCONNECTING; gStatus = GAPCentralRole_TerminateLink( simpleBLEConnHandle ); LCD_WRITE_STRING( "Disconnecting", HAL_LCD_LINE_1 ); } } if ( keys & HAL_KEY_DOWN ) { // Start or cancel RSSI polling if ( simpleBLEState == BLE_STATE_CONNECTED ) { if ( !simpleBLERssi ) { simpleBLERssi = TRUE; GAPCentralRole_StartRssi( simpleBLEConnHandle, DEFAULT_RSSI_PERIOD ); } else { simpleBLERssi = FALSE; GAPCentralRole_CancelRssi( simpleBLEConnHandle ); LCD_WRITE_STRING( "RSSI Cancelled", HAL_LCD_LINE_1 ); } } } }
/********************************************************************* * @fn timeAppIndGattMsg * * @brief Handle indications and notifications. * * @param pMsg - GATT message. * * @return none */ void timeAppIndGattMsg( gattMsgEvent_t *pMsg ) { uint8 i; // Look up the handle in the handle cache for ( i = 0; i < HDL_CACHE_LEN; i++ ) { if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[i] ) { break; } } // Perform processing for this handle switch ( i ) { case HDL_CURR_TIME_CT_TIME_START: // Set clock to time read from time server timeAppClockSet( pMsg->msg.handleValueNoti.pValue ); break; case HDL_NWA_NWA_START: // Display network availability state if ( pMsg->msg.handleValueInd.pValue[0] == 1 ) { LCD_WRITE_STRING( "Network: Yes", HAL_LCD_LINE_1 ); } else { LCD_WRITE_STRING( "Network: None", HAL_LCD_LINE_1 ); } break; case HDL_ALERT_NTF_UNREAD_START: // Display unread message alert { uint8 *p = pMsg->msg.handleValueNoti.pValue; uint8 len = pMsg->msg.handleValueNoti.len; if ( p[0] <= ALERT_CAT_ID_MAX && len == 2 ) { LCD_WRITE_STRING_VALUE( (char *) timeAppAlertCatStr[p[0]], p[1], 10, HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); } } break; case HDL_ALERT_NTF_NEW_START: // Display incoming message timeAppDisplayAlert( pMsg->msg.handleValueNoti.pValue, pMsg->msg.handleValueNoti.len ); break; case HDL_BATT_LEVEL_START: // Display battery level LCD_WRITE_STRING_VALUE( "Battery%", pMsg->msg.handleValueNoti.pValue[0], 10, HAL_LCD_LINE_2 ); break; case HDL_PAS_ALERT_START: // Display phone alert status LCD_WRITE_STRING_VALUE( "Phone Alert:", pMsg->msg.handleValueNoti.pValue[0], 16, HAL_LCD_LINE_1 ); break; case HDL_PAS_RINGER_START: // Display ringer state if ( pMsg->msg.handleValueNoti.pValue[0] == 0 ) { LCD_WRITE_STRING( "Ringer Off", HAL_LCD_LINE_2 ); } else { LCD_WRITE_STRING( "Ringer On", HAL_LCD_LINE_2 ); } break; default: break; } // Send confirm for indication if ( pMsg->method == ATT_HANDLE_VALUE_IND ) { ATT_HandleValueCfm( pMsg->connHandle ); } }
/********************************************************************* * @fn simpleBLECentralEventCB * * @brief Central event callback function. * * @param pEvent - pointer to event structure * * @return none */ static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent ) { switch ( pEvent->gap.opcode ) { case GAP_DEVICE_INIT_DONE_EVENT: { LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str(pEvent->initDone.devAddr ), HAL_LCD_LINE_2 ); } break; case GAP_DEVICE_INFO_EVENT: { // if filtering device discovery results based on service UUID if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE ) { if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen ) ) { simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete simpleBLEScanning = FALSE; // if not filtering device discovery results based on service UUID if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE ) { // Copy results simpleBLEScanRes = pEvent->discCmpl.numDevs; osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); } LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes, 10, HAL_LCD_LINE_1 ); if ( simpleBLEScanRes > 0 ) { LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 ); } // initialize scan index to last device simpleBLEScanIdx = simpleBLEScanRes; } break; case GAP_LINK_ESTABLISHED_EVENT: { if ( pEvent->gap.hdr.status == SUCCESS ) { simpleBLEState = BLE_STATE_CONNECTED; simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle; simpleBLEProcedureInProgress = TRUE; // If service discovery not performed initiate service discovery if ( simpleBLECharHdl == 0 ) { osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY ); } LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 ); } else { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 ); LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 ); } } break; case GAP_LINK_TERMINATED_EVENT: { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; simpleBLECharHdl = 0; simpleBLEProcedureInProgress = FALSE; LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason, 10, HAL_LCD_LINE_2 ); } break; case GAP_LINK_PARAM_UPDATE_EVENT: { LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 ); } break; default: break; } }
/********************************************************************* * @fn simpleBLECentralEventCB * * @brief Central event callback function. * * @param pEvent - pointer to event structure * * @return none */ static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent ) { switch ( pEvent->gap.opcode ) { case GAP_DEVICE_INIT_DONE_EVENT: { LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 ); #if 1 // Start or stop discovery if ( simpleBLEState != BLE_STATE_CONNECTED ) { if ( !simpleBLEScanning ) { simpleBLEScanning = TRUE; simpleBLEScanRes = 0; LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); //HCI_EXT_SetRxGainCmd(HCI_EXT_RX_GAIN_HIGH); //HCI_EXT_SetTxPowerCmd(HCI_EXT_TX_POWER_0_DBM); GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST ); HalLedSet(HAL_LED_1,HAL_LED_MODE_ON); } else { HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF); GAPCentralRole_CancelDiscovery(); } } #endif } break; case GAP_DEVICE_INFO_EVENT: { // if filtering device discovery results based on service UUID //HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF); if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE ) { if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen ) ) { //HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF); simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType ); } } } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete simpleBLEScanning = FALSE; // if not filtering device discovery results based on service UUID if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE ) { // Copy results simpleBLEScanRes = pEvent->discCmpl.numDevs; osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList, (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) ); //HalLedSet(HAL_LED_2,HAL_LED_MODE_ON); } LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes, 10, HAL_LCD_LINE_1 ); if ( simpleBLEScanRes > 0 ) { LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 ); //HalLedSet(HAL_LED_2,HAL_LED_MODE_OFF); } // initialize scan index to last device simpleBLEScanIdx = simpleBLEScanRes; #if 1 // Display discovery results if ( !simpleBLEScanning && simpleBLEScanRes > 0 ) { // Increment index of current result (with wraparound) simpleBLEScanIdx++; if ( simpleBLEScanIdx >= simpleBLEScanRes ) { simpleBLEScanIdx = 0; } LCD_WRITE_STRING_VALUE( "Device", simpleBLEScanIdx + 1, 10, HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( simpleBLEDevList[simpleBLEScanIdx].addr ), HAL_LCD_LINE_2 ); } uint8 addrType; uint8 *peerAddr; // Connect or disconnect if ( simpleBLEState == BLE_STATE_IDLE ) { // if there is a scan result if ( simpleBLEScanRes > 0 ) { // connect to current device in scan result peerAddr = simpleBLEDevList[simpleBLEScanIdx].addr; addrType = simpleBLEDevList[simpleBLEScanIdx].addrType; simpleBLEState = BLE_STATE_CONNECTING; GAPCentralRole_EstablishLink( DEFAULT_LINK_HIGH_DUTY_CYCLE, DEFAULT_LINK_WHITE_LIST, addrType, peerAddr ); LCD_WRITE_STRING( "Connecting", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( peerAddr ), HAL_LCD_LINE_2 ); } else { #if 1 // Start or stop discovery if ( simpleBLEState != BLE_STATE_CONNECTED ) { if ( !simpleBLEScanning ) { simpleBLEScanning = TRUE; simpleBLEScanRes = 0; LCD_WRITE_STRING( "Discovering...", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); //HCI_EXT_SetRxGainCmd(HCI_EXT_RX_GAIN_HIGH); //HCI_EXT_SetTxPowerCmd(HCI_EXT_TX_POWER_0_DBM); GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST ); //HalLedSet(HAL_LED_1,HAL_LED_MODE_ON); } else { HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF); GAPCentralRole_CancelDiscovery(); } } #endif } } #endif } break; case GAP_LINK_ESTABLISHED_EVENT: { if ( pEvent->gap.hdr.status == SUCCESS ) { simpleBLEState = BLE_STATE_CONNECTED; simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle; simpleBLEProcedureInProgress = TRUE; // If service discovery not performed initiate service discovery if ( simpleBLECharHdl == 0 ) { osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY ); } LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 ); HalLedSet(HAL_LED_2,HAL_LED_MODE_ON); } else { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 ); LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 ); } } break; case GAP_LINK_TERMINATED_EVENT: { simpleBLEState = BLE_STATE_IDLE; simpleBLEConnHandle = GAP_CONNHANDLE_INIT; simpleBLERssi = FALSE; simpleBLEDiscState = BLE_DISC_STATE_IDLE; simpleBLECharHdl = 0; simpleBLEProcedureInProgress = FALSE; LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason, 10, HAL_LCD_LINE_2 ); HalLedSet(HAL_LED_2,HAL_LED_MODE_OFF); } break; case GAP_LINK_PARAM_UPDATE_EVENT: { LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 ); } break; default: break; } }