Question

I am trying to create a custom BLE advertisement and scan response. The advertisement is an iBeacon. I also want it to broadcast the availability of a service. I cannot put the service uuid in the advertisment data because it would be too long (from my understanding, Bluegiga's BGScript only allows 32 octets in the advertisment data). I put the service uuid in the scan response, hoping that that would allow a mobile device to see the service in order to search for and connect to the device. For some reason, I cannot get it to work. iOS is no longer picking up the BLE device up as an iBeacon, and doesn't recognize that the service is available. What AD type would I use for the service uuid, and how would I format that data (including the service uuid)?

Here is what I have so far:

Advertisement data

02 01 06 // flags
1a ff 4c 00 02 15 // manufacturer data, apple company id, iBeacon preamble
aa aa aa aa - aa aa - aa aa - aa aa - aa aa aa aa aa aa // iBeacon UUID
00 01 00 01 // iBeacon major, minor
c6 // measured tx power

Scan response data

11 // length
16 // ad type (I am not sure what this should be)
a5 b7 67 a0 - 74 9b - 11 e3 - 98 1f - 08 00 20 0c 9a 66 // service UUID

For better context, here is the section from the BGScript for the BLE112:

event system_boot( major, minor, patch, build, ll_version, protocol_version, hw )

    call gap_set_adv_parameters( 20, 100, 7 )

    call gap_set_mode( gap_general_discoverable, gap_undirected_connectable )

    # Flags
    data( 0:1) = $02
    data( 1:1) = $01
    data( 2:1) = $06

    # Manufacturer data
    data( 3:1) = $1a
    data( 4:1) = $ff

    # Preamble
    data( 5:1) = $4c
    data( 6:1) = $00
    data( 7:1) = $02
    data( 8:1) = $15

    # UUID
    data( 9:1) = $aa
    data(10:1) = $aa
    data(11:1) = $aa
    data(12:1) = $aa
    data(13:1) = $aa
    data(14:1) = $aa
    data(15:1) = $aa
    data(16:1) = $aa
    data(17:1) = $aa
    data(18:1) = $aa
    data(19:1) = $aa
    data(20:1) = $aa
    data(21:1) = $aa
    data(22:1) = $aa
    data(23:1) = $aa
    data(24:1) = $aa

    # Major
    data(25:1) = $00
    data(26:1) = $01

    # Minor
    data(27:1) = $00
    data(28:1) = $01

    # Measured power (specified in 2's complement, so 0xC6 is -58)
    data(29:1) = $c6

    # Scan Response Data
    sr_data( 0:1) = $11
    sr_data( 1:1) = $21

    # Service Uuid
    sr_data( 2:1) = $a5
    sr_data( 3:1) = $b7
    sr_data( 4:1) = $67
    sr_data( 5:1) = $a0
    sr_data( 6:1) = $74
    sr_data( 7:1) = $9b
    sr_data( 8:1) = $11
    sr_data( 9:1) = $e3
    sr_data(10:1) = $98
    sr_data(11:1) = $1f
    sr_data(12:1) = $08
    sr_data(13:1) = $00
    sr_data(14:1) = $20
    sr_data(15:1) = $0c
    sr_data(16:1) = $9a
    sr_data(17:1) = $66

    # Set advertisement data
    call gap_set_adv_data(0, 30, data(0:30))
    call gap_set_adv_data(1, 18, sr_data(0:18))

    #set bondable mode
    call sm_set_bondable_mode(1)

end
Was it helpful?

Solution

I was able to get the service uuid to broadcast in the scan response packet. It works fine with both CLLocationManager (iBeacon) and CBCentralManager (BLE) simultaneously. I think there were a few other changes elsewhere that made it work, but I am not sure where they were. I used the "Incomplete List of 128-bit Service Class UUIDs" AD type (0x06) and I figured out that I had the endianness of the uuid backward.

Here is the scan response data I used:

    # Scan Response Data
    sr_data( 0:1) = $11
    sr_data( 1:1) = $06

    # Service Uuid
    sr_data( 2:1) = $66
    sr_data( 3:1) = $9a
    sr_data( 4:1) = $0c
    sr_data( 5:1) = $20
    sr_data( 6:1) = $00
    sr_data( 7:1) = $08
    sr_data( 8:1) = $1f
    sr_data( 9:1) = $98
    sr_data(10:1) = $e3
    sr_data(11:1) = $11
    sr_data(12:1) = $9b
    sr_data(13:1) = $74
    sr_data(14:1) = $a0
    sr_data(15:1) = $67
    sr_data(16:1) = $b7
    sr_data(17:1) = $a5

OTHER TIPS

Why do you need the service UUID at all? You should be able to just connect to the iBeacon after scanning for it using CoreBluetooth.

See here for an example. This example is designed to prove that it is impossible to read the iBeacon identifiers using CoreBluetooth. But it also shows that CoreBluetooth APIs let you can connect to an iBeacon after you scan for it, even if you can't read its identifiers.

It is also possible to use CoreBluetooth to query the beacon for services after this connection is made.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top