Winsock 2 discovering Bluetooth devices only showing previously paired devices - bluetooth

I am currently trying to use the WINSOCK 2 API in order to discover available Bluetooth devices near by. I am using code which is based on a Microsoft example which can be found here.
I am mainly using WSALookupServiceNext to iterate through the available devices. The issue is that I only get a list of previous paired Bluetooth devices, and I am not seeing any other devices. I added some code in order to print device information:
*********************
Winsock search started!
*********************
Device #:1
Device name:MagicBox II
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x00025b3dc371, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:2
Device name:Mpow Flame
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x501801101c68, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:3
Device name:WH-1000XM2
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x702605aba41d, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:4
Device name:Magicbuds
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x5017032a701b, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Here is the corresponding code section, ( I did call WSAStartup beforehand):
void WSALookupAvailableDevices(void)
{
WSAQUERYSET wsaQuery{};
LPWSAQUERYSET pwsaResults{};
HANDLE hLookup{};
CSADDR_INFO *pAddrInfo{};
SOCKADDR_BTH *pBtSockRemote{},
*pBtSockLocal{};
char buffer[4096] = {};
int nDevicesFound = 1;
DWORD swSize = sizeof(buffer);
DWORD flags = LUP_RETURN_ADDR | LUP_RETURN_NAME | LUP_RES_SERVICE | LUP_CONTAINERS | LUP_RETURN_BLOB | LUP_RETURN_TYPE;
/*Preparing the query set*/
wsaQuery.dwNameSpace = NS_BTH;
wsaQuery.dwSize = sizeof(WSAQUERYSET);
if (WSALookupServiceBegin(&wsaQuery, flags, &hLookup) == SOCKET_ERROR)
{
wprintf(L"Shit something went wrong! error: %d!\n", WSAGetLastError());
return;
}
wprintf(L"*********************\n");
wprintf(L"Winsock search started!\n");
wprintf(L"*********************\n\n");
/*Preparing the queryset return buffer*/
pwsaResults = (LPWSAQUERYSET)buffer;
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->dwSize = sizeof(WSAQUERYSET);
while (WSALookupServiceNext(hLookup, flags, &swSize, pwsaResults) == NO_ERROR)
{
pAddrInfo = (CSADDR_INFO*)pwsaResults->lpcsaBuffer;
pBtSockRemote = (SOCKADDR_BTH*)(pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr);
pBtSockLocal = (SOCKADDR_BTH*)(pwsaResults->lpcsaBuffer->LocalAddr.lpSockaddr);
wprintf(L"Device #:%d\n", nDevicesFound);
wprintf(L"Device name:%s\n", pwsaResults->lpszServiceInstanceName);
wprintf(L"Device connected: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_CONNECTED));
wprintf(L"Device remembered: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_REMEMBERED)>0);
wprintf(L"Device authenticated: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_AUTHENTICATED)>0);
wprintf(L"Remote Bluetooth device is 0x%04x%08x, server channel = %d\n",
GET_NAP(pBtSockRemote->btAddr), GET_SAP(pBtSockRemote->btAddr), pBtSockRemote->port);
wprintf(L"Local Bluetooth device is 0x%04x%08x, server channel = %d\n",
GET_NAP(pBtSockLocal->btAddr), GET_SAP(pBtSockLocal->btAddr), pBtSockLocal->port);
nDevicesFound++;
}
WSALookupServiceEnd(hLookup);
wprintf(L"\n");
}
Thanks for the help in advance!

LUP_FLUSHCACHE is what you need. And yes, it will always return paired device (in addition to discovered). I mean that if device paired WSALookup returns it in the list even it is not available (turned off or out of range).
https://learn.microsoft.com/en-us/windows/desktop/bluetooth/bluetooth-and-wsalookupservicebegin-for-device-inquiry
DWORD flags = LUP_RETURN_ADDR | LUP_RETURN_NAME | LUP_RES_SERVICE | LUP_CONTAINERS | LUP_RETURN_BLOB | LUP_RETURN_TYPE | LUP_FLUSHCACHE;
But the best way to discover devices is to use this flags set.
DWORD flags = LUP_RETURN_ADDR | LUP_CONTAINERS | LUP_FLUSHCACHE;
Also it is good idea to provide additional information (BTH_QUERY_DEVICE) so you can set discovering timeout and other params
BTH_QUERY_DEVICE qDev;
qDev.LAP = 0;
qDev.length = bTimeout; // Timeout in seconds
BLOB Blb;
Blb.cbSize = sizeof(BTH_QUERY_DEVICE);
Blb.pBlobData = (PBYTE)&qDev;
QuerySet.lpBlob = &Blb;
https://learn.microsoft.com/th-th/windows/desktop/api/ws2bth/ns-ws2bth-_bth_query_device
After discovering completed (please note that WSALookupServiceBegin takes time (blocks) until discovering finished) you can use BluetoothGetDeviceInfo to get extended information such as device's name and other info.
https://learn.microsoft.com/en-us/windows/desktop/api/bluetoothapis/nf-bluetoothapis-bluetoothgetdeviceinfo
You should know that because of some Bluetooth limitations name resolution can be executed only after discovering completed. And this operation may take time. So if you call to BluetoothGetDeviceInfo right after discovering completed you can still get empty device name for new discovered devices (devices that was not previouslt discovered).
There is not easy way to resolve this issue except switch to WinRT API or wait for some time before reading device name. You also can use WM_DEVICECHANGE message to get notification about device name resolution
https://learn.microsoft.com/en-us/windows/desktop/bluetooth/bluetooth-and-wm-devicechange-messages
And there is one more problem: MS stack always returnsd paired devices during discovering even they are not available.

Related

Error when reading/writing from CAN and sensor simultaneously over I2C

I am using a can board and an IMU MPU6050 to be able use motors while also reading an angle from the IMU.
When using them separately it works, the IMU reads and the CAN can activate and run the motors. The issue arises when both are activated at the same time and the script gives the following error:
IOError: [Errno 5] Input/output error
Here are the registers:
# MPU6050 Registers
MPU6050_ADDR = 0x68#0x0c
PWR_MGMT_1 = 0x6B
SMPLRT_DIV = 0x19
CONFIG = 0x1A
GYRO_CONFIG = 0x1B
ACCEL_CONFIG = 0x1C
INT_PIN_CFG = 0x37
INT_ENABLE = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
And fault messages arises when I try to write a byte to the IMU at the same time as the CAN bus is activated:
# Write to Configuration register
bus.write_byte_data(MPU6050_ADDR, CONFIG, 0)
I created a new I2C bus for the IMU which is bus #3 which gives me the addresses 0x68 and 0x0c.
I have checked the wiring which is correct. Otherwise I should get the same error when running them separately.
Does anyone have any suggestions on what to try next?

Gammu - Entry is empty, cannot set SMSC

Short description:
when I try to send a SMS I receive the error: "Failed to get SMSC number from phone."
so I try to set the SMSC number and I receive the error: "Entry is empty."
Commnads are:
root#mail:/home/victor# echo "Dragon Ball super is Awsome!" | gammu --sendsms TEXT +40740863629
Failed to get SMSC number from phone.
root#mail:/home/victor# gammu setsmsc 1 "+40748438759"
Entry is empty.
Result of command gammu identify is:
root#mail:/home/victor# gammu identify
Device : /dev/ttyUSB0
Manufacturer : Qualcomm
Model : unknown (HSDPA Modem)
Firmware : 01.02.04 1 [Nov 27 2015 14:33:39]
SIM IMSI : +CIMI:226102317883481
Maybe my device is not supported by gammu?
This is my configuration file ... I tried different configuration:
[gammu]
port = /dev/ttyUSB0
model =
connection = at19200
synchronizetime = no
logfile = /var/log/gammu.log
logformat = textall
use_locking =
gammuloc =
I used my Ubuntu gammu version 1.37.
I just read the manual of the device, the solution is to load the right driver:
modprobe usbserial vendor=0x5c6 product=0x6000
After this the SMS can be send, no need to set SMSC manualy

Pin Muxing in linux kernel

I want to do following pin muxing.
i.e USART Tx -> to GPIO -> Back to USART Tx pin inside Linux kernel for some purpose.
I tried to make the PIN as GPIO using gpio_request and gpio_direction_output, so i am able to make that pin as GPIO . But as i want to switch back from GPIO to USART Tx pin, it is not working, I tried following at91_set_A_periph to that pin, still no luck.
Working on kernel : 3.18 and at91 atmel board.
You can have a look at the i2c-imx driver. It does exactly that.
You need to use pinctrl_lookup_state to retrieve the different pinctrl states (one of those being USART Tx and the other one GPIO). Then you can switch between both with pinctrl_select_state.
To sum it up, you'd have something like that in your uart node:
usart3: serial#fc00c000 {
pinctrl-names = "default","gpio";
pinctrl-0 = <&pinctrl_usart3>;
pinctrl-1 = <&pinctrl_usart3_gpio>;
tx-gpio = <&pioE 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
In the driver code:
pinctrl_pins_default = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_DEFAULT);
pinctrl_pins_gpio = pinctrl_lookup_state(pinctrl, "gpio");
tx_gpio = of_get_named_gpio(pdev->dev.of_node, "tx-gpio", 0);
Then, you can use pinctrl_select_state to switch back and forth between pinctrl_pins_default and pinctrl_pins_gpio. tx_gpio is your gpio.

Windows 10 Bluetooth Low Energy GATT Pairing Is Not working c#

This is code for BLE pairing. it's working on Bluetooth refreshing from windows 10 setting at every time.
DevicePairingKinds ceremoniesSelected = DevicePairingKinds.ConfirmOnly | DevicePairingKinds.DisplayPin | DevicePairingKinds.ProvidePin | DevicePairingKinds.ConfirmPinMatch;
DevicePairingProtectionLevel protectionLevel = DevicePairingProtectionLevel.Default;
DeviceInformationCustomPairing customPairing = deviceInfoDisp.DeviceInformation.Pairing.Custom;
customPairing.PairingRequested += PairingRequestedHandler;
DevicePairingResult result = await customPairing.PairAsync(ceremoniesSelected, protectionLevel);
customPairing.PairingRequested -= PairingRequestedHandler;

TinyX shows display using builtin fbtft touchscreen driver but touch doesn't work

I'm using an "adafruitts" touchscreen with a raspi to control a usb peripheral.
The full raspbian kernel takes forever to boot (50 seconds), and part of that is due to the touchscreen driver loading (by modprobe/udev) and initializing.
During the first 20-30 seconds of boot, the display is not loaded, so it is blank. I need this to be a user-friendly item that cannot be blank for 30 seconds each time it is turned on, so I've used buildroot to build a small kernel with the touchscreen driver built-in. (I am on a steep learning curve with buildroot and kernel building in general).
The display driver is fbtft_device.c patched to include the adafruitts display. This patch defines the "touch" half:
/* Touch device spi-half of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "stmpe610",
.max_speed_hz = 500000,
.mode = SPI_MODE_0,
.chip_select = 1,
.platform_data = &(struct stmpe_platform_data) {
.blocks = STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_GPIO,
.irq_over_gpio = 1,
.irq_gpio = 24,
.irq_trigger = IRQF_TRIGGER_FALLING,
.irq_base = GPIO_IRQ_START + GPIO_IRQS,
.ts = &(struct stmpe_ts_platform_data) {
.sample_time = 4,
.mod_12b = 1,
.ref_sel = 0,
.adc_freq = 2,
.ave_ctrl = 3,
.touch_det_delay = 4,
.settling = 2,
.fraction_z = 7,
.i_drive = 0,
},
}
},
.is_support = 1,
.gpio_settings = (struct gpio_setting []) {
{
.gpio = 24,
.pull = pull_up,
}
},
.gpio_num_settings = 1,
},
and the LCD half:
}, {
/* LCD component of adafruit touchscreen */
.name = "adafruitts",
.spi = &(struct spi_board_info) {
.modalias = "fb_ili9340",
.max_speed_hz = 16000000,
.mode = SPI_MODE_0,
.chip_select = 0,
.platform_data = &(struct fbtft_platform_data) {
.display = {
.buswidth = 8,
.backlight = 1,
},
.bgr = true,
.gpios = (const struct fbtft_gpio []) {
{ "dc", 25 },
{},
},
}
}
}, {
by including:
fbtft_device.name=adafruitts
in the cmdline.txt for the boot loader, I've gotten the display half of the system to work (it boots in ~ 5 seconds :) ) with tinyX/matchbox desktop showing the desktop, but I cannot get the touchscreen part to work (the cursor does not move when I touch the screeen).
Somehow I have to bind the touch part of the touchscreen to tinyX, but I have not been able to figure out how to do this.
I have tried to specify the keyboard (and mouse) when launching tinyX:
X -keybd smpte610 (for example)
but X reports it cannot find the driver.
How can I verify the touch screen input device was successfully loaded?
The boot log has these messages about fbtft_device:
fbtft_device: SPI devices registered:
fbtft_device: spidev spi0.0 500kHz 8 bits mode=0x00
fbtft_device: spidev spi0.1 500kHz 8 bits mode=0x00
fbtft_device: 'fb' Platform devices registered:
fbtft_device: bcm2708_fb id=-1 pdata? no
fbtft_device: Deleting spi0.1 (spi0.1)
fbtft_device: Looking at item 0
fbtft_device: Setting pin 24 to 2
stmpe-spi: probe of spi0.1 failed with error -22
fbtft_device: Deleting spi0.0 (spi0.0)
Console: switching to colour frame buffer device 40x30
graphics fb0: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 16 KiB buffer memory, fps=20, spi0.0 at 16 MHz
fbtft_device: GPIOS used by 'adafruitts':
fbtft_device: 'dc' = GPIO25
fbtft_device: SPI devices registered:
fbtft_device: stmpe610 spi0.1 48000kHz 8 bits mode=0x00
fbtft_device: fb_ili9340 spi0.0 16000kHz 8 bits mode=0x00
kgdb: Registered I/O driver kgdboc.
Is the kgdb message associated with fbtft_device or something else?
If I look in /dev/input I see: event0, event1, and mice. event0 and event1 are associated with an attached keyboard (according to the boot log) and I have no mouse attached. Should there be some other items in input?
If the touch screen input device IS loaded, how to I specify the correct driver for tinyX?
Thanks
What I learned:
By comparing the boot messages in my modprobe/udev/module loading kernel with the fast built-in kernel, it shows:
stmpe-spi: probe of spi0.1 failed with error -22
is a "bad" thing.
A successful driver load will say (something like):
bcm2708_spi.0: registered child spi0.0
and then later:
input: stmpe-ts as /devices/virtual/input/input0
I fixed the "probe" failure by making these changes to my kernel configuration file. (Sorry, I don't want to include the whole thing, so these are the changes from when I had the issue to when the driver successfully loaded according to the syslog):
< Touch Did Not respond > Touch Did respond
> CONFIG_INPUT_FF_MEMLESS=y
< CONFIG_INPUT_POLLDEV=m > CONFIG_INPUT_POLLDEV=y
< CONFIG_INPUT_EVDEV=m > CONFIG_INPUT_EVDEV=y
< CONFIG_TOUCHSCREEN_STMPE=m > CONFIG_TOUCHSCREEN_STMPE=y
> CONFIG_KEYBOARD_STMPE=y
< CONFIG_SERIO=m > CONFIG_SERIO_SERPORT=m
> CONFIG_SPI_DEBUG=y
< CONFIG_SPI_SPIDEV=y
> CONFIG_SPI_GPIO=y
My main objective with these changes was to try to make sure that the dependent drivers were also built-in, and I enabled the debug. (Some of these were magically set by menuconfig, and this is diff from the "non-default" values from buildroot, so the diff is - different)
With this config, I now have event0, event1, event2, mice, and mouse0. The syslog says event1 and event2 are associated with the usb keyboard I have attached. I have no extra mouse attached.
I could use "evtest" to see events from /dev/input/event0 whenever I touched the display. evtest'ing /dev/input/mouse0 threw "Inappropriate ioctl for device"
I restarted X (tinyX) using:
X -mouse mouse,,/dev/input/mouse0
and touches worked, but the touch axis is rotated from the display axis.
I could not figure out a way to fix this in tinyX, so I'm going with a full blown Xorg implementation.
Make sure you have enabled the evdev input support in tinyx (BR2_PACKAGE_XSERVER_XORG_SERVER_KDRIVE_EVDEV) and use the syntax specified in hw/kdrive/src/kinput.c:
/*
* You can call your kdriver server with something like:
* $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
* evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
*/

Resources