Why pjmedia_snd_port_create(...) fails initializing the sound port? - c++

I am trying to initialise a sound port from pjsip and pjsua with the standart pjmedia_snd_port_create but the result is always not successful.
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pool = pj_pool_create(&cp.factory,
"pool1",
4000,
4000,
NULL);
pjmedia_snd_port *snd_port1 = NULL;
status = pjmedia_snd_port_create(pool, id1, id1, clock_rate,
channel_count, samples_per_frame,
bits_per_sample,
0, &snd_port1);
My device id1 is 0, as i got it from the audio device manager. I`ve tried with the -1 for defaults but always fails me. I have endpoint created with the pjsua2 api from a C++ class, the lib is OK and running, I can create conference bridges also but the sound port fails me. A bit of a hint will be great.

I`ve fixed it with initialising loop, I guess it has nothing to do with the setup, what I need is actually to register all of my playback and rec devices from my hardware.

Related

BlueZ over DBus stops responding within varying intervals

I am currently using the BlueZ DBus API to scan for BLE devices but it stops responding completely after varying intervals. Sometimes it's minutes, other times it's one or two hours.
My assumption is that I am forgetting to do something. The strange thing is, that after I exit the application, tools like bluetoothctl and hciconfig also no longer respond. Sometimes a reboot is not enough to get it to work again and I need to power-cycle the machines. It happens on several different machines as well.
I am acquiring the bus using:
GError* error = nullptr;
mConnection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
Starting the loop:
mLoop = g_main_loop_new(nullptr, false);
g_main_loop_run(mLoop);
Then I power on the adapter by setting the Powered property to true and calling StartDiscovery. Devices are then reported through:
guint iface_add_sub = g_dbus_connection_signal_subscribe(mConnection, "org.bluez", "org.freedesktop.DBus.ObjectManager", "InterfacesAdded", nullptr, nullptr, G_DBUS_SIGNAL_FLAGS_NONE, device_appeared, this, nullptr);
guint iface_remove_sub
= g_dbus_connection_signal_subscribe(mConnection, "org.bluez", "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved", nullptr, nullptr, G_DBUS_SIGNAL_FLAGS_NONE, device_disappeared, this, nullptr);
Is there anything I am missing to prevent BlueZ from stopping to respond?
bluetoothd -v = 5.53
ldd --version = GLIBC 2.31-0ubuntu9.2
Bluez cannot scan indefinitely because it will crash, as you are observing. In my opinion it is a bug…
What I do is to scan for 8 seconds and then stop the scan. Bluez will then clean up internal cache. After allowing 1 second for cleanup, I restart the scan.
This way it will hold up much longer. Nonetheless after a week or so it might still crash…

C++ Disable Delayed Ack on Windows

I am trying to replicate a real time application on a windows computer to be able to debug and make changes easier, but I ran into issue with Delayed Ack. I have already disabled nagle and confirmed that it improve the speed a bit. When sending a lots of small packets, window doesn't ACK right away and delay it by 200 ms. Doing more research about it, I came across this. Problem with changing the registry value is that, it will affect the whole system rather than just the application that I am working with. Is there anyway to disable delayed ACK on window system like TCP_QUICKACK from linux using setsockopt? I tried hard coding 12, but got WSAEINVAL from WSAGetLastError.
I saw some dev on github that mentioned to use SIO_TCP_SET_ACK_FREQUENCY but I didn't see any example on how to actually use it.
So I tried doing below
#define SIO_TCP_SET_ACK_FREQUENCY _WSAIOW(IOC_VENDOR,23)
result = WSAIoctl(sock, SIO_TCP_SET_ACK_FREQUENCY, 0, 0, info, sizeof(info), &bytes, 0, 0);
and I got WSAEFAULT as an error code. Please help!
I've seen several references online that TCP_QUICKACK may actually be supported by Winsock via setsockopt() (opt 12), even though it is NOT documented, or officially confirmed anywhere.
But, regarding your actual question, your use of SIO_TCP_SET_ACK_FREQUENCY is failing because you are not providing any input buffer to WSAIoctl() to set the actual frequency value. Try something like this:
int freq = 1; // can be 1..255, default is 2
result = WSAIoctl(sock, SIO_TCP_SET_ACK_FREQUENCY, &freq, sizeof(freq), NULL, 0, &bytes, NULL, NULL);
Note that SIO_TCP_SET_ACK_FREQUENCY is available in Windows 7 / Server 2008 R2 and later.

windows: detect same device on both bluetooth api and setupapi

I'm currently creating a program that's divided in two parts, one where I detect nearby bluetooth devices and connect them to the pc if the name match and the other where I search for the device with setupapi and get an handle for HID comunication.
My problem is that I cannot find anything that tells me that the device I just connected is the same I found in setupapi.
So in the first part I have something like this:
BLUETOOTH_DEVICE_INFO btdi;
//--- Code omitted ---
BluetoothGetDeviceInfo(radio_handle, &btdi);
if(std::wstring(btdi.szName) == /*my name*/)
// Device found! now connect
BluetoothSetServiceState(radio_handle, &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE);
And the setupapi related code:
SP_DEVICE_INTERFACE_DATA device_data;
device_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
//--- Code omitted ---
SetupDiEnumDeviceInterfaces(device_infos, NULL, &hid_guid, index, &device_data);
I was thinking about using the bluetooth address of the device but there seem to be no way to get that from setupapi.
So, to recap, is there any way to get the address of the device from setupi? And, if not, is there any other way to be sure that they're both the same device?
Here I posted the code how to find Wiimote connected as HID using its MAC. You have to rework that code so it can use your HID device (change VID and PID).

How to enumerate an USB hub that is attached to the first port of root hub on Windows Embedded 7

I am posting here for the first time, I hope this will be clear and readable.
I am currently trying to test the presence of usb devices on an embedded system using a specific HCD and port path programmatically using C++ and Visual Studio 2008.
The idea is to pass in the port number and the hcd value as the parameters of the function, and the function will return a true or false that indicates the connection status.
I have written some code to populate the root hub and prove that the device attached to port 1 of the root hub is a hub using bool DeviceIsHub from usbioctl.h.
However, when I attempt to enumerate the usb hub attached to port 1 of root so that I may test for the connection status of the downstream ports for the presence of device(ports 1 and 2 of this usb hub). It does not seem to know how many downstream ports the usb hub has.
I checked USBVIEW/TreeView, both application tells me that devices are there
but I am not sure what ioctl command code to use such that I can enumerate the downstream ports so I can check the connection status.
The structure of the device based on USB view and USB tree provides the following.
Root hub - it has 7 ports, only the first port is being used.
A USB hub (it has four available ports) is attached to the first port of the root hub.
Two USB devices (USB mouse and USB keyboard) are attached to port 1 and port 2 of the USB hub.
I have tried IOCTL_USB_GET_CONNECTION_INFORMATION, IOCTL_USB_GET_CONNECTION_NAME,
IOCTL_USB_GET_CONNECTION_INFORMATION_EX, IOCTL_USB_PORT_CONNECTOR_PROPERTIES
(which is not supported, it can only be used in windows 8, this is the exact ioctl call they used to enumerate the ports).
Please ignore the MessageBoxes, those are for me to check the control path status and determine which route it was following.
Please find the code that I wrote as I attempt to enumerate/populate the usb hub. I did not include the Root hub code because it would make this snippet too big.
My questions mainly resides in the enumeration process of the secondary USB hub I believe.
I just checked the registry key of the device. it appears that the USB hub is enumerated and present on the device since the information is shown under regedit HKLM->System->CurrentControlSet->Enum->USB. I believe I am not enumerating it correctly within my test application.
Any help would be greatly appreciated.
Update
The part that I am most concerned about is the DeviceIoControl Calls that attempts to get the size and the actual name of that USB hub.
It currently only takes in USB_GET_NODE_INFORMATION. Any other ioctl calls that are intended to retrieve the name of the hub will fail at the first DeviceIoControl where it attempts to get the size of the hub name so that it know how much memory to allocate
for it.
Update Part 2
From observing the usbview open source code, I believe I need to enumerate the host controller and all the devices first before checking for the presence of device. I drew a conclusion such that without doing the enumeration of controller, it only goes so far down the tree (at best second layer, which is where the external hub is attached to in my case).
I am currently attempting to enumerate the other devices and controllers in hope that I can get to the third layer of device. I will keep on updating this thread until either I figure out the problem myself or someone is capable of answering my questions.
//we are connected to the external hub, now we can begin the configuration and enumeration of the external hub.
ULONG kBytes = 0;
USB_HUB_NAME SubHubName;
//Create a Handle for the external hub driver
char Name[16];
wsprintf(Name, "\\\\.\\HCD%d", HcdSub);
HANDLE SubHub = CreateFile(Name,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
//Check to see if the handle was created successfully
if (SubHub == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,"SubHandle Fail ","TEST",MB_OK);
return false;
}
//Query the SUBHUB/External Hub for the structure, this will tell us the number of down stream ports we need to enumerate
ioctlSuccess = DeviceIoControl(SubHub,
IOCTL_USB_GET_NODE_INFORMATION,
0,
0,
&SubHubName,
sizeof(SubHubName),
&kBytes,
NULL);
//If the command failed, close the handle and return false.
if(!ioctlSuccess)
{
CloseHandle(SubHub);
MessageBox(NULL," sub hub size fail ","TEST",MB_OK);
return false;
}
//Prepare to receive the SubHubName
kBytes = SubHubName.ActualLength;
USB_HUB_NAME *subHubNameW = (USB_HUB_NAME *) malloc(sizeof(USB_HUB_NAME) * kBytes);
//Check if the allocation failed, if it did, free the memory allocated and return false.
if (subHubNameW == NULL)
{
free(subHubNameW);
CloseHandle(SubHub);
MessageBox(NULL,"SUBHubNameW=NULL ","TEST",MB_OK);
return false;
}
//Send the command to retrieve the name
ioctlSuccess = DeviceIoControl(SubHub,
IOCTL_USB_GET_NODE_INFORMATION,
NULL,
0,
subHubNameW,
kBytes,
&kBytes,
NULL);
//We no longer need this handle.
CloseHandle(SubHub);
if(!ioctlSuccess)
{
if(subHubNameW !=NULL)
{
free(subHubNameW);
}
MessageBox(NULL,"GET NODE INFO FAIL ","TEST",MB_OK);
return false;
}
//Converts the SubHubNAme from widechar to a cahr.
MessageBox(NULL,"BEGIN CONVERTION","TEST",MB_OK);
kBytes = wcslen(subHubNameW->HubName) + 1;
char *subhubname = (char *) malloc(sizeof(char)*kBytes);
wcstombs(subhubname,subHubNameW->HubName, kBytes);
//we no longer need subHubNameW the information is now in subhubname.
if(subHubNameW !=NULL)
{
free(subHubNameW);
}
//Attempt to open a handle to driver for sub hub.
int SubhdnSize = strlen(subhubname) + sizeof("\\\\.\\");
char *subhubnamelength = (char *) malloc(sizeof(char) * SubhdnSize);
sprintf(subhubnamelength, "\\\\.\\%s", subhubname);
//We no longer need subhubname, so free it.
if(subhubname !=NULL) free(subhubname);
//Attempt to open a handle for enumerating ports on this hub.
HANDLE ExternalHub = CreateFile(subhubnamelength,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
//we no longer need subhubnamelength, so free it if it is not NULL
if(subhubnamelength != NULL) free(subhubnamelength);
//Check and see if the handle was created successfully, if not, return false.
if(ExternalHub == INVALID_HANDLE_VALUE)
{
CloseHandle(ExternalHub);
MessageBox(NULL,"EXT handle fail ","TEST",MB_OK);
return false;
}
}
USB_NODE_CONNECTION_ATTRIBUTES *PortConnection =
(USB_NODE_CONNECTION_ATTRIBUTES *) malloc(sizeof(USB_NODE_CONNECTION_ATTRIBUTES));
PortConnection ->ConnectionIndex = Port;
ioctlSuccess = DeviceIoControl(ExternalHub,
IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES,
PortConnection,
sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
PortConnection,
sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
&kBytes,
NULL);
if(!ioctlSuccess)
{
MessageBox(NULL,"DEVICE CONNECTION FAIL ","TEST",MB_OK);
return false;
}
if(PortConnection->ConnectionStatus !=DeviceConnected)
{
printf("The Connection Status Returns: %d",PortConnection->ConnectionStatus);
printf("\n");
return false;
}
Enumerating USB on Windows 7 will fail if UAC is enabled and application doesn't have enough privilege. Windows Embedded 7 may fail also on similar task.
There is also a possibility to enumerate through registry.
You can not enumerate anything possibly. Normally the usb device is either a bus device or a child of a bus device. Sense the bus device is not removable, it is automatically enumerated by acpi.sys the root device during boot, or if a bus device for some other device attached to the root node, then that device has to undergo some event that means it detects the device and then enumerates it, plug and play will automatically look for it's device type's driver and if installed will load it. If the usb say has 4 actual usb connectors, that are controlled from a central device, there could be a usb driver/mini driver pair. In that case the miniport driver is a child of the usb driver and is enumerated by it and attached to it. The miniport's job is to know the actual hardware, and irp's and all other io will come from it's parent. If there are several physical connections there may be additional child drivers. They all operate the hardware and there is a hot plug. When the firmware detects the installation of a usb device it communicates this to the miniport driver and on down the stack to the bus and ultimately it is processed by plug and play. Plug and play will then have the miniport driver enumerate it's device, but it needs to get a hardware id. Then it can find it's driver and load that, then the device is installed and ready for operation.
With out knowing the device stack it is not clear what device it is referring to. Keep in mind the driver stack may not reflect the actual hardware topology. There are also things called logical devices which do not represent any piece of hardware. Any of these would have to be taken into account and you need to know which device corresponds to the end of the node.
Also one little detail. I'm not as familiar with user mode api's and drivers as I am kernel, but it seems wsprintf second argument controls format of the output buffer from the input. It should be %[]%[] were [] is a symbol that represents the format. It would format the first character according to the first symbol then the second character with teh second symbol. Seems you are doing something different.
A final note, it appears the use of wsprintf() is now deprecated instead for other api's.

Monitoring Application Network Traffic in Qt

I've been searching for this for a while, but is there a way to monitor the network traffic coming/going from a specific application using the appliances that are already built into the Qt library? I've found some solutions using things like WinPCap and other similar utilities, but I was hoping to keep it all in the Qt (in C++) house as that is what I am most familiar with.
Thanks! Any pointers are greatly appreciated!
Some example of c# sniffer socket creation.
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.IP);
// Bind the socket to the selected IP address
mainSocket.Bind(newIPEndPoint(IPAddress.Parse(cmbInterfaces.Text),0));
// Set the socket options
mainSocket.SetSocketOption(SocketOptionLevel.IP, //Applies only to IP packets
SocketOptionName.HeaderIncluded, //Set the include header
true); //option to true
byte[] byTrue = newbyte[4]{1, 0, 0, 0};
byte[] byOut = newbyte[4];
//Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
mainSocket.IOControl(IOControlCode.ReceiveAll, //SIO_RCVALL of Winsock
byTrue, byOut);
//Start receiving the packets asynchronously
mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
newAsyncCallback(OnReceive), null);
May be qt provides some api for creating such sockets.After creating such socket you'll get raw pacets on it parsing headers and other info is on you.