static void cmd_write_execute(struct client *cli, char *cmd_str) { char *argvbuf[516]; char **argv = argvbuf; int argc = 0; char *endptr = NULL; unsigned int session_id; bool execute; if (!bt_gatt_client_is_ready(cli->gatt)) { printf("GATT client not initialized\n"); return; } if (!parse_args(cmd_str, 514, argv, &argc)) { printf("Too many arguments\n"); write_value_usage(); return; } if (argc < 2) { write_execute_usage(); return; } session_id = strtol(argv[0], &endptr, 0); if (!endptr || *endptr != '\0') { printf("Invalid session id: %s\n", argv[0]); return; } if (session_id != cli->reliable_session_id) { printf("Invalid session id: %u != %u\n", session_id, cli->reliable_session_id); return; } execute = !!strtol(argv[1], &endptr, 0); if (!endptr || *endptr != '\0') { printf("Invalid execute: %s\n", argv[1]); return; } if (execute) { if (!bt_gatt_client_write_execute(cli->gatt, session_id, write_cb, NULL, NULL)) printf("Failed to proceed write execute\n"); } else { bt_gatt_client_cancel(cli->gatt, session_id); } cli->reliable_session_id = 0; }
static void cmd_write_long_value(struct client *cli, char *cmd_str) { int opt, i; char *argvbuf[516]; char **argv = argvbuf; int argc = 1; uint16_t handle; uint16_t offset; char *endptr = NULL; int length; uint8_t *value = NULL; bool reliable_writes = false; if (!bt_gatt_client_is_ready(cli->gatt)) { printf("GATT client not initialized\n"); return; } if (!parse_args(cmd_str, 514, argv + 1, &argc)) { printf("Too many arguments\n"); write_value_usage(); return; } optind = 0; argv[0] = "write-long-value"; while ((opt = getopt_long(argc, argv, "+r", write_long_value_options, NULL)) != -1) { switch (opt) { case 'r': reliable_writes = true; break; default: write_long_value_usage(); return; } } argc -= optind; argv += optind; if (argc < 2) { write_long_value_usage(); return; } handle = strtol(argv[0], &endptr, 16); if (!endptr || *endptr != '\0' || !handle) { printf("Invalid handle: %s\n", argv[0]); return; } endptr = NULL; offset = strtol(argv[1], &endptr, 10); if (!endptr || *endptr != '\0' || errno == ERANGE) { printf("Invalid offset: %s\n", argv[1]); return; } length = argc - 1; if (length > 0) { if (length > UINT16_MAX) { printf("Write value too long\n"); return; } value = malloc(length); if (!value) { printf("Failed to construct write value\n"); return; } for (i = 2; i < argc; i++) { if (strlen(argv[i]) != 2) { printf("Invalid value byte: %s\n", argv[i]); free(value); return; } value[i-2] = strtol(argv[i], &endptr, 16); if (endptr == argv[i] || *endptr != '\0' || errno == ERANGE) { printf("Invalid value byte: %s\n", argv[i]); free(value); return; } } } if (!bt_gatt_client_write_long_value(cli->gatt, reliable_writes, handle, offset, value, length, write_long_cb, NULL, NULL)) printf("Failed to initiate long write procedure\n"); free(value); }
static void cmd_write_value(struct client *cli, char *cmd_str) { int opt, i; char *argvbuf[516]; char **argv = argvbuf; int argc = 1; uint16_t handle; char *endptr = NULL; int length; uint8_t *value = NULL; bool without_response = false; if (!bt_gatt_client_is_ready(cli->gatt)) { printf("GATT client not initialized\n"); return; } if (!parse_args(cmd_str, 514, argv + 1, &argc)) { printf("Too many arguments\n"); write_value_usage(); return; } optind = 0; argv[0] = "write-value"; while ((opt = getopt_long(argc, argv, "+w", write_value_options, NULL)) != -1) { switch (opt) { case 'w': without_response = true; break; default: write_value_usage(); return; } } argc -= optind; argv += optind; if (argc < 1) { write_value_usage(); return; } handle = strtol(argv[0], &endptr, 16); if (!endptr || *endptr != '\0' || !handle) { printf("Invalid handle: %s\n", argv[0]); return; } length = argc - 1; if (length > 0) { if (length > UINT16_MAX) { printf("Write value too long\n"); return; } value = malloc(length); if (!value) { printf("Failed to construct write value\n"); return; } for (i = 1; i < argc; i++) { if (strlen(argv[i]) != 2) { printf("Invalid value byte: %s\n", argv[i]); goto done; } value[i-1] = strtol(argv[i], &endptr, 16); if (endptr == argv[i] || *endptr != '\0' || errno == ERANGE) { printf("Invalid value byte: %s\n", argv[i]); goto done; } } } if (without_response) { if (!bt_gatt_client_write_without_response(cli->gatt, handle, false, value, length)) { printf("Failed to initiate write without response " "procedure\n"); goto done; } printf("Write command sent\n"); goto done; } if (!bt_gatt_client_write_value(cli->gatt, handle, value, length, write_cb, NULL, NULL)) printf("Failed to initiate write procedure\n"); done: free(value); }
static void cmd_write_prepare(struct client *cli, char *cmd_str) { int opt, i, val; char *argvbuf[516]; char **argv = argvbuf; int argc = 0; unsigned int id = 0; uint16_t handle; uint16_t offset; char *endptr = NULL; unsigned int length; uint8_t *value = NULL; if (!bt_gatt_client_is_ready(cli->gatt)) { printf("GATT client not initialized\n"); return; } if (!parse_args(cmd_str, 514, argv + 1, &argc)) { printf("Too many arguments\n"); write_value_usage(); return; } /* Add command name for getopt_long */ argc++; argv[0] = "write-prepare"; optind = 0; while ((opt = getopt_long(argc, argv , "s:", write_prepare_options, NULL)) != -1) { switch (opt) { case 's': if (!optarg) { write_prepare_usage(); return; } id = atoi(optarg); break; default: write_prepare_usage(); return; } } argc -= optind; argv += optind; if (argc < 3) { write_prepare_usage(); return; } if (cli->reliable_session_id != id) { printf("Session id != Ongoing session id (%u!=%u)\n", id, cli->reliable_session_id); return; } handle = strtol(argv[0], &endptr, 0); if (!endptr || *endptr != '\0' || !handle) { printf("Invalid handle: %s\n", argv[0]); return; } endptr = NULL; offset = strtol(argv[1], &endptr, 0); if (!endptr || *endptr != '\0' || errno == ERANGE) { printf("Invalid offset: %s\n", argv[1]); return; } /* * First two arguments are handle and offset. What remains is the value * length */ length = argc - 2; if (length == 0) goto done; if (length > UINT16_MAX) { printf("Write value too long\n"); return; } value = malloc(length); if (!value) { printf("Failed to allocate memory for value\n"); return; } for (i = 2; i < argc; i++) { val = strtol(argv[i], &endptr, 0); if (endptr == argv[i] || *endptr != '\0' || errno == ERANGE || val < 0 || val > 255) { printf("Invalid value byte: %s\n", argv[i]); free(value); return; } value[i-2] = val; } done: cli->reliable_session_id = bt_gatt_client_prepare_write(cli->gatt, id, handle, offset, value, length, write_long_cb, NULL, NULL); if (!cli->reliable_session_id) printf("Failed to proceed prepare write\n"); else printf("Prepare write success.\n" "Session id: %d to be used on next write\n", cli->reliable_session_id); free(value); }