No name or address. CBCentralManager no longer working on macOS 12 - bluetooth

every since I updated macOS to macOS 12, I have trouble using CoreBluetooth.
In one of my apps, I will list all BLE devices using the CGCentralManager class.
This has worked for years. But now, when I start my app, the following output appears in Xcode:
[CoreBluetooth] No name or address
[CoreBluetooth] No name or address
[CoreBluetooth] No name or address
[CoreBluetooth] No name or address
[CoreBluetooth] No name or address
The macOS Console app has many messages like this (I don't know if this is related, the process is bluetoothd instead of my app):
Destroying pairing agent for session <appname>
Erasing session 0x7f795824af00 from SessionMap for "appname-2890-84"
Received 'stop scan' request from session "com.apple.bluetoothd-central-143-2" updateScanParams:YES shouldUpdateState:YES
Stopping scan as there are no remaining scan agents permitted to scan
If my app is not running, the bluetoothd process seems to be rather quiet. Once started, the bluetoothd process seems to have some kind of problem. The question is: which one?
Disabling the Sandbox did not change anything, so I don't think that it has something to do with missing permissions.
I also built a very basic example in a new app. I instantiated a new CBCentralManager and started scanning. The devices were discovered.
I my main app, no delegate function is triggered. None at all.
Did anyone encounter the same issue?

UPDATE: It appears that Apple has fixed the bug in macOS 12.3.
Original answer below applies to 12.0, 12.1 and 12.2.
It appears that Apple has updated macOS to behave more like iOS. The docs for scanForPeripheralsWithServices:options: say:
Your app can scan for Bluetooth devices in the background by specifying the bluetooth-central background mode. To do this, your app must explicitly scan for one or more services by specifying them in the serviceUUIDs parameter. The CBCentralManager scan option has no effect while scanning in the background.
Command line programs cannot ever be considered the foreground app since they are not a .app and therefore the background scanning rules apply. (This is conjecture, but I suspect that NSWorkspace.frontmostApplication might be used to determine the "foreground" application).
If background scanning is acceptable and the Bluetooth devices in use include a service UUID in the advertising data, then a list of service UUIDs can be supplied to scanForPeripheralsWithServices:options:.
If not, then you have to create a signed .app to use foreground scanning.
Some additional details and an ugly workaround for running a command line tool without a GUI as a .app (outside of the XCode debugger) can be found at https://github.com/hbldh/bleak/issues/720. This link is Python-specific but one should be able to extrapolate it to other environments.

Related

How do I turn off the console on an embedded system built with Yocto?

I am running Linux kernel 4.14.149 built by Yocto Zeus, and I am running 2019.07 U-boot. At the recommendation of our security team, I am trying to get rid of the Linux console. I am not worried about debugging (once I get this to work anyways); we have other ways of getting the system logs out of the machine, and this will not be done on software development boards. That mechanism is already in place and is tested working. We have an i.MX6 as our core (this is an embedded system), and we have dedicated UART5 to our console on dev boards.
I have tried a few different methods to do this. The first was to disable the framebuffer console kernel config (CONFIG_FRAMEBUFFER_CONSOLE). The primary issue with this approach is that it disabled the splash screen. We have a splash screen that is put up in U-boot (and it is displayed again by Linux), but Linux appears to reset the framebuffer or something when it is booting, resulting in the display flickering and being blank for a bit before our applications start, which was unacceptable (and is the reason we put the splash screen up in both U-boot and Linux).
I also tried just setting "console=" on our command line. This is close to what we want to achieve in that the console doesn't come out the UART anymore, but we see it start to appear on the display on top of the splash screen. I haven't found any way to fix that (I can upload a screenshot if desired).
Just eliminating the console parameter entirely didn't appear to work, it still came out the UART. This is to be expected based on the serial console documentation which says it just uses the first available device.
I have tried commenting out the console initialization in main.c in the Linux source, which exploded rather quickly.
I tried setting to be a netconsole (see Where do you send the kernel console on an embedded system?) but the splash screen still got overwritten, same as the setting it nothing case.
The last thing I have tried was just setting it to a bogus device ("console=ttymxc9" on the Linux command line). While this appears to work (there is no data on the display or the UART) it appears to stall (crash?) partway through bootup and without being able to get the logs (it stalls before our application service runs). I say stall because we have Linux configured for a heartbeat and we do still get proper LED heartbeat behavior. None of the systemd services I added to our build however appear to run (I added one to save the journalctl log file after boot to a file on an external SD card for debugging purposes until I get this working)
At this point, I have run out of ideas on how to get rid of the console while keeping the splash screen intact. What is the proper way to disable the Linux console?
For kernel versions 5.11 and newer:
In the submenu "Character devices" under "Device Drivers" from make menuconfig, there is an option called "Null TTY driver" (CONFIG_NULL_TTY) that you can enable and add console=ttynull to the kernel boot cmdline so that all console output will be simply discarded.
You can also disable CONFIG_VT and CONFIG_UNIX98_PTYS, since you don't need to interact with your program via console at all.
For older kernels (like my 4.14):
You can add this support with the diffs at: https://lore.kernel.org/lkml/20190403131213.GA4246#kroah.com/T/ and then follow the instructions above.
More recent versions of yocto use systemd and a service called getty.target to load the serial port console. Disable by running the following command (once):
systemctl mask getty.target
This answer may not fully fit your question, however, it could serve as a research source for other users, just like me. I use the commands below to temporarily turn the console (ttyS0) on and off.
systemctl stop serial-getty#ttyS0.service
and
systemctl start serial-getty#ttyS0.service

Prompting for Bluetooth permission on Big Sur (11.0.1)

Upon upgrading to Big Sur (macOS 11.0.1), our app is now asking the user to grant permission to use Bluetooth. However, we are not running any bluetooth code to my knowledge. We do link to CoreBluetooth, but it's been like that for a long time, and this prompt has not appeared.
When running in Xcode 12.2 it does crash with this message:
2020-11-13 13:21:58.685610-0800 Fuze[31049:200367] [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothAlwaysUsageDescription key with a string value explaining to the user how the app uses this data.
But to my knowledge, NSBluetoothAlwaysUsageDescription is only applicable for iOS devices.
I suspect this is something new with Big Sur, because the System Preferences UI for Security & Privacy -> Privacy, did not have a Bluetooth section in Catalina, and it does in Bug Sur. But the Apple documentation does not make mention of this key being applicable for macOS.
https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription
So my questions are:
Is this key now applicable for macOS and we should have it, even though the documentation says it's only for other platforms, or is there a different key for bluetooth for macOS? I haven't found one.
Is there a way to control this prompting or not, because we aren't actually using the bluetooth code. We need the framework for a particular feature, but it's not applicable for many users, so it's confusing to ask permission for it right when the app launches.
Thank you!
I'm not confident about this, but I've been running into some Bluetooth on Big Sur strangeness today as well. In my case, I run a Bluetooth peripheral from the Terminal, and I was also recently prompted to provide the Terminal with Bluetooth permission (which I'd never seen before).
For testing purposes, you can try the "Privacy — Bluetooth Peripheral Usage Description" or "Privacy - Bluetooth Always Usage Description" - and see whether that resolves the crash (I assume it would). It's strange, as I didn't think either of these were required in the past - but it looks like Big Sur is definitely cracking down on permissions.
When you go to "Signing and Capabilities", if there is an option to enable "Hardware -> Bluetooth" in the "App Sandbox" - I would try that out too (you may also need to enable Location, but I can't recall). I'm curious if modifying that flag would change anything regarding permissions.
When you link to CoreBluetooth, are you using the API at all? Because the permission check should happen on the first API call. But, Bluetooth is weird, so it might kick in as soon as the app launches...
In thinking about it, I've actually never optionally used Bluetooth in an app - it's always initialized from app start, so I can't say when the permission check occurs.

Web-Bluetooth error "GATT operation not authorized" occurs on Windows only

I have been working with web-bluetooth for the past several months on iOS and ChromeOS without any problems. But today, I tried to run some of my examples on Windows for the first time, and to my surprise, most of the things I had implemented didn't work with Windows. I am able to successfully connect to my peripheral, but whenever I try reading or writing anything to a custom service with a custom characteristic, I get the error "GATT operation not authorized". I have tried looking around but there is no information anywhere about this.
I am including below the simplest example I have which is just for turning the LEDs on / off on an nrf52832 board. There is only one custom service and one custom characteristic implemented, the value of which controls the states of the LEDs. This works without any problems on Chromebooks and Macs but does not work on Windows. Here is the link to this simple project including the embedded code and the web-app.
https://github.com/shtarbanov/WebBluetooth-Feather-nRF52832/tree/master/LED%20Control
I have made two implementations of the same thing, one based on promises and another based on async-await located in the folders "WebApp (Async)" and "WebApp (Promises)", respectively. Both of those implementations work fine on Mac and Cromebook, but not on Windows.
It is a known issue that secure characteristics are not accessible using Web Bluetooth on Windows. On other platforms the pairing occurs automatically, but not on Windows. There is an issue tracking this:
https://bugs.chromium.org/p/chromium/issues/detail?id=960258
Stuck with this also and as for workaround i can recommend for windows platform to pair device firstly using windows itself and than to pair it via browser(as a workaround). Not much but hope this helps, at list a little.
P.S. it should be paired via windows only once, so PC will remember device, and than you can pair via browser as long as PC remembers device.

How can I run a distributed domain under RedHawk

I am trying to create a distributed domain using RedHawk 2.0.1 and cannot find enough information on setting it up in the manual. I have two related issues. I want to run the domain manager on the same host as the IDE but run one or more components on another node. I see how to create a new node project but do not see how to specify the network location it should run on. I can add it to the domain but it simply runs two device managers on the local host. I also do not see details of how to make specific components run on the alternate node. Does this require manually adding allocation properies?
The related issue is that I would like to use a non-x86 node as the remote node. I am trying to use an ARM processor and following the instructions in the Sub$100 manual I was able to build and install the runtime system on my ARM, but I find that the GPP device's GPP.spd.xml still has x86 as the processor name while the prf.xml has arm as the required property.
The manual seems to indicate that the binaries for all nodes will be in the sdr of the domain manager, so am I supposed to copy the sdr entries for my arm gpp device and all components back to the sdr of the domain manager host and then they will be deployed back to my arm at domain and waveform launch?
Are there better detailed instructions for distributed domains somewhere that I am missing?
I believe the last supported version of REDHAWK for the Sub$100 project was 1.10, so we're in uncharted territory. That being said, let's take a stab at it.
The first thing you should do is make sure the /etc/omniORB.cfg file for your Domain Manager looks like this:
InitRef = NameService=corbaname::<external IP>:2809
InitRef = EventService=corbaloc::<external IP>10.3.1.245:11169/omniEvents
where should be replaced with your network IP (i.e., not localhost or 127.0.0.1). Restart the CORBA naming and event services with this command:
sudo $OSSIEHOME/bin/cleanomni
The next step is to configure your ARM device to point to the Domain Manager. Edit the /etc/omniORB.cfg file on the ARM device to match the one from your Domain Manager, even the IP address. Note that you don't have to start the naming and event services on the ARM device.
Now for running the GPP on the ARM device, you will have to create that node on the ARM device, since the Domain doesn't know about that device yet and cannnot access its filesystem. Page 16 of the 1.10 version of the Sub$100 document (http://ufpr.dl.sourceforge.net/project/redhawksdr/redhawk-doc/1.10.0/REDHAWK-Sub100-Manual-v1.10.0.pdf) has the instructions for installing the GPP.
Note that the newest version of the GPP is actually a C++ Device now, so the second step should be 'cd framework-GPP/cpp' and the third step should be 'git checkout 2.0.1'. Once that's installed, there are still a couple of more issues to take care of. First, run the following command:
$SDRROOT/dev/devices/GPP/cpp/devconfig.py --location $SDRROOT/dev/devices/GPP
That will configure your GPP to recognize that it is on an ARM platform (as long as your processor is an armv7l processor).
Next, run the following:
$SDRROOT/dev/devices/GPP/cpp/create_node.py --domainname <RH Domain Name>
That will actually create the DeviceManager profile that will contain your GPP.
The final step involves making sure that the node will be configured correctly. Check out Page 21, Steps 5. Basically you can remove the x86_64 implementation and replace any instances of 'x86' with an 'armv7l'.
As for your question about building your components, yes, you have to build them for the platform of interest and then install them to the Domain Manager SDRROOT. If you have a cross-compiler set up to build your components (and the framework), this will make your life a lot easier. However, if you don't, the workaround is to build the components on your ARM device, then install the XML files and the executable to the Domain. In order to make any components work with your ARM GPP, they will need to have an ARM implementation with a processor name that matches that of your GPP in their SPD.
I know that's a lot and I haven't run through these instructions in a while, so let me know if you have any questions or anything doesn't work.
apparently replies are very limited in length so I'll call this an answer. Thanks for your response. I have actually tried part of this but will try to see if your information gets me any further. After writing this question I explored a little further. I found that the code I had compiled on the ARM and installed still had "x86" and "x86-64" in the domain profile for the device manager and no "armv7l" so I patched the profile and tried starting the device manager on the ARM manually (after setting the omniORB.cfg to point to the name server on the domain manager host. It started up fine and said it was trying to connect, and the name server on the domain manager host now had an entry for the ARM device manager but the IDE did not list the additional device manager and if I killed the ARM device manager it said that it was intrupted while waiting to register so I assume that the device manager registered with the name server but never got a reply from the domain manager. This does not make me hopeful that your steps will work, but I'll give them a try.
Update. Following more closely the steps in sub$100 document, it appears that $SDRROOT/dev/devices/GPP/cpp/devconfig.py did not edit GPP.spd.xml to put in the correct processor and compiler version but after hand editing these, I was able launch the full domain (domainManager, deviceManager, GPPdevice) on the ARM processor and was able to connect to this running domain from the IDE running on x86. After exporting and rebuilding my waveform components and editing their domain profiles I was able to use the IDE to launch successfully a very small three component waveform and control it. So running the entire domain on the ARM works ok.
But I still cannot start the deviceManager on the ARM and have it register with the DomainManager on x86 (after editing the DCD to point to the x86 domain, ie, running a distributed domain with two nodes. It starts and says it is registering with the domainManager, and it must partly succeed because the devMgr shows up in the NamingService under the domain, but the IDE never shows the new deviceManager in the domain. And the devMgr never starts the GPPdevice. If the devMgr is killed it prints "Interrupted waiting to register with DomainManager", so even though it got registered into the Naming Service it appears that the DomainManager never replied to the registration request.

Intermittent Issue with SCAN_Enable error on app load

I acquired a batch of WT0490 wearable pdas with detachable scan head, so converted an application originally made for Windows Mobile (which has been running perfectly for several years) to run on the WT4090s. The devices use these versions:
Windows CE 5.0
EMDK 2.6
ASP.net CF 2.0
Since rollout I've seen some very frustrating behaviour, which seems to start happening after the devices have been operating a few days. Users are reporting the following error:
Unexpected error in application
SCAN_Enable
There doesnt seem to be any noticeable pattern, several devices will be working perfectly for a few days then suddenly this error will show. THen a few days and a few reboots later they work again.
All devices were taken right back to stock settings then our cabs deployed to them. All identical models. We've tried altering memory allocation, swapping scanner headers etc but there is no pattern.
The error seems to occur on load of the first form after login, the login screen displays a list of users in a dropdown with a password box so that part of the app works ok, it seems to be when the scanner is initialised that this failure happens.
I had 40 devices, now 30+ have gone down with this same issue so my gut is telling me its a software issue but as yet ive not been able to find out why.
We've tried warm boots, cold boots, complete reprovisionings as well. We have a couple of dev units that don't show the problem although they are not in regular use so maybe we just haven't seen the problem 'yet'.
I hope someone out there has had this issue and knows how to fix it.
Thanks in advance.
WT4090 was built by Motorola Solution enterprise business, now part of Zebra Technologies. The WT4090 is currently in EOS (End Of Sales) but is still supported by Zebra if you've a maintenance contract.
You can check if you've the latest OS version and fixes installed on the device looking on Zebra Technologies support website.
For question on how to develop for Zebra Technologies devices you can take a look at Launchpad, Zebra's developer community website.
It's Worth noting that these devices have detachable barcode scanners - so if the scanner is not correctly attached, you get a SCAN_Enable error.
If you don't release the scanner, you can also see this error as a previous form could have the scanner blocked.
You may also find you have the ScanWedge app running - this will also block the scanner so you cannot get it enabled. The EMDK needs exclusive access to the scanner to enable it.

Resources