gatttool and hcitool on Linux - linux

I'm trying to connect to a device using gatttool on Linux. I run hcitool lescan to get the device MAC address, and then gatttool -i hci1 -b <macaddr> -t random -I. Then I type connect. I see [CON] as expected, but the problem is that it disappears automatically after about 1s, with no error messages. I have been searching for hours, but I don't see why that is so?
Note: I have run hcitool lecc before running gatttool one time just to try it, but it seems to me that since then, gatttool connection is not working properly anymore (unexpected disconnection as explained above). Is it because I have used hcitool lecc? If yes, is there a way to "undo" it?

Not sure if this helps you because I'm seeing this behavior on my Raspberry Pi (an up-to-date wheezy version) and bluez 5.18 (released April 2014.)
I can connect to my BLE peripheral from the command line after doing an lecc without any problems. I don't think you need to reset after an lecc. Regardless, if you do want to reset your BT dongle because it is in some funky state, look at this excellent step-by-step guide to reset the BT dongle. I have followed these steps with consistent results.
I can connect and query say primary but more often than not, the connection drops before I can manually type in primary. See the results below. If I use the up/down arrows after connecting to quickly scroll to primary, I am able to see primary services offered by this peripheral without any problems.
~ $ sudo gatttool -I -i hci0 -m 48 -b 20:CD:39:A8:11:AF
[20:CD:39:A8:11:AF][LE]> connect
Attempting to connect to 20:CD:39:A8:11:AF
Connection successful
[20:CD:39:A8:11:AF][LE]> primary
Command Failed: Disconnected

Related

hcitool cc and hcitool auth returns Input/output error

I have successfully set up and enabled Bluetooth on my server running Debian Buster. That in itself is quite an achievement. Anyhow, I am trying to use a Node package called node-bluetooth-serial-port to connect to a tiny Bluetooth speaker with a display. I manage to list/scan devices, but it cannot send anything to the device. I'm thinking this is because my server hasn't been paired with the device yet.
$ hcitool scan
Scanning ...
11:22:33:44:55:66 TimeBox-mini-audio
$ sudo hcitool cc 11:22:33:44:55:66; sudo hcitool auth 11:22:33:44:55:66
HCI authentication request failed: Input/output error
So hcitool can find the device, but it cannot connect to it, for some reason. dmesg doesn't show me any errors what so ever.
I have tried to pair with other devices (like my phone), but that doesn't work either.
The device does not require a 4-digit pin to auth.
What can I do here?

Serial port unavaliable arduino

Trying to upload a code to arduino, but whether in the Arduino IDE or Arduino Create, both return this erro while uploading. Running on Linux Tara(mint 19 cinnamon).
./opt/arduino-builder/arduino-builder -compile -core-api-version 10611 -hardware opt/arduino-builder/hardware -hardware ./opt/cores -tools opt/arduino-builder/tools -tools ./opt/tools -built-in-libraries opt/libraries/latest -logger humantags -fqbn arduino:avr:mega:cpu=atmega2560 -build-cache /tmp -build-path /tmp/716441957/build -verbose -libraries /tmp/716441957/custom -libraries /tmp/716441957/pinned /tmp/716441957/sketch_oct8a
Sketch uses 8280 bytes (3%) of program storage space. Maximum is 253952 bytes.
Global variables use 443 bytes (5%) of dynamic memory, leaving 7749 bytes for local variables. Maximum is 8192 bytes.
Programming with: Serial
Flashing with command:/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/bin/avrdude -C/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/etc/avrdude.conf -q -q -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino-create-agent734074237/sketch_oct8a.hex:i
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
ioctl("TIOCMGET"): Inappropriate ioctl for device
ioctl("TIOCMGET"): Inappropriate ioctl for device
1#
First, check the port in your IDE. In Arduino tools->port
If the port is hidden or you can not move the cursor over this then run this commands in your terminal.If everything ok then skips this and follow the second part.
sudo apt-get install librxtx-java -y
sudo usermod -aG dialout $USER
sudo apt-get install gnome-system-tools
2#
After this again check the first method. If it is not working then run this commands
ls -l /dev/ttyACM*
sudo usermod -a -G dialout <username>
You probably have another program running which is already using this port.
You should close most other programs like putty or another serial monitor app.
Otherwise, try to reconnect the Arduino to the PC.
I know that these ideas below come from using a Teensy, but they may help you.
Sometimes there are the ACM* ports listed in the Arduino IDE. Try looking at the ser ports. I know when I am running my Teensy, sometimes I have them switched and need to select the correct one.
Also, from my experience with the Teensy, you might need to add a udev rule to allow permissions to access the port from non-root user. Here is the link that shows the udev file.
There is no direct way to solve this issue. In addition to it, you are not using an IDE. I will list the things you need to check, I am sure this will solve your problem.
I am not good at Linux environment so I will refer to applications names as window, you go the corresponding application in Linux.
Go to linux device manager and see for your arduino board. It should have proper naming like "arduino uno at port 3", then use the correct port in your command. If this name does not come properly then it means Driver is not available in your machine. So, go to step2.
Find the driver online and install it in your system, I am not sure about the support of linux with arduino, once it is done please repeat step1.
So, I conclude in short that you do not have the proper driver (which is strongly believe) or pointing the wrong port. I am not an expert with the udev rules, but it is definitely an issue you can experience with these kinds of micro-controllers.

How to reply to a USSD menu using Linux command line tools?

I want to obtain information about the account balance of a SIM card I have installed in a mobile broadband modem in my computer. For my mobile network operator, this works using the USSD code 100#.
I found that gammu can send that USSD code using gammu getussd '100#'. In response, gammu shows me this USSD menu:
Press Ctrl+C to break...
USSD received
Status : Action needed
Service reply : "Reply with your option:
1.Account Balance
2.Buy a Data Plan
3.Top Up Now
No response in specified timeout. Probably phone not connected.
How can select an option from that menu (like, 1)?
It seems to me that ModemManager (and its command line client interface mmcli) is currently the most sophisticated, highest-quality solution for interacting with USSD and USSD menus under Linux.
Installation (under Debian / Ubuntu Linux):
sudo apt-get install modemmanager modem-manager-gui
Usage (following the manpage):
Listing your modems: mmcli -L. This will show a modem device path like /org/freedesktop/ModemManager1/Modem/12 and you can use the number at its end to specify the modem to use after the -m option in the following commands.
Showing attributes of your modem: mmcli -m 12.
Enabling the modem (needed before using it for USSD): mmcli -m 12 -e
Starting a USSD session. For example, for Ncell this command shows the main USSD menu: mmcli -m 12 --3gpp-ussd-initiate="*100#"
Responding to a USSD menu. After the session is started, you may use a command like this to respond, here using option 1: mmcli -m 12 --3gpp-ussd-respond="1"
Canceling the USSD session on the given modem: mmcli -m 12 --3gpp-ussd-cancel.
Obtaining the status of all USSD sessions (of all available modems): mmcli --3gpp-ussd-status.
With most hardware, this should work properly and immediately as described.
(With my hardware however, I could not use mmcli so far due to a bug. All USSD related commands in mmcli would reply error: modem not unlocked yet, and mmcli -m 12 | grep " lock" would show that the sim-pin2 lock is enabled. But it is not (means I could not get past this by disabling the lock). And even if it would be enabled, that lock would not limit USSD usage (it's rather just meant for limiting outgoing calls to certain numbers). So, I'll have to remove this overzealous test condition from here, compile it myself and test again … .)
The Linux command line tool gsm-ussd has support for USSD sessions that will allow you to answer to USSD menus. For detailed installation and configuration instructions see here. The version 0.4 Debian package offered there for installation is the latest dev branch version.
However, the support for this is not yet stable [source]. At least for me, it does not work. With different hardware and / or mobile network operators, you might have more luck.
The way it is meant to be used is like this (using Ncell as example):
$ gsm-ussd -m /dev/ttyUSB1 "*100#"
USSD session open, to cancel use "gsm-ussd -c".
1 Account
2 Services operations
3 Offices information
4 How to call Call Center
5 Change password
Note:
Back:* Top:#
To reply and select an option, you would send something like:
$ gsm-ussd -m /dev/ttyUSB1 "1"
To end the session and return back to normal single-command USSD mode, you would execute gsm-ussd -c. More complete documentation is here.
I found that I can successfully navigate USSD menus with AT commands directly. Given my system's issues with the otherwise preferable mmcli solution (see my other answer for details), this is so far the only working solution to navigate USSD for me.
How to get this to work:
(1) Install an AT terminal. I chose atinout to communicate with the modem via AT commands. You can also use any other AT terminal software like putty, minicom etc.. To install atinout:
sudo apt-get install ruby-ronn;
git clone git://git.code.sf.net/p/atinout/code atinout;
cd atinout;
make;
sudo checkinstall make install;
(2) If you use ModemManager (which is the default under Ubuntu Linux), you might have to disable it first to allow atinout to access your modem:
sudo stop modemmanager;
(3) Now, to receive and reply to an USSD menu, you would use a command like this:
atinout - /dev/ttyUSB1 - < <(echo "AT+CUSD=1,\"100#\",15") && sleep 4 && \
atinout - /dev/ttyUSB1 - < <(echo "AT") && \
\
atinout - /dev/ttyUSB1 - < <(echo "AT+CUSD=1,\"1\",15") && sleep 4 && \
atinout - /dev/ttyUSB1 - < <(echo "AT");
This assumes your modem is at /dev/ttyUSB1 and the code to receive the USSD menu is 100#. Adapt to your situation.
Explanation: The command sends 100# to the network to receive the USSD menu, and then 1 to choose the first option. Spreading one USSD menu session over multiple atinout calls like this does not break the session if you don't exceed the timeouts (which are usually >20s).
Troubleshooting: If the above all-in-one command does not work, try executing the individual parts manually, repeating those that fail. If something fails repeatedly ("resource busy" etc.), your modem might be in a strange state. Reset it, or just let the computer go through a suspend / resume cycle.
It's currently not possible with Gammu command line, but you can use simple Python script using python-gammu: https://github.com/gammu/python-gammu/blob/master/examples/service_numbers.py
The answer from the link below worked great for me.
You can add the modemmanager PPA and update your apt. There's a bug mentioned in the link for some usb modems, but that has been fixed with the update
sudo add-apt-repository ppa:aleksander-m/modemmanager-xenial<br>
sudo apt-get update
Then follow this: https://stackoverflow.com/a/31864567/6161579
Thanks #tanius

How to setup serial communication in Processing to /dev/rfcomm0

I am trying to perform serial communication on between Ubuntu 12.04 and a JY-MCU bluetooth serial module connected to an Arduino.
I have created this configuration in /etc/bluetooth/rfcomm.conf
rfcomm0 {
# # Automatically bind the device at startup
bind yes;
#
# # Bluetooth address of the device
device 00:12:11:19:08:54
# # RFCOMM channel for the connection
channel 1;
# # Description of the connection
comment "Linvor Bluetooth Module";
}
I can use putty to communicate with the /dev/rfcomm0 serial port and this works perfectly.
However, despite many attempts I simply cannot see how to create a serial port in Processing that works in any way.
For example :
println(Serial.list());
prints nothing at all.
If I execute:
String portName = "/dev/rfcomm0";
myPort = new Serial(this, portName, 9600);
println(myPort);
I see this in the monitor:
processing.serial.Serial#1712651
But if I then call:
myPort.write('9');
I get an exception:
java.lang.NullPointerException
at processing.serial.Serial.write(Serial.java:572)
...
I can't understand why this fails. I have been following all the instructions from Tom Igoe's "Making Things Talk", but this just does not work the way he says...
Any help would b great!
Thanks,
Bob
Aftert searching high and low, I have made this work.
The key issue is that processing uses the rxtx java library (RXTX-2.1-7) for serial communications.
The RXTX wiki says:
"rxtx tries to detect ports on by scanning /dev for files matching any
of a set of known-good prefixes, such as 'ttyS', 'ttym', and since 2.2
'ttyUSB' and so on. "
And since the bluetooth device is named rfcomm* it cannot be detected.
The trick is to create a sym link to fool rxtx (use a ttyS device that is not yet assigned):
$ sudo ln -s /dev/rfcomm0 /dev/ttyS99
Then, connect:
$ sudo rfcomm connect 0
Connected /dev/rfcomm0 to 00:12:11:19:08:54 on channel 1
Press CTRL-C for hangup
At this point the red led on the JY-MCU becomes solid and processing can detect it:
println(Serial.list());
output is:
[0] "/dev/ttyACM0"
[1] "/dev/ttyS99"
So, serial communication can work.
To summarize, the following process will allow a processing script to communicate via a serial port with a JY-MCU device in a BlueZ linux framework
One time setup:
power up the JY-MCU,
use the following command to get its hardware address, mine is 00:12:11:19:08:54
$ hcitool scan
use that to create the /etc/bluetooth/rfcomm.conf file; you'll note that I chose 0 for the rfcomm device , we need that for connection later:
$ cat /etc/bluetooth/rfcomm.conf
rfcomm0 {
bind yes;
device 00:12:11:19:08:54;
channel 1;
comment "Linvor Bluetooth Module";
}
use BlueMan to pair the JY-MCU.
Every time you want to use the JY-MCU
create the sym link:
$ sudo ln -s /dev/rfcomm0 /dev/ttyS99
connect to the JY-MCU:
$ sudo rfcomm connect 0
Connected /dev/rfcomm0 to 00:12:11:19:08:54 on channel 1
Press CTRL-C for hangup
you can now run a processing script and connect to the JY-MCU with
the code:
String portName = "/dev/ttyS99";
myPort = new Serial(this, portName, 9600);
after running the processing script, be sure to CTRL-C at the
command line to disconnect the JY-MCU.
That should do it!
Ciao,
Bob
Just something popped up in my mind.
I had similar problems that were caused due to channel 1 is already used. If you bind to a channel which already is in use, bad things may happen.
sdptool browse local
Use that command to see which channels are available on your Ubuntu device.

Linux command line howto accept pairing for bluetooth device without pin

Is there a way to pair a device in linux without requiring a pin(for testing purposes so I need it to be done w/out human interaction, assuming you have root access)?
bluez-simple-agent seems to require a pin except with some simple devices such as mice.
Entering a PIN is actually an outdated method of pairing, now called Legacy Pairing. Secure Simple Pairing Mode is available in Bluetooth v2.1 and later, which comprises most modern Bluetooth devices. SSPMode authentication is handled by the Bluetooth protocol stack and thus works without user interaction.
Here is how one might go about connecting to a device:
# hciconfig hci0 sspmode 1
# hciconfig hci0 sspmode
hci0: Type: BR/EDR Bus: USB
BD Address: AA:BB:CC:DD:EE:FF ACL MTU: 1021:8 SCO MTU: 64:1
Simple Pairing mode: Enabled
# hciconfig hci0 piscan
# sdptool add SP
# hcitool scan
00:11:22:33:44:55 My_Device
# rfcomm connect /dev/rfcomm0 00:11:22:33:44:55 1 &
Connected /dev/rfcomm0 to 00:11:22:33:44:55 on channel 1
Press CTRL-C for hangup
This would establish a serial connection to the device.
follow steps (CentOs):
bluetoothctl
devices
scan on
pair 34:88:5D:51:5A:95 (34:88:5D:51:5A:95 is my device code,replace it with yours)
trust 34:88:5D:51:5A:95
connect 34:88:5D:51:5A:95
If you want more details
https://www.youtube.com/watch?v=CB1E4Ir3AV4
Try setting security to none in /etc/bluetooth/hcid.conf
http://linux.die.net/man/5/hcid.conf
This will probably only work for HCI devices (mouse, keyboard, spaceball, etc.). If you have a different kind of device, there's probably a different but similar setting to change.
This worked like a charm for me, of-course it requires super-user privileges :-)
# hcitool cc <target-bdaddr>; hcitool auth <target-bdaddr>
To get <target-bdaddr> you may issue below command:
$ hcitool scan
Note: Exclude # & $ as they are command line prompts.
Courtesy
For Ubuntu 14.04 and Android try:
hcitool scan #get hardware address
sudo bluetooth-agent PIN HARDWARE-ADDRESS
PIN dialog pops up on Android device. Enter same PIN.
Note: sudo apt-get install bluez-utils might be necessary.
Note2: If PIN dialog does not appear, try pairing from Android first (will fail because of wrong PIN). Then try again as described above.
~ $ hciconfig noauth
This should do the trick (I'm using bluez 5.23 and there's no more simple-egent and blue-utils). However, I'm trying to look for a way to make changes hciconfig permanent because after power out and then power on, authentication is needed again. So far, the changes in hciconfig still stays the same when you reboot it. it reverts back only when power out. If anybody has found a way to make hciconfig permanent, do let me know!
~ $ hciconfig noauth
It worked for me in "Linux mx 4.19"
The exact steps are:
1) open a terminal - run: "hciconfig noauth"
2) use the blueman-manager gui to pair the device (in my case it was a keyboard)
3) from the blueman-manager choose "connect to HID"
step(3) is normally asking for a password - the "hciconfig noauth" makes step(3) passwordless

Resources