QLowEnergyService never transitions to ServiceDiscovered state on custom bluetooth service - qt

I have created a Bluetooth communicator in Qt 5.5.1 following the Qt documentation. I have gotten to the point where I am able to view a list of services offered by a Bluetooth device. The services are generated by:
QLowEnergyService *service = controller->createServiceObject(serviceUuid);
Where controller is a QLowEnergyController and serviceUuid is a QBluetoothUuid. The service is created successfully but since it is a custom service offered by the device I am trying to connect to, the name is unknown. At this point I call:
service->discoverDetails();
which transitions the service to the QLowEnergyService::DiscoveringServices state from the QLowEnergyService::DiscoveryRequired state. Once this happens, the state never changes again and no error is ever thrown. Is there a way to pull the characteristics of an "unknown service"? I have checked the Uuid against what I expected for the service and it is correct. I also have the Uuid of the expected characteristics.

Note: I am using a pyqt (Python binding library of QT C++).
I stumbled upon issue while trying to connect to some device which offers two services. One is the standard battery service and another is private custom non-standard service.
I noticed that I was able to discover the batter service successfully, but I was not able to discover that custom service. However, for some reason, when I subscribed to service_error signal, the discovery works fine, and whenever i comment it out, it does not work.
void QLowEnergyService::error(QLowEnergyService::ServiceError newError)
I know it is funny and I do not have an explanation, but it could be related and i felt it is worth sharing.

QMetaObject::invokeMethod(this, "discoverCharacteristics", Qt::QueuedConnection);
void discoverCharacteristics() {
service->discoverDetails();
}

Related

Missing videoTrack in a multitrack stream in Ant media server 2.4.1

We have a Multitrack web conference implementation using AMS 2.4.1 version. Its working great for our use case, except in one scenario. When there are N (< 3) number of users and they on there camera simultaneously, then few remote users are not rendered as we don't receive the video tracks for those users in newStreamAvailable. We only receive the audio track for those users. We are able to reproduce this quite frequently.
As a backup, I am trying to poll AMS using getTrackList with the main track Id to get all available streams, but I am not getting any message trackList
var jsCmd =
{
command : "getTrackList",
streamId : streamId, // this is roomId or main track id
token : token
}
Any insight would be helpful.
Thanks,
We were able to resolve the issue, posting here to help anyone who might be facing a similar issue.
With push notifications from the server, we might encounter issues when for some reason push operation doesn't succeed. In that case, it's better to have a backup plan to pull from the server and sync.
The Ant Media Server suggests pulling the server periodically for the room info. The server will respond with active streams and the application should synchronize.
For reference, please refer to following link https://resources.antmedia.io/docs/webrtc-websocket-messaging-reference

propagate OpenTracing TraceIds from publisher to consumer using MassTransit.RabbitMQ

Using MassTransit.RabbitMQ v5.3.2 and OpenTracing.Contrib.NetCore v0.5.0.
I'm able publish and consume events to RabbitMQ using MassTransit and I've got OpenTracing working with Jaeger, but I haven't managed to get my OpenTracing TraceIds propogated from my message publisher to my message consumer - The publisher and consumer traces have different TraceIds.
I've configured MassTransit with the following filter:
cfg.UseDiagnosticsActivity(new DiagnosticListener("test"));
I'm not actually sure what the listener name should be, hence "test". The documentation doesn't have an example for OpenTracing. Anyways, this adds a 'Publishing Message' span to the active trace on the publish side, and automatically sets up a 'Consuming Message' trace on the consumer side; however they're separate traces. How would I go about consolidating this into a single trace?
I could set a TraceId header using:
cfg.ConfigureSend(configurator => configurator.UseExecute(context => context.Headers.Set("TraceId", GlobalTracer.Instance.ActiveSpan.Context.TraceId)))
but then how would I configure my message consumer so that this is the root TraceId? Interested to see how I might do this, or if there's a different approach...
Thanks!
If anyone is interested; I ended up solving this by creating some publish and consume MassTransit middleware to do the trace propagation via trace injection and extraction respectively.
I've put the solution up on GitHub - https://github.com/yesmarket/MassTransit.OpenTracing
Still interested to hear if there's a better way of doing this...

How to check if the biometric scanner is available and initialized in Xamarin android BiometricPrompt

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.

Qt 5.8 How to use the SCXML framework with sub state machines?

I am trying to build a system, which is orchestrated by a main state machine and has different sub state machines for the tasks it is executing. Being a long-time Qt user I looked at the new SCXML implementation in Qt 5.8. However I cannot figure out how to use the API provided with 5.8 to implement sub state machines properly.
My idea is to use a main state machine and then invoke the specific sub state machines in the states of the main state machine. While invoking the sub state machines works I could not figure out how to access them after the top state machine objects emits invokedServicesChanged(..) I can access the pointer to QScxmlInvokableService but not to the concerning state machine.
Also the top level state machine object only exposes states and events from the top and not from the invoked state machines. For example topLevelStateMachine->activeStateNames() only lists the top states.
Looking at Qt's source code I saw that QScxmlInvokableService is actually a the base class for QScxmlScxmlService which contains a pointer to the concerning state machine. Unfortunately QScxmlScxmlService is defined in qscxmlinvokableservice_p.h which is private as the _p in the name indicates. So how am I supposed to use the public SCXML API? Am I missing something? IIRC SCXML support was a technical preview in 5.7 but is now included in 5.8 as part of the normal distribution.
I spent the last week or so studying the examples and then writing my own state machine and code that responds to it. It took a while as the documentation is not as clear as it could be.
I have found that activeStateNames does retrieve all states contained within the state machine, including sub-states.
It took me a couple of readings of the traffic light example to get figure this out. The key is that the sub-state machines are contained in specific states. (The graphical view of the state machine helps here.)
In the example there are only two states in the over-all, top-level machine: working and broken. The transitions are controlled by events smash and repair.
Within each of the two states are smaller state machines. Broken contains a state machine of two states: blinking and unblinking. That state machine starts in the state blinking when broken is entered.
When the in the sub-state blinking of broken, activeStateNames will return blinking if called with false (defaulted) or blinking and broken when called with true.
So how do you use this?
If I have something I want to set/unset according to a specific state, I can connectToState in the machine. The slot I connect to will get called when the state changes between active and inactive, and it will receive a boolean value saying if the state is active. In the traffic light example, the state red is connected to the redLight. Since redLight should be on when in the red state and not otherwise, it is connected to a slot takes a boolean: true turns the light on, false turns it off.
Okay, but what if I want to catch an event when I enter a state?
I simply select the state, then add an onEntry -> send and specify the event name. This will cause an event to be sent when I enter the state. This event can be routed to a slot (in Qt 5.8) using connectToEvent. [The Qt 5.7 version only has a generic eventOccurred signal which you can send to a slot and then query which event using event.name().]

Are group subscriptions automatically handled on Reconnect?

I have a chat room using SignalR Hub for its messaging. Occasionally I get reports from users where it 'freezes'. Now this can be interpreted as no messages are coming through, I suspect as they have been dropped from a group.
My question is, does the connection get re-subscribed back into its groups automatically, or do you have to do something yourself in the Reconnect method:
public Task Reconnect(IEnumerable<string> groups)
{
return Clients.rejoined(Context.ConnectionId, DateTime.Now.ToString());
}
Yes, in 1.0.0.0-alpha1 you can enable auto rejoining of groups by using the new AutoRejoiningGroupsModule pipeline module using the EnableAutoRejoiningGroups extension method for the hub pipeline you build. This feature was not available in previous versions of the framework.
So you would end up with this somewhere in your startup code:
GlobalHost.HubPipeline.EnableAutoRejoiningGroups();
UPDATE:
Please note that the final version of SignalR 1.0 made auto-rejoining of groups the default behavior and so EnableAutoRejoiningGroups was removed. You can see this answer for more details.

Resources