sandeepmistry / node-ancs

A node.js lib to access the Apple Notification Center Service (ANCS)
MIT License
67 stars 19 forks source link

Use bleno as ANCS accessories #3

Closed desar closed 10 years ago

desar commented 10 years ago

Hi Sandeep,

I believe ANCS doesn't dictate anything about GAP role (central or peripheral).

Since node-ancs is using noble instead of bleno, I assume that it work as central role. In this case you gonna need app on iPhone to work as peripheral. (LightBlue will do).

Now, based on this blog: http://blog.punchthrough.com/post/63658238857/the-apple-notification-center-service-or-wtf-is If you can advertise ANCS service solicitation, iPhone can see that advertiser(peripheral) as accessories. So you don't need any application on iPhone.

I did the following test: on Linux: hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 03 11 15 D0 00 2D 12 1E 4B 0F A4 99 4E CE B5 31 F4 05 79 00 00 00 00 00 00 00 00 00 00 *) this will advertise ANCS uuid (7905F431-B5CE-4E99-A40F-4B1E122D00D0) as service solicitation (AD Type: 0x15).

on iPhone: Open The default Settings>Bluetooth. After you type the above command on linux you should see the peripheral listed as "Accessories". You can click to do pairing. *) note that ANCS scanning seem to be in sparse interval that regular scanning (few seconds should do)

My request: Also implement ancs with bleno to act as peripheral.

Thanks

sandeepmistry commented 10 years ago

Are you able to get an example of this going on OS X using CoreBluetooth?

desar commented 10 years ago

I use Raspberry Pi for hcitool (advertising via bt 4 usb dongle). Ah, I think you already know. But you also need the usual command for advertising (hciconfig hci0 up; hciconfig hci0 leadv). The above command is only for setting the advertising data) It should be the same with OS X. I leave my Mac today, but I could try it tonight.

sandeepmistry commented 10 years ago

Cool, do you think CoreBluetooth can handle the stuff after a connection is established?

desar commented 10 years ago

Sorry if I'm wrong. You are talking about CoreBluetooth on iPhone right? I don't think so. I think ANCS is handled automatically within iOS7 itself. If I want other BLE stuff beside ANCS, I would need to write the iPhone app myself. But all I want is ANCS notification (mail, etc) to be send to the peripheral so in this scenario CoreBluetooth isn't needed. BTW, I think currently NP is sending all notifications, not only notification generated by specific app. I already test to connect to LightBlue on iPhone using Android as ANCS client, and I can get notification send to Gmail app on iPhone broadcast-ed to Android.

desar commented 10 years ago

Okay,

Now I see that implementation on linux and mac os x is quiet different, and why you need CoreBluetooth on Mac OS X side. Ignore my previous comment about CoreBluetooth.

  1. Based on Apple doc, I don't see how you can advertise solicitation service uuid with CBPeripheralManager. Too bad, since CBCentralManager can access it. Maybe we should wait Apple to publish the API, other than that I don't know if it can be done with Mac OS X.
  2. Now, we still can do it with linux version thought. But since bleno->peripheral->gatt server, noble->central->gatt client, this could be much work than what I think. In this scenario we need peripheral->gatt client, so a mix of bleno and noble somehow. Still, it is appealing if it can be implemented with Raspberry Pi.
sandeepmistry commented 10 years ago

@desar seems like it's possible to do on Linux if you have the time.

I like to keep OS X and Linux features consistent for both noble and bleno.

desar commented 10 years ago

OK understood.

Since I'm only doing a little experiments, I'll do it with bluez plugin instead. Hope someday Apple provide all access to Advertise Data with its CoreBluetooth.

BTW, I was unable to run node-ancs (test.js) on my Mac. Got some error after connecting. Could open another issues.

Closing this one.

sandeepmistry commented 10 years ago

Cool, are you planning on open sourcing the bluez plugin?

desar commented 10 years ago

Nope, it will only be an experimental code. Doesn't deserved to be OSS.

andybee commented 9 years ago

@desar Did you manage to get this working within Bleno (port bits from Noble)? I'm attempting to implement the same functionality and I am happy with it being Linux-only. If you're not happy to share your code, could you possibly share a few pointers please? Thanks in advance.

robotastic commented 9 years ago

I was interested in doing the same thing. Let me know if you get started and I would be happy to help. My end goal is to have ANCS working on a Pi.

Sent from my iPhone

On Nov 30, 2014, at 3:34 PM, Andy Buckingham notifications@github.com wrote:

@desar Did you manage to get this working? I'm attempting to implement the same functionality and I am happy with it being Linux-only. If you're not happy to share your code, could you possibly share a few pointers please? Thanks in advance.

— Reply to this email directly or view it on GitHub.

desar commented 9 years ago

@andybee, @robotastic

Nope, no code. I was rather interested in peripheral mode with embedded things since. I got POC for ANCS working with mbed platform (no bluez, it was reliable sdk from specific ble chip maker, Nordic Semi.) Anyway, seeing the bluez release note, look like bluez support/fix for ble has improved somehow (still has no faith in it, seeing many bugs and no doc.), and look like 3.17 kernel branch for Raspbian was put on git, (some bluez code is implemented in kernel mode) so I think I will have a look again into this. Just give me several days to try it and see the current state with the latest sources available first. (Intel Edison is using bluez too, so could be interesting to see bluez working nicely with ancs)

robotastic commented 9 years ago

That would be awesome! I would be happy to help where I can. I am interested in having the Raspberry Pi be a peripheral so no special Apps are need. iOS will automatically detect BLE peripherals that advertise an ANCS Id service request.

On Nov 30, 2014, at 5:36 PM, desar notifications@github.com wrote:

@andybee https://github.com/andybee, @robotastic https://github.com/robotastic Nope, no code. I was rather interested in peripheral mode with embedded things since. I got POC for ANCS working with mbed platform (no bluez, it was reliable sdk from specific ble chip maker, Nordic Semi.) Anyway, seeing the bluez release note, look like bluez support/fix for ble has improved somehow (still has no faith in it, seeing many bugs and no doc.), and look like 3.17 kernel branch for Raspbian was put on git, (some bluez code is implemented in kernel mode) so I think I will have a look again into this. Just give me several days to try it and see the current state with the latest sources available first. (Intel Edison is using bluez too, so could be interesting to see bluez working nicely with ancs)

— Reply to this email directly or view it on GitHub https://github.com/sandeepmistry/node-ancs/issues/3#issuecomment-65003679.

desar commented 9 years ago

Current state of affairs:

I was able to build raspbian kernel 3.17 (replacing bluetooth source with bluetooth.git) bluetooth-next.git currently won't compile, but I guess bluetooth.git should be good enough.

Bluez 5.25: http://www.bluez.org/ "There are also various GATT related fixed." Not interested to check the commit one by one to see what they are, but 5.25 seems it is.

Nah, 5.24, 5.25 won't compile on current raspbian release (update). ps. 5.23 compile fine. http://www.raspbsarierrypi.org/forums/viewtopic.php?t=92900&p=648069 Look like 5.25 are using newer dep. libraries. But those compile error seem not to be related to this... (Will try to fix it if possible, and run it on wheezy)

Still going to try jessie anyway, due to lib dep mentioned above. A bit of warning though, jessie is currently still in beta/experimental. Going to grab a blank sdcard for Jessie cause I don't want to destroy my current install. Will try it tonight.

Now, the reason I'm trying to use the latest code, As I said before, bluez has too many bugs, and I don't want to waste my time on that. The latest symptom (few months ago) was iOS disconnecting after few sec. This is not happening on my embedded platform, so I'm guessing that the culprit might be bluez itself.

IF, everything goes allright (have soft combination where raspberry, bluez and iOS work, although those combination could be experimental...), you still have need work to use ancs. Options are sandeep's ancs node modules (need apps on iPhone as RPi will be a central role), or you might to code a bluez plugin (peripheral) for that. (There are, already, oss on that but I did not research the current state. Bluez also has experimental gatt api and might be exposing dbus api?, but poor or almost no doc. could make someone stuck trying)

I could try to code those plugin, but that gonna require more times I guess. More than happy if someone would do research on current oss possibilities, or start coding the plugin. (there are sample for gatt plugin on plugins/gatt-example.c in bluez source folder, it is gatt server. Also profiles/ folder have some implementation of gatt client too.)

Cheers

desar commented 9 years ago

So far, so good.

Okay, was able to get rid from the compiling error. (somebody really need to donate RPi board to bluez guys, so they can check before releasing...)

There are 2 errors. One can be fix by adding proper lib options, But the other one was more concerning. Cast-align, I just temporary get rid of it by suppressing from compile options. It will need a more depth look later, as it was in gatt-client.c which might cause problem later. So, I don't think I'm gonna need jessie. Last raspbian with update seem to be fine for me. Don't know where those lib dep req. info came from.

Anyway, I run the daemon, set advertising parameter (solicite ancs uuid) I was able to connect from iOS settings. Hey, the connection was not disconnected by iOS. (Currently using the latest 8.1.1, is there a chance that they also fix something in iOS? who knows)

So the came out seem to look promising. (I only do the connection, iOS might disconnect if I start to accessing the ancs service etc.) What next,

  1. Checking Sandeep node-ancs if Issues #4 persist.
  2. Try to start coding the plugin (so no app req.)

Could came out with the result for #1 by tonight or tomorrow.

Cheers

robotastic commented 9 years ago

Wow! Awesome work. I will start getting a clean version of things up and running on my Pi so I can catch up.

IOS 8.0 broke the ANCS stuff I had working on Arduino with 7.0.

Sent from my iPhone

On Dec 2, 2014, at 1:06 AM, desar notifications@github.com wrote:

So far, so good.

Okay, was able to get rid from the compiling error. (somebody really need to donate RPi board to bluez guys, so they can check before releasing...)

There are 2 errors. One can be fix by adding proper lib options, But the other one was more concerning. Cast-align, I just temporary get rid of it by suppressing from compile options. It will need a more depth look later, as it was in gatt-client.c which might cause problem later. So, I don't think I'm gonna need jessie. Last raspbian with update seem to be fine for me. Don't know where those lib dep req. info came from.

Anyway, I run the daemon, set advertising parameter (solicite ancs uuid) I was able to connect from iOS settings. Hey, the connection was not disconnected by iOS. (Currently using the latest 8.1.1, is there a chance that they also fix something in iOS? who knows)

So the came out seem to look promising. (I only do the connection, iOS might disconnect if I start to accessing the ancs service etc.) What next,

  1. Checking Sandeep node-ancs if Issues #4 persist.
  2. Try to start coding the plugin (so no app req.)

Could came out with the result for #1 by tonight or tomorrow.

Cheers

— Reply to this email directly or view it on GitHub.

desar commented 9 years ago

Hi guys.

Just check with Issues #4 (iOS disconnect after few sec) and the bad news is, it still persist.

But I think I'm gonna still try to create the bluez plugin anyway. (node-ancs work as central so RPi do the connection to iOS, perhaps we can get a better luck if we reverse that, iOS do the connection to RPi. The test I did in the post before was exactly this way, iOS do the connection to RPi and it not disconnected. But I'm not doing anything after the connection. iOS could disconnect, if I start to accessing its gatt server from Rpi)

I'm not going to make any commitment, but perhaps will start this weekend. I'll give any update if any, could take several days or weeks.

Thanks.

sander commented 9 years ago

@desar Did you find a way eventually to use ANCS with a Bluez peripheral? I’m trying to get iOS notifications on my Intel Edison board, and as you describe, it currently connects only when a central app is running, and disconnects after several seconds.

sandeepmistry commented 9 years ago

@sander you can try out ancs-test.js in the role-reversal branch of bleno

robotastic commented 9 years ago

Awesome! @sander, let me know if you get it to work. I have some Arduino code here that can process the ANCS messages.

https://github.com/robotastic/ANCS-Library

On Mon, May 18, 2015 at 8:11 AM, Sandeep Mistry notifications@github.com wrote:

@sander https://github.com/sander you can try out ancs-test.js https://github.com/sandeepmistry/bleno/blob/role-reversal/ancs-test.js in the role-reversal branch of bleno https://github.com/sandeepmistry/bleno/tree/role-reversal

— Reply to this email directly or view it on GitHub https://github.com/sandeepmistry/node-ancs/issues/3#issuecomment-103039980 .

sander commented 9 years ago

@sandeepmistry Great, thanks! I’ve had it running on OS X, but on my Edison I get this error:

# node ancs-test.js
bleno

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:1011:11)
    at Process.ChildProcess._handle.onexit (child_process.js:802:34)

I’ve tried after rfkill unblock bluetooth, with and without the iPhone connected in bluetoothctl, and with and without bluetoothd running. With bleno.on('error', ...) there’s no difference. Is there a way to get a better stack trace, or do you already know what this error could be?

sander commented 9 years ago

Figured out what that error came from by monkey patching require('child_process').spawn and worked around it with ln -s node_modules/noble/build . in thebleno dir.. Now the script runs but doesn’t get further than advertisingStart. Will try some more things, let me know if you have ideas.

desar commented 9 years ago

Just putting some comment here. This was few months ago, my memory could be wrong. anyway.

@desar Did you find a way eventually to use ANCS with a Bluez peripheral?

@sander, unfortunately not with bluez. If I remember correctly I end up using bluegiga dongle with rpi as peripheral for ANCS. Unlike, a normal ble dongle, bluegiga has usb to serial function, so you will see it as a com port on your host (ex. rpi). You can almost use any language for BLE gatt programming, since bluegiga soft on nordic chip will convert serial data to access nordic softdevices. bluegiga is used in commercial products like myo armband and also lumo lift I guess. (I bet maintaining different code for both windows and mac is burden for them, and they could also make some profit by selling those dongle too)

Edison is using qualcomm ble chip I guess. Will be nice if bluez working with ANCS. As central, when connecting to iPhone from bluez, I did try to set the connection parameter to satisfy Apple Bluetooh Guideline without any success (disconnected after few sec). Perhaps, not only connection parameters but some hci command sequence that iOS don't like and decided to close the connection. (Using ble packet capture and analyze it might reveal something). BLE might not need apple MFi, but they sure will collect some consultation fee if you go commercial this way....

Only got weekend for hobby, but I might also interested in trying sandeep's ancs-test in bleno. Hope you got it resolved before that;) Also the latest bluez (see release note for 5.30) had some improvement for GATT API, "experimental, support both 'client' and server functionality" so maybe worth checking too. (Although you can always grab dev. source, they do release monthly, so 5.31 is imminent)

robotastic commented 9 years ago

It worked fine when I tried ants-test.js on OS X. Oddly, I didn’t even need to pair and my macbook didn’t show up under bluetooth devices. I wonder if it is because HandOff was running.

I couldn’t get it working on Ubuntu though. I comes up fine and I can see the ‘test’ bluetooth id under Device on the iPhone. I can connect, but no ANCS notifications show up on the ubuntu side.

Has anyone gotten it work on Linux?

This is all I got:

bleno on -> stateChange: poweredOn on -> advertisingStart: success

On May 18, 2015, at 9:40 PM, desar notifications@github.com wrote:

Just putting some comment here. This was few months ago, my memory could be wrong. anyway.

@desar https://github.com/desar Did you find a way eventually to use ANCS with a Bluez peripheral?

@sander https://github.com/sander, unfortunately not with bluez. If I remember correctly I end up using bluegiga dongle with rpi as peripheral for ANCS. Unlike, a normal ble dongle, bluegiga has usb to serial function, so you will see it as a com port on your host (ex. rpi). You can almost use any language for BLE gatt programming, since bluegiga soft on nordic chip will convert serial data to access nordic softdevices. bluegiga is used in commercial products like myo armband and also lumo lift I guess. (I bet maintaining different code for both windows and mac is burden for them, and they could also make some profit by selling those dongle too)

Edison is using qualcomm ble chip I guess. Will be nice if bluez working with ANCS. As central, when connecting to iPhone from bluez, I did try to set the connection parameter to satisfy Apple Bluetooh Guideline without any success (disconnected after few sec). Perhaps, not only connection parameters but some hci command sequence that iOS don't like and decided to close the connection. (Using ble packet capture and analyze it might reveal something). BLE might not need apple MFi, but they sure will collect some consultation fee if you go commercial this way....

Only got weekend for hobby, but I might also interested in trying sandeep's ancs-test in bleno. Hope you got it resolved before that;) Also the latest bluez (see release note for 5.30) had some improvement for GATT API, "experimental, support both 'client' and server functionality" so maybe worth checking too. (Although you can always grab dev. source, they do release monthly, so 5.31 is imminent)

— Reply to this email directly or view it on GitHub https://github.com/sandeepmistry/node-ancs/issues/3#issuecomment-103295014.

sandeepmistry commented 9 years ago

@sander be sure to run npm install and node-gyp rebuild. The *-ble binaries from noble are not compatible, bleno has it's own version of those.

sander commented 9 years ago

@desar thanks for your comments! Good to know that reliable ANCS is possible with non-Apple clients.

@sandeepmistry thanks, didn’t know about node-gyp. I’ve recompiled the bleno binaries and run ancs-test.js on OS X and Edison (self-compiled BlueZ 5.30). Got the same issues, but now I’ve kept logs:

OS X logs (tarball, containing plain text, BTSnoop and PacketLogger formats), procedure:

  1. OS X and iPhone were already paired.
  2. Start logging with PacketLogger.
  3. Start node ancs-test.js.
  4. Several notifications come in on stdout.
  5. Stop node.
  6. Stop logging.

Edison logs (hcidump and stdout, plain text on Gist), procedure:

  1. Start Edison. The Edison and iPhone are not paired.
  2. rfkill unblock bluetooth. Interface hci0 is up according to hciconfig.
  3. Start logging with hcidump.
  4. Start node ancs-test.js.
  5. On iPhone, go to Settings > Bluetooth, and pair with edison under MY DEVICES. After a few seconds, the status changes to Connected.
  6. Wait, create some notifications that appear on iPhone. They don’t appear in stdout on Edison.
  7. After seconds, stop node.
  8. Stop logging.

I have to stop for now, but maybe the logs can help compare what happens on OS X vs what happens on BlueZ? There seems to be a way to get BT logs from iOS as well, but I didn’t do that yet.

(edit: updated logs, forgot to do DEBUG=* on node previously)

sandeepmistry commented 9 years ago

@sander You could try killing bluetoothd, see: https://github.com/sandeepmistry/bleno/issues/24

However, it's needed for pairing security. So, try killing it, starting the bleno app, and they starting bluetoothd.

sander commented 9 years ago

@sandeepmistry Thanks, that helped to get pairing to work. Still no notifications however. I’ve followed these steps:

  1. Start Edison. Edison and iPhone not paired.
  2. rfkill unblock bluetooth
  3. killall bluetoothd
  4. Start logging with hcidump.
  5. Start DEBUG=* node ancs-test.js.
  6. hciconfig hci0 up
  7. Pair from iPhone.
  8. systemctl start bluetooth
  9. Create several notifications. They appear on iPhone but not on Edison.

Here are the logs: https://gist.github.com/sander/ce61da9cfb8937dadafb Not sure if it’s related, but the node log has over 32000 occurrences of these lines:

Mon, 25 May 2015 20:21:39 GMT bleno-l2cap-ble buffer = "security = low\n"
Mon, 25 May 2015 20:21:39 GMT bleno-l2cap-ble line = security = low
Mon, 25 May 2015 20:22:22 GMT l2cap-ble 44:a0:1f:de:61:63: buffer = "security = low\n"
Mon, 25 May 2015 20:22:22 GMT l2cap-ble 44:a0:1f:de:61:63: line = security = low

Any ideas? Is there another way to access ANCS from bluez (5.30, with kernel 3.10) that has been shown to work?

sander commented 9 years ago

To answer my last question, I now have a connection that is lasting for at least 5 minutes. Not useful yet, and maybe not news, but it made me happy to see that it is possible with bluez (5.24 again) on Edison. Steps:

  1. Run systemctl stop bluetooth.
  2. Run hcitool lescan.
  3. Launch an iOS app that advertises a BLE server, such as BLE Utility.
  4. From the scan, copy the temporary UUID that matches the iOS app. For example, 5C:71:C9:4D:A5:64.
  5. Run gatttool -I -b 5C:71:C9:4D:A5:64 -t random.
  6. In the program, run sec-level high, connect, characteristics.
  7. From the result, take the value handle from the notification channel, e.g. 0x001e.
  8. Run char-desc 0x001e, and take the handle from the characteristic following the notification channel ID, e.g. 0x001f.
  9. Run char-write-req 0x001f 0100.
  10. Wait for notifications to come in.
sandeepmistry commented 9 years ago

@sander I haven't tried with BlueZ 5.x, it works with BlueZ 4.101 on my Raspberry Pi though. Since it's on a branch of bleno, keep in mind it's highly experimental.

Your last comment is operating ANCS in central mode, which is identical to the library in this repo.

robotastic commented 9 years ago

How far off is the role-reversal branch of Bleno? Should I try to merge before I try getting ancs-test.js to work?

sandeepmistry commented 9 years ago

@robotastic it's pretty far off. However, with the node-bluetooth-hci-socket changes, it should be a much simpler, as everything is HCI socket handle based.

robotastic commented 9 years ago

Thanks @sandeepmistry ! What do you think the best way to get ANCS working with the current branch of Bleno? Should I try to reimplement ancs-test.js?

sandeepmistry commented 9 years ago

@robotastic I would actually try to do everything but advertising in noble now.

You can report a role reversal "discover" here: https://github.com/sandeepmistry/noble/blob/master/lib/hci-socket/bindings.js#L160 depending on the value of role, then store it somewhere. Then stub out the connect method based on the role for that handle.

That's what's in my head currently ...

robotastic commented 9 years ago

@sandeepmistry I have tried messing around with this but haven't had much luck. Does this approach seem right?

Start the advertisement using Bleno and the code from ancs-test.js and then listen for a Noble.discover and look at the role to see what the role is.

I am having a problem where noble gets the connect event, but is failing because it doesn't have the peripheral in _peripheral:

on -> stateChange: poweredOn on -> advertisingStart: error Error: Command Disallowed noble: unknown peripheral 5a8f5801fc85 connected! https://github.com/sandeepmistry/noble/blob/master/lib/noble.js#L156

How should I hand off between Bleno and Noble? Should it happen after a particular blend event occurs?

I saw that there is a HCI Event for Role Change: Role Change - 0x12 - Status, BD_ADDR, New_Role

It doesn't look like that is a defined event. Do you think it would get passed through if I define things out and test for it?

robotastic commented 9 years ago

I looked back through the Role Reversal branch and I think I have a little better sense of some of the changes that are needed to Noble. It looks like you need to hook onto the Bleno Accept event and then pass the client address to Noble’s discover event.

Additional pointers would be great though.

On Sep 12, 2015, at 2:58 PM, Sandeep Mistry notifications@github.com wrote:

@robotastic https://github.com/robotastic I would actually try to do everything but advertising in noble now.

You can report a role reversal "discover" here: https://github.com/sandeepmistry/noble/blob/master/lib/hci-socket/bindings.js#L160 https://github.com/sandeepmistry/noble/blob/master/lib/hci-socket/bindings.js#L160 depending on the value of role, then store it somewhere. Then stub out the connect method based on the role for that handle.

That's what's in my head currently ...

— Reply to this email directly or view it on GitHub https://github.com/sandeepmistry/node-ancs/issues/3#issuecomment-139809726.