Service Discovery Protocol: Check for multiple Services at once - c++

I followed the instructions on https://people.csail.mit.edu/albert/bluez-intro/x604.html to check for a specified Bluetooth service of a device. I can succesfully check for the Serial Port Profile.
From Bluetooth traces, I noticed that some devices search for multiple services at the same time. Is it possible to extend the source code from the website mentioned above to get this functionality? I tried
[...]
search_list = sdp_list_append( NULL, &svc_uuid_1 );
search_list = sdp_list_append( NULL, &svc_uuid_2 );
[...]
but this seems not to work, it does not really 'append' the UUID in the search_list but does overwrite it.
Moreover, the traces show that one single SDP request does cover SPP, RFCOMM and L2CAP. Can profiles and protocols be mixed in SDP request?
Additionally, I'm confused by the following snippet, also from website above:
// specify that we want a list of all the matching applications' attributes
uint32_t range = 0x0000ffff;
attrid_list = sdp_list_append( NULL, &range );
What exactly is range? What options does it offer? Unfortunately, I couldn't find any explanations in Bluetooth core documentation v4.2.

Related

Connect to multiple queue managers in different servers

I am trying to connect a C++ application (using MQCONNX) based on a PaaS IBM MQ client to two different queue managers, each one based on a different server (one in a PaaS server and the other one in a Unix server). Unfortunately I am not able to do it as I am getting a message when I try to connect to the second server saying that it is not possible as it is connected to the first queue manager. I am using two different MQHCONN connections, one for each queue manager, but the problem is still there.
I have taken a look into this link, but I still have some doubts, as for example, from which server should I copy the CCDT to the client?
https://www.ibm.com/support/pages/connecting-mq-clients-multiple-queue-managers-client-channel-definition-table-ccdt
Any help would be much appreciated, or even a quick sample of how to use CCDT, as right now I am completely stuck.
Many thanks in advance for any help.
Assuming Queue Manager 1 is called MQG1 and Queue Manager 2 is called MQG2 and these can be found using connection names of machine1.com(1701) and machine2.com(1702) respectively, and using channel names MQG1.SVRCONN and MQG2.SVRCONN respectively, you can create your CCDT, on your client application machine, thus:-
runmqsc -n
issue these commands into runmqsc:-
DEFINE CHANNEL(MQG1.SVRCONN) CHLTYPE(CLNTCONN) CONNAME('machine1.com(1701)') QMNAME(MQG1)
DEFINE CHANNEL(MQG2.SVRCONN) CHLTYPE(CLNTCONN) CONNAME('machine2.com(1702)') QMNAME(MQG2)
Then you can code your 2 x MQCONN (or MQCONNX if you need to specify any additional things on the connection) thus:-
#include <cmqc.h> /* Includes for MQI constants */
#include <cmqstrc.h> /* Convert MQRC into string */
MQHCONN hConn1 = MQHC_UNUSABLE_HCONN;
MQHCONN hConn2 = MQHC_UNUSABLE_HCONN;
MQCHAR QMName1[MQ_Q_MGR_NAME_LENGTH] = "MQG1";
MQCHAR QMName2[MQ_Q_MGR_NAME_LENGTH] = "MQG2";
MQLONG CompCode, Reason;
MQCONN(QMName1,
&hConn1,
&CompCode,
&Reason);
if (CompCode)
{
printf("MQCONN to %s failed with reason code %s (%d)\n", QMName1, MQRC_STR(Reason), Reason);
}
MQCONN(QMName2,
&hConn2,
&CompCode,
&Reason);
if (CompCode)
{
printf("MQCONN to %s failed with reason code %s (%d)\n", QMName2, MQRC_STR(Reason), Reason);
}
Take care with how you are linking your program. If you try to make two local connections, you will get a return code of MQRC_ANOTHER_Q_MGR_CONNECTED. Ensure you either link with the client library, set connection option MQCNO_CLIENT (which means you must use MQCONNX) or set the environment variable MQ_CONNECT_TYPE=CLIENT.
You might find the following blog post useful additional reading:-
IBM MQ Little Gem #30: MQ_CONNECT_TYPE

Get HID report Descriptor from .pcap file

I am building a C++ app on windows that should reinterpret USB data stream captured by Wireshark and USBPCap stored into a .pcap file. I am currently having trouble to get HID Report descriptor, so then i would be able to interpret data that mouse sends to the host.
The site USB Made Simple has been a great source of information so far, and i have also read a tons of tutorials how to write your own HID Report descriptor in order to understand them. But what i need is to retrieve one from current data flow.
According to wireshark, mouse is sending me a DEVICE DESCRIPTOR (example here), after that it sends CONFIGURATION DESCRIPTOR with its INTERFACE, HID and ENDPOINT DESCRIPTORS (example here).
According to value of wDescriptorLength in HID DESCRIPTOR, there should be HID REPORT DESCRIPTOR of length 56, but there is not. After this there is only ENDPOINT DESCRIPTOR of length 7 and another INTERFACE and HID DESCRIPTOR of total lenght 18.
Is there any way to get HID REPORT DESCRIPTOR from this or am I missing something out ?
Thank you for any input.
Is there any way to get HID REPORT DESCRIPTOR from this or am I missing something out ?
Don't know about you but for me that looks like Wireshark/USBPCap is missing something.
If you compare it with mine example it looks like entries with USBHID protocol are missing in your part.
Please check your Wireshark version or if you don't have enabled any filters in capture configuration.
If you click 'gear' icon on the left side of USBPcap interface you can check your current settings:
Important note:
Despite fact that "Inject already connected devices descriptors..." is checked it doesn't work for me like I would expect and to capture Report Descriptor you have to reconnect device: unplug USB-HID device -> Start capture -> Plug in USB device -> Now you can stop capture.
You should be able to use the Win32 HID-parse utilities to do this:
https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/preparsed-data
See here for an example of use, where the HID report is accessed using WM_INPUT:
https://github.com/supersmo/Using-Raw-Input-API-to-Process-Joystick-Input
...in particular these methods:
// determine buffer size required
CHECK( GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, NULL, &bufferSize) == 0 );
// allocate buffer
CHECK( pPreparsedData = (PHIDP_PREPARSED_DATA)HeapAlloc(hHeap, 0, bufferSize) );
// determine the usages etc
CHECK( (int)GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_PREPARSEDDATA, pPreparsedData, &bufferSize) >= 0 );
// Button caps
CHECK( HidP_GetCaps(pPreparsedData, &Caps) == HIDP_STATUS_SUCCESS )
// Value caps
CHECK( pValueCaps = (PHIDP_VALUE_CAPS)HeapAlloc(hHeap, 0, sizeof(HIDP_VALUE_CAPS) * Caps.NumberInputValueCaps) );
capsLength = Caps.NumberInputValueCaps;
CHECK( HidP_GetValueCaps(HidP_Input, pValueCaps, &capsLength, pPreparsedData) == HIDP_STATUS_SUCCESS )
Another thing to look at is the ReactOS hidusb source which can be found (today) here:
https://doxygen.reactos.org/dd/d06/hidusb_8c_source.html
...pay particular attention to e.g. HidUsb_GetReportDescriptor
Hope this points you in the right direction.

How to track screens through time? [duplicate]

I have a setup with two regular displays and three projectors connected to a windows pc. In my win32 program I need to uniquely identify each monitor and store information for each such that I can retrieve the stored information even after computer restart.
The EnumDisplayDevices seems to return different device orders after restarting the computer. There is also GetPhysicalMonitorsFromHMONITOR which at least gives me the display's name. However, I need something like a serial number for my projectors, since they are the same model. How can I get such a unique identifier?
EDIT: This is the solution I came up with after reading the answer from user Anders (thanks!):
DISPLAY_DEVICEA dispDevice;
ZeroMemory(&dispDevice, sizeof(dispDevice));
dispDevice.cb = sizeof(dispDevice);
DWORD screenID;
while (EnumDisplayDevicesA(NULL, screenID, &dispDevice, 0))
{
// important: make copy of DeviceName
char name[sizeof(dispDevice.DeviceName)];
strcpy(name, dispDevice.DeviceName);
if (EnumDisplayDevicesA(name, 0, &dispDevice, EDD_GET_DEVICE_INTERFACE_NAME))
{
// at this point dispDevice.DeviceID contains a unique identifier for the monitor
}
++screenID;
}
EnumDisplayDevices with the EDD_GET_DEVICE_INTERFACE_NAME flag should give you a usable string. And if not, you can use this string with the SetupAPI to get the hardware id or driver key or whatever is unique enough for your purpose.
Set this flag to EDD_GET_DEVICE_INTERFACE_NAME (0x00000001) to retrieve the device interface name for GUID_DEVINTERFACE_MONITOR, which is registered by the operating system on a per monitor basis. The value is placed in the DeviceID member of the DISPLAY_DEVICE structure returned in lpDisplayDevice. The resulting device interface name can be used with SetupAPI functions and serves as a link between GDI monitor devices and SetupAPI monitor devices.

Get unique identifier for Windows monitors

I have a setup with two regular displays and three projectors connected to a windows pc. In my win32 program I need to uniquely identify each monitor and store information for each such that I can retrieve the stored information even after computer restart.
The EnumDisplayDevices seems to return different device orders after restarting the computer. There is also GetPhysicalMonitorsFromHMONITOR which at least gives me the display's name. However, I need something like a serial number for my projectors, since they are the same model. How can I get such a unique identifier?
EDIT: This is the solution I came up with after reading the answer from user Anders (thanks!):
DISPLAY_DEVICEA dispDevice;
ZeroMemory(&dispDevice, sizeof(dispDevice));
dispDevice.cb = sizeof(dispDevice);
DWORD screenID;
while (EnumDisplayDevicesA(NULL, screenID, &dispDevice, 0))
{
// important: make copy of DeviceName
char name[sizeof(dispDevice.DeviceName)];
strcpy(name, dispDevice.DeviceName);
if (EnumDisplayDevicesA(name, 0, &dispDevice, EDD_GET_DEVICE_INTERFACE_NAME))
{
// at this point dispDevice.DeviceID contains a unique identifier for the monitor
}
++screenID;
}
EnumDisplayDevices with the EDD_GET_DEVICE_INTERFACE_NAME flag should give you a usable string. And if not, you can use this string with the SetupAPI to get the hardware id or driver key or whatever is unique enough for your purpose.
Set this flag to EDD_GET_DEVICE_INTERFACE_NAME (0x00000001) to retrieve the device interface name for GUID_DEVINTERFACE_MONITOR, which is registered by the operating system on a per monitor basis. The value is placed in the DeviceID member of the DISPLAY_DEVICE structure returned in lpDisplayDevice. The resulting device interface name can be used with SetupAPI functions and serves as a link between GDI monitor devices and SetupAPI monitor devices.

Windows Audio Endpoint API. Getting the names of my Audio Devices

My main goal at the moment is to get detailed information about all of the local machine's Audio Endpoint Devices. That is the objects representing the audio peripherals. I want to be able to choose which device to record from based on some logic (or eventually allow the user to manually do so).
Here's what I've got so far. I'm pretty new to c++ so dealing with all of these abstract classes is getting a bit tricky so feel free to comment on code quality as well.
//Create vector of IMMDevices
UINT endpointCount = NULL;
(*pCollection).GetCount(&endpointCount);
std::vector<IMMDevice**> IMMDevicePP; //IMMDevice seems to contain all endpoint devices, so why have a collection here?
for (UINT i = 0; i < (endpointCount); i++)
{
IMMDevice* pp = NULL;
(*pCollection).Item(i, &pp);
IMMDevicePP.assign(1, &pp);
}
My more technical goal at present is to get objects that implement this interface: http://msdn.microsoft.com/en-us/library/windows/desktop/dd371414(v=vs.85).aspx
This is a type that is supposed to represent a single Audio Endpoint device whereas the IMMDevice seems to contain a collection of devices. However IMMEndpoint only contains a method called GetDataFlow so I'm unsure if that will help me. Again the goal is to easily select which endpoint device to record and stream audio from.
Any suggestions? Am I using the wrong API? This API definitely has good commands for the actual streaming and sampling of the audio but I'm a bit lost as to how to make sure I'm using the desired device.
WASAPI will allow you to do what you need so you're using the right API. You're mistaken about IMMDevice representing a collection of audio devices though, that is IMMDeviceCollection. IMMDevice represents a single audio device. By "device", WASAPI does't mean audio card as you might expect, rather it means a single input/output on such card. For example an audio card with analog in/out + digital out will show up as 3 IMMDevices each with it's own IMMEndpoint. I'm not sure what detailed info you're after but it seems to me IMMDevice will provide you with everything you need. Basically, you'll want to do something like this:
Create an IMMDeviceEnumerator
Call EnumAudioEndpoints specifying render, capture or both, to enumerate into an IMMDeviceCollection
Obtain individual IMMDevice instances from IMMDeviceCollection
Device name and description can be queried from IMMDevice using OpenPropertyStore (http://msdn.microsoft.com/en-us/library/windows/desktop/dd370812%28v=vs.85%29.aspx). Additional supported device details can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/dd370794%28v=vs.85%29.aspx.
IMMDevice instances obtained from IMMDeviceCollection will also be instances of IMMEndpoint, use QueryInterface to switch between the two. However, as you noted, this will only tell you if you've got your hands on a render or capture device. Much easier to only ask for what you want directly on EnumAudioEndpoints.
About code quality: use x->f() instead if (*x).f(), although it's technically the same thing the -> operator is the common way to call a function through an object pointer
Don't use vector::assign, apparently that replaces the contents of the entire vector on each call so you'll end up with a collection of size 1 regardless of the number of available devices. Use push_back instead.
After enumerating your IMMDevices as Sjoerd stated it is a must to retrieve the IPropertyStore
information for the device. From there you have to extract the PROPVARIANT object as such:
PROPERTYKEY key;
HRESULT keyResult = (*IMMDeviceProperties[i]).GetAt(p, &key);
then
PROPVARIANT propVari;
HRESULT propVariResult = (*IMMDeviceProperties[i]).GetValue(key, &propVari);
according to these documents:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761471(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072(v=vs.85).aspx
And finally to navigate the large PROPVARIANT structure in order to get the friendly name of the audio endpoint device simply access the pwszVal member of the PROPVARIANT structure as illustrated here:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd316594(v=vs.85).aspx
All about finding the right documentation!