Commit ee746e51 authored by Frederic Danis's avatar Frederic Danis

Add sample app to change TX power

This sample app changes the running TX Power and level and perform a
reconnection to the remote device, which allows to apply the new TX Power
level.
It should be run as root.
Signed-off-by: Frederic Danis's avatarFrédéric Danis <frederic.danis@collabora.com>
parent b2bc8b04
......@@ -14,3 +14,13 @@ pkg_check_modules(BLUEZ REQUIRED bluez>=5.48)
target_link_libraries(btcsrtest ${BLUEZ_LIBRARIES} btcsr)
install(TARGETS btcsrtest DESTINATION bin)
add_executable(bttxpower bttxpower.c)
pkg_check_modules(BLUEZ REQUIRED bluez>=5.48)
pkg_check_modules(GLIB2 REQUIRED glib-2.0)
pkg_check_modules(GIO2 REQUIRED gio-2.0)
target_link_libraries(bttxpower ${BLUEZ_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO2_LIBRARIES} btcsr)
include_directories(${GLIB2_INCLUDE_DIRS})
install(TARGETS bttxpower DESTINATION bin)
......@@ -10,7 +10,7 @@ make
This will build `libbtcsr.so` library and `btcsrtest` application to exercise libbtcsr and BlueZ functions related to RSSI, Tx Power, Link Quality and AFH.
## Test app
## btcsrtest app
```
$ ./btcsrtest -h
......@@ -50,3 +50,20 @@ For example, to request second HCI device to set _AFH Host Channel Classificatio
```
$ ./btcsrtest -i hci1 set-afh 0xff 0xff 0xff 0x00 0x00 0x80 0xff 0xff 0xff 0x7f
```
## bttxpower app
```
$ ./bttxpower
Usage:
./bttxpower <HCI device> <Remote device address> <TX power level>
```
HCI device to use is in same form as in _hciconfig_.\
This sample app changes the running TX Power level and perform a reconnection to the remote device, which allows to apply the new TX Power level.\
__It should be run as root__.
For example, to set TX Power Level of the 1st Bluetooth adapter `hci0` to `4` and apply it to the connection to the remote device `11:22:33:44:55:66`:
```
$ sudo ./bttxpower hci0 11:22:33:44:55:66 4
```
/*
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2019 Collabora Ltd
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <glib.h>
#include <gio/gio.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include "btcsr.h"
GDBusConnection *con;
GMainLoop *loop;
static void connect_done(GObject *con, GAsyncResult *res, gpointer data)
{
GVariant *result = NULL;
GError *error = NULL;
result = g_dbus_connection_call_finish((GDBusConnection *)con, res, &error);
if(error != NULL) {
g_print("Unable to get result: %s\n", error->message);
g_main_loop_quit(loop);
return;
}
g_print("Connect done\n");
g_variant_unref(result);
g_main_loop_quit(loop);
}
static void disconnect_done(GObject *con, GAsyncResult *res, gpointer data)
{
gchar *path = (gchar *)data;
GVariant *result = NULL;
GError *error = NULL;
result = g_dbus_connection_call_finish((GDBusConnection *)con, res, &error);
if(error != NULL) {
g_print("Unable to get result: %s\n", error->message);
g_main_loop_quit(loop);
return;
}
g_print("Disconnect done\n");
/* Disconnect is done, reconnect to the remote device */
g_dbus_connection_call((GDBusConnection *)con, "org.bluez", path,
"org.bluez.Device1", "Connect", NULL, NULL,
G_DBUS_CALL_FLAGS_NONE, -1, NULL, connect_done, path);
g_variant_unref(result);
}
int main(int argc, char *argv[])
{
int dev_id, dd;
gchar *path, *addr;
int16_t level;
if (argc != 4) {
g_print("Usage:\n"
"\t%s <HCI device> <Remote device address> <TX power level>\n",
argv[0]);
return 1;
}
dev_id = hci_devid(argv[1]);
if (dev_id < 0) {
g_print("Invalid device\n");
return 1;
}
/* Replace ':' by '_' in remote address to be used in DBus path */
for (char *p = argv[2]; p = strchr(p, ':'); ++p)
*p = '_';
/* Create DBus path for the remote device */
path = g_strdup_printf("/org/bluez/%s/dev_%s", argv[1], argv[2]);
if (!strncasecmp(argv[3], "0x", 2))
level = strtol(argv[3] + 2, NULL, 16);
else
level = atoi(argv[3]);
con = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
if (con == NULL) {
g_print("Not able to get connection to system bus\n");
return 1;
}
loop = g_main_loop_new(NULL, FALSE);
/* Change the Max TX Power level for the adapter */
dd = hci_open_dev(dev_id);
if (dd < 0) {
perror("HCI device open failed");
return 1;
}
if (btcsr_set_max_tx_power(dd, level) < 0) {
perror("Failed to set running Max TX power");
return 1;
}
hci_close_dev(dd);
/* Disconnect then reconnect to the remote device to apply the new
* Max TX Power level to the connection */
g_dbus_connection_call(con, "org.bluez", path, "org.bluez.Device1",
"Disconnect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
-1, NULL, disconnect_done, path);
g_main_loop_run(loop);
g_free(path);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment