Trying to Connect to BLE Device for Bonding/ANCS

Posted on
  • I'm working on implementing ANCS (Apple Notification Service) on the Puck so that when my iPhone gets an alert its sent over BLE to the puck. I've had some success using the nRF toolbox on my Android phone to connect to the iPhone and I can see alerts coming over. Therefore I know the iPhone side is working.

    However I can't seem to implement it on the puck, from what I can tell I first need to bond the Puck to the iPhone and then I can connect to the ANCS service and subscribe to the Notification Service.
    However the puck doesn't seem to be able to initiate a connection to the iPhone let alone get as far as bonding, I've tried both discovering the device and then connecting as well as responding to an incomming connection, both of which the NRF.connect fails with a connection timeout.
    I'm using a serial console now so that the pucks BLE device is free to connect to the iPhone and I can debug on the console, code is below,

    var devices;
    var ios;
    
    //Discover BLE Devices
    NRF.findDevices(function(d) {
      devices = d;
      console.log(devices);
    }, 5000);
        
    
    // Find one with the ANCS Service
    for (var i = 0; i < devices.length; i++) {
        if (devices[i].services.indexOf("7905f431-b­5ce-4e33-a455-4b1e122d00d0") != -1){
          ios = devices[i];
        }         
    }
    
    //Bond to it
    ios.gatt.connect().then(function(g) {
      gatt = g;
      console.log("connected");
      return gatt.startBonding();
    }).then(function() {
      console.log("bonded", gatt.getSecurityStatus());
      LED2.set();
      gatt.disconnect();
    }).catch(function(e) {
        LED1.set();
        console.log("ERROR",e);
    });
    
    
  • Looks like a really fun thing to try and do :) It's not because something else (nRF toolbox) is already connected to the iPhone is it?

    I guess you're uploading that code in sections, manually?

    You could try responding to this event and seeing if you get any useful error numbers? http://www.espruino.com/Reference#l_Blue­toothDevice_gattserverdisconnected

    If it's not connecting then I guess it might be because of some negotiation issue?

  • I don't think so, I've tried having everything else turned off to reduce the various BLE options in the room, from what I can see the iPhone just doesn't accept unsolicited connections.

    Over the weekend I got ANCS working on an Arduino with an nRF 8001 board as there are some pre-built libraries for that (also the contest I'm working on is Arduino centered so I need to use that!)

    It looks as if the Arduino is advertising some other services (battery etc) which the iPhone then sees in the Bluetooth devices and I can initiate the connection from the iPhone at which point the Arduino requests pairing (bonding)

    I'll need to go back and take a look at the services it advertises to see if I can re-create these on the Puck.
    This is the xml file that the nRF uses to expose services, I'm guessing this might make sense to you?

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE AttributeServer>
    <Profile Version="1.3">
        <SetupId>1</SetupId>
        <Device>nRF8001_Dx</Device>
        <Service Type="local" PrimaryService="true">
            <Name>TX Power</Name>
            <Uuid>1804</Uuid>
            <Characteristic>
                <Name>TX Power Level</Name>
                <Uuid>2a07</Uuid>
                <DefaultValue>0</DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>1</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>false</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <SetPipe>true</SetPipe>
                <AckIsAuto>true</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="local" PrimaryService="true">
            <Name>Immediate Alert</Name>
            <Uuid>1802</Uuid>
            <Characteristic>
                <Name>Alert Level</Name>
                <Uuid>2a06</Uuid>
                <DefaultValue></DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>1</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <WriteWithoutResponse>true</WriteWithout­Response>
                    <Write>false</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <SetPipe>false</SetPipe>
                <AckIsAuto>true</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="local" PrimaryService="true">
            <Name>Link Loss Alert</Name>
            <Uuid>1803</Uuid>
            <Characteristic>
                <Name>Alert Level</Name>
                <Uuid>2a06</Uuid>
                <DefaultValue>0</DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>1</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>true</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <SetPipe>false</SetPipe>
                <AckIsAuto>true</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="local" PrimaryService="true">
            <Name>Battery</Name>
            <Uuid>180f</Uuid>
            <Characteristic>
                <Name>Battery Level</Name>
                <Uuid>2a19</Uuid>
                <DefaultValue>64</DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>1</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>false</Write>
                    <Notify>true</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <SetPipe>true</SetPipe>
                <AckIsAuto>false</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="4" NameSpace="01" Unit="27AD"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="remote" PrimaryService="true">
            <Name>Immediate Alert</Name>
            <Uuid>1802</Uuid>
            <Characteristic>
                <Name>Alert Level</Name>
                <Uuid>2a06</Uuid>
                <DefaultValue>0</DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>1</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <Read>false</Read>
                    <WriteWithoutResponse>true</WriteWithout­Response>
                    <Write>false</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <AckIsAuto>true</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="local" PrimaryService="true">
            <Name>Device Information</Name>
            <Uuid>180a</Uuid>
            <Characteristic>
                <Name>Hardware Revision String</Name>
                <Uuid>2a27</Uuid>
                <DefaultValue></DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>9</MaxDataLength>
                <AttributeLenType>2</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>false</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <SetPipe>true</SetPipe>
                <AckIsAuto>false</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="25" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Service Type="remote" PrimaryService="true">
            <Name>ANCS</Name>
            <Uuid BaseUUID="79050000B5CE4E99A40F4B1E122D00­D0" BaseUUIDName="ANCS">f431</Uuid>
            <Characteristic>
                <Name>Notification Source</Name>
                <Uuid BaseUUID="9fbf0000630142d98c5825e699A21D­BD" BaseUUIDName="ANCS Notification Source">120d</Uuid>
                <DefaultValue></DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>20</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <Read>false</Read>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>false</Write>
                    <Notify>true</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <AckIsAuto>false</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
            <Characteristic>
                <Name>Control Point</Name>
                <Uuid BaseUUID="69D1000045E149A898219BBDFDAAD9­D9" BaseUUIDName="ANCS Control Point">d8f3</Uuid>
                <DefaultValue></DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>20</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <Read>false</Read>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>true</Write>
                    <Notify>false</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <AckIsAuto>false</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
            <Characteristic>
                <Name>Data Source</Name>
                <Uuid BaseUUID="22EA000024D64BB5BE44B36ACE7C7B­FB" BaseUUIDName="ANCS Data Source">c6e9</Uuid>
                <DefaultValue></DefaultValue>
                <UsePresentationFormat>0</UsePresentatio­nFormat>
                <MaxDataLength>20</MaxDataLength>
                <AttributeLenType>1</AttributeLenType>
                <ForceOpen>false</ForceOpen>
                <Properties>
                    <Read>false</Read>
                    <WriteWithoutResponse>false</WriteWithou­tResponse>
                    <Write>false</Write>
                    <Notify>true</Notify>
                    <Indicate>false</Indicate>
                    <Broadcast>false</Broadcast>
                </Properties>
                <AckIsAuto>false</AckIsAuto>
                <PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
                <PeriodForReadingThisCharacteristic>0</P­eriodForReadingThisCharacteristic>
                <PeriodForProperties/>
            </Characteristic>
        </Service>
        <Gapsettings>
            <Name>ANCS Rusk</Name>
            <DeviceNameWriteLength>0</DeviceNameWrit­eLength>
            <LocalPipeOnDeviceName>false</LocalPipeO­nDeviceName>
            <DeviceNameShortLength>3</DeviceNameShor­tLength>
            <Apperance>0240</Apperance>
            <SecurityLevel>1</SecurityLevel>
            <AuthenticationReq>0</AuthenticationReq>­
            <IoCapabilities>0</IoCapabilities>
            <BondTimeout>600</BondTimeout>
            <SecurityRequestDelay>99</SecurityReques­tDelay>
            <MinimumKeySize>7</MinimumKeySize>
            <MaximumKeySize>16</MaximumKeySize>
            <AdvertisingDataBondedBitmap>10</Adverti­singDataBondedBitmap>
            <AdvertisingDataGeneralBitmap>10</Advert­isingDataGeneralBitmap>
            <AdvertisingDataBrodcastBitmap>0</Advert­isingDataBrodcastBitmap>
            <AdvertisingDataBondedScanResponseBitmap­>2c40</AdvertisingDataBondedScanResponse­Bitmap>
            <AdvertisingDataGeneralScanResponseBitma­p>2c40</AdvertisingDataGeneralScanRespon­seBitmap>
            <AdvertisingDataBrodcastScanResponseBitm­ap>0</AdvertisingDataBrodcastScanRespons­eBitmap>
            <AdvertisingDataBondedBitmapCustom>1</Ad­vertisingDataBondedBitmapCustom>
            <AdvertisingDataGeneralBitmapCustom>1</A­dvertisingDataGeneralBitmapCustom>
            <AdvertisingDataBrodcastBitmapCustom>0</­AdvertisingDataBrodcastBitmapCustom>
            <AdvertisingDataBondedScanResponseBitmap­Custom>0</AdvertisingDataBondedScanRespo­nseBitmapCustom>
            <AdvertisingDataGeneralScanResponseBitma­pCustom>0</AdvertisingDataGeneralScanRes­ponseBitmapCustom>
            <AdvertisingDataBrodcastScanResponseBitm­apCustom>0</AdvertisingDataBrodcastScanR­esponseBitmapCustom>
            <TxPowerLevelOffset>0</TxPowerLevelOffse­t>
            <MinimumConnectionInterval>400</MinimumC­onnectionInterval>
            <MaximumConnectionInterval>800</MaximumC­onnectionInterval>
            <SlaveLatency>0</SlaveLatency>
            <TimeoutMultipler>600</TimeoutMultipler>­
            <AddServiceUpdateCharacteristic>true</Ad­dServiceUpdateCharacteristic>
            <AddServiceUpdateCharacteristicPipe>true­</AddServiceUpdateCharacteristicPipe>
            <SercieToSolicitate>
                <Uuid BaseUUID="79050000B5CE4E99A40F4B1E122D00­D0" BaseUUIDName="ANCS">f431</Uuid>
            </SercieToSolicitate>
            <CustomAdTypes>
                <AdType index="1">
                    <Type>19</Type>
                    <Value>4002</Value>
                </AdType>
                <AdType index="2">
                    <Type>18</Type>
                    <Value></Value>
                </AdType>
            </CustomAdTypes>
        </Gapsettings>
        <Hardwaresettings>
            <Clocksource>1</Clocksource>
            <ClockAccuracy>1</ClockAccuracy>
            <InitialTxPower>3</InitialTxPower>
            <HfClkSource>0</HfClkSource>
            <DcDcConverter>0</DcDcConverter>
            <ActiveSignalModeIndex>0</ActiveSignalMo­deIndex>
            <ActiveSignalToTickDistance>0</ActiveSig­nalToTickDistance>
            <DynamicWindowLimitingEnabled>true</Dyna­micWindowLimitingEnabled>
        </Hardwaresettings>
        <CurrentInput>
            <BatteryCharge>220</BatteryCharge>
            <Master32KhzClockAccuracy>10</Master32Kh­zClockAccuracy>
            <ConnectionInterval>1000</ConnectionInte­rval>
            <PercentOfTimeSleeping>0</PercentOfTimeS­leeping>
            <PercentOfTimeAdvertising>0</PercentOfTi­meAdvertising>
            <AdvertisingInterval>1280</AdvertisingIn­terval>
        </CurrentInput>
    </Profile>
    
  • That would make sense actually - perhaps the iPhone needs to have seen the Puck to check that it's an alert device before it'll allow a connection from it?

    Is that dump the XML from the iPhone itself, rather than the device that needs to connect to it?

  • Yeah, its certainly far easier from a UX perspective to initiate the pairing from the iPhone and ust have the embedded device accept whatever tried to connect.

    No that XML is from the nRF8001 Arduino example https://github.com/NordicSemiconductor/b­le-sdk-arduino/tree/master/libraries/BLE­/examples/ble_ANCS_template It looks like you run that through an nRF app on your machine (nrfGo ??) to generate a services.h file that then gets flashed onto the 8001

  • It looks like there's an ANCS client for the nRF52 in the Nordic SDK, https://infocenter.nordicsemi.com/index.­jsp?topic=%2Fcom.nordic.infocenter.sdk52­.v0.9.2%2Fble_sdk_app_ancs.html would be VERY cool if this was part of espruino one day with some nice high level API calls to respond to alerts

  • Yes, I noticed that. I had a quick look and I don't think there's anything in there that couldn't be implemented in JS though - so it's something I'd really like to avoid pulling in if at all possible.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Trying to Connect to BLE Device for Bonding/ANCS

Posted by Avatar for sammachin @sammachin

Actions