Is it possible to programmatically access the error codes logged by CoreBluetooth? - iphone

I am implementing a BLE central device on the iPhone, using as peripheral a custom BLE device developed (whose firmware has been written by a colleague).
The peripheral for some operation will return a BLE error code, conforming to the standard Bluetooth ATT error codes as defined in BLE specifications.
On the iPhone side, where I'm using the CoreBluetooth stack to develop the central device, I am notified of such errors on the debugger output window of xCode as:
CoreBluetooth[WARNING] Unknown error: XX
and then I receive in the callbacks a CBError* object. My problem is that the CBError* object which I get in the callback (e.g., in CBPeripheralDelegate's didWriteValueForCharacteristic callback) just contains code=0 and localizedDescription="Unknown error".
Is it possible to retrieve somehow the error code which is logged on the debugger output window by the CoreBluetooth stack?
From my research it appears that CoreBluetooth maps almost all BLE standard error codes into "unknown errors" (with internal code 0, see CBError reference); I would like to get more detailed error codes, like those coded by CBAttError.

In an application you can only use the CoreBluetooth APIs. Those expose only CBError which, as you see it right in many cases can mask the real error. So the answer for officially accessing the source errors is that you can't do it.
However, if you want, you can access the Apple System Logs programmatically. (See post: Using Objective C to read log messages posted to the device console) You can define a query to return the items you are interested in and try to deduct the real reason of the error. This is a heuristic method but at the moment, unfortunately, we have no other way to do it.

Related

NRF52 How to erase a protected firmware program (knowing the protected password)

I'm trying to deploy a new firmware to my hardware device but I get the following error in the nrf Connect (v3.6.1) Programmer (v1.4.8):
16:47:36.937
Error when getting device info: Error: Error: Error occured when get device info. Errorcode: CouldNotCallFunction (0x9) Lowlevel error: NOT_AVAILABLE_BECAUSE_PROTECTION (ffffffa6)
16:47:36.937
Could not fetch memory size of target devkit: Cannot read property 'family' of undefined
I cannot read nor erase from the device through the programmer because of this error.
I assume this is because the device is password protected. I know this password, is there a way to erase the device's current firmware?
(I'm using the NRF52-DK to connect/program with it, and the pins are accessible, which is how I'm connecting and I know the chipset is a nrf52840)
Wiring now is as followed:
So I'm currently not using the debug output to connect with the device
I've provided power to the custom device by batteries now, no change in the result.
It's unclear what you mean by a "device password" for the nRF52840.
NOT_AVAILABLE_BECAUSE_PROTECTION occurs when the APPROTECT register has been enabled. According to the nRF52840 product spec
Access port protection is disabled by issuing an ERASEALL command via CTRL-AP
Alternatively, if you are using pynrfjprog, the recover() method removes the protection.
No matter what, flash will always be erased when clearing APPROTECT (unless utilizing the APPROTECT power glitch, but that's another topic)

Core Bluetooth: Cannot get iPhone (the central) and Mac (the peripheral) to pair

I am developing an iPhone application and a Mac application that communicate with each other via Bluetooth LE. The iPhone is the central, and the Mac is the peripheral. I would like the iPhone application to be able to reconnect to the Mac application after a relaunch. Therefore, I save the UUID of the peripheral representing the Mac in NSUserDefaults, and then when the iPhone app launches, I call -[CBCentralManager retrievePeripheralsWithIdentifiers:], passing in the UUID. Although this method returns the peripheral, when I call -[CBCentralManager connectPeripheral:options:], the iPhone never reconnects to the Mac. According to this SO post, the problem is that the two devices need to be paired so that the UUID of the Mac is persistent. This brings me to my problem. I cannot for the life of me get the iPhone and the Mac to pair. According to this page of the Core Bluetooth Programming Guide, the way to require a paired connection is for the peripheral to set the characteristic's properties and permissions to the appropriate values. I quote:
You can ensure that only trusted devices have access to sensitive characteristic values by setting the appropriate characteristic properties and permissions. To continue the example above, to allow only trusted devices to retrieve a member’s email address, set the appropriate characteristic’s properties and permissions, like this:
emailCharacteristic = [[CBMutableCharacteristic alloc]
initWithType:emailCharacteristicUUID
properties:CBCharacteristicPropertyRead
| CBCharacteristicPropertyNotifyEncryptionRequired
value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
However, this does not work. Even when I set the correct permissions and properties for the characteristic, the iPhone can still read/write to it without a pairing dialog being displayed. Elsewhere I am told that the way to initiate pairing is for the peripheral to reject a read/write request with an insufficient authentication error. According to this post,
To pair, you need to respond to a write request with an insufficient authentication error. For example, for an iOS peripheral you would write something like:
- (void)peripheralManager:(CBPeripheralManager *)peripheralManager didReceiveWriteRequests:(NSArray *)requests {
...
[peripheralManager respondToRequest:request withResult:CBATTErrorInsufficientAuthentication];
...
}
But this still doesn't work! When the Mac rejects the write request with an insufficient authentication error, the iPhone receives a -[CBPeripheralDelegate peripheral:didWriteValueForCharacteristic:error:] callback with an error that says, "Authentication is insufficient." No pairing dialog. I have no idea what to do and am considering dropping Core Bluetooth altogether if I cannot get this to work. If you have any idea how to get this to work, please let me know.
From Apple DTS:
"I have checked with other engineers here and we don’t believe that the pairing popup is possible between two iOS devices, but an iOS device and a BLE peripheral."
So, pairing popup happens only between a iOS/Mac app and a peripheral. rdar time.

iPhone iAds: Very inconsistent, sometimes bannerViewDidLoadAd does not get called

So I show my iAd banners when I get a callback to:
'bannerViewDidLoadAd'
But I've noticed that sometimes this doesn't get called. I have a constant high-speed
internet connection but if I run my app 10 times. 4 of out 10 times it won't show the iAds (i.e., bannerViewDidLoadAd does not get called).
Has anyone else experienced this (and what have you done about this)?
This is by design (I'm assuming you're still running in a dev environment) so that you can test your application when an iAd is available and when an iAd isn't available.
While you are developing your
application, iAd Network sends test
advertisements to your application. To
assist you in validating your
implementation, the iAd Network
occasionally returns errors to test
your error handling code. You can also
test your error handling support by
turning your device’s wireless
capability off.
per Apple's documentation

iAd strange console "Unhandled error"

I'm seeing in the console:
"Unhandled error (no delegate or
delegate does not implement
didFailToReceiveAdWithError:):"
Although didFailToReceiveAdWithError is being invoked (I can see that with check points and in the console log)
Does someone has any reasonable explanation? It's like it's working and not working all in the same time. I'm not using IB for the adview, and have added it programmatically and have set the adview.delegate = self. I'm also using three20 in this project if that changes anything.
It's like sometimes he knows who's his delegate and sometime not...
The Apple documentation says:
While you are developing your application, iAd Network sends test advertisements to your application. To assist you in validating your implementation, the iAd Network occasionally returns errors to test your error handling code.
In my app iAd also returns a mix of correct banners, error 3, error 5, ... and so on. Maybe this problem will disappear after the release of the app when iAd changes from
iAd Network serves test ads
to
iAd Network serves live ads if you signed the iAd Network Agreement and enabled advertising for your application

iPhone Crash Catching Options on Published Apps

I am wondering about embedding the CrashCatcher framework (http://code.google.com/p/plcrashreporter) in a production app. I have written some code that will upload a crash report directly to a server. And, my intent on this was to have quicker access to crash reports and not need to go through Apple/iTunes to get them.
Does anyone know whether or not embedding the CrashCatcher framework is likely to pass the application review process? And, if it does, is it likely to cause any problems or conflict with the crash catching mechanisms that Apple has built into iTunes/iTunesConnect?
Thoughts?
I corresponded with one of the authors of CrashReporter, Landon (thank you!), to provide some additional clarity on this.
Apparently, the mechanisms used by CrashReporter (signals) and Apple's crash catching (Mach exceptions) are distinct and mutually compatible.
Do you understand the differences between how Apple is catching crashes vs CrashReporter? I have not looked closely at the CrashReporter source, but from what I read/remember it works by registering signal handlers? Is this accurate?
Right -- PLCrashReporter registers standard signals handlers for the signals its interested in:
http://code.google.com/p/plcrashreporter/source/browse/trunk/Source/PLCrashSignalHandler.m#41
http://code.google.com/p/plcrashreporter/source/browse/trunk/Source/PLCrashSignalHandler.m#223
Do you know if Apple leveraging a different mechanism?
Apple makes use of a Mach exception handler to implement their crash reporting on both Mac OS X and the iPhone; mach exceptions can be handled by an exception server (either in-process or external to the process) -- the default kernel-provided UNIX exception handler maps mach exceptions to UNIX signals.
The UNIX exception handler is registered here:
http://fxr.watson.org/fxr/source/bsd/kern/bsd_init.c?v=xnu-1456.1.26#L999
For crash reporting, the advantage of the Mach exception API is that you can simply pass the unmodified exceptions directly on to the next handler. I investigated implementing this early on, but the necessary API is private[1], so settled on registering standard UNIX signal handlers. If you want to read more about the Mach exception system, I'd recommend starting with Chapter 9, Section 7 of Mac OS X Internals.
Cheers,
Landon
[1] Unity 3d recently ran issues with mach exception private API via exc_server():
http://blogs.unity3d.com/2009/11/14/unity-iphone-app-store-submissions-problem-solved/
I'm using a service called Crittercism (saw it on Techcrunch) on my production apps. Haven't had any problems with the app store.
www.crittercism.com
The guys that created the framework got numerous apps on the store. If someone uses it successfully in a production app, they must know about it. You should try to contact: http://www.plausiblelabs.com/
It should be fine, however you should give users the choice as to whether you send back the crash report.
When we did it we pre populated an email when the app started after a crash with the appropriate stacktrace in it. The user could the choose to send or not.