Linux Bluetooth l2ping with signal strength (without connecting?) - c

For any Linux BlueZ/BT experts here:
I'm looking for a way to "ping" known BT devices (known BDADDR) and if they are in range I'd like to know the approximate signal strength.
I know that I could first run l2ping, then establish a connection to the device and finally check the rssi or link quality if the connection worked without pairing first.
However what I'm looking for is a way of getting the signal strength without connecting to the device first. Perfect would be a signal strength measurement from the l2ping reply packet, but I don't know if that info is available at all and passed along the stack.

You can obtain RSSI during inquiry scan, without connecting to devices. Here's an example using pybluez. You could also do the same thing directly from C using Bluez on linux.
inquiry-with-rssi.py

I'm using this code with my iPhone 7 and Raspberry Pi and it works great.
#!/bin/bash
sudo hcitool cc AA:BB:CC:DD:EE:FF 2> /dev/null
while true
do
bt=$(hcitool rssi AA:BB:CC:DD:EE:FF 2> /dev/null)
if [ "$bt" == "" ]; then
sudo hcitool cc AA:BB:CC:DD:EE:FF 2> /dev/null
bt=$(hcitool rssi AA:BB:CC:DD:EE:FF 2> /dev/null)
fi
echo "$bt"
done

Very old question, but someone might be still interested in.
The previous answers talk about the RSSI during an inquiry scan. It's correct but not always doable, i.e. undiscoverable devices.
For this class of devices you can establish a connection and eventually ask for the connection RSSI. Connection RSSI can be obtained using BlueZ command hcitool rssi <MAC:ADDRESS>.
Blend l2ping and hcitool rssi do the trick.
For this reason, I created this repository: [https://github.com/edoardesd/myBluez]
Output:
44 bytes from XX:XX:XX:XX:XX:XX id 8 time 8.23ms with RSSI -9

Related

How to send Sysrq programmatically over serial and is CONFIG_MAGIC_SYSRQ_SERIAL required

I keep getting the SysRq HELP printout, basically seems i can send over serial the sysrq but it won't accept the next key within 5 seconds ie the command key (b) to reboot.
I need to send the command programmatically over serial console connection to reboot system.
I can reboot the system via echo b > /proc/sysrq-trigger and cat /proc/sys/kernel/sysrq is 1 (ie full sysrq is enabled)
But I notice that kernel (2.6.32) image I'm booting with only has CONFIG_MAGIC_SYSRQ=y and there's no mention of CONFIG_MAGIC_SYSRQ_SERIAL. I'd like to know if that setting is required for 2.6.32 or if it was "assumed enabled" and its only required in new kernels.
According to this, I don't need that in my kernel since it was only added to apparently optionally disable sysrq over serial to prevent unwanted triggers.
Anyway I don't really care if PERL is used or PYTHON or C code with tcsendbreak or any programmatic method to send alt-sysrq-b over /dev/ttyUSB0 to reboot linux over serial. So far all i can do is send break sequence and see output of:
SysRq : HELP : loglevel(0-9) reBoot Crash terminate-all-tasks(E) memory-full-oom
l-active-cpus(L) show-memory-usage(M) nice-all-RT-tasks(N) powerOff show-registe
-blocked-tasks(W)
But the command key sent afterward never does anything. So I'm not sure what's wrong. FYI, the system I'm trying to send sysrq over serial to is an embedded linux system that boots via uboot with uimage and dtb file.
Instead of using a break signal I would prefer a technique where the code actually sends the Alt-SysRq-b keyboard keys over the serial console connection.

Get signal level of the connected WiFi network

Using wpa_supplicant 2.4 on ARM Debian.
Is there a way to get signal level, in decibels or percents, of the wireless network I’m currently connected to?
STATUS command only returns the following set of values: bssid, freq, ssid, id, mode, pairwise_cipher, group_cipher, key_mgmt, wpa_state, ip_address, p2p_device_address, address, uuid
I can run SCAN afterwards, wait for results and search by SSID. But that’s slow and error-prone, I'd like to do better.
The driver should already know that information (because connected, and adjusting transmit levels for energy saving), is there a way to just query for that?
This question is not about general computing hardware and software. I'm using wpa_supplicant through a C API defined in wpa_ctrl.h header, interacting with the service through a pair of unix domain sockets (one for commands, another one for unsolicited events).
One reason I don’t like my current SCAN + SCAN_RESULT solution, it doesn’t work for hidden SSID networks. Scan doesn’t find the network, therefore I’m not getting signal level this way. Another issue is minor visual glitch at application startup. My app is launched by systemd, After=multi-user.target. Unless it’s the very first launch, Linux is already connected to Wi-Fi by then. In my app’s GUI (the product will feature a touch screen), I render a phone-like status bar, that includes WiFi signal strength icon. Currently, it initially shows minimal level (I know it's connected because STATUS command shows SSID), only after ~1 second I’m getting CTRL-EVENT-SCAN-RESULTS event from wpa_supplicant, run SCAN_RESULT command and update signal strength to the correct value.
On the API level my code is straightforward. I have two threads for that, both call wpa_ctrl_open, the command thread calls wpa_ctrl_request, the event thread has an endless loop that calls poll passing wpa_ctrl_get_fd() descriptor and POLLIN event mask, followed by wpa_ctrl_pending and wpa_ctrl_recv.
And here's the list of files in /sys/class/net/wlan0:
./mtu
./type
./phys_port_name
./netdev_group
./flags
./power/control
./power/async
./power/runtime_enabled
./power/runtime_active_kids
./power/runtime_active_time
./power/autosuspend_delay_ms
./power/runtime_status
./power/runtime_usage
./power/runtime_suspended_time
./speed
./dormant
./name_assign_type
./proto_down
./addr_assign_type
./phys_switch_id
./dev_id
./duplex
./gro_flush_timeout
./iflink
./phys_port_id
./addr_len
./address
./operstate
./carrier_changes
./broadcast
./queues/rx-0/rps_flow_cnt
./queues/rx-0/rps_cpus
./queues/rx-1/rps_flow_cnt
./queues/rx-1/rps_cpus
./queues/rx-2/rps_flow_cnt
./queues/rx-2/rps_cpus
./queues/rx-3/rps_flow_cnt
./queues/rx-3/rps_cpus
./queues/tx-0/xps_cpus
./queues/tx-0/tx_maxrate
./queues/tx-0/tx_timeout
./queues/tx-0/byte_queue_limits/limit
./queues/tx-0/byte_queue_limits/limit_max
./queues/tx-0/byte_queue_limits/limit_min
./queues/tx-0/byte_queue_limits/hold_time
./queues/tx-0/byte_queue_limits/inflight
./queues/tx-1/xps_cpus
./queues/tx-1/tx_maxrate
./queues/tx-1/tx_timeout
./queues/tx-1/byte_queue_limits/limit
./queues/tx-1/byte_queue_limits/limit_max
./queues/tx-1/byte_queue_limits/limit_min
./queues/tx-1/byte_queue_limits/hold_time
./queues/tx-1/byte_queue_limits/inflight
./queues/tx-2/xps_cpus
./queues/tx-2/tx_maxrate
./queues/tx-2/tx_timeout
./queues/tx-2/byte_queue_limits/limit
./queues/tx-2/byte_queue_limits/limit_max
./queues/tx-2/byte_queue_limits/limit_min
./queues/tx-2/byte_queue_limits/hold_time
./queues/tx-2/byte_queue_limits/inflight
./queues/tx-3/xps_cpus
./queues/tx-3/tx_maxrate
./queues/tx-3/tx_timeout
./queues/tx-3/byte_queue_limits/limit
./queues/tx-3/byte_queue_limits/limit_max
./queues/tx-3/byte_queue_limits/limit_min
./queues/tx-3/byte_queue_limits/hold_time
./queues/tx-3/byte_queue_limits/inflight
./tx_queue_len
./uevent
./statistics/rx_fifo_errors
./statistics/collisions
./statistics/rx_errors
./statistics/rx_compressed
./statistics/rx_dropped
./statistics/tx_packets
./statistics/tx_errors
./statistics/rx_missed_errors
./statistics/rx_over_errors
./statistics/tx_carrier_errors
./statistics/tx_heartbeat_errors
./statistics/rx_crc_errors
./statistics/multicast
./statistics/tx_fifo_errors
./statistics/tx_aborted_errors
./statistics/rx_bytes
./statistics/tx_compressed
./statistics/tx_dropped
./statistics/rx_packets
./statistics/tx_bytes
./statistics/tx_window_errors
./statistics/rx_frame_errors
./statistics/rx_length_errors
./dev_port
./ifalias
./ifindex
./link_mode
./carrier
You can get the signal level of the connected wifi by wpa_supplicant cmd SIGNAL_POLL
The wpa_supplicant would return:
RSSI=-60
LINKSPEED=867
NOISE=9999
FREQUENCY=5745
The value of the RSSI is the signal level.
You can get the signal level of the connected wifi by wpa_supplicant cmd BSS <bssid>.
About the bssid of the connected wifi, you can get from wpa_supplicant cmd STATUS.
https://android.googlesource.com/platform/external/wpa_supplicant_8/+/622b66d6efd0cccfeb8623184fadf2f76e7e8206/wpa_supplicant/ctrl_iface.c#1986
For iw compatible devices:
Following command gives the current station(aka AP) signal strength:
iw dev wlp2s0 station dump -v
If you need C API, just dig the source code of iw.
After a quick glance, the function you need is here
For broadcom devices, try search broadcom wl. It is close source, don't know if C API is provided.

How can I identify the protocol used in hard disk?

I have an application which needs to read information from a hard disk, stuff like serial model etc.
Now of course it matters if the drive is a SAS, SATA or FC drive.
Is there a reliable way that I can identify which protocol a connected drive uses? Either via an OS command or checking some logs or inquiring the device?
I don't want to use sysfs structure. I want to know how the OS know if it's an ATA, SCSI or whatever type of disk.
As you have mentioned in comments to user3588161's answer, you are having SATA and SAS disk attached to the same SAS controller, so I'd suggest to use the smartctl command!
The smartctl command act as a control and monitor Utility for SMART disks under Linux and Unix like operating systems. Type the following command to get information about /dev/sda (SATA disk):
# smartctl -d ata -a -i /dev/sda
For SAS disk use one of the following syntax:
# smartctl -d scsi --all /dev/sgX
# smartctl -d scsi --all /dev/sg1
# smartctl -d scsi --all /dev/sg1 -H
I guess all of the information is somehow related to this location :-
/sys/class/scsi_device/?:?:?:?/device/model
I suggest you try doing this too to check what output does it render.
cat /sys/class/scsi_device/0\:0\:0\:0/device/{model,vendor}
(The backslashes next to zeros are for escaping special char :.)
Also, I'd like to suggest you to visit these two links in order for more information or detail like sample output,etc :-
Find Out Hard Disk Specs
To Check Disk behind Adaptec RAID Controllers
Checking boot information, it seems the disk type is set in kernel ahci calls. You can check (as root) with dmesg | grep ahci (on sysvinit systems) or with journalctl -k -b -0 -l --no-pager | grep ahci (with systemd). The relevant query/setting looks to be:
kernel: ahci 0000:00:12.0: version 3.0
kernel: ahci 0000:00:12.0: controller can't do 64bit DMA, forcing 32bit
kernel: ahci 0000:00:12.0: AHCI 0001.0100 32 slots 4 ports 3 Gbps 0xf impl SATA mode
kernel: ahci 0000:00:12.0: flags: ncq sntf ilck pm led clo pmp pio slum part ccc
The third line holds the controller/type information you are looking for. This seems to be where the information comes from, but from your questions standpoint, it isn't a viable solution.
The question becomes where does this information get recorded or stored within /dev /proc or /sys. I have looked and cannot find a one-to-one correlation between this initial determination of disk type on boot and any flag stored. This information may well be part of the coded data, for example, /sys/class/scsi_disk/0:0:0:0/device or similar location. Hopefully this information may allow you or others to help pinpoint if, and if so, where this information is captured and available on a running system.
Answer rewritten in view of clarification: libATA is what you want. It's what hdparm calls and it reports the transport too. It's hard to find up to date docs on it though. See http://docs.huihoo.com/linux/kernel/2.6.26/libata/index.html for example.
I have not used libATA (directly) myself, so I can't be more specific as to the API calls needed. Since not many people need to write something like hdparm themselves, your best bet is to consult its sources to see what exactly it calls.
hdparm can report stuff like:
[root#alarmpi ~]# hdparm -I /dev/sdb
/dev/sdb:
ATA device, with non-removable media
Model Number: TOSHIBA DT01ACA200
Serial Number: Z36GKMKGS
Firmware Revision: MX4OABB0
Transport: Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0; Revision: ATA8-AST T13 Project D1697 Revision 0b
If your actual problem is that only sdparm works on your system for SCSI drives (can happen) then it seems the problem is reduced to figuring out which of hdparm or sdparm to call isn't it? You could use udevinfo for that. See https://chromium.googlesource.com/chromiumos/third_party/laptop-mode-tools/+/775acea9e819bdee90cca8d2363827c13967a14b/laptop-mode-tools_1.52/usr/share/laptop-mode-tools/modules/hdparm for example.

SCPI Queries with question marks throw -110 error

I apparently inadvertently changed some setting so all SCPI commands sent to my device that include a question mark throw a -110 (Command Header Error) as documented here:
-110 Command Header Error - Indicates there is a syntax error in the command. In this case two colons between SENSE and VOLT.Example " :SENSE::VOLT:RANGE 10"
All other commands (when used properly, of course) work fine.
Because of the error, my guess is that there's something wrong with how my computer is sending non-letters?
Note: I'm sending commands using #echo "READ?" > /dev/ttyS0. I still receive a reply using cat /dev/ttyS0 but I get a beep and error. (Same error occurs in my C code)
Just figured out the solution!
It appears that somehow (perhaps the blue screen I had yesterday on the Windows where I was running my linux VM from) the settings for ttyS0 were reset so that there was software flow control for sending data but not receiving. Thus, my transmissions didn't work with either no flow control or xon_xoff.
To fix this, I set no flow control on my external serial device and ran stty -F /dev/ttyS0 -ixon on the linux box.
Alternatively, I could have set flow control on the serial device to xon_xoff and ran stty -F /dev/ttyS0 ixoff on the linux box.

snmptrap IPv6 destination not working

I compile snmptrap as a "stand alone" application to run on an enbedded device.
Sending trap with IPv4 works like a charm, but when using an IPv6 address as the destination, the following is showing in the logs:
tdomain: tdomain_transport_full("snmptrap", "udp6:[fd64:3ef5:bb33::2]", 0, "[NIL]", "[NIL]")
tdomain: Found no domain from specifier "udp6"
I compiled my net-snmp (v5.7.2) libraries with
--enable-ipv6
--with-mib-modules="mibII/ipv6 host notification snmpv3mibs"
--with-transports="UDPIPv6 TCPIPv6"
And excecute the commandline app as:
snmptrap -v 1 -M ./mibs/ -c public 'udp6:[fd64:3ef5:bb33::2]' '1.2.
3.4.5.6' '172.16.11.144' 6 99 '55' 1.11.12.13.14.15 s "teststring"
Can anyone point me in the right direction for solving this?
Cheers,
Frank
Make sure the Ipv6[fd64:3ef5:bb33::2] address is reachable, and you have successfully compiled the net-snmp library using --ipv6 enable,
After compilation you have instructed the snmpd to use both udp and udp6 protocol.
you can debug the SNMP protocol using Wireshark
Alternately you can try other client as well to send the IPv6 pdu to make sure your client is sending the right data.

Resources