diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index 58a03bd..3bcb7e1 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
struct bt_gatt_client *gatt;
unsigned int reliable_session_id;
+ bool sec_retry;
};
static void print_prompt(void)
fprintf(stderr, "Failed to allocate memory for client\n");
return NULL;
}
+ cli->sec_retry = true;
cli->att = bt_att_new(fd, false);
if (!cli->att) {
char *argv[512];
int i;
char *endptr = NULL;
+ unsigned int id;
if (!bt_gatt_client_is_ready(cli->gatt)) {
printf("GATT client not initialized\n");
}
}
- if (!bt_gatt_client_read_multiple(cli->gatt, value, argc,
- read_multiple_cb, NULL, NULL))
+ id = bt_gatt_client_read_multiple(cli->gatt, value, argc,
+ read_multiple_cb, NULL, NULL);
+ if (!id)
printf("Failed to initiate read multiple procedure\n");
+ else if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt, id, false);
free(value);
}
int argc = 0;
uint16_t handle;
char *endptr = NULL;
+ unsigned int id;
if (!bt_gatt_client_is_ready(cli->gatt)) {
printf("GATT client not initialized\n");
return;
}
- if (!bt_gatt_client_read_value(cli->gatt, handle, read_cb,
- NULL, NULL))
+ id = bt_gatt_client_read_value(cli->gatt, handle, read_cb,
+ NULL, NULL);
+ if (!id)
printf("Failed to initiate read value procedure\n");
+ else if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt, id, false);
}
static void read_long_value_usage(void)
uint16_t handle;
uint16_t offset;
char *endptr = NULL;
+ unsigned int id;
if (!bt_gatt_client_is_ready(cli->gatt)) {
printf("GATT client not initialized\n");
return;
}
- if (!bt_gatt_client_read_long_value(cli->gatt, handle, offset, read_cb,
- NULL, NULL))
+ id = bt_gatt_client_read_long_value(cli->gatt, handle, offset, read_cb,
+ NULL, NULL);
+ if (!id)
printf("Failed to initiate read long value procedure\n");
+ else if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt, id, false);
}
static void write_value_usage(void)
uint8_t *value = NULL;
bool without_response = false;
bool signed_write = false;
+ unsigned int id;
if (!bt_gatt_client_is_ready(cli->gatt)) {
printf("GATT client not initialized\n");
goto done;
}
- if (!bt_gatt_client_write_value(cli->gatt, handle, value, length,
+ id = bt_gatt_client_write_value(cli->gatt, handle, value, length,
write_cb,
- NULL, NULL))
+ NULL, NULL);
+ if (!id)
printf("Failed to initiate write procedure\n");
+ else if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt, id, false);
done:
free(value);
int length;
uint8_t *value = NULL;
bool reliable_writes = false;
+ unsigned int id;
if (!bt_gatt_client_is_ready(cli->gatt)) {
printf("GATT client not initialized\n");
}
}
- if (!bt_gatt_client_write_long_value(cli->gatt, reliable_writes, handle,
+ id = bt_gatt_client_write_long_value(cli->gatt, reliable_writes, handle,
offset, value, length,
write_long_cb,
- NULL, NULL))
+ NULL, NULL);
+ if (!id)
printf("Failed to initiate long write procedure\n");
+ else if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt, id, false);
free(value);
}
value, length,
write_long_cb, NULL,
NULL);
- if (!cli->reliable_session_id)
+ if (!cli->reliable_session_id) {
printf("Failed to proceed prepare write\n");
- else
+ } else {
+ if (!cli->sec_retry)
+ bt_gatt_client_set_retry(cli->gatt,
+ cli->reliable_session_id,
+ false);
+
printf("Prepare write success.\n"
"Session id: %d to be used on next write\n",
cli->reliable_session_id);
+ }
free(value);
}
printf("Security level: %u\n", level);
}
+static void set_security_retry_usage(void)
+{
+ printf("Usage: set-security-retry <y/n>\n"
+ "e.g.:\n"
+ "\tset-security-retry n\n");
+}
+
+static void cmd_set_security_retry(struct client *cli, char *cmd_str)
+{
+ char *argv[2];
+ int argc = 0;
+
+ if (!bt_gatt_client_is_ready(cli->gatt)) {
+ printf("GATT client not initialized\n");
+ return;
+ }
+
+ if (!parse_args(cmd_str, 1, argv, &argc) || argc != 1) {
+ set_security_retry_usage();
+ return;
+ }
+
+ if (argv[0][0] == 'y')
+ cli->sec_retry = true;
+ else if (argv[0][0] == 'n')
+ cli->sec_retry = false;
+ else
+ printf("Invalid argument: %s\n", argv[0]);
+}
+
static bool convert_sign_key(char *optarg, uint8_t key[16])
{
int i;
"\tSet security level on le connection"},
{ "get-security", cmd_get_security,
"\tGet security level on le connection"},
+ { "set-security-retry", cmd_set_security_retry,
+ "\tSet retry on security error by elevating security"},
{ "set-sign-key", cmd_set_sign_key,
"\tSet signing key for signed write command"},
{ }