2 * Libble main test suite
14 #define DEFAULT_MAC_ADDR NULL
15 #define DEFAULT_READ_HANDLE 8
16 #define DEFAULT_WRITE_HANDLE 9
17 #define DEFAULT_WRITE_VALUE 0x0003
20 # define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
23 static char *progname
;
24 static int verbose
= 1;
25 static int raw_bytes
= 0;
27 static void scan_cb(void *cb_data
, const char *addr
, const char *name
)
32 ble_log_append(1, "found: type %s, addr %s, name %s\n", text
, addr
, name
);
35 static int do_scan(struct ble_desc
*desc
, int duration
)
39 ble_log_append(1, "scan: classic\n");
40 rc
= ble_config_cb_scan(desc
, scan_cb
, "BT");
43 rc
= ble_scan_bt(desc
, duration
);
47 ble_log_append(1, "scan: low energy\n");
48 rc
= ble_config_cb_scan(desc
, scan_cb
, "LE");
51 rc
= ble_scan_le(desc
, duration
);
58 static int do_rfcomm(struct ble_desc
*desc
, int read_delay
)
60 static const char *texts
[] = {
61 "Hi server, I am the client.",
62 "This is the first line of text.",
63 "Here is another line of text.",
64 "Bye server, nice talking to you.",
72 rc
= ble_connect_rfcomm(desc
);
75 for (idx
= 0; text
= texts
[idx
]; idx
++) {
76 rc
= ble_write(desc
, text
, strlen(text
));
78 ble_log_append(0, "sent: %s\n", text
);
80 rc
= ble_read(desc
, buff
, sizeof(buff
));
83 ble_log_append(0, "rcvd: %s\n", buff
);
87 usleep(read_delay
* 1000);
89 rc
= ble_read(desc
, buff
, sizeof(buff
));
92 ble_log_append(0, "rcvd: %s\n", buff
);
101 /* No processing, mere dump of received payload bytes. */
102 int process(void *cb_data
, uint8_t *data
, size_t len
)
108 fwrite(data
, sizeof(uint8_t), len
, stdout
);
113 ble_log_append(1, "BLE payload data: %zu bytes", len
);
115 ble_log_append(1, ":");
117 ble_log_append(1, " %02x", *data
++);
118 ble_log_append(1, "\n");
124 static int do_ble_indnot(struct ble_desc
*desc
, int read_delay
)
128 rc
= ble_connect_ble(desc
);
130 ble_log_append(0, "Failed to connect, rc %d\n", rc
);
133 ble_log_append(3, "Connected.\n");
135 rc
= ble_config_cb_data(desc
, process
, NULL
);
139 /* Initiate reception of data, and have the received data processed. */
140 rc
= ble_start_notify(desc
);
142 ble_log_append(0, "Failed to setup notifications, rc %d\n", rc
);
145 ble_log_append(3, "Receiving notifications.\n");
147 rc
= ble_check_notify(desc
);
149 ble_log_append(0, "Failed to check notifications, rc %d\n", rc
);
151 ble_log_append(5, "usleep() start\n");
152 usleep(read_delay
* 1000);
153 ble_log_append(5, "usleep() done\n");
156 ble_log_append(3, "Done receiving.\n");
158 ble_log_append(3, "Disconnecting.\n");
159 ble_disconnect(desc
);
163 static void synopsis(FILE *f
)
166 fprintf(f
, "synopsis: %s [-h] [-vq] [-i <addr>] [-I <nr>] [-s <len>] [-m <addr>] [-R <nr>] [-r <hdl>] [-w <hdl>] [-W <val>] [-b] [-d <msec>]\n", progname
);
167 fprintf(f
, "options:\n");
168 fprintf(f
, "\t-h\tprint builtin help (this text)\n");
169 fprintf(f
, "\t-v, -q\tadjust verbosity\n");
170 fprintf(f
, "\t-i, -I\tspecify local adapter to use\n");
171 fprintf(f
, "\t-s\tscan for the specified length (number times 1.28s)\n");
172 fprintf(f
, "\t-m\tspecify (remote) device address\n");
173 fprintf(f
, "\t-R\tconnect to this channel of an RFCOMM server\n");
174 fprintf(f
, "\t-r, -w\tspecify read/write handle\n");
175 fprintf(f
, "\t-W\tspecify write value\n");
176 fprintf(f
, "\t-b\tdump raw bytes to output (text by default)\n");
177 fprintf(f
, "\t-d\tdelay between reads for this many msecs\n");
180 int main(int argc
, char **argv
)
184 const char *local_mac
;
185 const char *remote_mac
;
186 size_t rfcomm_channel
;
187 uint16_t read_handle
;
188 uint16_t write_handle
, write_value
;
190 struct ble_desc
*desc
;
193 /* Preset defaults. */
194 progname
= basename(argv
[0]);
195 ble_log_setup(verbose
);
199 remote_mac
= DEFAULT_MAC_ADDR
;
201 read_handle
= DEFAULT_READ_HANDLE
;
202 write_handle
= DEFAULT_WRITE_HANDLE
;
203 write_value
= DEFAULT_WRITE_VALUE
;
205 /* Scan command line arguments. */
206 while ((c
= getopt(argc
, argv
, "bd:hi:I:m:qr:R:s:vw:W:")) != EOF
) {
212 read_delay
= strtol(optarg
, NULL
, 0);
219 free((void *)local_mac
);
220 local_mac
= strdup(optarg
);
224 free((void *)local_mac
);
225 num
= strtol(optarg
, NULL
, 0);
226 local_mac
= ble_adapter_get_address(num
);
228 ble_log_append(0, "cannot get address for HCI dev %d\n", num
);
239 read_handle
= strtol(optarg
, NULL
, 0);
242 rfcomm_channel
= strtol(optarg
, NULL
, 0);
245 scan_time
= strtol(optarg
, NULL
, 0);
251 write_handle
= strtol(optarg
, NULL
, 0);
254 write_value
= strtol(optarg
, NULL
, 0);
263 ble_log_setup(verbose
);
265 desc
= ble_desc_new();
267 ble_log_append(0, "Failed to create BLE descriptor.\n");
271 ble_log_append(2, "local addr '%s'\n", local_mac
);
272 rc
= ble_config_addr_local(desc
, local_mac
);
277 ble_log_append(2, "device addr '%s'\n", remote_mac
);
278 rc
= ble_config_addr_remote(desc
, remote_mac
);
282 ble_log_append(3, "Preparing.\n");
285 ble_log_append(2, "scanning for devices\n");
286 rc
= do_scan(desc
, scan_time
);
287 } else if (rfcomm_channel
) {
288 ble_log_append(2, "RFCOMM client, channel %d\n", rfcomm_channel
);
289 rc
= ble_config_rfcomm(desc
, rfcomm_channel
);
292 rc
= do_rfcomm(desc
, read_delay
);
294 ble_log_append(2, "indications/notifications\n");
295 ble_log_append(2, "read/write hdl %u/%u, write val %u\n", read_handle
, write_handle
, write_value
);
296 rc
= ble_config_notify(desc
, read_handle
, write_handle
, write_value
);
299 rc
= do_ble_indnot(desc
, read_delay
);