/********************************************************************* * @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 simpleTopology_taskFxn * * @brief Application task entry point for the Simple BLE Multi. * * @param a0, a1 - not used. * * @return None. */ static void simpleTopology_taskFxn(UArg a0, UArg a1) { // Initialize application simpleTopology_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) { uint8 safeToDealloc = TRUE; if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) { // Process inter-task message safeToDealloc = simpleTopology_processStackMsg((ICall_Hdr *)pMsg); } if (pMsg && safeToDealloc) { ICall_freeMsg(pMsg); } } // If RTOS queue is not empty, process app message. while (!Queue_empty(appMsgQueue)) { sbtEvt_t *pMsg = (sbtEvt_t *)Util_dequeueMsg(appMsgQueue); if (pMsg) { // Process message. simpleTopology_processAppMsg(pMsg); // Free the space from the message. ICall_free(pMsg); } } } // the trigger was a periodic event // trigger was the SCAN_EVENT if (!!(events & SCAN_EVENT)) { // effectively mark off the event as "handled" events &= ~SCAN_EVENT; // now start discovery. // CJ: I think that the scan parameters are set in such a way // that it will start and stop itself scanningStarted = true; GAPRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); } } }