/* * vehicle-tool * * Example vehicle control tool for Anki Drive SDK * * Copyright (C) 2014 Anki, Inc. * * 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 * * Portions of this software are derived from BlueZ, a Bluetooth protocol stack for * Linux. The license for BlueZ is included below. */ /* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 Nokia Corporation * Copyright (C) 2010 Marcel Holtmann * * * 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 * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include static char *opt_src = NULL; static char *opt_dst = NULL; static char *opt_dst_type = NULL; static char *opt_value = NULL; static char *opt_sec_level = NULL; static bt_uuid_t *opt_uuid = NULL; static int opt_handle = -1; static int opt_mtu = 0; static int opt_psm = 0; static GMainLoop *event_loop; static gboolean got_error = FALSE; static GSourceFunc operation; struct characteristic_data { GAttrib *attrib; uint16_t start; uint16_t end; }; static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data) { GAttrib *attrib = user_data; uint8_t *opdu; uint16_t handle, i, olen = 0; size_t plen; handle = att_get_u16(&pdu[1]); switch (pdu[0]) { case ATT_OP_HANDLE_NOTIFY: g_print("Notification handle = 0x%04x value: ", handle); break; case ATT_OP_HANDLE_IND: g_print("Indication handle = 0x%04x value: ", handle); break; default: g_print("Invalid opcode\n"); return; } for (i = 3; i < len; i++) g_print("%02x ", pdu[i]); g_print("\n"); if (pdu[0] == ATT_OP_HANDLE_NOTIFY) return; opdu = g_attrib_get_buffer(attrib, &plen); olen = enc_confirmation(opdu, plen); if (olen > 0) g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL); } static GOptionEntry options[] = { { "adapter", 'i', 0, G_OPTION_ARG_STRING, &opt_src, "Specify local adapter interface", "hciX" }, { "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst, "Specify remote Bluetooth address", "MAC" }, { "addr-type", 't', 0, G_OPTION_ARG_STRING, &opt_dst_type, "Set LE address type. Default: random", "[public | random]"}, { "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu, "Specify the MTU size", "MTU" }, { "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm, "Specify the PSM for GATT/ATT over BR/EDR", "PSM" }, { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level, "Set security level. Default: low", "[low | medium | high]"}, { NULL }, }; int main(int argc, char *argv[]) { GOptionContext *context; GOptionGroup *gatt_group, *params_group, *char_rw_group; GError *gerr = NULL; GIOChannel *chan; opt_dst_type = g_strdup("random"); opt_sec_level = g_strdup("low"); context = g_option_context_new(NULL); g_option_context_add_main_entries(context, options, NULL); if (!g_option_context_parse(context, &argc, &argv, &gerr)) { g_printerr("%s\n", gerr->message); g_clear_error(&gerr); } interactive(opt_src, opt_dst, opt_dst_type, opt_psm); done: g_option_context_free(context); g_free(opt_src); g_free(opt_dst); g_free(opt_uuid); g_free(opt_sec_level); if (got_error) exit(EXIT_FAILURE); else exit(EXIT_SUCCESS); }