I'm trying to send a message from an Android companion app to a Pebble watchface app, but this fails with an APP_MSG_BUSY error. Reading the logs, I can reconstruct the following sequence of events, which is happening repeatedly:
Pebble app calls app_message_outbox_send.
Android companion app receives PebbleDataReceiver.receiveData call.
Android companion app calls PebbleDataReceiver.sendAckToPebble(context, id).
Pebble app receives outbox_sent call.
Android companion app does some work which takes less about 70ms.
Android companion app calls PebbleKit.sendDataToPebble.
Pebble app receives inbox_dropped call with APP_MSG_BUSY.
adb logcat shows the following warnings:
Pbl : [AppMessage] there is not UUID for transactionId : -1
Pbl : [JsInAppMessageHandler] sendAckNackToJs: run: can not send ack message to javascript code because uuid is null
APP_MSG_BUSY suggests there is an incoming or outgoing message in progress. However, you can see from the events above that there is no outgoing message. Also, this is happening for every incoming message, even the first that the Pebble app receives after restarting.
Can anyone offer some insight into what's going on here?
I found my mistake: when I called app_message_open, I passed a value for size_inbound that was too small to receive any of the messages that were being sent. Unfortunately, the AppMessageResult given to my inbox_dropped function wasn't APP_MSG_BUFFER_OVERFLOW as one might expect, but APP_MSG_BUSY.
Now for sheer speculation: what might have exacerbated this was that size_outbound was large enough. In fact, my mistake was swapping the size_inbound and size_outbound arguments. Maybe, by some logic, it didn't make sense to send APP_MSG_BUFFER_OVERFLOW because at least one of the buffers was large enough?
Related
Working on an Android app to send data to a peripheral device via BLE. Question about Android BluetoothGATTCallback onCharacteristicWrite function - how does it know that the write transaction was successful? Is success assumed so long as no error occurs? Or does it record a success response of some sort sent from the peripheral device characteristic to which data is written?
I would say matdev's comments in his answer is not correct, at least according to my experience.
Assuming you use "Write With Response" (WRITE_TYPE_DEFAULT) rather than "Write Without Response" (WRITE_TYPE_NO_RESPONSE), the following applies:
First you call writeCharacteristic. This method performs some sanity checks, such as the characteristic you are trying to write to has the "write" property, there are no other pending GATT operations on this BluetoothGatt object, and that the object is not closed. If those sanity checks are passed, this method returns true.
The write request is then transferred over the air to the remote device's GATT server. Here the request is processed and the GATT server returns a Write Response or an Error Response with an error code, which is sent back to the Android device. When Android receives a Write Response, it will call onCharacteristicWrite with GATT_SUCCESS (0) as status. If Android instead receives an Error Response, it will call onCharacteristicWrite and set the status to the code included in the Error Response. If the GATT server e.g. returns 0x80 (Application Error) or 0x13 (Value Not Allowed), this is the status code you will receive in your callback.
If the connection drops before the response is received, Android will call the callback with some currently undocumented non-success status code.
If you instead use "Write Without Response" (WRITE_TYPE_NO_RESPONSE), the behaviour of onCharacteristicWrite changes. Now, this callback is instead used for flow control. When the local Bluetooth stack's buffers are ready to accept another packet, this is when you will get the callback. This can happen even before the packet is sent over the air.
You can assume the BLE write transaction is successful if the status param of BluetoothGATTCallback's onCharacteristicWrite() equals BluetoothGatt.GATT_SUCCESS i.e. 0
If an error occurs, the status value will indicate the type of error, such as
/** GATT write operation is not permitted */
public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
Here is an extract of the doc about onCharacteristicWrite():
Params:
...
status – The result of the write operation BluetoothGatt.GATT_SUCCESS if the operation succeeds.
I am using firebase v4 to push notifications to android devices. When the Send method of the instance of messaging.Client fails, I only get a string error value and I wonder if this error string is localized. If not, I could compare it against e.g. "Requested entity was not found." to detect devices that have uninstalled my app. Is this string always plain english or does this depend on the locale the app is running under? Or does this error string come from the server, so I can never be sure if it stays the same?
What other options do I have to properly detect such an error, even if my golang binary runs on computer systems with any locale or language? I am running my golang binary on windows.
Any help or insights appreciated,
--
Stefan
In general, all error messages from Firebase SDKs are in English only. They are generally not suitable for display or comparison in an app. You should instead use the provided error codes (which will not vary) in the error or exception object to determine what exactly went wrong.
I have an expected last-minute failure regarding the interaction of our code with a Telegram bot API. I have been using a Nordic Sem. gently provided Telegram related code running over its nRF9160 chip.
Everything has worked properly and continuously for several days, with the mentioned code managing both outcoming and incoming Telegram messages successfully and without interruption until last week, when the code suddenly become unable to deal with the Telegram API and started delivering the errno22 each time it executed the send function below stated.
int num_bytes = send(client_fd, send_buf, send_data_len, 0)
Error:
ERROR!!! -> num_bytes = -1
As far as I know, this error means Invalid Argument, but I do obviously pass to the function the same arguments used from the beginning of the successful tests (nothing has been changed between successful and failed operation), so I cannot understand this unpredictable program break.
On the other hand, I have been aware that last week Telegram deprecated the use of TLS versions 1.0 and 1.1 and strongly recommended developers to upgrade to 1.2v to avoid service interruption. Theoretically, this update should not suppose a problem since the code provided by the chip support staff states within its arguments the TLS 1.2 version (see below) and, thus, I must assume that this is the version currently use by the chip manufacturer.
int client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2)
Nevertheless, information about this subject or any detected issues concerning the new TLS Telegram requirements would be very much appreciated as well as any other suggestion of how I can work around this issue.
Failed biometric(fingerprint) scan attempts are handled by OnAuthenticationFailed() callback of BiometricPrompt.AuthenticationCallback class.
The behavior I noticed is, it lets the user attempt 5 invalid fingerprint scans (each time the fail callback is invoked) and then the prompt dismisses. Within the next 30 secs, if we try to re-build a BiometricPrompt instance and try to authenticate, it does not show the prompt which I think is the default behavior of BiometricPrompt.
Is there anyway to check if the biometric scanner is available and initialised if the user attempts to re-invoke biometric prompt within the said 30secs?
How can I handle that use case?
xamarin android BiometricPrompt.AuthenticationCallback does not have an override method "onAuthenticationError" to handle error callbacks and thus I'm unable to handle error code "BIOMETRIC_ERROR_TIMEOUT".
If someone has a solution for this, please do let me know your resolution.
I believe that BiometricPrompt is not fully ported to Xamarin yet...
I'm still looking for a source that can double check this info for me, but I haven't found it either.
I'm building a simple talker/listener app that receives OSC data through UDP. I'm using OSCKit pod which itself uses CocoaAsyncSocket library for the internal UDP communication.
When I'm listening to a particular port to receive data from another OSC capable software, I log the received commands to a NSTextView. The problem is that sometimes, I receive thousands of messages in a very short period of time (EDIT: I just added a counter to see how many messages I'm receiving. I got over 14000 in just a few seconds and that is only a single moving object in my software). There is no way to predict when this is gonna happen so I cannot lock the textStorage object of the NSTextView to keep it from sending all its notifications to update the UI. The data is processed through a delegate callback function.
So how would you go around that limitation?
///Handle incoming OSC messages
func handle(_ message: OSCMessage!) {
print("OSC Message: \(message)")
let targetPath = message.address
let args = message.arguments
let msgAsString = "Path: \"\(targetPath)\"\nArguments: \n\(args)\n\n"
print(msgAsString)
oscLogView.string?.append(msgAsString)
oscLogView.scrollToEndOfDocument(self)
}
As you can see here (this is the callback function) I'm updating the TextView directly from the callback (both adding data and scrolling to the end), every time a message is received. This is where Instruments tell me the slow down happens and the append is the slowest one. I didn't go further than that in the analysis, but it certainly is due to the fact that it tries to do a visual update, which takes a lot more time than parsing 32bits of data, and when it's finished it receives another update right away from the server's buffer.
Could I send that call to the background thread? I don't feel like filling up the background thread with visual updates is such a great idea. Maybe growing my own string buffer and flushing it to the TextView every now and then with a timer?
I want to give this a console feel, but a console that freezes is not a console.
Here is a link to the project on github. the pods are all there and configured with cocoapods, so just open the workspace. You guys might not have anything to generate that much OSC traffic, but if you really feel like digging in, you can get IanniX, which is an open-source sequencer/trajectory automator that can generate OSC and a lot of it. I've just downloaded it and I'll build a quick project that should send enough data to freeze the app and I'll add it to the repo if anybody want to give it a shot.
I append the incoming data to a buffer variable and I use a timer that flushes that buffer to the textview every 0.2 seconds. The update cycle of the textview is way too slow to handle the amount of incoming data so unloding the network callback to a timer let the server process the data instead of being stopped every 32bits.
If anybody come up with a more elegant method, I'm open minded.