static void read_reply(DBusMessage *message, void *user_data) { DBusError error; DBusMessageIter iter, array; uint8_t *value; int len; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == TRUE) { rl_printf("Failed to read: %s\n", error.name); dbus_error_free(&error); return; } dbus_message_iter_init(message, &iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { rl_printf("Invalid response to read\n"); return; } dbus_message_iter_recurse(&iter, &array); dbus_message_iter_get_fixed_array(&array, &value, &len); if (len < 0) { rl_printf("Unable to parse value\n"); return; } rl_hexdump(value, len); }
void gatt_register_profile(DBusConnection *conn, GDBusProxy *proxy, wordexp_t *w) { GList *l; l = g_list_find_custom(managers, proxy, match_proxy); if (!l) { rl_printf("Unable to find GattManager proxy\n"); return; } if (g_dbus_register_interface(conn, PROFILE_PATH, PROFILE_INTERFACE, methods, NULL, NULL, NULL, NULL) == FALSE) { rl_printf("Failed to register profile object\n"); return; } if (g_dbus_proxy_method_call(l->data, "RegisterProfile", register_profile_setup, register_profile_reply, w, NULL) == FALSE) { rl_printf("Failed register profile\n"); return; } }
static void read_attribute(GDBusProxy *proxy) { if (g_dbus_proxy_method_call(proxy, "ReadValue", NULL, read_reply, NULL, NULL) == FALSE) { rl_printf("Failed to read\n"); return; } rl_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy)); }
static void register_profile_reply(DBusMessage *message, void *user_data) { DBusError error; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == TRUE) { rl_printf("Failed to register profile: %s\n", error.name); dbus_error_free(&error); return; } rl_printf("Profile registered\n"); }
/* * Undo changes to tty mode */ void ReadLineTtyUnset (void) { #if HAVE_TCGETATTR if (!tty_saved) return; if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &tty_saved_attr) != 0) { rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE); rl_printf (i18n (2524, "Can't restore terminal modes.\n")); } else tty_saved = 0; #endif }
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { uint8_t value[plen]; ssize_t vlen; int i; GString *s; if (status != 0) { error("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status)); return; } vlen = dec_read_resp(pdu, plen, value, sizeof(value)); if (vlen < 0) { error("Protocol error\n"); return; } s = g_string_new("Characteristic value/descriptor: "); for (i = 0; i < vlen; i++) g_string_append_printf(s, "%02x ", value[i]); rl_printf("%s\n", s->str); g_string_free(s, TRUE); }
/* * Checks the file request response. */ BOOL PeerFileAccept (Connection *peer, UWORD ackstatus, UDWORD port) { Connection *flist, *fpeer; flist = PeerFileCreate (peer->serv); fpeer = ServerFindChild (flist->serv, peer->cont, TYPE_FILEDIRECT); if (!flist || !fpeer || !port || (ackstatus == TCP_ACK_REFUSE)) { if (fpeer) TCPClose (fpeer); return 0; } ASSERT_MSGDIRECT(peer); ASSERT_FILELISTEN(flist); ASSERT_FILEDIRECT(fpeer); fpeer->connect = 0; fpeer->oscar_dc_seq = 0; fpeer->port = port; fpeer->ip = peer->ip; s_repl (&fpeer->server, s_ip (fpeer->ip)); if (prG->verbose) rl_printf (i18n (2520, "Opening file transfer connection to %s:%s%ld%s... \n"), s_wordquote (fpeer->server), COLQUOTE, UD2UL (fpeer->port), COLNONE); TCPDispatchConn (fpeer); return 1; }
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data) { uint16_t mtu; uint16_t cid; if (err) { set_state(STATE_DISCONNECTED); error("%s\n", err->message); return; } bt_io_get(io, &err, BT_IO_OPT_IMTU, &mtu, BT_IO_OPT_CID, &cid, BT_IO_OPT_INVALID); if (err) { g_printerr("Can't detect MTU, using default: %s", err->message); g_error_free(err); mtu = ATT_DEFAULT_LE_MTU; } if (cid == ATT_CID) mtu = ATT_DEFAULT_LE_MTU; attrib = g_attrib_new(iochannel, mtu, false); g_attrib_register(attrib, ATT_OP_HANDLE_NOTIFY, GATTRIB_ALL_HANDLES, events_handler, attrib, NULL); g_attrib_register(attrib, ATT_OP_HANDLE_IND, GATTRIB_ALL_HANDLES, events_handler, attrib, NULL); set_state(STATE_CONNECTED); rl_printf("Connection successful\n"); }
static void cmd_mtu(int argcp, char **argvp) { if (conn_state != STATE_CONNECTED) { failed("Disconnected\n"); return; } if (opt_psm) { failed("Operation is only available for LE transport.\n"); return; } if (argcp < 2) { rl_printf("Usage: mtu <value>\n"); return; } if (opt_mtu) { failed("MTU exchange can only occur once per connection.\n"); return; } errno = 0; opt_mtu = strtoll(argvp[1], NULL, 0); if (errno != 0 || opt_mtu < ATT_DEFAULT_LE_MTU) { error("Invalid value. Minimum MTU size is %d\n", ATT_DEFAULT_LE_MTU); return; } gatt_exchange_mtu(attrib, opt_mtu, exchange_mtu_cb, NULL); }
static void cmd_anki_vehicle_sdk_mode(int argcp, char **argvp) { uint8_t *value; size_t plen; int handle; if (conn_state != STATE_CONNECTED) { failed("Disconnected\n"); return; } if (argcp < 2) { rl_printf("Usage: %s <new value>\n", argvp[0]); return; } handle = vehicle.write_char.value_handle; int arg = atoi(argvp[1]); anki_vehicle_msg_t msg; plen = anki_vehicle_msg_set_sdk_mode(&msg, arg); value = (uint8_t *)&msg; gatt_write_char(attrib, handle, value, plen, NULL, NULL); }
/* * Create a new file listener unless one already exists. */ Connection *PeerFileCreate (Server *serv) { Connection *flist; assert (serv); if (!serv->oscar_dc || serv->oscar_dc->version < 6) return NULL; if ((flist = ServerFindChild (serv, NULL, TYPE_FILELISTEN))) return flist; flist = ServerChild (serv, NULL, TYPE_FILELISTEN); if (!flist) return NULL; flist->oscar_dc_seq = -1; flist->version = serv->oscar_dc->version; flist->cont = serv->oscar_dc->cont; flist->port = ServerPrefVal (serv, CO_OSCAR_DC_PORT); flist->dispatch = &TCPDispatchMain; if (prG->verbose) rl_printf (i18n (2519, "Opening file listener connection at %slocalhost%s:%s%ld%s... "), COLQUOTE, COLNONE, COLQUOTE, UD2UL (flist->port), COLNONE); UtilIOListenTCP (flist); return flist; }
static void notify_reply(DBusMessage *message, void *user_data) { bool enable = GPOINTER_TO_UINT(user_data); DBusError error; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == TRUE) { rl_printf("Failed to %s notify: %s\n", enable ? "start" : "stop", error.name); dbus_error_free(&error); return; } rl_printf("Notify %s\n", enable == TRUE ? "started" : "stopped"); }
static void cmd_anki_vehicle_write(int argcp, char **argvp) { uint8_t *value; size_t plen; int handle; if (conn_state != STATE_CONNECTED) { failed("Disconnected\n"); return; } if (argcp < 2) { rl_printf("Usage: %s <handle> <new value>\n", argvp[0]); return; } handle = vehicle.write_char.value_handle; plen = gatt_attr_data_from_string(argvp[1], &value); if (plen == 0) { error("Invalid value\n"); return; } if (g_strcmp0("send-data-req", argvp[0]) == 0) gatt_write_char(attrib, handle, value, plen, char_write_req_cb, NULL); else gatt_write_cmd(attrib, handle, value, plen, NULL, NULL); g_free(value); }
static void cmd_connect(int argcp, char **argvp) { GError *gerr = NULL; if (conn_state != STATE_DISCONNECTED) return; if (argcp > 1) { g_free(opt_dst); opt_dst = g_strdup(argvp[1]); g_free(opt_dst_type); if (argcp > 2) opt_dst_type = g_strdup(argvp[2]); else opt_dst_type = g_strdup("public"); } if (opt_dst == NULL) { error("Remote Bluetooth address required\n"); return; } rl_printf("Attempting to connect to %s\n", opt_dst); set_state(STATE_CONNECTING); iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level, opt_psm, opt_mtu, connect_cb, &gerr); if (iochannel == NULL) { set_state(STATE_DISCONNECTED); error("%s\n", gerr->message); g_error_free(gerr); } else g_io_add_watch(iochannel, G_IO_HUP, channel_watcher, NULL); }
static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct att_data_list *list; int i; GString *s; if (status != 0) { error("Read characteristics by UUID failed: %s\n", att_ecode2str(status)); return; } list = dec_read_by_type_resp(pdu, plen); if (list == NULL) return; s = g_string_new(NULL); for (i = 0; i < list->num; i++) { uint8_t *value = list->data[i]; int j; g_string_printf(s, "handle: 0x%04x \t value: ", get_le16(value)); value += 2; for (j = 0; j < list->len - 2; j++, value++) g_string_append_printf(s, "%02x ", *value); rl_printf("%s\n", s->str); } att_data_list_free(list); g_string_free(s, TRUE); }
static void cmd_help(int argcp, char **argvp) { int i; for (i = 0; commands[i].cmd; i++) rl_printf("%-15s %-30s %s\n", commands[i].cmd, commands[i].params, commands[i].desc); }
static void unregister_profile_reply(DBusMessage *message, void *user_data) { DBusConnection *conn = user_data; DBusError error; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == TRUE) { rl_printf("Failed to unregister profile: %s\n", error.name); dbus_error_free(&error); return; } rl_printf("Profile unregistered\n"); g_dbus_unregister_interface(conn, PROFILE_PATH, PROFILE_INTERFACE); }
void ad_advertise_manufacturer(const char *arg) { wordexp_t w; unsigned int i; char *endptr = NULL; long int val; if (wordexp(arg, &w, WRDE_NOCMD)) { rl_printf("Invalid argument\n"); return; } ad_clear_manufacturer(); if (w.we_wordc == 0) goto done; val = strtol(w.we_wordv[0], &endptr, 0); if (!endptr || *endptr != '\0' || val > UINT16_MAX) { rl_printf("Invalid manufacture id\n"); goto done; } ad_manufacturer_id = val; for (i = 1; i < w.we_wordc; i++) { if (i >= G_N_ELEMENTS(ad_service_data)) { rl_printf("Too much data\n"); goto done; } val = strtol(w.we_wordv[i], &endptr, 0); if (!endptr || *endptr != '\0' || val > UINT8_MAX) { rl_printf("Invalid value at index %d\n", i); ad_clear_service(); goto done; } ad_manufacturer_data[ad_manufacturer_data_len] = val; ad_manufacturer_data_len++; } done: wordfree(&w); }
void gatt_unregister_profile(DBusConnection *conn, GDBusProxy *proxy) { GList *l; l = g_list_find_custom(managers, proxy, match_proxy); if (!l) { rl_printf("Unable to find GattManager proxy\n"); return; } if (g_dbus_proxy_method_call(l->data, "UnregisterProfile", unregister_profile_setup, unregister_profile_reply, conn, NULL) == FALSE) { rl_printf("Failed unregister profile\n"); return; } }
static DBusMessage *release_advertising(DBusConnection *conn, DBusMessage *msg, void *user_data) { rl_printf("Advertising released\n"); ad_release(conn); return dbus_message_new_method_return(msg); }
static void register_reply(DBusMessage *message, void *user_data) { DBusConnection *conn = user_data; DBusError error; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == FALSE) { registered = TRUE; rl_printf("Advertising object registered\n"); } else { rl_printf("Failed to register advertisement: %s\n", error.name); dbus_error_free(&error); if (g_dbus_unregister_interface(conn, AD_PATH, AD_IFACE) == FALSE) rl_printf("Failed to unregister advertising object\n"); } }
static void cmd_anki_vehicle_lights_pattern(int argcp, char **argvp) { uint8_t *value; size_t plen; int handle; if (conn_state != STATE_CONNECTED) { failed("Disconnected\n"); return; } if (argcp < 6) { rl_printf("Usage: %s <channel> <effect> <start> <end> <cycles_per_min>\n", argvp[0]); rl_printf(" channels: RED, TAIL, BLUE, GREEN, FRONTL, FRONTR\n"); rl_printf(" effects: STEADY, FADE, THROB, FLASH, RANDOM\n"); return; } handle = vehicle.write_char.value_handle; uint8_t channel = get_channel_by_name(argvp[1]); if (channel == channel_invalid) { rl_printf("Unrecognized channel: %s\n", argvp[1]); return; } uint8_t effect = get_effect_by_name(argvp[2]); if (effect == effect_invalid) { rl_printf("Unrecognized channel: %s\n", argvp[2]); return; } uint8_t start = atoi(argvp[3]); uint8_t end = atoi(argvp[4]); uint16_t cycles_per_min = atoi(argvp[5]); anki_vehicle_msg_t msg; plen = anki_vehicle_msg_lights_pattern(&msg, channel, effect, start, end, cycles_per_min); value = (uint8_t *)&msg; gatt_write_char(attrib, handle, value, plen, NULL, NULL); }
gboolean static writehnd() { //rl_printf("test\n"); int chs = getChannelstatus(); //rl_printf("status=%s\n",data); if (conn_state == STATE_DISCONNECTED && chs==1) { myconnect(); } if(chs==0) { disconnect_io(); return TRUE; } if(conn_state == STATE_CONNECTING) return TRUE; if(attrib ==NULL) return TRUE; http(); rl_printf("data = %s\n",data); if( pre_state != 31 && atoi(data) ==1) { size_t plen; uint8_t *value; plen = gatt_attr_data_from_string("31", &value); gatt_write_cmd(attrib, 14, value, plen, NULL, NULL); g_free(value); pre_state = 31; } else if(pre_state != 30 && atoi(data)==0) { size_t plen; uint8_t *value; plen = gatt_attr_data_from_string("30", &value); gatt_write_cmd(attrib, 14, value, plen, NULL, NULL); g_free(value); pre_state = 30; } //http(); return TRUE; }
/* * Read in given amount of data and parse as TLVs. * * The resulting array of TLV does not have pointers into the given Packet. */ TLV *TLVRead (Packet *pak, UDWORD TLVlen) { TLV *tlv = calloc (__maxTLV, sizeof (TLV)); int typ, pos, i = __minTLV, n, max = __maxTLV; UDWORD len; assert (tlv); while (TLVlen >= 4) { typ = PacketReadB2 (pak); len = PacketReadB2 (pak); if (TLVlen < len) { rl_printf (i18n (1897, "Incomplete TLV %d, len %ld of %ld - ignoring.\n"), typ, TLVlen, len); return tlv; } if (typ >= __minTLV || tlv[typ].str.len) n = i++; else n = typ; if (i + 1 == max) { TLV *tlvn; max += 5; tlvn = calloc (max, sizeof (TLV)); assert (tlvn); memcpy (tlvn, tlv, (max - 5) * sizeof (TLV)); free (tlv); tlv = tlvn; } pos = PacketReadPos (pak); if (len == 2) tlv[n].nr = PacketReadAtB2 (pak, pos); if (len == 4) tlv[n].nr = PacketReadAtB4 (pak, pos); PacketReadData (pak, &tlv[n].str, len); if (tlv[n].str.max < len) return tlv; tlv[n].str.txt[len] = '\0'; tlv[n].tag = typ; TLVlen -= 2 + 2 + len; } return tlv; }
static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data) { struct att_data_list *list; guint8 format; uint16_t handle = 0xffff; int i; if (status != 0) { rl_printf("Discover descriptors finished: %s\n", att_ecode2str(status)); return; } list = dec_find_info_resp(pdu, plen, &format); if (list == NULL) return; for (i = 0; i < list->num; i++) { char uuidstr[MAX_LEN_UUID_STR]; uint8_t *value; bt_uuid_t uuid; value = list->data[i]; handle = att_get_u16(value); if (format == 0x01) uuid = att_get_uuid16(&value[2]); else uuid = att_get_uuid128(&value[2]); bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR); rl_printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr); } att_data_list_free(list); if (handle != 0xffff && handle < end) gatt_discover_char_desc(attrib, handle + 1, end, char_desc_cb, NULL); }
static void write_reply(DBusMessage *message, void *user_data) { DBusError error; dbus_error_init(&error); if (dbus_set_error_from_message(&error, message) == TRUE) { rl_printf("Failed to write: %s\n", error.name); dbus_error_free(&error); return; } }
io_ssl_err_t UtilIOSSLSupported (void) { io_ssl_err_t rcgnutls = IOGnuTLSSupported (); io_ssl_err_t rcopenssl = rcgnutls == IO_SSL_OK ? IO_SSL_NOLIB : IOOpenSSLSupported (); if (rcgnutls == IO_SSL_OK || rcopenssl == IO_SSL_OK) return IO_SSL_OK; if (rcgnutls != IO_SSL_NOLIB) { rl_printf (i18n (2374, "SSL error: %s [%d]\n"), IOGnuTLSInitError (), 0); rl_printf (i18n (2371, "SSL init failed.\n")); } if (rcopenssl == IO_SSL_INIT) { rl_printf (i18n (2374, "SSL error: %s [%d]\n"), IOOpenSSLInitError (), 0); rl_printf (i18n (2371, "SSL init failed.\n")); } else rl_printf (i18n (2581, "Install the GnuTLS library and enjoy encrypted connections to peers!\n")); return IO_SSL_NOLIB; }
/* * Change tty mode for mICQ */ void ReadLineTtySet (void) { #if HAVE_TCGETATTR if (tcgetattr (STDIN_FILENO, &tty_attr) != 0) { rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE); rl_printf (i18n (2525, "Can't read terminal modes.\n")); return; } if (!tty_saved) { tty_saved_attr = tty_attr; tty_saved = 1; } tty_attr.c_lflag &= ~(ECHO | ICANON); if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &tty_attr) != 0) { rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE); rl_printf (i18n (2526, "Can't modify terminal modes.\n")); return; } tty_attr.c_cc[VMIN] = 1; if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &tty_attr) != 0) { rl_printf ("%s%s%s ", COLERROR, i18n (1619, "Warning:"), COLNONE); rl_printf (i18n (2526, "Can't modify terminal modes.\n")); } #endif }
void rl_hexdump(const unsigned char *buf, size_t len) { static const char hexdigits[] = "0123456789abcdef"; char str[68]; size_t i; if (!len) return; str[0] = ' '; for (i = 0; i < len; i++) { str[((i % 16) * 3) + 1] = ' '; str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4]; str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf]; str[(i % 16) + 51] = isprint(buf[i]) ? buf[i] : '.'; if ((i + 1) % 16 == 0) { str[49] = ' '; str[50] = ' '; str[67] = '\0'; rl_printf("%s\n", str); str[0] = ' '; } } if (i % 16 > 0) { size_t j; for (j = (i % 16); j < 16; j++) { str[(j * 3) + 1] = ' '; str[(j * 3) + 2] = ' '; str[(j * 3) + 3] = ' '; str[j + 51] = ' '; } str[49] = ' '; str[50] = ' '; str[67] = '\0'; rl_printf("%s\n", str); } }
static void cmd_sec_level(int argcp, char **argvp) { GError *gerr = NULL; BtIOSecLevel sec_level; if (argcp < 2) { rl_printf("sec-level: %s\n", opt_sec_level); return; } if (strcasecmp(argvp[1], "medium") == 0) sec_level = BT_IO_SEC_MEDIUM; else if (strcasecmp(argvp[1], "high") == 0) sec_level = BT_IO_SEC_HIGH; else if (strcasecmp(argvp[1], "low") == 0) sec_level = BT_IO_SEC_LOW; else { rl_printf("Allowed values: low | medium | high\n"); return; } g_free(opt_sec_level); opt_sec_level = g_strdup(argvp[1]); if (conn_state != STATE_CONNECTED) return; if (opt_psm) { rl_printf("Change will take effect on reconnection\n"); return; } bt_io_set(iochannel, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level, BT_IO_OPT_INVALID); if (gerr) { error("%s\n", gerr->message); g_error_free(gerr); } }