void BLEPeripheral::handleGattsEvent(ble_client_gatts_event_t event, struct ble_gatts_evt_msg *event_data) { if (BLE_CLIENT_GATTS_EVENT_WRITE == event) { uint16_t handle = event_data->wr.attr_handle; for (int i = 0; i < _num_attributes; i++) { BLEAttribute* attribute = _attributes[i]; if (attribute->type() != BLETypeCharacteristic) { continue; } BLECharacteristic* characteristic = (BLECharacteristic*)attribute; if (characteristic->valueHandle() == handle) { characteristic->setValue(_central, event_data->wr.data, event_data->wr.len); break; } else if (characteristic->cccdHandle() == handle) { uint16_t cccdValue = 0; memcpy(&cccdValue, event_data->wr.data, event_data->wr.len); characteristic->setCccdValue(_central, cccdValue); break; } } } }
void BLEPeripheral::handleGapEvent(ble_client_gap_event_t event, struct ble_gap_event *event_data) { if (BLE_CLIENT_GAP_EVENT_CONNECTED == event) { _state = BLE_PERIPH_STATE_CONNECTED; _central.setAddress(event_data->connected.peer_bda); if (_event_handlers[BLEConnected]) { _event_handlers[BLEConnected](_central); } } else if (BLE_CLIENT_GAP_EVENT_DISCONNECTED == event) { for (int i = 0; i < _num_attributes; i++) { BLEAttribute* attribute = _attributes[i]; if (attribute->type() == BLETypeCharacteristic) { BLECharacteristic* characteristic = (BLECharacteristic*)attribute; characteristic->setCccdValue(_central, 0x0000); // reset CCCD } } if (_event_handlers[BLEDisconnected]) _event_handlers[BLEDisconnected](_central); _state = BLE_PERIPH_STATE_READY; _central.clearAddress(); _startAdvertising(); } else if (BLE_CLIENT_GAP_EVENT_CONN_TIMEOUT == event) { _state = BLE_PERIPH_STATE_READY; _startAdvertising(); } }
void BLEPeripheral::addAttribute(BLEAttribute& attribute) { if (_attributes == NULL) { _attributes = (BLEAttribute**)malloc(BLEAttribute::numAttributes() * sizeof(BLEAttribute*)); } _attributes[_num_attributes] = &attribute; _num_attributes++; BLEAttributeType type = attribute.type(); if (BLETypeCharacteristic == type) { _last_added_characteritic = (BLECharacteristic*)&attribute; } else if (BLETypeDescriptor == type) { if (_last_added_characteritic) { BLEDescriptor* descriptor = (BLEDescriptor*)&attribute; if (strcmp("2901", descriptor->uuid()) == 0) { _last_added_characteritic->setUserDescription(descriptor); } else if (strcmp("2904", descriptor->uuid()) == 0) { _last_added_characteritic->setPresentationFormat(descriptor); } } } }
void BLEPeripheral::begin() { unsigned char advertisementData[20]; unsigned char scanData[20]; unsigned char advertisementDataLength = 0; unsigned char scanDataLength = 0; if (this->_advertisedServiceUuid){ BLEUuid advertisedServiceUuid = BLEUuid(this->_advertisedServiceUuid); unsigned char advertisedServiceUuidLength = advertisedServiceUuid.length(); advertisementDataLength = 2 + advertisedServiceUuidLength; advertisementData[0] = (advertisedServiceUuidLength > 2) ? 0x06 : 0x02; advertisementData[1] = advertisedServiceUuidLength; memcpy(&advertisementData[2], advertisedServiceUuid.data(), advertisedServiceUuidLength); } else if (this->_manufacturerData && this->_manufacturerDataLength > 0) { if (this->_manufacturerDataLength > sizeof(advertisementData)) { this->_manufacturerDataLength = sizeof(advertisementData); } advertisementDataLength = 2 + this->_manufacturerDataLength; advertisementData[0] = 0xff; advertisementData[1] = this->_manufacturerDataLength; memcpy(&advertisementData[2], this->_manufacturerData, this->_manufacturerDataLength); } if (this->_localName){ unsigned char originalLocalNameLength = strlen(this->_localName); unsigned char localNameLength = originalLocalNameLength; if (localNameLength > sizeof(scanData)) { localNameLength = sizeof(scanData); } scanDataLength = 2 + localNameLength; scanData[0] = (originalLocalNameLength > sizeof(scanData)) ? 0x08 : 0x09; scanData[1] = localNameLength; memcpy(&scanData[2], this->_localName, localNameLength); } for (int i = 0; i < this->_numAttributes; i++) { BLEAttribute* attribute = this->_attributes[i]; if (attribute->type() == BLETypeCharacteristic) { BLECharacteristic* characteristic = (BLECharacteristic*)attribute; characteristic->setValueChangeListener(*this); } } this->_nRF8001.begin(advertisementData, advertisementDataLength, scanData, scanDataLength, this->_attributes, this->_numAttributes); this->_nRF8001.requestAddress(); }
bool BLEPeripheral::begin() { BleStatus status; status = _init(); if (status != BLE_STATUS_SUCCESS) { return false; } /* Populate advertising data */ _advDataInit(); status = ble_client_gap_wr_adv_data(_adv_data, _adv_data_len); if (BLE_STATUS_SUCCESS != status) { return false; } uint16_t lastServiceHandle = 0; for (int i = 0; i < _num_attributes; i++) { BLEAttribute* attribute = _attributes[i]; BLEAttributeType type = attribute->type(); bool addResult = false; if (BLETypeService == type) { BLEService* service = (BLEService*)attribute; addResult = service->add(); lastServiceHandle = service->handle(); } else if (BLETypeCharacteristic == type) { BLECharacteristic* characteristic = (BLECharacteristic*)attribute; addResult = characteristic->add(lastServiceHandle); } else if (BLETypeDescriptor == type) { BLEDescriptor *descriptor = (BLEDescriptor*)attribute; if (strcmp(descriptor->uuid(), "2901") == 0 || strcmp(descriptor->uuid(), "2902") == 0 || strcmp(descriptor->uuid(), "2903") == 0 || strcmp(descriptor->uuid(), "2904") == 0) { continue; // skip } addResult = descriptor->add(lastServiceHandle); } if (!addResult) { return false; } } return (_startAdvertising() == BLE_STATUS_SUCCESS); }
// GATT server only ssize_t profile_write_process(bt_conn_t *conn, const bt_gatt_attr_t *attr, const void *buf, uint16_t len, uint16_t offset) { pr_info(LOG_MODULE_BLE, "%s1", __FUNCTION__); BLEAttribute *bleattr = (BLEAttribute *)attr->user_data; BLECharacteristicImp* blecharacteritic; BLEAttributeType type = bleattr->type(); if ((BLETypeCharacteristic != type) || 0 != offset) { return 0; } blecharacteritic = (BLECharacteristicImp*)bleattr; blecharacteritic->setValue((const uint8_t *) buf, len); return len; }
// GATT Server Only ssize_t profile_read_process(bt_conn_t *conn, const bt_gatt_attr_t *attr, void *buf, uint16_t len, uint16_t offset) { const unsigned char *pvalue; BLEAttribute *bleattr = (BLEAttribute *)attr->user_data; BLEAttributeType type = bleattr->type(); if (BLETypeCharacteristic == type) { BLECharacteristicImp* blecharacteritic = (BLECharacteristicImp*)bleattr; pvalue = blecharacteritic->value(); return bt_gatt_attr_read(conn, attr, buf, len, offset, pvalue, blecharacteritic->valueLength()); } else if (BLETypeDescriptor == type) { BLEDescriptorImp* bledescriptor = (BLEDescriptorImp*)bleattr; pvalue = bledescriptor->value(); return bt_gatt_attr_read(conn, attr, buf, len, offset, pvalue, bledescriptor->valueLength()); } return 0; }