示例#1
0
/**@brief GAP initialization.
 *
 * @details This function shall be used to setup all the necessary GAP (Generic Access Profile)
 *          parameters of the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
    uint32_t                err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
    err_code = sd_ble_gap_device_name_set(&sec_mode, DEVICE_NAME, strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR);
    APP_ERROR_CHECK(err_code);
    
    memset(&gap_conn_params, 0, sizeof(gap_conn_params));

    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;

    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}
示例#2
0
/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
static void advertising_init(void)
{
    uint32_t                err_code;
    ble_advdata_t           advdata;
    ble_gap_conn_sec_mode_t sec_mode;
    uint8_t                 flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    // Set GAP parameters
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

    err_code =
        sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_WATCH);
    APP_ERROR_CHECK(err_code);

    // Build and set advertising data
    memset(&advdata, 0, sizeof (advdata));

    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags              = flags;

    err_code = ble_advdata_set(&advdata, NULL);
    APP_ERROR_CHECK(err_code);

    // Initialize advertising parameters (used when starting advertising)
    memset(&m_adv_params, 0, sizeof (m_adv_params));

    m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;
    m_adv_params.p_peer_addr = NULL; // Undirected advertisement
    m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval    = APP_ADV_INTERVAL;
    m_adv_params.timeout     = APP_ADV_TIMEOUT_IN_SECONDS;
}
示例#3
0
/**@brief Function for adding report characteristics.
 *
 * @param[in]   p_hids              HID Service structure.
 * @param[in]   p_properties        Report characteristic properties.
 * @param[in]   max_len             Maximum length of report value.
 * @param[in]   p_rep_ref           Report Reference descriptor.
 * @param[in]   p_rep_ref_attr_md   Characteristic security settings.
 * @param[in]   is_read_resp        Characteristic read authorization.
 * @param[out]  p_rep_char          Handles of new characteristic.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t rep_char_add(ble_hids_t *                   p_hids,
                             ble_gatt_char_props_t *        p_properties,
                             uint16_t                       max_len,
                             ble_srv_report_ref_t *         p_rep_ref,
                             ble_srv_cccd_security_mode_t * p_rep_ref_attr_md,
                             bool                           is_read_resp,
                             ble_hids_rep_char_t *          p_rep_char)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;
    uint8_t             encoded_rep_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
    
    // Add Report characteristic
    if (p_properties->notify)
    {
        memset(&cccd_md, 0, sizeof(cccd_md));
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        cccd_md.write_perm = p_rep_ref_attr_md->cccd_write_perm;
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    }
    
    memset(&char_md, 0, sizeof(char_md));
    
    char_md.char_props       = *p_properties;
    char_md.p_char_user_desc = NULL;
    char_md.p_char_pf        = NULL;
    char_md.p_user_desc_md   = NULL;
    char_md.p_cccd_md        = (p_properties->notify) ? &cccd_md : NULL;
    char_md.p_sccd_md        = NULL;
    
    BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_CHAR);
    
    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_rep_ref_attr_md->read_perm;
    attr_md.write_perm = p_rep_ref_attr_md->write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = is_read_resp ? 1 : 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 1;
    
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    
    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = 0;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = max_len;
    attr_char_value.p_value   = NULL;
    
    err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_rep_char->char_handles);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // Add Report Reference descriptor
    BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);
    
    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_rep_ref_attr_md->read_perm;
    attr_md.write_perm = p_rep_ref_attr_md->write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;
    
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    
    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = ble_srv_report_ref_encode(encoded_rep_ref, p_rep_ref);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = attr_char_value.init_len;
    attr_char_value.p_value   = encoded_rep_ref;
    
    return sd_ble_gatts_descriptor_add(p_rep_char->char_handles.value_handle,
                                       &attr_char_value,
                                       &p_rep_char->ref_handle);
}
示例#4
0
/**
 * @brief BLEスタック初期化
 *
 * @detail BLE関連の初期化を行う。
 *      -# SoftDeviceハンドラ初期化
 *      -# システムイベントハンドラ初期化
 *      -# BLEスタック有効化
 *      -# BLEイベントハンドラ設定
 *      -# デバイス名設定
 *      -# Appearance設定(GAP_USE_APPEARANCE定義時)
 *      -# PPCP設定
 *      -# Service初期化
 *      -# Advertising初期化
 *      -# Connection初期化
 */
static void ble_stack_init(void)
{
    uint32_t err_code;

    /* BLEスタックの有効化 */
    {
        ble_enable_params_t ble_enable_params;

        memset(&ble_enable_params, 0, sizeof(ble_enable_params));
        ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
        err_code = sd_ble_enable(&ble_enable_params);
        APP_ERROR_CHECK(err_code);
    }

    /* デバイス名設定 */
    {
        //デバイス名へのWrite Permission(no protection, open link)
        ble_gap_conn_sec_mode_t sec_mode;

        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                            (const uint8_t *)GAP_DEVICE_NAME,
                                            strlen(GAP_DEVICE_NAME));
        APP_ERROR_CHECK(err_code);
    }

#ifdef GAP_USE_APPEARANCE
    /* Appearance設定 */
    err_code = sd_ble_gap_appearance_set(GAP_USE_APPEARANCE);
    APP_ERROR_CHECK(err_code);
#endif  //GAP_USE_APPEARANCE

    /*
     * Peripheral Preferred Connection Parameters(PPCP)
     * ここで設定しておくと、Connection Parameter Update Reqを送信せずに済むらしい。
     */
    {
        ble_gap_conn_params_t   gap_conn_params = {0};

        gap_conn_params.min_conn_interval = MSEC_TO_UNITS(CONN_MIN_INTERVAL, UNIT_1_25_MS);
        gap_conn_params.max_conn_interval = MSEC_TO_UNITS(CONN_MAX_INTERVAL, UNIT_1_25_MS);
        gap_conn_params.slave_latency     = CONN_SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = MSEC_TO_UNITS(CONN_SUP_TIMEOUT, UNIT_10_MS);

        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    }

    /*
     * Service初期化
     */
    {
        ble_ios_init_t ios_init;

        ios_init.evt_handler_in = svc_ios_handler_in;
        //ios_init.evt_handler_out = svc_ios_handler_out;
        ios_init.len_in = 64;
        ios_init.len_out = 32;
        ble_ios_init(&m_ios, &ios_init);
    }

    /*
     * Advertising初期化
     */
    {
        ble_uuid_t adv_uuids[] = { { IOS_UUID_SERVICE, m_ios.uuid_type } };
        ble_advdata_t advdata;
        ble_advdata_t scanrsp;

        memset(&advdata, 0, sizeof(advdata));
        memset(&scanrsp, 0, sizeof(scanrsp));

        /*
         * ble_advdata_name_type_t (ble_advdata.h)
         *
         * BLE_ADVDATA_NO_NAME    : デバイス名無し
         * BLE_ADVDATA_SHORT_NAME : デバイス名あり «Shortened Local Name»
         * BLE_ADVDATA_FULL_NAME  : デバイス名あり «Complete Local Name»
         *
         * https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
         * https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v7.x.x/doc/7.2.0/s110/html/a01015.html#ga03c5ccf232779001be9786021b1a563b
         */
        advdata.name_type = BLE_ADVDATA_FULL_NAME;

        /*
         * Appearanceが含まれるかどうか
         */
#ifdef GAP_USE_APPEARANCE
        advdata.include_appearance = true;
#else   //GAP_USE_APPEARANCE
        advdata.include_appearance = false;
#endif  //GAP_USE_APPEARANCE
        /*
         * Advertisingフラグの設定
         * CSS_v4 : Part A  1.3 FLAGS
         * https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v7.x.x/doc/7.2.0/s110/html/a00802.html
         *
         * BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE = BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED
         *      BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE : LE Limited Discoverable Mode
         *      BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED : BR/EDR not supported
         */
        advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;    //探索時間に制限あり

        /* SCAN_RSPデータ設定 */
        scanrsp.uuids_complete.uuid_cnt = ARRAY_SIZE(adv_uuids);
        scanrsp.uuids_complete.p_uuids  = adv_uuids;

        err_code = ble_advdata_set(&advdata, &scanrsp);
        APP_ERROR_CHECK(err_code);
    }

    /*
     * Connection初期化
     */
    {
        ble_conn_params_init_t cp_init = {0};

		/* APP_TIMER_PRESCALER = 0 */
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = APP_TIMER_TICKS(CONN_FIRST_PARAMS_UPDATE_DELAY, 0);
        cp_init.next_conn_params_update_delay  = APP_TIMER_TICKS(CONN_NEXT_PARAMS_UPDATE_DELAY, 0);
        cp_init.max_conn_params_update_count   = CONN_MAX_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = conn_params_evt_handler;
        cp_init.error_handler                  = conn_params_error_handler;

        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }

#ifdef BLE_DFU_APP_SUPPORT
    /** @snippet [DFU BLE Service initialization] */
    {
        ble_dfu_init_t   dfus_init;

        // Initialize the Device Firmware Update Service.
        memset(&dfus_init, 0, sizeof(dfus_init));

        dfus_init.evt_handler    = dfu_app_on_dfu_evt;
        dfus_init.error_handler  = NULL; //service_error_handler - Not used as only the switch from app to DFU mode is required and not full dfu service.
        dfus_init.evt_handler    = dfu_app_on_dfu_evt;
        dfus_init.revision       = DFU_REVISION;

        err_code = ble_dfu_init(&m_dfus, &dfus_init);
        APP_ERROR_CHECK(err_code);

        dfu_app_reset_prepare_set(dfu_reset_prepare);
    }
    /** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT
}
示例#5
0
void nRF51822::begin(unsigned char advertisementDataType,
                      unsigned char advertisementDataLength,
                      const unsigned char* advertisementData,
                      unsigned char scanDataType,
                      unsigned char scanDataLength,
                      const unsigned char* scanData,
                      BLELocalAttribute** localAttributes,
                      unsigned char numLocalAttributes,
                      BLERemoteAttribute** remoteAttributes,
                      unsigned char numRemoteAttributes)
{

#ifdef __RFduino__
  sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, NULL);
#else
  sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL); // sd_nvic_EnableIRQ(SWI2_IRQn);
#endif

#ifdef NRF51_S130
  ble_enable_params_t enableParams = {
      .gatts_enable_params = {
          .service_changed = true
      }
  };

  sd_ble_enable(&enableParams);
#endif

#ifdef NRF_51822_DEBUG
  ble_version_t version;

  sd_ble_version_get(&version);

  Serial.print(F("version = "));
  Serial.print(version.version_number);
  Serial.print(F(" "));
  Serial.print(version.company_id);
  Serial.print(F(" "));
  Serial.print(version.subversion_number);
  Serial.println();
#endif

  ble_gap_conn_params_t gap_conn_params;

  gap_conn_params.min_conn_interval = 40;  // in 1.25ms units
  gap_conn_params.max_conn_interval = 80;  // in 1.25ms unit
  gap_conn_params.slave_latency     = 0;
  gap_conn_params.conn_sup_timeout  = 4000 / 10; // in 10ms unit

  sd_ble_gap_ppcp_set(&gap_conn_params);
  sd_ble_gap_tx_power_set(0);

  unsigned char srData[31];
  unsigned char srDataLen = 0;

  this->_advDataLen = 0;

  // flags
  this->_advData[this->_advDataLen + 0] = 2;
  this->_advData[this->_advDataLen + 1] = 0x01;
  this->_advData[this->_advDataLen + 2] = 0x06;

  this->_advDataLen += 3;

  if (advertisementDataType && advertisementDataLength && advertisementData) {
    this->_advData[this->_advDataLen + 0] = advertisementDataLength + 1;
    this->_advData[this->_advDataLen + 1] = advertisementDataType;
    this->_advDataLen += 2;

    memcpy(&this->_advData[this->_advDataLen], advertisementData, advertisementDataLength);

    this->_advDataLen += advertisementDataLength;
  }

  if (scanDataType && scanDataLength && scanData) {
    srData[0] = scanDataLength + 1;
    srData[1] = scanDataType;
    memcpy(&srData[2], scanData, scanDataLength);

    srDataLen = 2 + scanDataLength;
  }

  sd_ble_gap_adv_data_set(this->_advData, this->_advDataLen, srData, srDataLen);
  sd_ble_gap_appearance_set(0);

  for (int i = 0; i < numLocalAttributes; i++) {
    BLELocalAttribute *localAttribute = localAttributes[i];

    if (localAttribute->type() == BLETypeCharacteristic) {
      this->_numLocalCharacteristics++;
    }
  }

  this->_numLocalCharacteristics -= 3; // 0x2a00, 0x2a01, 0x2a05

  this->_localCharacteristicInfo = (struct localCharacteristicInfo*)malloc(sizeof(struct localCharacteristicInfo) * this->_numLocalCharacteristics);

  unsigned char localCharacteristicIndex = 0;

  uint16_t handle = 0;
  BLEService *lastService = NULL;

  for (int i = 0; i < numLocalAttributes; i++) {
    BLELocalAttribute *localAttribute = localAttributes[i];
    BLEUuid uuid = BLEUuid(localAttribute->uuid());
    const unsigned char* uuidData = uuid.data();
    unsigned char value[255];

    ble_uuid_t nordicUUID;

    if (uuid.length() == 2) {
      nordicUUID.uuid = (uuidData[1] << 8) | uuidData[0];
      nordicUUID.type = BLE_UUID_TYPE_BLE;
    } else {
      unsigned char uuidDataTemp[16];

      memcpy(&uuidDataTemp, uuidData, sizeof(uuidDataTemp));

      nordicUUID.uuid = (uuidData[13] << 8) | uuidData[12];

      uuidDataTemp[13] = 0;
      uuidDataTemp[12] = 0;

      sd_ble_uuid_vs_add((ble_uuid128_t*)&uuidDataTemp, &nordicUUID.type);
    }

    if (localAttribute->type() == BLETypeService) {
      BLEService *service = (BLEService *)localAttribute;

      if (strcmp(service->uuid(), "1800") == 0 || strcmp(service->uuid(), "1801") == 0) {
        continue; // skip
      }

      sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &nordicUUID, &handle);

      lastService = service;
    } else if (localAttribute->type() == BLETypeCharacteristic) {
      BLECharacteristic *characteristic = (BLECharacteristic *)localAttribute;

      if (strcmp(characteristic->uuid(), "2a00") == 0) {
        ble_gap_conn_sec_mode_t secMode;
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&secMode); // no security is needed

        sd_ble_gap_device_name_set(&secMode, characteristic->value(), characteristic->valueLength());
      } else if (strcmp(characteristic->uuid(), "2a01") == 0) {
        const uint16_t *appearance = (const uint16_t*)characteristic->value();

        sd_ble_gap_appearance_set(*appearance);
      } else if (strcmp(characteristic->uuid(), "2a05") == 0) {
        // do nothing
      } else {
        uint8_t properties = characteristic->properties() & 0xfe;
        uint16_t valueLength = characteristic->valueLength();

        this->_localCharacteristicInfo[localCharacteristicIndex].characteristic = characteristic;
        this->_localCharacteristicInfo[localCharacteristicIndex].notifySubscribed = false;
        this->_localCharacteristicInfo[localCharacteristicIndex].indicateSubscribed = false;
        this->_localCharacteristicInfo[localCharacteristicIndex].service = lastService;

        ble_gatts_char_md_t characteristicMetaData;
        ble_gatts_attr_md_t clientCharacteristicConfigurationMetaData;
        ble_gatts_attr_t    characteristicValueAttribute;
        ble_gatts_attr_md_t characteristicValueAttributeMetaData;

        memset(&characteristicMetaData, 0, sizeof(characteristicMetaData));

        memcpy(&characteristicMetaData.char_props, &properties, 1);

        characteristicMetaData.p_char_user_desc  = NULL;
        characteristicMetaData.p_char_pf         = NULL;
        characteristicMetaData.p_user_desc_md    = NULL;
        characteristicMetaData.p_cccd_md         = NULL;
        characteristicMetaData.p_sccd_md         = NULL;

        if (properties & (BLENotify | BLEIndicate)) {
          memset(&clientCharacteristicConfigurationMetaData, 0, sizeof(clientCharacteristicConfigurationMetaData));

          BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationMetaData.read_perm);
          BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationMetaData.write_perm);

          clientCharacteristicConfigurationMetaData.vloc = BLE_GATTS_VLOC_STACK;

          characteristicMetaData.p_cccd_md = &clientCharacteristicConfigurationMetaData;
        }

        memset(&characteristicValueAttributeMetaData, 0, sizeof(characteristicValueAttributeMetaData));

        if (properties & (BLERead | BLENotify | BLEIndicate)) {
          if (this->_bondStore) {
            BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&characteristicValueAttributeMetaData.read_perm);
          } else {
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&characteristicValueAttributeMetaData.read_perm);
          }
        }

        if (properties & (BLEWriteWithoutResponse | BLEWrite)) {
          if (this->_bondStore) {
            BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&characteristicValueAttributeMetaData.write_perm);
          } else {
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(&characteristicValueAttributeMetaData.write_perm);
          }
        }

        characteristicValueAttributeMetaData.vloc       = BLE_GATTS_VLOC_STACK;
        characteristicValueAttributeMetaData.rd_auth    = 0;
        characteristicValueAttributeMetaData.wr_auth    = 0;
        characteristicValueAttributeMetaData.vlen       = !characteristic->fixedLength();

        for (int j = (i + 1); j < numLocalAttributes; j++) {
          localAttribute = localAttributes[j];

          if (localAttribute->type() != BLETypeDescriptor) {
            break;
          }

          BLEDescriptor *descriptor = (BLEDescriptor *)localAttribute;

          if (strcmp(descriptor->uuid(), "2901") == 0) {
            characteristicMetaData.p_char_user_desc        = (uint8_t*)descriptor->value();
            characteristicMetaData.char_user_desc_max_size = descriptor->valueLength();
            characteristicMetaData.char_user_desc_size     = descriptor->valueLength();
          } else if (strcmp(descriptor->uuid(), "2904") == 0) {
            characteristicMetaData.p_char_pf = (ble_gatts_char_pf_t *)descriptor->value();
          }
        }

        memset(&characteristicValueAttribute, 0, sizeof(characteristicValueAttribute));

        characteristicValueAttribute.p_uuid       = &nordicUUID;
        characteristicValueAttribute.p_attr_md    = &characteristicValueAttributeMetaData;
        characteristicValueAttribute.init_len     = valueLength;
        characteristicValueAttribute.init_offs    = 0;
        characteristicValueAttribute.max_len      = characteristic->valueSize();
        characteristicValueAttribute.p_value      = NULL;

        sd_ble_gatts_characteristic_add(BLE_GATT_HANDLE_INVALID, &characteristicMetaData, &characteristicValueAttribute, &this->_localCharacteristicInfo[localCharacteristicIndex].handles);

        if (valueLength) {
          for (int j = 0; j < valueLength; j++) {
            value[j] = (*characteristic)[j];
          }

          sd_ble_gatts_value_set(this->_localCharacteristicInfo[localCharacteristicIndex].handles.value_handle, 0, &valueLength, value);
        }

        localCharacteristicIndex++;
      }
    } else if (localAttribute->type() == BLETypeDescriptor) {
      BLEDescriptor *descriptor = (BLEDescriptor *)localAttribute;

      if (strcmp(descriptor->uuid(), "2901") == 0 ||
          strcmp(descriptor->uuid(), "2902") == 0 ||
          strcmp(descriptor->uuid(), "2903") == 0 ||
          strcmp(descriptor->uuid(), "2904") == 0) {
        continue; // skip
      }

      uint16_t valueLength = descriptor->valueLength();

      ble_gatts_attr_t descriptorAttribute;
      ble_gatts_attr_md_t descriptorMetaData;

      memset(&descriptorAttribute, 0, sizeof(descriptorAttribute));
      memset(&descriptorMetaData, 0, sizeof(descriptorMetaData));

      descriptorMetaData.vloc = BLE_GATTS_VLOC_STACK;
      descriptorMetaData.vlen = (valueLength == descriptor->valueLength()) ? 0 : 1;

      if (this->_bondStore) {
        BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&descriptorMetaData.read_perm);
      } else {
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&descriptorMetaData.read_perm);
      }

      descriptorAttribute.p_uuid    = &nordicUUID;
      descriptorAttribute.p_attr_md = &descriptorMetaData;
      descriptorAttribute.init_len  = valueLength;
      descriptorAttribute.max_len   = descriptor->valueLength();
      descriptorAttribute.p_value   = NULL;

      sd_ble_gatts_descriptor_add(BLE_GATT_HANDLE_INVALID, &descriptorAttribute, &handle);

      if (valueLength) {
        for (int j = 0; j < valueLength; j++) {
          value[j] = (*descriptor)[j];
        }

        sd_ble_gatts_value_set(handle, 0, &valueLength, value);
      }
    }
  }

  if ( numRemoteAttributes > 0) {
    numRemoteAttributes -= 2; // 0x1801, 0x2a05
  }

  for (int i = 0; i < numRemoteAttributes; i++) {
    BLERemoteAttribute *remoteAttribute = remoteAttributes[i];

    if (remoteAttribute->type() == BLETypeService) {
      this->_numRemoteServices++;
    } else if (remoteAttribute->type() == BLETypeCharacteristic) {
      this->_numRemoteCharacteristics++;
    }
  }

  this->_remoteServiceInfo = (struct remoteServiceInfo*)malloc(sizeof(struct remoteServiceInfo) * this->_numRemoteServices);
  this->_remoteCharacteristicInfo = (struct remoteCharacteristicInfo*)malloc(sizeof(struct remoteCharacteristicInfo) * this->_numRemoteCharacteristics);

  BLERemoteService *lastRemoteService = NULL;
  unsigned char remoteServiceIndex = 0;
  unsigned char remoteCharacteristicIndex = 0;

  for (int i = 0; i < numRemoteAttributes; i++) {
    BLERemoteAttribute *remoteAttribute = remoteAttributes[i];
    BLEUuid uuid = BLEUuid(remoteAttribute->uuid());
    const unsigned char* uuidData = uuid.data();

    ble_uuid_t nordicUUID;

    if (uuid.length() == 2) {
      nordicUUID.uuid = (uuidData[1] << 8) | uuidData[0];
      nordicUUID.type = BLE_UUID_TYPE_BLE;
    } else {
      unsigned char uuidDataTemp[16];

      memcpy(&uuidDataTemp, uuidData, sizeof(uuidDataTemp));

      nordicUUID.uuid = (uuidData[13] << 8) | uuidData[12];

      uuidDataTemp[13] = 0;
      uuidDataTemp[12] = 0;

      sd_ble_uuid_vs_add((ble_uuid128_t*)&uuidDataTemp, &nordicUUID.type);
    }

    if (remoteAttribute->type() == BLETypeService) {
      this->_remoteServiceInfo[remoteServiceIndex].service = lastRemoteService = (BLERemoteService *)remoteAttribute;
      this->_remoteServiceInfo[remoteServiceIndex].uuid = nordicUUID;

      memset(&this->_remoteServiceInfo[remoteServiceIndex].handlesRange, 0, sizeof(this->_remoteServiceInfo[remoteServiceIndex].handlesRange));

      remoteServiceIndex++;
    } else if (remoteAttribute->type() == BLETypeCharacteristic) {
      this->_remoteCharacteristicInfo[remoteCharacteristicIndex].characteristic = (BLERemoteCharacteristic *)remoteAttribute;
      this->_remoteCharacteristicInfo[remoteCharacteristicIndex].service = lastRemoteService;
      this->_remoteCharacteristicInfo[remoteCharacteristicIndex].uuid = nordicUUID;

      memset(&this->_remoteCharacteristicInfo[remoteCharacteristicIndex].properties, 0, sizeof(this->_remoteCharacteristicInfo[remoteCharacteristicIndex].properties));
      this->_remoteCharacteristicInfo[remoteCharacteristicIndex].valueHandle = 0;

      remoteCharacteristicIndex++;
    }
  }

  if (this->_bondStore && this->_bondStore->hasData()) {
#ifdef NRF_51822_DEBUG
    Serial.println(F("Restoring bond data"));
#endif
#ifdef NRF51_S130
    this->_bondStore->getData(this->_bondData, 0, sizeof(this->_bondData));
#else
    this->_bondStore->getData(this->_authStatusBuffer, 0, sizeof(this->_authStatusBuffer));
#endif
  }

  this->startAdvertising();

#ifdef __RFduino__
  RFduinoBLE_enabled = 1;
#endif
}
示例#6
0
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Running Speed and Cadence, Battery and Device Information services.
 */
static void services_init(void)
{
    uint32_t        err_code;
    ble_rscs_init_t rscs_init;
    ble_bas_init_t  bas_init;
    ble_dis_init_t  dis_init;

    // Initialize Running Speed and Cadence Service

    memset(&rscs_init, 0, sizeof(rscs_init));

    rscs_init.evt_handler = NULL;
    rscs_init.feature     = BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT |
                            BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT;
    
    rscs_init.initial_rcm.is_inst_stride_len_present = true;
    rscs_init.initial_rcm.is_total_distance_present  = false;
    rscs_init.initial_rcm.is_running                 = false;
    rscs_init.initial_rcm.inst_stride_length         = 0;
    
    // Here the sec level for the Running Speed and Cadence Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_meas_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_feature_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_feature_attr_md.write_perm);

    err_code = ble_rscs_init(&m_rscs, &rscs_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
		
#ifdef BLE_DFU_APP_SUPPORT
    /** @snippet [DFU BLE Service initialization] */
    ble_dfu_init_t   dfus_init;

    // Initialize the Device Firmware Update Service.
    memset(&dfus_init, 0, sizeof(dfus_init));

    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.error_handler = NULL;
    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.revision      = DFU_REVISION;

    err_code = ble_dfu_init(&m_dfus, &dfus_init);
    APP_ERROR_CHECK(err_code);

    dfu_app_reset_prepare_set(reset_prepare);
    dfu_app_dm_appl_instance_set(m_app_handle);
    /** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT		
		
#ifdef BLE_DATA_SYNC_SUPPORT
		ble_data_sync_init_t		data_syncs_init;
		
		memset(&data_syncs_init, 0, sizeof(data_syncs_init));
		
		data_syncs_init.revision = 0X02;
		
		err_code = ble_data_sync_init(&m_data_syncs, &data_syncs_init);
    APP_ERROR_CHECK(err_code);
	  
#endif
}
示例#7
0
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Cycling Speed and Cadence, Battery and Device Information services.
 */
static void services_init(void)
{
    uint32_t        err_code;
    ble_cscs_init_t cscs_init;
    ble_bas_init_t  bas_init;
    ble_dis_init_t  dis_init;
    ble_sensor_location_t sensor_location;

    // Initialize Cycling Speed and Cadence Service.
    memset(&cscs_init, 0, sizeof(cscs_init));

    cscs_init.evt_handler = NULL;
    cscs_init.feature     = BLE_CSCS_FEATURE_WHEEL_REV_BIT | BLE_CSCS_FEATURE_CRANK_REV_BIT | BLE_CSCS_FEATURE_MULTIPLE_SENSORS_BIT;

    // Here the sec level for the Cycling Speed and Cadence Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cscs_init.csc_meas_attr_md.cccd_write_perm);    // for the measurement characteristic, only the CCCD write permission can be set by the application, others are mandated by service specification
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cscs_init.csc_feature_attr_md.read_perm);       // for the feature characteristic, only the read permission can be set by the application, others are mandated by service specification
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cscs_init.csc_ctrlpt_attr_md.write_perm);       // for the SC control point characteristic, only the write permission and CCCD write can be set by the application, others are mandated by service specification
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cscs_init.csc_ctrlpt_attr_md.cccd_write_perm);  // for the SC control point characteristic, only the write permission and CCCD write can be set by the application, others are mandated by service specification

    cscs_init.ctrplt_supported_functions    = BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED
            |BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED
            |BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED;
    cscs_init.ctrlpt_evt_handler            = sc_ctrlpt_event_handler;
    cscs_init.list_supported_locations      = supported_locations;
    cscs_init.size_list_supported_locations = sizeof(supported_locations) / sizeof(ble_sensor_location_t);

    sensor_location           = BLE_SENSOR_LOCATION_FRONT_WHEEL;                    // initializes the sensor location to add the sensor location characteristic.
    cscs_init.sensor_location = &sensor_location;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cscs_init.csc_sensor_loc_attr_md.read_perm);    // for the sensor location characteristic, only the read permission can be set by the application, others are mendated by service specification

    err_code = ble_cscs_init(&m_cscs, &cscs_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
}
//============================================================================//
// This is where we initialize our services and register them with the stack.
//
// The services that we create are:
//
// 1) Custom Service
// 2) Battery Service
// 3) Device Information Service
// 4) DFU Service (if enabled via macro)
static void services_init(void)
{
    uint32_t       err_code;
    ble_bas_init_t bas_init;
    ble_dis_init_t dis_init;

	//--------------------------------------------------------------------------
    // Set up the Custom Service
    err_code = CS_Init(&_cs);
    APP_ERROR_CHECK(err_code);
	//--------------------------------------------------------------------------
    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));
	//--------------------------------------------------------------------------
    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&_bas, &bas_init);
    APP_ERROR_CHECK(err_code);
	//--------------------------------------------------------------------------
    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
	ble_srv_ascii_to_utf8(&dis_init.model_num_str, (char *)MODEL_NUMBER);
	ble_srv_ascii_to_utf8(&dis_init.serial_num_str, (char *)SERIAL_NUMBER);
	ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, (char *)HARDWARE_REVISION);
	ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, (char *)FIRMWARE_REVISION);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);

#ifdef BLE_DFU_APP_SUPPORT
    /** @snippet [DFU BLE Service initialization] */
    ble_dfu_init_t dfus_init;

    // Initialize the Device Firmware Update Service.
    memset(&dfus_init, 0, sizeof(dfus_init));

    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.error_handler = NULL;
    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.revision      = DFU_REVISION;

    err_code = ble_dfu_init(&_dfus, &dfus_init);
    APP_ERROR_CHECK(err_code);

    dfu_app_reset_prepare_set(reset_prepare);
    dfu_app_dm_appl_instance_set(_app_handle);
    /** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT
}
示例#9
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
  PROCESS_BEGIN();

  uint32_t                err_code;

  // Initialize the SoftDevice handler module.
  SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
  // Register with the SoftDevice handler module for BLE events.
  err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
  APP_ERROR_CHECK(err_code);
  // Register with the SoftDevice handler module for BLE events.
  err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
  APP_ERROR_CHECK(err_code);

  ble_gap_conn_sec_mode_t sec_mode;
  char name_buffer[9];
  sprintf(name_buffer, "%08X",(unsigned int) NRF_FICR->DEVICEID[0]);
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
  err_code = sd_ble_gap_device_name_set(&sec_mode,
                                        (const uint8_t *)name_buffer,
                                        strlen(name_buffer));
  APP_ERROR_CHECK(err_code);

  ble_advdata_t advdata;
  uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
  ble_advdata_service_data_t service_data[2];
  uint8_t battery_data = 98;//battery_level_get();
  uint32_t temperature_data = 0xFE001213;
  service_data[0].service_uuid = BLE_UUID_BATTERY_SERVICE;
  service_data[0].data.size    = sizeof(battery_data);
  service_data[0].data.p_data  = &battery_data;
  service_data[1].service_uuid = BLE_UUID_HEALTH_THERMOMETER_SERVICE;
  service_data[1].data.size    = sizeof(temperature_data);
  service_data[1].data.p_data  = (uint8_t *) &temperature_data;
  // Build and set advertising data
  memset(&advdata, 0, sizeof(advdata));
  advdata.name_type            = BLE_ADVDATA_FULL_NAME;
  advdata.include_appearance   = false;
  advdata.flags.size           = sizeof(flags);
  advdata.flags.p_data         = &flags;
  advdata.service_data_count   = 2;
  advdata.p_service_data_array = service_data;
  err_code = ble_advdata_set(&advdata, NULL);
  APP_ERROR_CHECK(err_code);

  ble_gap_adv_params_t adv_params;
  // Start advertising
  memset(&adv_params, 0, sizeof(adv_params));
  adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
  adv_params.p_peer_addr = NULL;
  adv_params.fp          = BLE_GAP_ADV_FP_ANY;
  adv_params.interval    = ADV_INTERVAL;
  adv_params.timeout     = ADV_TIMEOUT_IN_SECONDS;
  err_code = sd_ble_gap_adv_start(&adv_params);
  APP_ERROR_CHECK(err_code);
  leds_off(LEDS_ALL);
  leds_on(LEDS_RED);

  PROCESS_PAUSE();
  etimer_set(&et_hello, CLOCK_SECOND/2);
  rand_val = 0;
  blinks = 0;

  while(1) {
    PROCESS_WAIT_EVENT();

    if(ev == PROCESS_EVENT_TIMER) {
    	sd_rand_application_vector_get(&blinks,1);
      printf("Sensor says #%X\n", (unsigned int) blinks);

      etimer_reset(&et_hello);
    }
  }

  PROCESS_END();
}
示例#10
0
文件: simble.c 项目: m1zol3/nrf51-sdk
void
simble_adv_start(void)
{
        struct ble_gap_advdata advdata = { .length = 0 };

        struct ble_gap_ad_flags flags = {
                .payload_length = 1,
                .type = BLE_GAP_AD_TYPE_FLAGS,
                .flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE,
        };
        simble_add_advdata(&flags, &advdata);

        struct ble_gap_ad_name name;
        uint16_t namelen = sizeof(advdata);
        if (sd_ble_gap_device_name_get(name.name, &namelen) != NRF_SUCCESS)
                namelen = 0;
        name.type =  BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
        name.payload_length = namelen;
        simble_add_advdata(&name, &advdata);

        sd_ble_gap_adv_data_set(advdata.data, advdata.length, NULL, 0);

        ble_gap_adv_params_t adv_params = {
                .type = BLE_GAP_ADV_TYPE_ADV_IND,
                .fp = BLE_GAP_ADV_FP_ANY,
                .interval = 0x400,
        };
        sd_ble_gap_adv_start(&adv_params);
        onboard_led(ONBOARD_LED_ON);
}

static void
simble_srv_tx_init(void)
{
        uint16_t srv_handle;
        ble_uuid_t srv_uuid = {.type = BLE_UUID_TYPE_BLE, .uuid = 0x1804};
        sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                 &srv_uuid,
                                 &srv_handle);

        ble_gatts_char_handles_t chr_handles;
        ble_gatts_char_md_t char_meta = {.char_props = {.read = 1}};
        ble_uuid_t chr_uuid = {.type = BLE_UUID_TYPE_BLE, .uuid = 0x2a07};
        ble_gatts_attr_md_t chr_attr_meta = {
                .vloc = BLE_GATTS_VLOC_STACK,
        };
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&chr_attr_meta.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&chr_attr_meta.write_perm);
        uint8_t tx_val = 0;
        ble_gatts_attr_t chr_attr = {
                .p_uuid = &chr_uuid,
                .p_attr_md = &chr_attr_meta,
                .init_offs = 0,
                .init_len = sizeof(tx_val),
                .max_len = sizeof(tx_val),
                .p_value = &tx_val,
        };
        sd_ble_gatts_characteristic_add(srv_handle,
                                        &char_meta,
                                        &chr_attr,
                                        &chr_handles);
}

/* DM requires a `app_error_handler` */
void __attribute__((weak))
app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
        app_trace_log("[simble]: err: %d, line: %d, file: %s\r\n", error_code, line_num, p_file_name);
        for (;;) {
                /* NOTHING */
        }
}

void
simble_init(const char *name)
{
        app_trace_init();
        sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL); /* XXX assertion handler */

        ble_enable_params_t ble_params = {
#if defined(SD120)
                .gap_enable_params = {
                        .role = BLE_GAP_ROLE_PERIPH,
                },
#endif
                .gatts_enable_params = {
                        .service_changed = 1,
                },
        };
        sd_ble_enable(&ble_params);

        ble_gap_conn_sec_mode_t mode;
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&mode);
        sd_ble_gap_device_name_set(&mode, (const uint8_t *)name, strlen(name));

        // flash storage
        pstorage_init();

        simble_srv_tx_init();
}

uint8_t
simble_get_vendor_uuid_class(void)
{
        ble_uuid128_t vendorid = {{0x13,0xb0,0xa0,0x71,0xfe,0x62,0x4c,0x01,0xaa,0x4d,0xd8,0x03,0,0,0x0b,0xd0}};
        static uint8_t vendor_type = BLE_UUID_TYPE_UNKNOWN;

        if (vendor_type != BLE_UUID_TYPE_UNKNOWN)
                return (vendor_type);

        sd_ble_uuid_vs_add(&vendorid, &vendor_type);
        return (vendor_type);
}

void
simble_srv_register(struct service_desc *s)
{
        s->next = services;
        services = s;

        sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                 &s->uuid,
                                 &s->handle);

        for (int i = 0; i < s->char_count; ++i) {
                struct char_desc *c = &s->chars[i];
                ble_gatts_attr_md_t cccd_md;
                memset(&cccd_md, 0, sizeof(cccd_md));
                BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
                BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
                cccd_md.vloc = BLE_GATTS_VLOC_STACK;
                int have_write = c->write_cb != NULL;
                ble_gatts_char_md_t char_meta = {
                        .char_props = {
                                .broadcast = 0,
                                .read = 1,
                                .write_wo_resp = have_write,
                                .write = have_write,
                                .notify = c->notify,
                                .indicate = c->indicate,
                                .auth_signed_wr = have_write,
                        },
                        .p_char_user_desc = (uint8_t *)c->desc,
                        .char_user_desc_size = strlen(c->desc),
                        .char_user_desc_max_size = strlen(c->desc),
                        .p_char_pf = c->format.format != 0 ? &c->format : NULL,
                        .p_cccd_md = (c->notify || c->indicate) ? &cccd_md : NULL,
                };
                ble_gatts_attr_md_t chr_attr_meta = {
                        .vlen = 1,
                        .vloc = BLE_GATTS_VLOC_STACK,
                        .rd_auth = 1,
                        .wr_auth = 1,
                };
                BLE_GAP_CONN_SEC_MODE_SET_OPEN(&chr_attr_meta.read_perm);
                if (have_write)
                        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&chr_attr_meta.write_perm);
                else
                        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&chr_attr_meta.write_perm);

                ble_gatts_attr_t chr_attr = {
                        .p_uuid = &c->uuid,
                        .p_attr_md = &chr_attr_meta,
                        .init_offs = 0,
                        .init_len = 0,
                        .max_len = c->length,
                };
                sd_ble_gatts_characteristic_add(s->handle,
                                                &char_meta,
                                                &chr_attr,
                                                &c->handles);
        }
}

void
simble_srv_init(struct service_desc *s, uint8_t type, uint16_t id)
{
        *s = (struct service_desc){
                .uuid = {.type = type,
                         .uuid = id},
                .char_count = 0,
        };
};

void
simble_srv_char_add(struct service_desc *s, struct char_desc *c, uint8_t type, uint16_t id, const char *desc, uint16_t length)
{
        *c = (struct char_desc){
                .uuid = {
                        .type = type,
                        .uuid = id
                },
                .desc = desc,
                .length = length,
        };
示例#11
0
文件: main.c 项目: CorBiNO/Atomwear
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Running Speed and Cadence, Battery and Device Information services.
 */
static void services_init(void)
{
    uint32_t        err_code;
	ble_hts_init_t   hts_init;
    ble_rscs_init_t rscs_init;
    ble_bas_init_t  bas_init;
    ble_dis_init_t  dis_init;
	
	// Initialize Health Thermometer Service
    memset(&hts_init, 0, sizeof(hts_init));

    hts_init.evt_handler                 = on_hts_evt;
    hts_init.temp_type_as_characteristic = 0;
    hts_init.temp_type                   = BLE_HTS_TEMP_TYPE_BODY;

    // Here the sec level for the Health Thermometer Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&hts_init.hts_meas_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hts_init.hts_meas_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hts_init.hts_meas_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&hts_init.hts_temp_type_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hts_init.hts_temp_type_attr_md.write_perm);

    err_code = ble_hts_init(&m_hts, &hts_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Running Speed and Cadence Service

    memset(&rscs_init, 0, sizeof(rscs_init));

    rscs_init.evt_handler = NULL;
    rscs_init.feature     = BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT|
								BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT|			//
									BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT;

    // Here the sec level for the Running Speed and Cadence Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_meas_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_feature_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_feature_attr_md.write_perm);

    err_code = ble_rscs_init(&m_rscs, &rscs_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
}
示例#12
0
/**@brief Function for adding TX characteristic.
 *
 * @param[in] p_nus       Nordic UART Service structure.
 * @param[in] p_nus_init  Information needed to initialize the service.
 *
 * @return NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t tx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init)
{
#if(ENABLE_OLD_UUID)
	ble_gatts_char_md_t char_md;
	ble_gatts_attr_t	attr_char_value;
	ble_uuid_t			ble_uuid;
	ble_gatts_attr_md_t attr_md;
  
	uint32_t			err_code;
	//25ccb714-151b-4d8e-b328-38f3fb42dc2e
	ble_uuid128_t	nus_base_uuid = {{0x73,0xa2,0x08,0x47,0x48,0x39,0xe0,0xff,0x3e,0x44,0x02,0xff,0x43,0x42,0x53,0x55}};//0xB714
									 
	memset(&char_md, 0, sizeof(char_md));
	
	char_md.char_props.write			= 1;
	char_md.char_props.write_wo_resp	= 1;
	char_md.p_char_user_desc			= NULL;
	char_md.p_char_pf					= NULL;
	char_md.p_user_desc_md				= NULL;
	char_md.p_cccd_md					= NULL;
	char_md.p_sccd_md					= NULL;
	
	// Add custom base UUID.
	err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &ble_uuid.type);
	if (err_code != NRF_SUCCESS)
	{
		return err_code;
	} 
	
	//ble_uuid.type 					  = p_nus->uuid_type;
	ble_uuid.uuid						= BLE_UUID_NUS_TX_CHARACTERISTIC;
	
	memset(&attr_md, 0, sizeof(attr_md));

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
	
	attr_md.vloc						= BLE_GATTS_VLOC_STACK;
	attr_md.rd_auth 					= 0;
	attr_md.wr_auth 					= 0;
	attr_md.vlen						= 1;
	
	memset(&attr_char_value, 0, sizeof(attr_char_value));

	attr_char_value.p_uuid				= &ble_uuid;
	attr_char_value.p_attr_md			= &attr_md;
	attr_char_value.init_len			= 1;
	attr_char_value.init_offs			= 0;
	attr_char_value.max_len 			= BLE_NUS_MAX_TX_CHAR_LEN;
	
	return sd_ble_gatts_characteristic_add(p_nus->service_handle,
										   &char_md,
										   &attr_char_value,
										   &p_nus->tx_handles);
#else
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.write         = 1;
    char_md.char_props.write_wo_resp = 1;
    char_md.p_char_user_desc         = NULL;
    char_md.p_char_pf                = NULL;
    char_md.p_user_desc_md           = NULL;
    char_md.p_cccd_md                = NULL;
    char_md.p_sccd_md                = NULL;

    ble_uuid.type = p_nus->uuid_type;
    ble_uuid.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC;

    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);

    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen    = 1;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = 1;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = BLE_NUS_MAX_TX_CHAR_LEN;

    return sd_ble_gatts_characteristic_add(p_nus->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_nus->tx_handles);
 #if ((DEBUG_UART_EN) && (ENABLE_BLE_DEBUG))
      DbgPrintf("tx_handles=%x\r\n",p_nus->service_handle);
#endif                                          
#endif
}
示例#13
0
/**@brief Function for adding the accel Level characteristic.
 *
 * @param[in]   p_acc        accel Service structure.
 * @param[in]   p_acc_init   Information needed to initialize the service.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t accel_level_char_add(ble_acc_t * p_acc, const ble_acc_init_t * p_acc_init)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    // ble_gatts_attr_t    attr_char_value_2;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;
    // ble_gatts_attr_md_t attr_md_2;
    ble_gatts_attr_md_t user_desc_md;
    ble_gatts_char_pf_t  accel_pf;
    uint8_t             initial_accel_level;
    uint8_t             encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
    uint8_t             init_len;
    uint8_t             user_desc[] = "ACCEL";

    // Add accel Level characteristic
    if (p_acc->is_notification_supported)
    {
        memset(&cccd_md, 0, sizeof(cccd_md));

        // According to acc_SPEC_V10, the read operation on cccd should be possible without
        // authentication.
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        cccd_md.write_perm = p_acc_init->accel_level_char_attr_md.cccd_write_perm;
        cccd_md.vloc       = BLE_GATTS_VLOC_STACK;
    }

    memset(&user_desc_md, 0, sizeof(user_desc_md));
    
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&user_desc_md.read_perm);
    // BLE_GAP_CONN_SEC_MODE_SET_OPEN(&user_desc_md.write_perm);
    user_desc_md.vloc = BLE_GATTS_VLOC_STACK;

    memset(&accel_pf, 0, sizeof(accel_pf));
    accel_pf.format    = BLE_GATT_CPF_FORMAT_UINT16;
    accel_pf.exponent  = 0;
    accel_pf.unit      = 0x2713; //acceleration data

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.write  = 1;
    char_md.char_props.notify = (p_acc->is_notification_supported) ? 1 : 0;
    char_md.p_char_user_desc  = user_desc;
    char_md.char_user_desc_max_size = 6;
    char_md.char_user_desc_size = 6;
    char_md.p_char_pf         = &accel_pf;
    char_md.p_user_desc_md    = &user_desc_md;
    char_md.p_cccd_md         = (p_acc->is_notification_supported) ? &cccd_md : NULL;
    char_md.p_sccd_md         = NULL;

    //adds the acce id to the softdevice stack, puts a reference to where it is
    //into acc_uuid_type
    ble_uuid.type = p_acc->uuid_type;
    ble_uuid.uuid = BLE_UUID_TYPE_VENDOR_BEGIN;

    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_acc_init->accel_level_char_attr_md.read_perm;
    attr_md.write_perm = p_acc_init->accel_level_char_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    initial_accel_level = p_acc_init->initial_batt_level;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = sizeof(uint16_t);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = sizeof(uint16_t);
    attr_char_value.p_value   = &initial_accel_level;

    err_code = sd_ble_gatts_characteristic_add(p_acc->service_handle, &char_md,
                                               &attr_char_value,
                                               &p_acc->accel_level_handles);

    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    if (p_acc_init->p_report_ref != NULL)
    {
        // Add Report Reference descriptor
        BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);

        memset(&attr_md, 0, sizeof(attr_md));

        attr_md.read_perm = p_acc_init->accel_level_report_read_perm;
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);

        attr_md.vloc    = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth = 0;
        attr_md.wr_auth = 0;
        attr_md.vlen    = 0;
        
        init_len = ble_srv_report_ref_encode(encoded_report_ref, p_acc_init->p_report_ref);
        
        memset(&attr_char_value, 0, sizeof(attr_char_value));

        attr_char_value.p_uuid    = &ble_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = init_len;
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = attr_char_value.init_len;
        attr_char_value.p_value   = encoded_report_ref;

        err_code = sd_ble_gatts_descriptor_add(p_acc->accel_level_handles.value_handle,
                                               &attr_char_value,
                                               &p_acc->report_ref_handle);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    }
    else
    {
        p_acc->report_ref_handle = BLE_GATT_HANDLE_INVALID;
    }

    return NRF_SUCCESS;
}
示例#14
0
文件: main.c 项目: lyncxy119/Sentry
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Running Speed and Cadence, Battery and Device Information services.
 */
static void services_init(void)
{
    uint32_t           err_code;
    ble_rscs_init_t    rscs_init;
    ble_bas_init_t     bas_init;
    ble_dis_init_t     dis_init;


    // Initialize Running Speed and Cadence Service

    memset(&rscs_init, 0, sizeof(rscs_init));

    rscs_init.evt_handler = NULL;
    rscs_init.feature     = BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT |
                            BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT;

    rscs_init.initial_rcm.is_inst_stride_len_present = true;
    rscs_init.initial_rcm.is_total_distance_present  = false;
    rscs_init.initial_rcm.is_running                 = false;
    rscs_init.initial_rcm.inst_stride_length         = 0;

    // Here the sec level for the Running Speed and Cadence Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_meas_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_meas_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&rscs_init.rsc_feature_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&rscs_init.rsc_feature_attr_md.write_perm);

    err_code = ble_rscs_init(&m_rscs, &rscs_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
}
示例#15
0
/**@brief Function for handling Peer Manager events.
 *
 * @param[in] p_evt  Peer Manager event.
 */
static void pm_evt_handler(pm_evt_t const * p_evt)
{
    ret_code_t err_code;

    switch (p_evt->evt_id)
    {
        case PM_EVT_BONDED_PEER_CONNECTED:
        {
            NRF_LOG_INFO("Connected to a previously bonded device.\r\n");
        } break;

        case PM_EVT_CONN_SEC_SUCCEEDED:
        {
            NRF_LOG_INFO("Connection secured. Role: %d. conn_handle: %d, Procedure: %d\r\n",
                         ble_conn_state_role(p_evt->conn_handle),
                         p_evt->conn_handle,
                         p_evt->params.conn_sec_succeeded.procedure);
        } break;

        case PM_EVT_CONN_SEC_FAILED:
        {
            /* Often, when securing fails, it shouldn't be restarted, for security reasons.
             * Other times, it can be restarted directly.
             * Sometimes it can be restarted, but only after changing some Security Parameters.
             * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
             * Sometimes it is impossible, to secure the link, or the peer device does not support it.
             * How to handle this error is highly application dependent. */
        } break;

        case PM_EVT_CONN_SEC_CONFIG_REQ:
        {
            // Reject pairing request from an already bonded peer.
            pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
            pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
        } break;

        case PM_EVT_STORAGE_FULL:
        {
            // Run garbage collection on the flash.
            err_code = fds_gc();
            if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
            {
                // Retry.
            }
            else
            {
                APP_ERROR_CHECK(err_code);
            }
        } break;

        case PM_EVT_PEERS_DELETE_SUCCEEDED:
        {
            err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
            APP_ERROR_CHECK(err_code);
        } break;

        case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
        {
            // The local database has likely changed, send service changed indications.
            pm_local_database_has_changed();
        } break;

        case PM_EVT_PEER_DATA_UPDATE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
        } break;

        case PM_EVT_PEER_DELETE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
        } break;

        case PM_EVT_PEERS_DELETE_FAILED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
        } break;

        case PM_EVT_ERROR_UNEXPECTED:
        {
            // Assert.
            APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
        } break;

        case PM_EVT_CONN_SEC_START:
        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
        case PM_EVT_PEER_DELETE_SUCCEEDED:
        case PM_EVT_LOCAL_DB_CACHE_APPLIED:
        case PM_EVT_SERVICE_CHANGED_IND_SENT:
        case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
        default:
            break;
    }
}


/**@brief Function for the GAP initialization.
 *
 * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
 *          device including the device name, appearance, and the preferred connection parameters.
 */
static void gap_params_init(void)
{
    uint32_t                err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *)DEVICE_NAME,
                                          strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);

    /* YOUR_JOB: Use an appearance value matching the application's use case.
    err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_);
    APP_ERROR_CHECK(err_code); */

    memset(&gap_conn_params, 0, sizeof(gap_conn_params));

    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;

    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Heart Rate, Battery and Device Information services.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_hrs_init_t hrs_init;
    ble_bas_init_t bas_init;
    ble_dis_init_t dis_init;
    uint8_t        body_sensor_location;

    // Initialize Heart Rate Service.
    body_sensor_location = BLE_HRS_BODY_SENSOR_LOCATION_FINGER;

    memset(&hrs_init, 0, sizeof(hrs_init));

    hrs_init.evt_handler                 = NULL;
    hrs_init.is_sensor_contact_supported = true;
    hrs_init.p_body_sensor_location      = &body_sensor_location;

    // Here the sec level for the Heart Rate Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&hrs_init.hrs_hrm_attr_md.cccd_write_perm);
		//***************MODIFIED
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&hrs_init.hrs_hrm_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&hrs_init.hrs_hrm_attr_md.write_perm);
		//*********************
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&hrs_init.hrs_bsl_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&hrs_init.hrs_bsl_attr_md.write_perm);

    err_code = ble_hrs_init(&m_hrs, &hrs_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
    
#ifdef BLE_DFU_APP_SUPPORT    
    /** @snippet [DFU BLE Service initialization] */
    ble_dfu_init_t   dfus_init;

    // Initialize the Device Firmware Update Service.
    memset(&dfus_init, 0, sizeof(dfus_init));

    dfus_init.evt_handler    = dfu_app_on_dfu_evt;
    dfus_init.error_handler  = NULL; //service_error_handler - Not used as only the switch from app to DFU mode is required and not full dfu service.

    err_code = ble_dfu_init(&m_dfus, &dfus_init);
    APP_ERROR_CHECK(err_code);
    
    dfu_app_reset_prepare_set(reset_prepare);
    /** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT    
}
示例#17
0
/*
 *  Function for adding the Temperature characteristic.
 */
static uint32_t temperature_char_add(ble_temp_t * p_temp)
{
    ble_gatts_char_md_t  char_md;
    ble_gatts_attr_md_t  cccd_md;
    ble_gatts_attr_t     attr_char_value;
    ble_uuid_t           ble_uuid;
    ble_gatts_attr_md_t  attr_md;
    ble_gatts_char_pf_t  char_pf;
    ble_gatts_attr_md_t  desc_md;

    static const uint8_t user_desc[] = "Temperature";

    // Setup CCCD attribute
    memset(&cccd_md, 0, sizeof(cccd_md));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;

    memset(&char_pf, 0, sizeof(char_pf));
    char_pf.format = BLE_GATT_CPF_FORMAT_UTF8S;

    // Setup User Description attribute
    memset(&desc_md, 0, sizeof(desc_md));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.read_perm);
    desc_md.vloc = BLE_GATTS_VLOC_STACK;

    // Temp Service Characterstic
    memset(&char_md, 0, sizeof(char_md));
    char_md.char_props.read         = 1;
    char_md.char_props.notify       = 1;
    char_md.p_char_user_desc        = (uint8_t*) &user_desc;
    char_md.char_user_desc_size     = sizeof(user_desc);
    char_md.char_user_desc_max_size = sizeof(user_desc);
    char_md.p_char_pf               = &char_pf;
    char_md.p_user_desc_md          = &desc_md;
    char_md.p_cccd_md               = &cccd_md;
    char_md.p_sccd_md               = NULL;

    ble_uuid.type = p_temp->uuid_type;
    ble_uuid.uuid = TEMP_UUID_TEMPERATURE_CHAR;

    memset(&attr_md, 0, sizeof(attr_md));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));
    attr_char_value.p_uuid       = &ble_uuid;
    attr_char_value.p_attr_md    = &attr_md;
    attr_char_value.init_len     = sizeof(uint16_t);
    attr_char_value.init_offs    = 0;
    attr_char_value.max_len      = sizeof(uint16_t);
    attr_char_value.p_value      = NULL;

    return sd_ble_gatts_characteristic_add(p_temp->service_handle, 
                                           &char_md,
                                           &attr_char_value,
                                           &p_temp->temperature_char_handles);
}
static uint32_t ach_report_char_add(const uint8_t uuid_type)
{
    // Report characteristic
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_md_t attr_md;

    ble_uuid_t          char_uuid;
    ble_gatts_attr_t    attr_char_value;


    // Controlpoint characteristic
    ble_gatts_char_md_t char_ctrlpt_md;
    ble_gatts_attr_md_t cccd_ctrlpt_md;
    ble_gatts_attr_md_t attr_ctrlpt_md;

    ble_uuid_t          char_ctrlpt_uuid;
    ble_gatts_attr_t    attr_char_ctrlpt_value;


    memset(&cccd_md, 0, sizeof(cccd_md));

    cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;

    char_uuid.type = uuid_type;
    char_uuid.uuid = LOCAL_CHAR_UUID;

    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);

    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth = 0;
    attr_md.wr_auth = 0;
    attr_md.vlen    = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));
//lint --e{545}     
    memset(&m_char_value, 0, APP_REPORT_CHAR_LEN);

    attr_char_value.p_uuid    = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = APP_REPORT_CHAR_LEN;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = APP_REPORT_CHAR_LEN;
    attr_char_value.p_value   = m_char_value;

    uint32_t err_code;
    err_code = sd_ble_gatts_characteristic_add(m_service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &m_char_handles);

    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    memset(&cccd_ctrlpt_md, 0, sizeof(cccd_ctrlpt_md));

    cccd_ctrlpt_md.vloc = BLE_GATTS_VLOC_STACK;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_ctrlpt_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_ctrlpt_md.write_perm);

    memset(&char_ctrlpt_md, 0, sizeof(char_ctrlpt_md));

    char_ctrlpt_md.char_props.notify   = 1;
    char_ctrlpt_md.char_props.write    = 1;
    char_ctrlpt_md.p_char_user_desc    = NULL;
    char_ctrlpt_md.p_char_pf           = NULL;
    char_ctrlpt_md.p_user_desc_md      = NULL;
    char_ctrlpt_md.p_cccd_md           = &cccd_ctrlpt_md;
    char_ctrlpt_md.p_sccd_md           = NULL;

    char_ctrlpt_uuid.type = uuid_type;
    char_ctrlpt_uuid.uuid = LOCAL_CHAR_CTRLPT_UUID;

    memset(&attr_ctrlpt_md, 0, sizeof(attr_ctrlpt_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_ctrlpt_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_ctrlpt_md.write_perm);

    attr_ctrlpt_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_ctrlpt_md.rd_auth = 0;
    attr_ctrlpt_md.wr_auth = 1;
    attr_ctrlpt_md.vlen    = 0;

    memset(&attr_char_ctrlpt_value, 0, sizeof(attr_char_ctrlpt_value));
//lint --e{545}     
    memset(&m_char_ctrlpt_value, 0, APP_CTRLPT_CHAR_LEN);

    attr_char_ctrlpt_value.p_uuid    = &char_ctrlpt_uuid;
    attr_char_ctrlpt_value.p_attr_md = &attr_ctrlpt_md;
    attr_char_ctrlpt_value.init_len  = APP_CTRLPT_CHAR_LEN;
    attr_char_ctrlpt_value.init_offs = 0;
    attr_char_ctrlpt_value.max_len   = APP_CTRLPT_CHAR_LEN;
    attr_char_ctrlpt_value.p_value   = m_char_ctrlpt_value;

    err_code = sd_ble_gatts_characteristic_add(m_service_handle,
                                               &char_ctrlpt_md,
                                               &attr_char_ctrlpt_value,
                                               &m_char_ctrlpt_handles);

    return err_code;
}
示例#19
0
文件: main.c 项目: azhn/smartbike
// init services
static void services_init (void) {
    uint32_t err_code;

    // set up service uuid
    ble_uuid_t data_transfer_uuid;
    data_transfer_uuid.uuid = data_transfer_srvc_uuid16;
    err_code = sd_ble_uuid_vs_add(&data_transfer_uuid128, &(data_transfer_uuid.type));
    APP_ERROR_CHECK(err_code);
    app.uuid_type = data_transfer_uuid.type;

    // add the custom service to the system
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
            &data_transfer_uuid, &(app.service_handle));
    APP_ERROR_CHECK(err_code);

    // add test characteristic
    {
        ble_gatts_char_md_t char_md;
        ble_uuid_t          char_uuid;
        ble_gatts_attr_md_t attr_md;
        ble_gatts_attr_t    attr_char_value;
        uint8_t* char_name = (uint8_t*)"Test Characteristic";

        // initial value
        data_transfer.test_char = 0x23;
        //memset(data_transfer.test_char, 0xBA, 500);

        // characteristic settings
        memset(&char_md, 0, sizeof(char_md));
        char_md.char_props.read         = true;
        char_md.char_props.write        = true;
        char_md.p_char_user_desc        = char_name;
        char_md.char_user_desc_max_size = sizeof(char_name);
        char_md.char_user_desc_size     = sizeof(char_name);

        // characteristic uuid
        char_uuid.type = app.uuid_type;
        char_uuid.uuid = test_char_uuid16;

        // attribute metadata
        memset(&attr_md, 0, sizeof(attr_md));
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
        //BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
        attr_md.vloc    = BLE_GATTS_VLOC_USER;
        attr_md.rd_auth = 0;
        attr_md.wr_auth = 0;
        attr_md.vlen    = 1;

        // gatt attributes
        memset(&attr_char_value, 0, sizeof(attr_char_value));
        attr_char_value.p_uuid    = &char_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_offs = 0;
        attr_char_value.init_len  = 1;
        attr_char_value.max_len   = 1;
        attr_char_value.p_value   = (uint8_t*)&data_transfer.test_char;
        //attr_char_value.init_len  = 500;
        //attr_char_value.max_len   = 500;
        //attr_char_value.p_value   = (uint8_t*)data_transfer.test_char;

        err_code = sd_ble_gatts_characteristic_add(app.service_handle,
                &char_md, &attr_char_value, &data_transfer.test_char_handles);
        APP_ERROR_CHECK(err_code);
    }
}
示例#20
0
static uint32_t mesh_md_char_add(mesh_metadata_char_t* metadata) {
	/* cccd for metadata char */
	ble_gatts_attr_md_t cccd_md;

	memset(&cccd_md, 0, sizeof(cccd_md));

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
	cccd_md.vloc = BLE_GATTS_VLOC_STACK;

	/* metadata char */
	ble_gatts_char_md_t ble_char_md;

	memset(&ble_char_md, 0, sizeof(ble_char_md));

	ble_char_md.char_props.read = 1;
	ble_char_md.char_props.notify = 1;

	ble_char_md.p_char_pf = NULL;
	ble_char_md.p_cccd_md = &cccd_md;
	ble_char_md.p_char_user_desc = NULL;
	ble_char_md.p_user_desc_md = NULL;

	/* ATT metadata */
	ble_gatts_attr_md_t ble_attr_md;

	memset(&ble_attr_md, 0, sizeof(ble_attr_md));

	ble_attr_md.read_perm.lv = 1;
	ble_attr_md.read_perm.sm = 1;
	ble_attr_md.write_perm.lv = 1;
	ble_attr_md.write_perm.sm = 1;

	ble_attr_md.rd_auth = 0;
	ble_attr_md.wr_auth = 0;
	ble_attr_md.vlen = 0;
	ble_attr_md.vloc = BLE_GATTS_VLOC_STACK;

	/* ble characteristic UUID */
	ble_uuid_t ble_uuid;

	ble_uuid.type = m_mesh_base_uuid_type;
	ble_uuid.uuid = MESH_MD_CHAR_UUID;

	/* metadata contents */
	uint8_t value_array[MESH_MD_CHAR_LEN];

	memcpy(&value_array[MESH_MD_CHAR_AA_OFFSET], &metadata->mesh_access_addr,
			sizeof(metadata->mesh_access_addr));

	memcpy(&value_array[MESH_MD_CHAR_ADV_INT_OFFSET],
			&metadata->mesh_interval_min_ms,
			sizeof(metadata->mesh_interval_min_ms));

	memcpy(&value_array[MESH_MD_CHAR_CH_OFFSET], &metadata->mesh_channel,
			sizeof(metadata->mesh_channel));

	/* ble attribute */
	ble_gatts_attr_t ble_attr;

	memset(&ble_attr, 0, sizeof(ble_attr));

	ble_attr.init_len = MESH_MD_CHAR_LEN;
	ble_attr.init_offs = 0;
	ble_attr.max_len = MESH_MD_CHAR_LEN;
	ble_attr.p_uuid = &ble_uuid;
	ble_attr.p_value = value_array;
	ble_attr.p_attr_md = &ble_attr_md;

	/* add characteristic */
	uint32_t error_code = sd_ble_gatts_characteristic_add(
			m_mesh_service.service_handle, &ble_char_md, &ble_attr,
			&m_mesh_service.ble_md_char_handles);

	if (error_code != NRF_SUCCESS) {
		return NRF_ERROR_INTERNAL;
	}

	return NRF_SUCCESS;
}
示例#21
0
void GATTController::bleMeshServiceInit()
{
	u32 err = 0;

	meshService.connectionHandle = BLE_CONN_HANDLE_INVALID;

	//##### At first, we register our custom service
	//Add our Service UUID to the BLE stack for management
	ble_uuid128_t baseUUID128 = { MESH_SERVICE_BASE_UUID128 };
	err = sd_ble_uuid_vs_add(&baseUUID128, &meshService.serviceUuid.type);
	APP_ERROR_CHECK(err); //OK

	//Add the service
	err = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &meshService.serviceUuid, &meshService.serviceHandle);
	APP_ERROR_CHECK(err); //OK

	//##### Now we need to add a characteristic to that service

	//BLE GATT Attribute Metadata http://developer.nordicsemi.com/nRF51_SDK/doc/7.1.0/s120/html/a00163.html
	//Read and write permissions, variable length, etc...
	ble_gatts_attr_md_t attributeMetadata;
	memset(&attributeMetadata, 0, sizeof(ble_gatts_attr_md_t));

	//If encryption is enabled, we want our mesh handle only to be accessable over an
	//encrypted connection with authentication
	if(Config->encryptionEnabled){
		BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attributeMetadata.read_perm);
		BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attributeMetadata.write_perm);
	}
	else
	{
		BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attributeMetadata.read_perm);
		BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attributeMetadata.write_perm);
	}

	attributeMetadata.vloc = BLE_GATTS_VLOC_STACK; //We currently have the value on the SoftDevice stack, we might port that to the application space
	attributeMetadata.rd_auth = 0;
	attributeMetadata.wr_auth = 0;
	attributeMetadata.vlen = 1; //Make it a variable length attribute

	//Client Characteristic Configuration Descriptor, whatever....
	ble_gatts_attr_md_t clientCharacteristicConfigurationDescriptor;
	memset(&clientCharacteristicConfigurationDescriptor, 0, sizeof(ble_gatts_attr_md_t));
	clientCharacteristicConfigurationDescriptor.vloc = BLE_GATTS_VLOC_STACK;
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationDescriptor.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationDescriptor.write_perm);

	//Characteristic metadata, whatever....
	ble_gatts_char_md_t characteristicMetadata;
	memset(&characteristicMetadata, 0, sizeof(ble_gatts_char_md_t));
	characteristicMetadata.char_props.read = 1; /*Reading value permitted*/
	characteristicMetadata.char_props.write = 1; /*Writing value with Write Request permitted*/
	characteristicMetadata.char_props.write_wo_resp = 1; /*Writing value with Write Command permitted*/
	characteristicMetadata.char_props.auth_signed_wr = 0; /*Writing value with Signed Write Command not permitted*/
	characteristicMetadata.char_props.notify = 1; /*Notications of value permitted*/
	characteristicMetadata.char_props.indicate = 0; /*Indications of value not permitted*/
	characteristicMetadata.p_cccd_md = &clientCharacteristicConfigurationDescriptor;

	//Set human readable name
	u8 humanReadableCharacteristicDescription[] = "meshWrite";
	characteristicMetadata.p_char_user_desc = humanReadableCharacteristicDescription;
	characteristicMetadata.char_user_desc_max_size = strlen((const char*) humanReadableCharacteristicDescription);
	characteristicMetadata.char_user_desc_size = strlen((const char*) humanReadableCharacteristicDescription);


	//Finally, the attribute
	ble_gatts_attr_t attribute;
	memset(&attribute, 0, sizeof(ble_gatts_attr_t));

	ble_uuid_t attributeUUID;
	attributeUUID.type = meshService.serviceUuid.type;
	attributeUUID.uuid = MESH_SERVICE_CHARACTERISTIC_UUID;

	attribute.p_uuid = &attributeUUID; /* The UUID of the Attribute*/
	attribute.p_attr_md = &attributeMetadata; /* The previously defined attribute Metadata */
	attribute.max_len = MESH_CHARACTERISTIC_MAX_LENGTH;
	attribute.init_len = 0;
	attribute.init_offs = 0;

	//Finally, add the characteristic
	err = sd_ble_gatts_characteristic_add(meshService.serviceHandle, &characteristicMetadata, &attribute, &meshService.sendMessageCharacteristicHandle);
	APP_ERROR_CHECK(err); //OK

}
示例#22
0
static uint32_t mesh_value_char_add(void) {
	/* cccd for value char */
	ble_gatts_attr_md_t cccd_md;

	memset(&cccd_md, 0, sizeof(cccd_md));

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
	cccd_md.vloc = BLE_GATTS_VLOC_STACK;

	/* BLE GATT metadata */
	ble_gatts_char_md_t ble_char_md;

	memset(&ble_char_md, 0, sizeof(ble_char_md));

	ble_char_md.char_props.read = 1;
	ble_char_md.char_props.write_wo_resp = 1;
	ble_char_md.char_props.notify = 1;

	ble_char_md.p_cccd_md = &cccd_md;
	ble_char_md.p_sccd_md = NULL;
	ble_char_md.p_char_user_desc = NULL;
	ble_char_md.p_user_desc_md = NULL;

	/* ATT metadata */

	ble_gatts_attr_md_t ble_attr_md;

	memset(&ble_attr_md, 0, sizeof(ble_attr_md));

	/* No security is required */
	ble_attr_md.read_perm.lv = 1;
	ble_attr_md.read_perm.sm = 1;
	ble_attr_md.write_perm.lv = 1;
	ble_attr_md.write_perm.sm = 1;

	ble_attr_md.vloc = BLE_GATTS_VLOC_STACK;
	ble_attr_md.rd_auth = 0;
	ble_attr_md.wr_auth = 0;
	ble_attr_md.vlen = 1;

	/* ble characteristic UUID */
	ble_uuid_t ble_uuid;

	ble_uuid.type = m_mesh_base_uuid_type;
	ble_uuid.uuid = MESH_VALUE_CHAR_UUID;

	/* ble attribute */
	ble_gatts_attr_t ble_attr;
	uint8_t default_value = 0;

	memset(&ble_attr, 0, sizeof(ble_attr));

	ble_attr.init_len = 1;
	ble_attr.init_offs = 0;
	ble_attr.max_len = sizeof(mesh_gatt_evt_t);
	ble_attr.p_attr_md = &ble_attr_md;
	ble_attr.p_uuid = &ble_uuid;
	ble_attr.p_value = &default_value;

	/* add to service */
	uint32_t error_code = sd_ble_gatts_characteristic_add(
			m_mesh_service.service_handle, &ble_char_md, &ble_attr,
			&m_mesh_service.ble_val_char_handles);

	if (error_code != NRF_SUCCESS) {
		return NRF_ERROR_INTERNAL;
	}

	return NRF_SUCCESS;
}
示例#23
0
/**@brief Function for adding the Battery Level characteristic.
 *
 * @param[in]   p_bas        Battery Service structure.
 * @param[in]   p_bas_init   Information needed to initialize the service.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;
    uint8_t             initial_battery_level;
    uint8_t             encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
    uint8_t             init_len;
    
    // Add Battery Level characteristic
    if (p_bas->is_notification_supported)
    {
        memset(&cccd_md, 0, sizeof(cccd_md));
    
        // According to BAS_SPEC_V10, the read operation on cccd should be possible without
        // authentication.
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        cccd_md.write_perm = p_bas_init->battery_level_char_attr_md.cccd_write_perm;
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    }
    
    memset(&char_md, 0, sizeof(char_md));
    
    char_md.char_props.read   = 1;
    char_md.char_props.notify = (p_bas->is_notification_supported) ? 1 : 0;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = (p_bas->is_notification_supported) ? &cccd_md : NULL;
    char_md.p_sccd_md         = NULL;
    
    BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_LEVEL_CHAR);
    
    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_bas_init->battery_level_char_attr_md.read_perm;
    attr_md.write_perm = p_bas_init->battery_level_char_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;
    
    initial_battery_level = p_bas_init->initial_batt_level;
    
    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid       = &ble_uuid;
    attr_char_value.p_attr_md    = &attr_md;
    attr_char_value.init_len     = sizeof(uint8_t);
    attr_char_value.init_offs    = 0;
    attr_char_value.max_len      = sizeof(uint8_t);
    attr_char_value.p_value      = &initial_battery_level;
    
    err_code = sd_ble_gatts_characteristic_add(p_bas->service_handle, &char_md,
                                               &attr_char_value,
                                               &p_bas->battery_level_handles);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    if (p_bas_init->p_report_ref != NULL)
    {
        // Add Report Reference descriptor
        BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);
        
        memset(&attr_md, 0, sizeof(attr_md));

        attr_md.read_perm = p_bas_init->battery_level_report_read_perm;
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);

        attr_md.vloc       = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth    = 0;
        attr_md.wr_auth    = 0;
        attr_md.vlen       = 0;
        
        init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref);
        
        memset(&attr_char_value, 0, sizeof(attr_char_value));

        attr_char_value.p_uuid       = &ble_uuid;
        attr_char_value.p_attr_md    = &attr_md;
        attr_char_value.init_len     = init_len;
        attr_char_value.init_offs    = 0;
        attr_char_value.max_len      = attr_char_value.init_len;
        attr_char_value.p_value      = encoded_report_ref;
        
        err_code = sd_ble_gatts_descriptor_add(p_bas->battery_level_handles.value_handle,
                                               &attr_char_value,
                                               &p_bas->report_ref_handle);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    }
    else
    {
        p_bas->report_ref_handle = BLE_GATT_HANDLE_INVALID;
    }
    
    return NRF_SUCCESS;
}
示例#24
0
uint32_t characteristic_add(uint16_t                   service_handle,
                            ble_add_char_params_t *    p_char_props,
                            ble_gatts_char_handles_t * p_char_handle)
{
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          char_uuid;
    ble_gatts_attr_md_t attr_md;
    ble_gatts_attr_md_t user_descr_attr_md;
    ble_gatts_attr_md_t cccd_md;

    if (p_char_props->uuid_type == 0)
    {
        char_uuid.type = BLE_UUID_TYPE_BLE;
    }
    else
    {
        char_uuid.type = p_char_props->uuid_type;
    }
    char_uuid.uuid = p_char_props->uuid;

    memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
    set_security_req(p_char_props->read_access, &attr_md.read_perm);
    set_security_req(p_char_props->write_access, & attr_md.write_perm);
    attr_md.rd_auth    = (p_char_props->is_defered_read ? 1 : 0);
    attr_md.wr_auth    = (p_char_props->is_defered_write ? 1 : 0);
    attr_md.vlen       = (p_char_props->is_var_len ? 1 : 0);
    attr_md.vloc       = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);


    memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
    if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
    {

        memset(&cccd_md, 0, sizeof(cccd_md));
        set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);

        cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

        char_md.p_cccd_md  = &cccd_md;
    }
    char_md.char_props = p_char_props->char_props;

    memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
    attr_char_value.p_uuid    = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.max_len   = p_char_props->max_len;
    if (p_char_props->p_init_value != NULL)
    {
        attr_char_value.init_len  = p_char_props->init_len;
        attr_char_value.p_value   = p_char_props->p_init_value;
    }
    if (p_char_props->p_user_descr != NULL)
    {
        memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
        char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
        char_md.char_user_desc_size     = p_char_props->p_user_descr->size;
        char_md.p_char_user_desc        = p_char_props->p_user_descr->p_char_user_desc;

        char_md.p_user_desc_md          = &user_descr_attr_md;

        set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
        set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);

        user_descr_attr_md.rd_auth      = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
        user_descr_attr_md.wr_auth      = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
        user_descr_attr_md.vlen         = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
        user_descr_attr_md.vloc         = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
    }
    if (p_char_props->p_presentation_format != NULL)
    {
        char_md.p_char_pf = p_char_props->p_presentation_format;
    }
    return sd_ble_gatts_characteristic_add(service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           p_char_handle);
}
示例#25
0
error_t custom_add_in_characteristic(uint16_t                  service_handle,
                                     ble_uuid_t               *p_uuid,
                                     uint8_t                   properties,
                                     SecurityManager::SecurityMode_t       requiredSecurity,
                                     uint8_t                  *p_data,
                                     uint16_t                  length,
                                     uint16_t                  max_length,
                                     const uint8_t            *userDescriptionDescriptorValuePtr,
                                     uint16_t                  userDescriptionDescriptorValueLen,
                                     bool                      readAuthorization,
                                     bool                      writeAuthorization,
                                     ble_gatts_char_handles_t *p_char_handle)
{
    /* Characteristic metadata */
    ble_gatts_attr_md_t   cccd_md;
    ble_gatt_char_props_t char_props;

    memcpy(&char_props, &properties, 1);

    if (char_props.notify || char_props.indicate) {
        /* Notification requires cccd */
        memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t));
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    }

    ble_gatts_char_md_t char_md = {0};

    char_md.char_props = char_props;
    char_md.p_cccd_md  =
        (char_props.notify || char_props.indicate) ? &cccd_md : NULL;
    if ((userDescriptionDescriptorValueLen > 0) && (userDescriptionDescriptorValuePtr != NULL)) {
        char_md.p_char_user_desc        = const_cast<uint8_t *>(userDescriptionDescriptorValuePtr);
        char_md.char_user_desc_max_size = userDescriptionDescriptorValueLen;
        char_md.char_user_desc_size     = userDescriptionDescriptorValueLen;
    }

    /* Attribute declaration */
    ble_gatts_attr_md_t attr_md = {0};

    attr_md.rd_auth = readAuthorization;
    attr_md.wr_auth = writeAuthorization;

    attr_md.vloc = BLE_GATTS_VLOC_STACK;
    /* Always set variable size */
    attr_md.vlen = 1;

    if (char_props.read || char_props.notify || char_props.indicate) {
        switch (requiredSecurity) {
            case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
                BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
                break;
            case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
                break;
            case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
                break;
            case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.read_perm);
                break;
            case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.read_perm);
                break;
            default:
                break;
        };
    }

    if (char_props.write || char_props.write_wo_resp) {
        switch (requiredSecurity) {
            case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
                BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
                break;
            case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
                break;
            case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.write_perm);
                break;
            case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.write_perm);
                break;
            case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
                BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.write_perm);
                break;
            default:
                break;
        };
    }

    ble_gatts_attr_t attr_char_value = {0};

    attr_char_value.p_uuid    = p_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = length;
    attr_char_value.max_len   = max_length;
    attr_char_value.p_value   = p_data;

    ASSERT_STATUS ( sd_ble_gatts_characteristic_add(service_handle,
                                                    &char_md,
                                                    &attr_char_value,
                                                    p_char_handle));

    return ERROR_NONE;
}
示例#26
0
/**@brief Function for initializing services that will be used by the application.
 *
 * @details Initialize the Heart Rate, Battery and Device Information services.
 */
static void services_init(void)
{
		uint32_t       err_code;
		
		ble_bas_init_t 	bas_init;
		ble_dis_init_t 	dis_init;
		
		// Initialize Battery Service.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.cccd_write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_char_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&bas_init.battery_level_char_attr_md.write_perm);

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&bas_init.battery_level_report_read_perm);

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    if (err_code == NRF_SUCCESS)
			debug_printf("Battery service initialised!\r\n");
		else
		{
			debug_printf("Error with initialising battery service.\r\n");
			APP_ERROR_CHECK(err_code);
		}

    // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&dis_init.dis_attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&dis_init.dis_attr_md.write_perm);

    err_code = ble_dis_init(&dis_init);
    if (err_code == NRF_SUCCESS)
			debug_printf("Device Information service initialised!\r\n");
		else
		{
			debug_printf("Error with initialising device information service.\r\n");
			APP_ERROR_CHECK(err_code);
		}		
		
		// Initialize CCH custom Service.
		cch_service_init(&m_cch_service);
		
		#ifdef BLE_DFU_APP_SUPPORT
    /** @snippet [DFU BLE Service initialization] */
    ble_dfu_init_t   dfus_init;

    // Initialize the Device Firmware Update Service.
    memset(&dfus_init, 0, sizeof(dfus_init));

    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.error_handler = NULL;
    dfus_init.evt_handler   = dfu_app_on_dfu_evt;
    dfus_init.revision      = DFU_REVISION;

    err_code = ble_dfu_init(&m_dfus, &dfus_init);
    APP_ERROR_CHECK(err_code);

    dfu_app_reset_prepare_set(reset_prepare);
    dfu_app_dm_appl_instance_set(m_app_handle);
    /** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT
}
uint32_t ble_crazyflies_init(uint8_t uuidType)
{
  uint32_t err;
  ble_uuid_t  service_uuid;
  ble_uuid_t  crtp_uuid;
  uint16_t service_handle;
  uint8_t initial_value = 0xFF;
  ble_gatts_attr_md_t cccd_md;

  service_uuid.uuid = UUID_CRAZYFLIE_SERVICE;
  service_uuid.type = uuidType;

  err = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                 &service_uuid,
                                 &service_handle);
  ERROR_CHECK(err);

  /* Bidirectional full-length CRTP characteristic  */
  memset(&cccd_md, 0, sizeof(cccd_md));

  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
  cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

  crtp_md.p_cccd_md  = &cccd_md;


  crtp_uuid.type = uuidType;
  crtp_uuid.uuid = UUID_CRAZYFLIE_CRTP;

  crtp_attr.p_uuid = &crtp_uuid;
  crtp_attr.p_value = &initial_value;
  crtp_attr.init_len = 1;

  err = sd_ble_gatts_characteristic_add(service_handle,
                                        &crtp_md,
                                        &crtp_attr,
                                        &crtp_handle);

  ERROR_CHECK(err);
  /* Uplink (nrf receives) segmented CRTP characteristic */
  memset(&cccd_md, 0, sizeof(cccd_md));

  //BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  //BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
  //cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

  crtp_md.p_cccd_md  = NULL; //&cccd_md;


  crtp_uuid.type = uuidType;
  crtp_uuid.uuid = UUID_CRAZYFLIE_CRTP_UP;

  crtpupdown_attr.p_uuid = &crtp_uuid;
  crtpupdown_attr.p_value = &initial_value;
  crtpupdown_attr.init_len = 1;

  err = sd_ble_gatts_characteristic_add(service_handle,
                                        &crtpup_md,
                                        &crtpupdown_attr,
                                        &crtpup_handle);

  ERROR_CHECK(err);
  /* Downlink (nrf Sends) segmented CRTP characteristic */
  memset(&cccd_md, 0, sizeof(cccd_md));

  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
  cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

  crtpdown_md.p_cccd_md  = &cccd_md;


  crtp_uuid.type = uuidType;
  crtp_uuid.uuid = UUID_CRAZYFLIE_CRTP_DOWN;

  crtpupdown_attr.p_uuid = &crtp_uuid;
  crtpupdown_attr.p_value = &initial_value;
  crtpupdown_attr.init_len = 1;

  err = sd_ble_gatts_characteristic_add(service_handle,
                                        &crtpdown_md,
                                        &crtpupdown_attr,
                                        &crtpdown_handle);

  ERROR_CHECK(err);

  return NRF_SUCCESS;
}
示例#28
0
uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t            * p_sc_ctrlpt,
                            const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init)
{
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;

    p_sc_ctrlpt->conn_handle      = BLE_CONN_HANDLE_INVALID;
    p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;

    p_sc_ctrlpt->size_list_supported_locations = p_sc_ctrlpt_init->size_list_supported_locations;

    if ((p_sc_ctrlpt_init->size_list_supported_locations != 0) &&
        (p_sc_ctrlpt_init->list_supported_locations != NULL))
    {
        memcpy(p_sc_ctrlpt->list_supported_locations,
               p_sc_ctrlpt_init->list_supported_locations,
               p_sc_ctrlpt->size_list_supported_locations * sizeof(ble_sensor_location_t));
    }

    p_sc_ctrlpt->service_handle         = p_sc_ctrlpt_init->service_handle;
    p_sc_ctrlpt->evt_handler            = p_sc_ctrlpt_init->evt_handler;
    p_sc_ctrlpt->supported_functions    = p_sc_ctrlpt_init->supported_functions;
    p_sc_ctrlpt->sensor_location_handle = p_sc_ctrlpt_init->sensor_location_handle;
    p_sc_ctrlpt->error_handler          = p_sc_ctrlpt_init->error_handler;

    memset(&cccd_md, 0, sizeof(cccd_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    cccd_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.cccd_write_perm;
    cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.indicate = 1;
    char_md.char_props.write    = 1;
    char_md.p_char_user_desc    = NULL;
    char_md.p_char_pf           = NULL;
    char_md.p_user_desc_md      = NULL;
    char_md.p_cccd_md           = &cccd_md;
    char_md.p_sccd_md           = NULL;

    BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SC_CTRLPT_CHAR);

    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
    attr_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 1;
    attr_md.vlen       = 1;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = 0;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = BLE_SC_CTRLPT_MAX_LEN;
    attr_char_value.p_value   = 0;

    return sd_ble_gatts_characteristic_add(p_sc_ctrlpt->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_sc_ctrlpt->sc_ctrlpt_handles);
}
示例#29
0
static uint32_t addCharPHYSEN(ble_pss_t * p_pss, const ble_pss_init_t * p_pss_init)
{   /// add phy sensor characteristics
    ble_gatts_char_md_t char_md;
    ble_gatts_char_md_t char_md_w;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_gatts_attr_t    attr_char_value_w;
    ble_uuid_t          ble_uuid;
    ble_uuid_t          ble_uuid_w;
    ble_gatts_attr_md_t attr_md;
    ble_gatts_attr_md_t attr_md_w;
    char user_desc[] = "Physics sensor";

    memset(&cccd_md, 0, sizeof(cccd_md));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;
    char_md.p_char_user_desc  = (uint8_t *) user_desc;
    char_md.char_user_desc_size = strlen(user_desc);
    char_md.char_user_desc_max_size = strlen(user_desc);

    memset(&char_md_w, 0, sizeof(char_md_w));

    char_md_w.char_props.write  = 1;
    char_md_w.p_char_user_desc  = NULL;
    char_md_w.p_char_pf         = NULL;
    char_md_w.p_user_desc_md    = NULL;
    char_md_w.p_cccd_md         = &cccd_md;
    char_md_w.p_sccd_md         = NULL;
    char_md_w.p_char_user_desc  = (uint8_t *) user_desc;
    char_md_w.char_user_desc_size = strlen(user_desc);
    char_md_w.char_user_desc_max_size = strlen(user_desc);


    ble_uuid.type = p_pss->uuid_type;
    ble_uuid.uuid = PHY_SENSOR_DATA_CHAR;

    ble_uuid_w.type = p_pss->uuid_type;
    ble_uuid_w.uuid = PHY_SENSOR_WRITE_CHAR;

    memset(&attr_md, 0, sizeof(attr_md));

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    memset(&attr_md_w, 0, sizeof(attr_md_w));

    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md_w.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md_w.write_perm);
    attr_md_w.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md_w.rd_auth    = 0;
    attr_md_w.wr_auth    = 0;
    attr_md_w.vlen       = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid       = &ble_uuid;
    attr_char_value.p_attr_md    = &attr_md;
    attr_char_value.init_len     = (SENSOR_ROW_SIZE);
    attr_char_value.init_offs    = 0;
    attr_char_value.max_len      = (SENSOR_ROW_SIZE);
    attr_char_value.p_value      = NULL;

    memset(&attr_char_value_w, 0, sizeof(attr_char_value_w));

    attr_char_value_w.p_uuid       = &ble_uuid_w;
    attr_char_value_w.p_attr_md    = &attr_md_w;
    attr_char_value_w.init_len     = (SENSOR_ROW_SIZE);
    attr_char_value_w.init_offs    = 0;
    attr_char_value_w.max_len      = (SENSOR_ROW_SIZE);
    attr_char_value_w.p_value      = NULL;

    sd_ble_gatts_characteristic_add(p_pss->service_handle, &char_md,
                                    &attr_char_value,
                                    &p_pss->phy_sen_level_handles);
    return sd_ble_gatts_characteristic_add(p_pss->service_handle_w, &char_md_w,
                                           &attr_char_value_w,
                                           &p_pss->phy_sen_level_handles_w) ;
}
示例#30
0
static uint32_t ble_stack_init(bool init_softdevice)
{
    uint32_t         err_code;
    nrf_clock_lf_cfg_t clock_lf_cfg = {
            .source        = NRF_CLOCK_LF_SRC_RC,
            .rc_ctiv       = 16, // recommended for nRF52
            .rc_temp_ctiv  = 2,  // recommended for nRF52
            .xtal_accuracy = 0};

    if (init_softdevice)
    {
        err_code = nrf_dfu_mbr_init_sd();
        VERIFY_SUCCESS(err_code);
    }

    NRF_LOG_INFO("vector table: 0x%08x\r\n", BOOTLOADER_START_ADDR);
    err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR);
    VERIFY_SUCCESS(err_code);

    SOFTDEVICE_HANDLER_APPSH_INIT(&clock_lf_cfg, true);

    ble_enable_params_t ble_enable_params;
    // Only one connection as a central is used when performing dfu.
    err_code = softdevice_enable_get_default_config(1, 1, &ble_enable_params);
    VERIFY_SUCCESS(err_code);

#if (NRF_SD_BLE_API_VERSION == 3)
    ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;
#endif    
    
    // Enable BLE stack.
    err_code = softdevice_enable(&ble_enable_params);
    return err_code;
}


/**@brief       Function for adding DFU Packet characteristic to the BLE Stack.
 *
 * @param[in]   p_dfu DFU Service structure.
 *
 * @return      NRF_SUCCESS on success. Otherwise an error code.
 */
static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
{
    ble_gatts_char_md_t char_md             = {{0}};
    ble_gatts_attr_t    attr_char_value     = {0};
    ble_gatts_attr_md_t attr_md             = {{0}};
    ble_uuid_t          char_uuid;

    char_md.char_props.write_wo_resp = 1;

    char_uuid.type = p_dfu->uuid_type;
    char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;

    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);

    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
    attr_md.vlen    = 1;

    attr_char_value.p_uuid    = &char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.max_len   = MAX_DFU_PKT_LEN;
    attr_char_value.p_value   = NULL;

    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
                                           &char_md,
                                           &attr_char_value,
                                           &p_dfu->dfu_pkt_handles);
}