Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Apple Notification Center Service #910

Open
1 task done
ryangodburn opened this issue Jan 4, 2022 · 33 comments
Open
1 task done

Implement Apple Notification Center Service #910

ryangodburn opened this issue Jan 4, 2022 · 33 comments

Comments

@ryangodburn
Copy link

Verification

  • I searched for similar feature request and found none was relevant.

Pitch us your idea!

Add the Apple Notification Center Service to allow for notification access on iOS.

Description

What is blocking Infinilink on iOS from notifications working is that the Apple Notification Center Service is not implemented, so if it can be added then notifications could work from iOS.

@JF002
Copy link
Collaborator

JF002 commented Jan 4, 2022

Duplicate of # 460

@JF002 JF002 marked this as a duplicate of #460 Jan 4, 2022
@ryangodburn
Copy link
Author

Apologies thought this would be a different thread for the notification service, not the music service.

@JF002
Copy link
Collaborator

JF002 commented Jan 4, 2022

Oh sorry, my bad! You're right! We talked about music control yesterday, and I mix them up with notifications! I'm removing the duplicate!

Sooo... Apple also need a specific API for notifications?

@JF002 JF002 marked this as not a duplicate of #460 Jan 4, 2022
@ryangodburn
Copy link
Author

Unfortunately, it is so. I have found some more information about it here. I would be more than happy to test if anything could be added.

@TheAwesome98-Real
Copy link

You should probably move this issue to InfiniLink since that’s where it should be implemented

@ryangodburn
Copy link
Author

The language used on its GitHub makes it seem like it needs to be implemented into the Infinitime firmware itself.
image

@TheAwesome98-Real
Copy link

Hm, that's weird. I thought all InfiniTime does is send play/pause/skip etc. requests to the device and the companion app (InfiniLink in this case) handles it.

@JF002
Copy link
Collaborator

JF002 commented Jan 5, 2022

@TheAwesome98-Real My understanding is that iOS notifications and music control can only happen on a specific Apple branded BLE API... So InfiniLink has no choice but use the Apple protocol instead of the more generic and standardized protocols currently supported by InfinITime.

@xan-m
Copy link
Contributor

xan-m commented Jan 7, 2022

InfiniLink dev here! @JF002 and @ryanmp4 are correct, notifications require ANCS (Apple Notification Center Service) and music requires AMS (Apple Music Service). I can't do anything from the iOS side to force notifications from outside InfiniLink through the existing notification API on the watch. InfiniTime does send play/pause/etc. to iOS, but without AMS I only can use InfiniTime's media characteristic to control Apple Music (not Spotify, Netflix, podcast apps, etc).

I've tried a couple of times to implement ANCS in InfiniTime, but unfortunately I can't really wrap my head around the level of C++ in InfiniTime... The link the @ryanmp4 listed above is the complete documentation to implement the notification service, so it's just a matter of someone with the ability and bandwidth to hack it in!

For reference, AMS spec is here.

@ck-telecom
Copy link

ck-telecom commented Jan 10, 2022

I have tried /* ANCS */ and AMS on my Zephyr pinetime project https://github.com/ck-telecom/pinetime, and I can recieve coressponding notification and entity attribute from console, but I have not make it on my UI.

@minacode
Copy link
Contributor

If I would try to implement this feature: how safe is it to test this on a sealed watch?
Otherwise I could still try to contribute code (or finally have to order a devkit 😄).

@JF002
Copy link
Collaborator

JF002 commented Feb 12, 2022

It should be quite safe as you'll add new features. You'll probably not touch the low-level driver or startup code so you'll be pretty safe.
In case of issue, the bootloader should always be able to revert to the previous version and load the recovery firmware as a last resort.

@scandinave
Copy link

@minacode I already start to implement ANCS. maybe we can work on it together. i can add you to my repo as contributor.

@minacode
Copy link
Contributor

Sure, I would like that 😊

@scandinave
Copy link

Sure, I would like that 😊

done

@ryanfortner
Copy link

Hi there, has there been any progress on adding the notification service?

@minacode
Copy link
Contributor

For me, not much, sorry. I do not have much time right now, but I tried to implement ANCS for Linux to learn how it generally works. This is still in progress, because

Due to the nature of iOS, the ANCS is not guaranteed to always be present. As a result, the NC should look for and subscribe to the Service Changed characteristic of the GATT service in order to monitor for the potential publishing and unpublishing of the ANCS at any time.

This is not fun to implement for me even on linux, so unless I am confident with this on a well debuggable device, I will not touch this on the Pinetime. The plan ist not dead though. I would still like to implement this in the hopefully-not-so-far future.

@ryanfortner
Copy link

I understand. Thanks for the update.

@jrmolin
Copy link

jrmolin commented Apr 30, 2022

I have a dev kit on the way. I would also like to get some notifications on my iOS device. Do you want to collaborate? I have a build environment setup, and I already modified one watch face (analog to get step counts on there) and OTA flashed it. No problems so far! However, I didn't want to OTA-only flash anything mucking with the guts of notifications.

@minacode
Copy link
Contributor

minacode commented May 1, 2022

The progress already made is here.

I can do a small writeup of my last progress there soon.

Also, i found OTA on the sealed watch to be safe, as long as you don't verify the new image, because you can always reboot into the previous firmware via holding the button pressed. At one point I debugged generating notifications by showing a new one at each touch input. It worked, but made the watch pretty much unusable 😄 The same should hold when messing with Bluetooth, where you might lock yourself out from OTA (I guess?) but can still just go back to the previous firmware. Despite trying a lot of builds I never got to this point.

@MagicTrevor
Copy link

Any more progress? I am getting a mini soon and want to start helping around this as well.

@minacode
Copy link
Contributor

minacode commented Jun 8, 2022

No, no progress sadly. I wrote a comment on the draft.

There are some architectural hurdles, because right now, InfiniTime seems to initialize all Bluetooth services upon connection.
This is fine, because they are just always there. But the ANCS can appear and disappear at any moment. I made a test implementation of ANCS on my laptop and it showed, that the ANCS is normally not available directly after connecting to my iPhone.

So the question is: How can we build the ANCS such that it can be on and off at any moment, determined by the GATT services ServiceChanged characteristic?

Edit: A good first step would be to implement the GATT service (0x1801) and its ServiceChanged characteristic.

@cole-wilson
Copy link

Where is the status of this now? Is there a proof of concept available? I would love to help out any way I can, but I don't think I have the necessary c++ skills!

@minacode
Copy link
Contributor

No progress.
What kind of proof of concept do you mean?
I can run ANCS on Bluez/Linux. And the watch can connect to devices via BLE.
ANCS on the watch is not implemented.
We should start by handling the GattService, as I mentioned before.
Sadly I don't see myself contributing this until September, because I just don't find the time.

@MagicTrevor
Copy link

Isn't an encrypted connection required first? Or has that issue with iOS been handled?

@minacode
Copy link
Contributor

minacode commented Jul 7, 2022

I could never do it, but someone reported to have done it by encrypting the battery service, I think. I am not 100% sure though.

Edit: #920

Just to reiterate: when testing a build from early in the bonding PR process (when the battery level characteristic was used to trigger bonding), the instant I connected the PineTime the bonding prompt with the PIN showed up on my phone and the watch. I don't have a sniffer so I'm not 100% sure to what degree my communications were encrypted after that bonding, but if my understanding of the process is right, it should only have to be one characteristic that requires authentication.

My hope is, that one of the Apple services is sufficient to trigger encryption.

@shymega
Copy link
Contributor

shymega commented Jul 25, 2024

I see there's a PR here, so I've pulled it into my fork and rebased it against main.

However, I think it would be best for the PR to be opened on this repo for collaboration. The PR on the fork was hard to find.

I've had experience with BLE characteristics with earbuds, so I'm fairly okay working with Apple's service here.

I'll keep checking in here as progress moves. I have an iPhone 13.

@minacode
Copy link
Contributor

Does it work? I would be very surprised.

@shymega
Copy link
Contributor

shymega commented Jul 25, 2024

It doesn't yet. I'm reading through the Apple spec when I have time. I have a devkit PineTime, so I can debug. Just waiting for my probe-rs device though.

@minacode
Copy link
Contributor

Nice! Debugging is what made me quit, because it wasn't really possible between a sealed watch and an iPhone. I would love to contribute if you get something going, though. If you have questions, feel free to ask. I wrote an ANCS implementation that ran on Linux when I worked on the PR.

@cyberneel
Copy link

Are there any updates on this? I’m trying to find a repo with latest work to see if I can mess with it.

@minacode
Copy link
Contributor

minacode commented Dec 14, 2024

No, sorry. I am also not planning to work on this in the mid-near future.

@GaryM0101
Copy link

Main problem: the services Apple devices expose can (and will) appear and disappear

So I was able to test ANCS on a nRF52832 Feather and paired it with my iPhone 13. The feather wouldn't show up in the bluetooth settings. So I used "nRF Connect" to start the ANCS service on the iPhone. The service also reconnects when back in BT range. This was the main sticking point of this fork dying.

Disconnected, reason = 0x3E
Connected
Discovering DIS ... Discovered
Manufacturer: Apple Inc.
Model: iPhone13,2

Discovering ANCS ... Discovered
Attempting to PAIR with the iOS device, please press PAIR on your phone ... Secured
Enabling notifications

IMG_7651

Screenshot 2024-12-13 094913

The ANCS setup for the Feather: https://github.com/adafruit/Adafruit_nRF52_Arduino/tree/master/libraries/Bluefruit52Lib/examples/Peripheral/ancs

I think this should work for infinitime with a little tweaking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests