I am able to find iBeacon using BLE Mini and
. The process is first send Device Discovery HCI copmmand, wait for the GAP_DeviceInformation. The device information contains iBeacon UUID, Major, Minor and Measured Power. Following Arduino code prints the details. I am working on a
sample, will publish later, may be this weekend.
#include <stdarg.h>
#define GAP_PROFILE_CENTRAL 0x08
#define KEYLEN 16
#define B_ADDR_LEN 6
#define BUILD_UINT16(loByte, hiByte) \
((uint16_t)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))
static uint8_t gapCentralRoleTaskId = 0;
static uint8_t gapCentralRoleIRK[KEYLEN] = {0};
static uint8_t gapCentralRoleSRK[KEYLEN] = {0};
static uint32_t gapCentralRoleSignCounter = 1;
static uint8_t gapCentralRoleBdAddr[B_ADDR_LEN];
static uint8_t gapCentralRoleMaxScanRes = 5;
void p(char *fmt, ... ){
char tmp[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(tmp, 128, fmt, args);
va_end (args);
Serial.print(tmp);
}
void setup(){
Serial.begin(57600);
hci_init();
}
void loop(){
if(Serial.available()){
ble_event_process();
}
}
byte ble_event_process(){
uint8_t type, event_code, data_len, status1;
uint16_t event;
uint8_t buf[64];
type = Serial.read();
delay(100);
event_code = Serial.read();
data_len = Serial.read();
for (int i = 0; i < data_len; i++)
buf[i] = Serial.read();
event = BUILD_UINT16(buf[0], buf[1]);
status1 = buf[2];
switch(event){
case 0x600:{
hci_start_discovery();
break;
}
case 0x060D:{
int rssi = buf[11] - 255;
p("\r\n");
p("RSSI: %d, %d\r\n", buf[11], rssi);
p("iBeacon UUID: ");
for(int i=22; i<38; i++){
if(i<37)
p("%02X:", buf[i]);
else
p("%02X", buf[i]);
}
p("\r\n");
p("iBeaconMajor: %d\r\n", BUILD_UINT16(buf[39], buf[38]));
p("Minor: %d\r\n", BUILD_UINT16(buf[41], buf[40]));
p("Measured Power: %X", buf[42]);
p("\r\n");
break;
}
case 0x601:{
hci_start_discovery();
break;
}
}
}
int hci_init(){
return GAP_DeviceInit( gapCentralRoleTaskId, GAP_PROFILE_CENTRAL,
gapCentralRoleMaxScanRes, gapCentralRoleIRK,
gapCentralRoleSRK, &gapCentralRoleSignCounter );
}
int hci_start_discovery(){
return GAP_DeviceDiscoveryRequest();
}
int GAP_DeviceInit( uint8_t taskID, uint8_t profileRole, uint8_t maxScanResponses, uint8_t *pIRK, uint8_t *pSRK, uint32_t *pSignCounter )
{
uint8_t buf[42];
uint8_t len = 0;
buf[len++] = 0x01; // -Type : 0x01 (Command)
buf[len++] = 0x00; // -Opcode : 0xFE00 (GAP_DeviceInit)
buf[len++] = 0xFE;
buf[len++] = 0x26; // -Data Length
buf[len++] = profileRole; // Profile Role
buf[len++] = maxScanResponses; // MaxScanRsps
memcpy(&buf[len], pIRK, 16); // IRK
len += 16;
memcpy(&buf[len], pSRK, 16); // SRK
len += 16;
memcpy(&buf[len], pSignCounter, 4); // SignCounter
len += 4;
Serial.write(buf, len);
return 1;
}
int GAP_DeviceDiscoveryRequest()
{
uint8_t buf[20];
uint8_t len = 0;
buf[len++] = 0x01; // -Type : 0x01 (Command)
buf[len++] = 0x04; // -Opcode : 0xFE04 (GAP_DeviceDiscoveryRequest)
buf[len++] = 0xFE;
buf[len++] = 0x03; // -Data Length
buf[len++] = 0x03; // Mode
buf[len++] = 0x01; // ActiveScan
buf[len++] = 0x00; // WhiteList
Serial.write(buf, len);
return 1;
}
void readChar(int len){
int i=0;
while(i<len){
char ch = Serial.read();
++i;
}
}