Scanning for and handling reception of multiple services in CoreBluetooth Framework? - core-bluetooth

When I scan for 2 peripherals each having a single service and characteristic (with cServiceArray being an NSArray of both service CBUUIDs) with the method:
[self.centralManager scanForPeripheralsWithServices:cServiceArray options:#{CBCentralManagerScanOptionAllowDuplicatesKey : #NO }];
I receive the following console response:
2013-10-18 13:58:37.069 BlueMarco[1137:60b] didDiscoverPeripheral peripheral description <CBPeripheral: 0x14e799d0 identifier = 33C98AC7-E25E-0803-82D2-326FC8C0FDB1, Name = "ICServer_2", state = disconnected>
...
2013-10-18 13:58:37.072 BlueMarco[1137:60b] didDiscoverPeripheral Connecting to peripheral ICServer_2
...
2013-10-18 13:58:37.076 BlueMarco[1137:60b] didDiscoverPeripheral peripheral description <CBPeripheral: 0x14e75b60 identifier = E634E343-0DCF-3A4F-1F88-D4C87EA731EA, Name = "ICServer_1", state = disconnected>
...
2013-10-18 13:58:37.079 BlueMarco[1137:60b] CoreBluetooth[WARNING] <CBPeripheral: 0x14e799d0 identifier = 33C98AC7-E25E-0803-82D2-326FC8C0FDB1, Name = "ICServer_2", state = connecting> is being dealloc'ed while connecting
2013-10-18 13:58:37.080 BlueMarco[1137:60b] didDiscoverPeripheral Connecting to peripheral ICServer_1
This shows the connection to one peripheral broken as I make a connection to the second server. Is this the expected behavior? If so, why does the method scanForPeripheralsWithServices allow an NSArray of service CBUUIDs as an argument? If not, can anyone show me how to scan for and handle the reception of multiple services?

The line showing CoreBluetooth[WARNING] indicates that you did not keep a strong reference to the CBPeripheral object in question and thus it is being deallocated despite the fact that a connection operation is in progress.
Make sure that as long as you use a CBPeripheral, you keep a strong reference to it or it will be automatically garbage collected by the system. This is probably not emphasized enough in the Core Bluetooth Programming Guide but is a must for correct operation.

Related

Issue with Synchronisation of Agents from different types in a shared discrete space projection

I have an issue regarding the synchronisation of different agents.
So I have a shared context with a BaseAgent class as the tutorial suggested for the case where we have more than 1 agent type in the same context. Then I have 4 more agent classes which are children of the Base Agent Class. For each of them I have the necessary serialisable agent packages and in my model class I also have specific package receivers and providers for each one of them.
All those agents are sharing a discrete spatial projection of the form:
repast::SharedDiscreteSpace<BaseAgentClass, repast::WrapAroundBorders, repast::SimpleAdder< BaseAgentClass > >* discreteSpace;
Three of my 4 agent types can move around and I have implemented their moves. However, they can move from one process to another and I need to use the 4 synchronisation statements which were introduced in the RepastHPC tutorial HPC:D03, Step 02: Agents Moving in Space.
The thing however is that I am not certain how to actually synchronise them, since the agents would need their specific providers, receivers and serialisable packages in order to be copied into the other process correctly. I tried doing the following:
discreteGridSpace->balance();
repast::RepastProcess::instance()->synchronizeAgentStatus<BaseAgentClass, SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver>(context, *specificAgentProvider, *specificAgentProvider, *specificAgentReceiver);
repast::RepastProcess::instance()->synchronizeProjectionInfo<BaseAgentClass, SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver>(context, *specificAgentProvider, *specificAgentProvider, *specificAgentReceiver);
repast::RepastProcess::instance()->synchronizeAgentStates< SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver >(* specificAgentProvider, * specificAgentReceiver);
However, when running I get the following error:
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 3224 RUNNING AT Aleksandars-MBP
= EXIT CODE: 11
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault: 11 (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
So I am not certain how to actually synchronise the agents for each specific agent type, since they are all sharing the same context and spatial projection with the BaseAgentClass.
Thank you for the help in advance!
The intention here is that you'd have a single package that can be used for all the agent types. For example, in the Zombies demo model, the package has entries for the agent id components, and also infected and infectionTime. These last two only apply to the Human agents and not to the Zombies.
The methods where you provide and receive content should check for the agent type and take the appropriate action. For example, in the Zombies Model we have
void ZombieObserver::provideContent(RelogoAgent* agent, std::vector<AgentPackage>& out) {
AgentId id = agent->getId();
AgentPackage content = { id.id(), id.startingRank(), id.agentType(), id.currentRank(), 0, false };
if (id.agentType() == humanType) {
Human* human = static_cast<Human*> (agent);
content.infected = human->infected();
content.infectionTime = human->infectionTime();
}
out.push_back(content);
}
Here you can see we fill the AgentPackage with some defaults for infected and infectionTime and then update those if the agent is of the Human type. This is a ReLogo style model, so some of the details might be different but hopefully it's clear that there is a single package type that can handle all the agent types, and that you use the agent type to distinguish between types in your provide methods.

Handling DisplayInformation::DisplayContentsInvalidated in D3D12

In the VS2019 project template for C++/CX D3D12, the DisplayInformation::DisplayContentsInvalidated event (documented here) is subscribed and when this event fires, the code in the project template attempts to validate the D3D12 device. The criteria being used to validate is whether the default adapter has changed:
// This method is called in the event handler for the DisplayContentsInvalidated event.
void DX::DeviceResources::ValidateDevice()
{
// The D3D Device is no longer valid if the default adapter changed since the device
// was created or if the device has been removed.
// First, get the LUID for the default adapter from when the device was created.
DXGI_ADAPTER_DESC previousDesc;
{
ComPtr<IDXGIAdapter1> previousDefaultAdapter;
DX::ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, &previousDefaultAdapter));
DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
}
// Next, get the information for the current default adapter.
DXGI_ADAPTER_DESC currentDesc;
{
ComPtr<IDXGIFactory4> currentDxgiFactory;
DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&currentDxgiFactory)));
ComPtr<IDXGIAdapter1> currentDefaultAdapter;
DX::ThrowIfFailed(currentDxgiFactory->EnumAdapters1(0, &currentDefaultAdapter));
DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(&currentDesc));
}
// If the adapter LUIDs don't match, or if the device reports that it has been removed,
// a new D3D device must be created.
if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart ||
previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart ||
FAILED(m_d3dDevice->GetDeviceRemovedReason()))
{
m_deviceRemoved = true;
}
}
However, it seems to me that the default adapter may not be the elected adapter, as you can see in this code, because it ensures the adapter can create a D3D12 device before electing it, and this same check does not exist in the validation code above:
// This method acquires the first available hardware adapter that supports Direct3D 12.
// If no such adapter can be found, *ppAdapter will be set to nullptr.
void DX::DeviceResources::GetHardwareAdapter(IDXGIAdapter1** ppAdapter)
{
ComPtr<IDXGIAdapter1> adapter;
*ppAdapter = nullptr;
for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, &adapter); adapterIndex++)
{
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
{
// Don't select the Basic Render Driver adapter.
continue;
}
// Check to see if the adapter supports Direct3D 12, but don't create the
// actual device yet.
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
{
break;
}
}
*ppAdapter = adapter.Detach();
}
Is this unintentionally relying on the default adapter being the elected adapter, or are there wider assumptions we can make based on the default adapter having changed?
What is the real meaning if DisplayInformation::DisplayContentsInvalidated? What is this telling me? Why does this suggest the device is possibly invalid? What are the cases where this event fires andthe device would or would not be invalid?
And since we are also checking for a DeviceRemovedReason here, are there cases where the default adapter doesn't change but the device was removed because of DisplayInformation::DisplayContentsInvalidated?
Do we even really need to handle this at all? What would happen if I just completely ignored this event and kept trying to render? Would I not end up handling whatever problem this event firing is indicating in the documented "device lost scenarios" per this document?
We are still investigating your question and get some information.
With regards to when the DisplayContentInvalidated Event will be triggered, it is typically invoked upon various activities including changing of the primary display or if the display configurations have changed in any other way. This would also include if there were certain types of issues occurring with the graphics, which this event should be able to be utilized to handle such situations.
With regards to the template, we ran some tests on our end and we indeed did see that the project uses the first adapter that it finds that can handle DirectX12 rather than an elected adapter. Upon further tests, we removed that particular check and found that the application does indeed continue to run as expected. The adapter may not be the one that was used to create the device at application startup. So indeed, this check does seem like it can potentially be ignored as indicated. However, having this event in the code might not hurt as it can provide the extra functionality should it be required for any situation.
Any other detailed information would likely be found in our documentation regarding this. However, it seems that the template is meant for demonstrating certain functionalities of DirextX12 and its various API’s so ignoring the DisplayContentInvalidated Event should typically not cause any issues.

Detect android wear sensor presence if related permission is not granted

My watch face needs access to heart rate sensor, and I would like to know whether there is a physical sensor present prior to asking for permission. According to documentation, I can do it in two ways:
private SensorManager mSensorManager;
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_HEART_RATE);
or
boolean heartRateSensorEnabled = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE) != null;
However, if permission is not granted (which is by default), I get empty sensor list and also no default sensor. That makes me force ask for permission even if it is meaningless (Sony SW3, for example, doesn't have the sensor). Is there a way to differentiate between "permission denied" and "no sensor present"?
Try looking into requestPermissions
https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,java.lang.String[], int) method. It has callback ActivityCompat.OnRequestPermissionsResultCallback which returns if the permission is denied or not.
To check if sensor is present or not, try to use the code in this SO thread where he listed the sensors and looked for TYPE_HEART_RATE.

Detecting if existing serial connection is lost due to device unplugged on Windows

I'm calling Win32 ReadFile to read from a Windows serial port. If my device is unplugged, ReadFile still returns success. How can I check if the connection to the device has been lost? I could do this by sending a message and not getting a response or listening for device events but is there any more straightforward way?
Serial ports are dumb in that there is no device independent way of knowing when something is or is/not plugged into the serial port. Because of this, most devices that use serial ports support some kind of communication protocol which will allow you to determine if something is connected or not.
Depends on the language, I am not certain if serial devices cause a device change event, and I do not have one at the moment to test.
However if PNP will pick it up I would try
From the WmiCode creator
Imports System
Imports System.Management
Imports System.Windows.Forms
Namespace WMISample
Public Class WMIReceiveEvent
Public Overloads Shared Function Main() As Integer
Try
Dim query As New WqlEventQuery( _
"SELECT * FROM Win32_DeviceChangeEvent")
Dim watcher As New ManagementEventWatcher(query)
Console.WriteLine("Waiting for an event...")
Dim eventObj As ManagementBaseObject = watcher.WaitForNextEvent()
Console.WriteLine("{0} event occurred.", eventObj("__CLASS"))
' Cancel the event subscription
watcher.Stop()
Return 0
Catch err As ManagementException
MessageBox.Show("An error occurred while trying to receive an event: " & err.Message)
End Try
End Function
End Class
End Namespace
From there you van further refine what was added or removed from the system.
It does little however for the fact the machine may have been booted without the device attached.
Either way I suggest in all communication protocols that proper communication error handing is essential. It is similar to the fact that you cannot guarantee that a socket has become disconnected between checking to see if connected and writing.

How to find the connection for a particular distributed objects method invocation?

I have a Cocoa client and server application that communicate using distributed objects implemented via NSSocketPorts and NSConnections in the standard way. The server vends a single object to the client applications, of which there may be several. Each client application can gain access to the same distributed object getting its own proxy.
The vended object supports a particular protocol, which includes a method similar to the following:
#protocol VendedObjectProtocol
- (void) acquireServerResource:(ServerResourceID)rsc;
#end
When a client application invokes this method, the server is supposed to allocate the requested resource to that client application. But there could be several clients that request the same resource, and the server needs to track which clients have requested it.
What I'd like to be able to do on the server-side is determine the NSConnection used by the client's method invocation. How can I do that?
One way I have thought about is this (server-side):
- (void) acquireServerResource:(ServerResourceID)rsc withDummyObject:(id)dummy {
NSConnection* conn = [dummy connectionForProxy];
// Map the connection to a particular client
// ...
}
However, I don't really want the client to have to pass through a dummy object for no real purpose (from the client's perspective). I could make the ServerResourceID be a class so that it gets passed through as a proxy, but I don't want to really do that either.
It seems to me that if I were doing the communications with raw sockets, I would be able to figure out which socket the message came in on and therefore be able to work out which client sent it without the client needing to send anything special as part of the message. I am needing a way to do this with a distributed objects method invocation.
Can anyone suggest a mechanism for doing this?
What you are looking for are NSConnection's delegate methods. For example:
- (BOOL)connection:(NSConnection *)parentConnection shouldMakeNewConnection:(NSConnection *)newConnnection {
// setup and map newConnnection to a particular client
id<VendedObjectProtocol> obj = //...
obj.connection = newConnection;
return YES;
}
You could design an object for each individual connection (like VendedObjectProtocol) and get the connection with self.connection.
- (void) acquireServerResource:(ServerResourceID)rsc {
NSConnection* conn = self.connection;
// Map the connection to a particular client
// ...
}
Or
You can make use of conversation tokens using +createConversationForConnection: and +currentConversation

Resources