예제 #1
0
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;
            }
        }
    }
}
예제 #2
0
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();
    }
}
예제 #3
0
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();
}
예제 #4
0
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);
}
예제 #5
0
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);
            }
        }
    }
}
예제 #6
0
// 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;
}
예제 #7
0
// 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;
}