uint8 glucoseCtlPntWrite(uint8 opcode, uint8 oper) { attWriteReq_t writeReq; uint8 status; writeReq.pValue = GATT_bm_alloc(glucCollConnHandle, ATT_WRITE_REQ, GLUCOSE_CTL_PNT_LEN, NULL); if (writeReq.pValue != NULL) { writeReq.pValue[0] = opcode; writeReq.pValue[1] = oper; writeReq.len = GLUCOSE_CTL_PNT_LEN; writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = glucoseHdlCache[HDL_GLUCOSE_CTL_PNT_START]; // Send the write request status = GATT_WriteCharValue( glucCollConnHandle, &writeReq, glucCollTaskId ); if (status != SUCCESS) { GATT_bm_free((gattMsg_t *)&writeReq, ATT_WRITE_REQ); } } else { status = bleMemAllocError; } return status; }
static void ClientWriteValue(void){ attWriteReq_t req; //one write last one seconds the most //WD_KICK(); if(TRUE == osal_memcmp(mac_buffer[send_record], mac_buffer[send_record+1] ,MAC_LEN)) //check if it is the last value to send CharSendingFlag =0; if(send_record <= Buffer_Top) osal_memcpy(req.value, mac_buffer[send_record++], BLEChar.len); else return; req.len = BLEChar.len; req.handle = BLEChar.handle; req.sig = 0; req.cmd = 0; uint8 result_value_send; if(result_value_send = GATT_WriteCharValue(CurrentConnectionInfo.Handle, &req, MasterSlaveSwitchTaskID )) LCDPrintText("send error",result_value_send,PRINT_VALUE); }
// Write by Handler void BLECtrlWriteByHdl(uint16 connHandle, uint8 task_id) { attWriteReq_t wrreq; wrreq.handle = blectrlCharHdl; wrreq.len = blectrlDataLen; VOID osal_memcpy( wrreq.value, blectrlData, blectrlDataLen ); wrreq.sig = 0; wrreq.cmd = 0; GATT_WriteCharValue( connHandle, &wrreq, task_id ); }
// Subscribe/Unsubscribe by Handler void BLECtrlSubscribeByHdl(uint16 connHandle, uint8 task_id, uint16 charHdl, uint8 subscribe) { attWriteReq_t wrreq; wrreq.handle = charHdl + 1; wrreq.len = 2; wrreq.value[0] = subscribe; wrreq.value[1] = 0x00; wrreq.sig = 0; wrreq.cmd = 0; GATT_WriteCharValue( connHandle, &wrreq, task_id ); }
void bleshield_central_enable_notification() { attWriteReq_t writeReq; writeReq.handle = 0x000e; writeReq.len = 2; writeReq.value[0] = 0x01; writeReq.value[1] = 0x00; GATT_WriteCharValue( 0x0000, &writeReq, 0 ); }
uint8 glucoseCtlPntWrite(uint8 opcode, uint8 oper) { attWriteReq_t writeReq; writeReq.value[0] = opcode; writeReq.value[1] = oper; writeReq.len = 2; writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = glucoseHdlCache[HDL_GLUCOSE_CTL_PNT_START]; return GATT_WriteCharValue( glucCollConnHandle, &writeReq, glucCollTaskId ); }
/********************************************************************* * @fn hidappEnableNotification * * @brief Enable notification for a given attribute handle. * * @param connHandle - connection handle to send notification on * @param attrHandle - attribute handle to send notification for * * @return none */ static void hidappEnableNotification( uint16 connHandle, uint16 attrHandle ) { attWriteReq_t req; uint8 notificationsOn[] = {0x01, 0x00}; req.handle = attrHandle; req.len = 2; osal_memcpy(req.value, notificationsOn, 2); req.sig = 0; req.cmd = 0; VOID GATT_WriteCharValue( connHandle, &req, hidappTaskId ); }
/********************************************************************* * @fn hidappEnableNotification * * @brief Enable notification for a given attribute handle. * * @param connHandle - connection handle to send notification on * @param attrHandle - attribute handle to send notification for * * @return none */ static void hidappEnableNotification( uint16 connHandle, uint16 attrHandle ) { attWriteReq_t req; req.pValue = GATT_bm_alloc( connHandle, ATT_WRITE_REQ, 2, NULL ); if ( req.pValue != NULL ) { uint8 notificationsOn[] = {0x01, 0x00}; req.handle = attrHandle; req.len = 2; osal_memcpy(req.pValue, notificationsOn, 2); req.sig = 0; req.cmd = 0; if ( GATT_WriteCharValue( connHandle, &req, hidappTaskId ) != SUCCESS ) { GATT_bm_free( (gattMsg_t *)&req, ATT_WRITE_REQ ); } } }
/********************************************************************* * @fn timeAppConfigNext() * * @brief Perform the characteristic configuration read or * write procedure. * * @param state - Configuration state. * * @return New configuration state. */ uint8 timeAppConfigNext( uint8 state ) { attReadReq_t readReq; attWriteReq_t writeReq; bool read; static uint8 alertNtfCtrlCmd; // Find next non-zero cached handle of interest while ( state < TIMEAPP_CONFIG_MAX && timeAppHdlCache[timeAppConfigList[state]] == 0 ) { state++; } // Return if reached end of list if ( state == TIMEAPP_CONFIG_MAX ) { return TIMEAPP_CONFIG_CMPL; } // Determine what to do with characteristic switch ( timeAppConfigList[state] ) { // Read these characteristics case HDL_CURR_TIME_LOC_INFO: case HDL_CURR_TIME_REF_INFO: case HDL_DST_CHG_TIME_DST: case HDL_NWA_NWA_START: case HDL_CURR_TIME_CT_TIME_START: case HDL_ALERT_NTF_NEW_CAT: case HDL_ALERT_NTF_UNREAD_CAT: case HDL_PAS_ALERT_START: case HDL_PAS_RINGER_START: case HDL_REF_TIME_UPD_STATE: read = TRUE; break; // Set notification for these characteristics case HDL_CURR_TIME_CT_TIME_CCCD: case HDL_ALERT_NTF_UNREAD_CCCD: case HDL_ALERT_NTF_NEW_CCCD: case HDL_BATT_LEVEL_CCCD: case HDL_PAS_ALERT_CCCD: case HDL_PAS_RINGER_CCCD: read = FALSE; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.sig = 0; writeReq.cmd = 0; break; // Set indication for these characteristics case HDL_NWA_NWA_CCCD: read = FALSE; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_INDICATE); writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_INDICATE); writeReq.sig = 0; writeReq.cmd = 0; break; // Alert notification control point case HDL_ALERT_NTF_CTRL: // initialize control point command if (state == TIMEAPP_ALERT_NTF_CTRL_START) { alertNtfCtrlCmd = ALERT_NOTIF_ENABLE_NEW; } read = FALSE; writeReq.len = 2; writeReq.value[0] = alertNtfCtrlCmd; writeReq.value[1] = ALERT_NOTIF_CAT_ALL; writeReq.sig = 0; writeReq.cmd = 0; // set next command to send if (alertNtfCtrlCmd == ALERT_NOTIF_ENABLE_NEW) { alertNtfCtrlCmd = ALERT_NOTIF_NOTIFY_NEW; } else if (alertNtfCtrlCmd == ALERT_NOTIF_NOTIFY_NEW) { alertNtfCtrlCmd = ALERT_NOTIF_ENABLE_UNREAD; } else if (alertNtfCtrlCmd == ALERT_NOTIF_ENABLE_UNREAD) { alertNtfCtrlCmd = ALERT_NOTIF_NOTIFY_UNREAD; } break; default: break; } // Do a GATT read or write if ( read ) { readReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_ReadCharValue( timeAppConnHandle, &readReq, timeAppTaskId ); } else { writeReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_WriteCharValue( timeAppConnHandle, &writeReq, timeAppTaskId ); } return state; }
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 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 Time_configNext() * * @brief Perform the characteristic configuration read or * write procedure. * * @param state - Configuration state. * * @return New configuration state. */ uint8_t Time_configNext(uint8_t state) { bool read; // Find next non-zero cached handle of interest while (state < TIME_CONFIG_MAX && Time_handleCache[Time_configList[state]] == 0) { state++; } // Return if reached end of list if (state >= TIME_CONFIG_MAX) { return TIME_CONFIG_CMPL; } // Determine what to do with characteristic switch (Time_configList[state]) { // Read these characteristics case HDL_CURR_TIME_CT_TIME_START: read = TRUE; break; // Set notification for these characteristics case HDL_CURR_TIME_CT_TIME_CCCD: read = FALSE; break; default: return state; } if(Time_configDone==TRUE) { return state; } // Do a GATT read or write if (read) { attReadReq_t readReq; readReq.handle = Time_handleCache[Time_configList[state]]; // Send the read request GATT_ReadCharValue(Time_connHandle, &readReq, ICall_getEntityId()); // Only reading time right now Time_configDone = TRUE; } else { attWriteReq_t writeReq; writeReq.pValue = GATT_bm_alloc(Time_connHandle, ATT_WRITE_REQ, 2, NULL); if (writeReq.pValue != NULL) { writeReq.len = 2; writeReq.pValue[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.pValue[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = Time_handleCache[Time_configList[state]]; // Send the read request if (GATT_WriteCharValue(Time_connHandle, &writeReq, ICall_getEntityId()) != SUCCESS) { GATT_bm_free((gattMsg_t *)&writeReq, ATT_WRITE_REQ); } } } return state; }
uint8 glucoseCtlPntWriteFilter(uint8 opcode, uint8 oper, uint8 filterType, void* param1, void* param2) { attWriteReq_t writeReq; uint8 status; writeReq.pValue = GATT_bm_alloc( glucCollConnHandle, ATT_WRITE_REQ, GLUCOSE_CTL_PNT_FILTER_LEN, NULL ); if (writeReq.pValue != NULL) { UTCTimeStruct *time1, *time2; uint16 *seqNum1, *seqNum2; uint8 *p = writeReq.pValue; *p++ = opcode; *p++ = oper; // The operator will tells us whether to include the filters or not // Note day and month are converted to date time struct values switch(oper) { case CTL_PNT_OPER_LESS_EQUAL: case CTL_PNT_OPER_GREATER_EQUAL: *p++ = filterType; if (filterType == CTL_PNT_FILTER_SEQNUM) { seqNum1 = param1; *p++ = LO_UINT16(*seqNum1); *p++ = HI_UINT16(*seqNum1); } else { time1 = param1; *p++ = LO_UINT16(time1->year); *p++ = HI_UINT16(time1->year); *p++ = (time1->month + 1); *p++ = (time1->day + 1); *p++ = time1->hour; *p++ = time1->minutes; *p++ = time1->seconds; } break; case CTL_PNT_OPER_RANGE: *p++ = filterType; if (filterType == CTL_PNT_FILTER_SEQNUM) { seqNum1 = param1; seqNum2 = param2; *p++ = LO_UINT16(*seqNum1); *p++ = HI_UINT16(*seqNum1); *p++ = LO_UINT16(*seqNum2); *p++ = HI_UINT16(*seqNum2); } else { time1 = param1; time2 = param2; *p++ = LO_UINT16(time1->year); *p++ = HI_UINT16(time1->year); *p++ = (time1->month + 1); *p++ = (time1->day + 1); *p++ = time1->hour; *p++ = time1->minutes; *p++ = time1->seconds; *p++ = LO_UINT16(time2->year); *p++ = HI_UINT16(time2->year); *p++ = (time2->month + 1); *p++ = (time2->day + 1); *p++ = time2->hour; *p++ = time2->minutes; *p++ = time2->seconds; } break; default: break; } writeReq.len = (p - writeReq.pValue); writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = glucoseHdlCache[HDL_GLUCOSE_CTL_PNT_START]; // Send the write request status = GATT_WriteCharValue( glucCollConnHandle, &writeReq, glucCollTaskId ); if (status != SUCCESS) { GATT_bm_free( (gattMsg_t *)&writeReq, ATT_WRITE_REQ ); } } else { status = bleMemAllocError; } return status; }
static void simpleBLECentral_HandleKeys( uint8 shift, uint8 keys ) { (void)shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_UP ) { // Start or stop discovery if ( simpleBLEState != BLE_STATE_CONNECTED ) { if ( !simpleBLEScanning ) { uint8 adc7 = HalAdcRead (HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_8); LCD_WRITE_STRING_VALUE( "Value",adc7, 16, HAL_LCD_LINE_2); advertData[6]= var1[6]; advertData[8]= 0xA9; if(adc7>0x7E) advertData[9]= 0x01; else advertData[9]= 0x02; advertData[10]= 0xB9; GAP_UpdateAdvertisingData( GAPROLE_ADVERT_ENABLED,TRUE, sizeof(advertData),advertData); 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 ); } } //////////////////////////////////////////////////////////////////////////////// // Advertising if ( keys & HAL_KEY_RIGHT ) { // ressing the right key should toggle advertising on and off uint8 current_adv_enabled_status; uint8 new_adv_enabled_status; uint8 adc7 = HalAdcRead (HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_8); LCD_WRITE_STRING_VALUE( "Value",adc7, 16, HAL_LCD_LINE_2); advertData[6]= var1[6]; advertData[8]= 0xA9; if(adc7>0x7E) advertData[9]= 0x01; else advertData[9]= 0x02; advertData[10]= 0xB9; GAP_UpdateAdvertisingData( GAPROLE_ADVERT_ENABLED,TRUE, sizeof(advertData),advertData); //Find the current GAP advertisement status if( current_adv_enabled_status == FALSE ) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } // if(var1[2] == 0x53) { //scanRspData[18] =0xAA; //scanRspData[19] =(uint8) var1[2]; //bStatus_t stat; //stat = GAP_UpdateAdvertisingData( 0, TRUE, 1, scanRspData); //} //change the GAP advertisement status to opposite of current status GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status ); } //////////////////////////////////////////////////////////////////////////////// /*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 ); } } } }
uint8 glucoseCtlPntWriteFilter(uint8 opcode, uint8 oper, uint8 filterType, void* param1, void* param2) { attWriteReq_t writeReq; UTCTimeStruct *time1, *time2; uint16 *seqNum1, *seqNum2; uint8 *p = writeReq.value; *p++ = opcode; *p++ = oper; // The operator will tells us whether to include the filters or not // Note day and month are converted to date time struct values switch(oper) { case CTL_PNT_OPER_LESS_EQUAL: case CTL_PNT_OPER_GREATER_EQUAL: *p++ = filterType; if (filterType == CTL_PNT_FILTER_SEQNUM) { seqNum1 = param1; *p++ = LO_UINT16(*seqNum1); *p++ = HI_UINT16(*seqNum1); } else { time1 = param1; *p++ = LO_UINT16(time1->year); *p++ = HI_UINT16(time1->year); *p++ = (time1->month + 1); *p++ = (time1->day + 1); *p++ = time1->hour; *p++ = time1->minutes; *p++ = time1->seconds; } break; case CTL_PNT_OPER_RANGE: *p++ = filterType; if (filterType == CTL_PNT_FILTER_SEQNUM) { seqNum1 = param1; seqNum2 = param2; *p++ = LO_UINT16(*seqNum1); *p++ = HI_UINT16(*seqNum1); *p++ = LO_UINT16(*seqNum2); *p++ = HI_UINT16(*seqNum2); } else { time1 = param1; time2 = param2; *p++ = LO_UINT16(time1->year); *p++ = HI_UINT16(time1->year); *p++ = (time1->month + 1); *p++ = (time1->day + 1); *p++ = time1->hour; *p++ = time1->minutes; *p++ = time1->seconds; *p++ = LO_UINT16(time2->year); *p++ = HI_UINT16(time2->year); *p++ = (time2->month + 1); *p++ = (time2->day + 1); *p++ = time2->hour; *p++ = time2->minutes; *p++ = time2->seconds; } break; default: break; } writeReq.len = (p - writeReq.value); writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = glucoseHdlCache[HDL_GLUCOSE_CTL_PNT_START]; return GATT_WriteCharValue( glucCollConnHandle, &writeReq, glucCollTaskId ); }
/********************************************************************* * @fn timeAppConfigNext() * * @brief Perform the characteristic configuration read or * write procedure. * * @param state - Configuration state. * * @return New configuration state. */ uint8 timeAppConfigNext( uint8 state ) { attReadReq_t readReq; attWriteReq_t writeReq; bool read; // Find next non-zero cached handle of interest while ( state < TIMEAPP_CONFIG_MAX && timeAppHdlCache[timeAppConfigList[state]] == 0 ) { state++; } // Return if reached end of list if ( state == TIMEAPP_CONFIG_MAX ) { return TIMEAPP_CONFIG_CMPL; } // Determine what to do with characteristic switch ( timeAppConfigList[state] ) { // Read these characteristics case HDL_CURR_TIME_CT_TIME_START: read = TRUE; break; // Set notification for these characteristics case HDL_CURR_TIME_CT_TIME_CCCD: read = FALSE; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.sig = 0; writeReq.cmd = 0; break; default: break; } if(timeConfigDone==TRUE) { return state; } // Do a GATT read or write if ( read ) { readReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_ReadCharValue( gapConnHandle, &readReq, bloodPressureTaskId ); //Only reading time right now timeConfigDone = TRUE; } else { writeReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_WriteCharValue( gapConnHandle, &writeReq, bloodPressureTaskId ); } return state; }
/********************************************************************* * @fn timeApp_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 timeApp_HandleKeys( uint8 shift, uint8 keys ) { if ( keys & HAL_KEY_UP ) { // Start or stop advertising if ( timeAppGapState != GAPROLE_CONNECTED ) { uint8 advState; // 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 advertising state GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &advState ); advState = !advState; GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState ); // Set state variable if (advState == FALSE) { timeAppAdvCancelled = TRUE; } } } if ( keys & HAL_KEY_LEFT ) { attWriteReq_t req; // Send command to alert notificaton control point if ( ( timeAppGapState == GAPROLE_CONNECTED ) && ( timeAppHdlCache[HDL_ALERT_NTF_CTRL] != 0 ) ) { // Send write request req.len = 2; req.value[0] = *pTimeAppAlertCmd; req.value[1] = ALERT_NOTIF_CAT_ALL; req.sig = 0; req.cmd = 0; req.handle = timeAppHdlCache[HDL_ALERT_NTF_CTRL]; GATT_WriteCharValue( timeAppConnHandle, &req, timeAppTaskId ); LCD_WRITE_STRING_VALUE( "Alert cmd:", *pTimeAppAlertCmd, 10, HAL_LCD_LINE_1); } // Cycle through command test values if ( *pTimeAppAlertCmd == ALERT_NOTIF_DISABLE_UNREAD ) { pTimeAppAlertCmd = timeAppAlertCmd; } else { pTimeAppAlertCmd++; } } if ( keys & HAL_KEY_RIGHT ) { attWriteReq_t req; // Do a reference time update if ( ( timeAppGapState == GAPROLE_CONNECTED ) && ( timeAppHdlCache[HDL_REF_TIME_UPD_CTRL] != 0 ) ) { // Send write command req.len = 1; req.value[0] = timeAppRefUpdateVal; req.sig = 0; req.cmd = 1; req.handle = timeAppHdlCache[HDL_REF_TIME_UPD_CTRL]; GATT_WriteNoRsp( timeAppConnHandle, &req ); LCD_WRITE_STRING_VALUE( "Time update:", timeAppRefUpdateVal, 10, HAL_LCD_LINE_1); // Toggle between two reference time update values if ( timeAppRefUpdateVal == REF_TIME_UPDATE_GET ) { timeAppRefUpdateVal = REF_TIME_UPDATE_CANCEL; } else { timeAppRefUpdateVal = REF_TIME_UPDATE_GET; } } } if ( keys & HAL_KEY_CENTER ) { // If connected, terminate connection if ( timeAppGapState == GAPROLE_CONNECTED ) { GAPRole_TerminateConnection(); } } if ( keys & HAL_KEY_DOWN ) { attWriteReq_t req; // Write ringer control point if ( ( timeAppGapState == GAPROLE_CONNECTED ) && ( timeAppHdlCache[HDL_PAS_CTRL] != 0 ) ) { // Send write command req.len = 1; req.value[0] = timeAppRingerCmd; req.sig = 0; req.cmd = 1; req.handle = timeAppHdlCache[HDL_PAS_CTRL]; GATT_WriteNoRsp( timeAppConnHandle, &req ); LCD_WRITE_STRING_VALUE( "Ringer ctrl:", timeAppRingerCmd, 10, HAL_LCD_LINE_1); // Toggle between values if ( ++timeAppRingerCmd > RINGER_CANCEL_SILENT ) { timeAppRingerCmd = RINGER_SILENT_MODE; } } } if ( keys & HAL_KEY_SW_6 ) { } }
/********************************************************************* * @fn glucoseConfigNext() * * @brief Perform the characteristic configuration read or * write procedure. * * @param state - Configuration state. * * @return New configuration state. */ uint8_t glucoseConfigNext(uint8_t state) { bool read; uint16_t charCfg; // Find next non-zero cached handle of interest while (state < GLUCOSE_CONFIG_MAX && glucoseHdlCache[glucoseConfigList[state]] == 0) { state++; } // Return if reached end of list if (state >= GLUCOSE_CONFIG_MAX) { glucCollCharHdls = true; return GLUCOSE_CONFIG_CMPL; } // Determine what to do with characteristic switch (glucoseConfigList[state]) { // Read these characteristics case HDL_DEVINFO_SYSTEM_ID: case HDL_DEVINFO_MANUFACTURER_NAME: case HDL_DEVINFO_MODEL_NUM: case HDL_GLUCOSE_FEATURE: read = TRUE; break; // Set notification for these characteristics case HDL_GLUCOSE_MEAS_CCCD: case HDL_GLUCOSE_CONTEXT_CCCD: read = FALSE; charCfg = GATT_CLIENT_CFG_NOTIFY; break; // Set indication for these characteristics case HDL_GLUCOSE_CTL_PNT_CCCD: read = FALSE; charCfg = GATT_CLIENT_CFG_INDICATE; break; default: return state; } // Do a GATT read or write if (read) { attReadReq_t readReq; readReq.handle = glucoseHdlCache[glucoseConfigList[state]]; // Send the read request GATT_ReadCharValue(glucCollConnHandle, &readReq, glucCollTaskId); } else { attWriteReq_t writeReq; writeReq.pValue = GATT_bm_alloc(glucCollConnHandle, ATT_WRITE_REQ, 2, NULL); if (writeReq.pValue != NULL) { writeReq.len = 2; writeReq.pValue[0] = LO_UINT16(charCfg); writeReq.pValue[1] = HI_UINT16(charCfg); writeReq.sig = 0; writeReq.cmd = 0; writeReq.handle = glucoseHdlCache[glucoseConfigList[state]]; // Send the write request if (GATT_WriteCharValue(glucCollConnHandle, &writeReq, glucCollTaskId) != SUCCESS) { GATT_bm_free((gattMsg_t *)&writeReq, ATT_WRITE_REQ); } } } return state; }