Skip to content

Bluefruit.Security.setIOCaps(false, true, false); I would like to inquire regarding this. #815

Open
@gujakoo

Description

@gujakoo

Operating System

Windows 10

IDE version

arduino 2.3.2

Board

adafruit feather nrf52832

BSP version

1.6.0

Sketch

#include <bluefruit.h>
#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>
using namespace Adafruit_LittleFS_Namespace;
#define KEY_FILE_PATH "/pairing_info.txt"

#define MAX_REMEMBERED_DEVICES 10

struct pairing {
  uint8_t connect;
  ble_gap_addr_t addr[MAX_REMEMBERED_DEVICES];
  uint8_t numDevices;
};

pairing pairingInfo;

File settingsFile(InternalFS);

#include <Adafruit_TinyUSB.h>

// Use built-in buttons if available, else use A0, A1

#define BUTTON_YES 3
#define BUTTON_NO 4


// Circuit Play Bluefruit has button active state = high
uint32_t const button_active_state = LOW;


// BLE Service
BLEUart bleuart;  // uart over ble

// Array to store addresses of the last connected smartphones
ble_gap_addr_t lastConnectedAddr[MAX_REMEMBERED_DEVICES];

void setup() {
  // Other setup routines remain the same
  Serial.begin(115200);
  Serial.println("Bluefruit52 Pairing Display Example");
  Serial.println("-----------------------------------\n");

  // pull high for active low, or pull low for active high

  pinMode(BUTTON_YES, INPUT_PULLDOWN);
  pinMode(BUTTON_NO, INPUT_PULLDOWN);


  // Setup the BLE LED to be enabled on CONNECT
  // Note: This is actually the default behavior, but provided
  // here in case you want to control this LED manually via PIN 19
  Bluefruit.autoConnLed(true);

  // Config the peripheral connection with maximum bandwidth
  // more SRAM required by SoftDevice
  // Note: All config***() function must be called before begin()
  Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);

  Bluefruit.begin();
  Bluefruit.setTxPower(4);  // Check bluefruit.h for supported values

  Bluefruit.Security.setIOCaps(false, true, false);  // display = true, yes/no = true, keyboard = false
  Bluefruit.Security.setPairPasskeyCallback(pairing_passkey_callback);
  Bluefruit.Security.setPairCompleteCallback(pairing_complete_callback);
  Bluefruit.Security.setSecuredCallback(connection_secured_callback);

  Bluefruit.Periph.setConnectCallback(connect_callback);
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  bleuart.setPermission(SECMODE_ENC_NO_MITM, SECMODE_ENC_NO_MITM);
  bleuart.begin();

  Serial.println("Please use Adafruit's Bluefruit LE app to connect in UART mode");
  Serial.println("Your phone should pop-up PIN input");
  Serial.println("Once connected, enter character(s) that you wish to send");

  startAdv();

  InternalFS.begin();
  if (digitalRead(BUTTON_NO) == HIGH) {
    Serial.print("Formating ... ");
    delay(1);  // for message appear on monitor

    // Format
    InternalFS.format();

    Serial.println("Done");
    delay(10);
  }
  loadPairing();
}

bool loadPairing() {
  Serial.println("loadPairing");
  settingsFile = InternalFS.open(KEY_FILE_PATH, FILE_O_READ);
  if (!settingsFile) {
    Serial.println("Settings file not found.");
    return false;
  }

  if (settingsFile.read((uint8_t *)&pairingInfo, sizeof(pairingInfo)) != sizeof(pairingInfo)) {
    Serial.println("Error reading settings.");
    settingsFile.close();
    return false;
  }

  settingsFile.close();
  // 읽은 내용 출력
  Serial.println("Loaded pairing information:");
  Serial.print("connect: ");
  Serial.println(pairingInfo.connect);
  Serial.print("Number of devices: ");
  Serial.println(pairingInfo.numDevices);
  for (int i = 0; i < pairingInfo.numDevices; ++i) {
    Serial.print("Device ");
    Serial.print(i + 1);
    Serial.print(": ");
    for (int j = 0; j < sizeof(ble_gap_addr_t); ++j) {
      Serial.print(pairingInfo.addr[i].addr[j], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  return true;
}

void savePairing() {
  Serial.println("savePairing");
  settingsFile = InternalFS.open(KEY_FILE_PATH, FILE_O_WRITE);
  if (!settingsFile) {
    Serial.println("Failed to open settings file for writing.");
    return;
  }

  if (settingsFile.write((uint8_t *)&pairingInfo, sizeof(pairingInfo)) != sizeof(pairingInfo)) {
    Serial.println("Error writing settings.");
    settingsFile.close();
    return;
  }

  settingsFile.close();
  Serial.println("Settings saved successfully.");
}

// Other callback functions remain the same

void startAdv(void) {
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addService(bleuart);
  Bluefruit.ScanResponse.addName();
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);
  Bluefruit.Advertising.setFastTimeout(30);
  Bluefruit.Advertising.start(0);
}

void loop() {

  if (Serial.available() > 0) {
    delay(2);
    uint8_t buf[64];
    int count = Serial.readBytes(buf, sizeof(buf));
    bleuart.write(buf, count);
  }

  if (Bluefruit.connected() && bleuart.notifyEnabled() && bleuart.available() > 0) {
    uint8_t ch;
    ch = (uint8_t)bleuart.read();
    Serial.write(ch);
  }
}

void connect_callback(uint16_t conn_handle) {
  BLEConnection *connection = Bluefruit.Connection(conn_handle);

  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));

  Serial.print("Connected to ");
  Serial.println(central_name);

  Serial.println("Please select the 'Neopixels' tab, click 'Connect' and have fun");

  
}

bool pairing_passkey_callback(uint16_t conn_handle, uint8_t const passkey[6], bool match_request) {
  Serial.println("Pairing Passkey");
  Serial.printf("    %.3s %.3s\n", passkey, passkey + 3);

  bool accept_pairing = false;

  Serial.println("Do you want to pair?");
  Serial.printf("Press button <%u> to Accept, button <%u> to Decline\n", BUTTON_YES, BUTTON_NO);

  uint32_t start_time = millis();
  while (millis() < start_time + 30000) {
    if (digitalRead(BUTTON_YES) == HIGH) {
      accept_pairing = true;
      break;
    }

    if (digitalRead(BUTTON_NO) == HIGH) {
      accept_pairing = false;
      break;
    }

    if (!Bluefruit.connected(conn_handle)) break;
  }

  if (accept_pairing) {
    Serial.println("Accepted");
  } else {
    Serial.println("Declined");
  }

  return accept_pairing;
}

void pairing_complete_callback(uint16_t conn_handle, uint8_t auth_status) {
  if (auth_status == BLE_GAP_SEC_STATUS_SUCCESS) {
    Serial.println("Succeeded");
  } else {
    Serial.println("Failed");
  }
}

void connection_secured_callback(uint16_t conn_handle) {
  Serial.println("Secured");

  BLEConnection *connection = Bluefruit.Connection(conn_handle);
  ble_gap_addr_t peer_addr = connection->getPeerAddr();

  // 연결된 스마트폰 주소를 기존에 저장된 주소와 비교하여 페어링 여부를 결정합니다.
  bool is_paired = false;
  for (int i = 0; i < pairingInfo.numDevices; ++i) {
    if (memcmp(&peer_addr, &pairingInfo.addr[i], sizeof(ble_gap_addr_t)) == 0) {
      Serial.println("Connected to a previously paired smartphone. Skipping pairing.");
      is_paired = true;
      break;
    }
  }
  // 페어링 되지 않은 스마트폰과의 연결이라면 페어링을 시작합니다.
  if (!is_paired) {
    // 페어링을 시작하기 전에 lastConnectedAddr 배열에 주소를 추가하고, 필요한 경우 페어링 정보를 저장합니다.
    if (pairingInfo.numDevices < MAX_REMEMBERED_DEVICES) {
      memcpy(&pairingInfo.addr[pairingInfo.numDevices], &peer_addr, sizeof(ble_gap_addr_t));
      pairingInfo.numDevices++;
      savePairing();
    }


    Serial.println("Connected to a new device. Initiating pairing...");
  }
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
  (void)conn_handle;
  (void)reason;

  Serial.println();
  Serial.print("Disconnected, reason = 0x");
  Serial.println(reason, HEX);
}

What happened ?

Bluefruit.Security.setIOCaps(false, true, false); // display = true, yes/no = true, keyboard = false

In this code setup, the button that pairs with the physical button is known as the button.

However, a button appears in the application and is registered immediately upon registration.

When attempting to connect, I would like to pair and connect using a physical button.

When pairing, both display mode and keyboard mode work well.

It's not just the button part.

It's not just the button part. Is this a bug? Or am I doing something wrong?

Thank you for your great advice.

How to reproduce ?

Just upload the code and connect via Bluetooth using the Bluefruit_LE_Connect_Android_V2-master app.

Debug Log

No response

Screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions