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_scan_bt(desc
, duration
, scan_cb
, "BT");
44 ble_log_append(1, "scan: low energy\n");
45 rc
= ble_scan_le(desc
, duration
, scan_cb
, "LE");
52 static int do_rfcomm(struct ble_desc
*desc
, size_t channel
, int read_delay
)
54 static const char *texts
[] = {
55 "Hi server, I am the client.",
56 "This is the first line of text.",
57 "Here is another line of text.",
58 "Bye server, nice talking to you.",
66 rc
= ble_connect_rfcomm(desc
, channel
);
69 for (idx
= 0; text
= texts
[idx
]; idx
++) {
70 rc
= ble_write(desc
, text
, strlen(text
));
72 ble_log_append(0, "sent: %s\n", text
);
74 rc
= ble_read(desc
, buff
, sizeof(buff
));
77 ble_log_append(0, "rcvd: %s\n", buff
);
81 usleep(read_delay
* 1000);
83 rc
= ble_read(desc
, buff
, sizeof(buff
));
86 ble_log_append(0, "rcvd: %s\n", buff
);
95 /* No processing, mere dump of received payload bytes. */
96 int process(void *cb_data
, uint8_t *data
, size_t len
)
102 fwrite(data
, sizeof(uint8_t), len
, stdout
);
107 ble_log_append(1, "BLE payload data: %zu bytes", len
);
109 ble_log_append(1, ":");
111 ble_log_append(1, " %02x", *data
++);
112 ble_log_append(1, "\n");
118 static int do_ble_indnot(struct ble_desc
*desc
, uint16_t read_handle
,
119 uint16_t write_handle
, uint16_t write_value
, int read_delay
)
123 rc
= ble_connect_ble(desc
);
125 ble_log_append(0, "Failed to connect, rc %d\n", rc
);
128 ble_log_append(3, "Connected.\n");
130 /* Initiate reception of data, and have the received data processed. */
131 rc
= ble_start_notify(desc
, read_handle
, write_handle
, write_value
);
133 ble_log_append(0, "Failed to setup notifications, rc %d\n", rc
);
136 ble_log_append(3, "Receiving notifications.\n");
138 rc
= ble_check_notify(desc
, process
, NULL
);
140 ble_log_append(0, "Failed to check notifications, rc %d\n", rc
);
142 usleep(read_delay
* 1000);
144 ble_log_append(3, "Done receiving.\n");
146 ble_log_append(3, "Disconnecting.\n");
147 ble_disconnect(desc
);
151 static void synopsis(FILE *f
)
154 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
);
155 fprintf(f
, "options:\n");
156 fprintf(f
, "\t-h\tprint builtin help (this text)\n");
157 fprintf(f
, "\t-v, -q\tadjust verbosity\n");
158 fprintf(f
, "\t-i, -I\tspecify local adapter to use\n");
159 fprintf(f
, "\t-s\tscan for the specified length (number times 1.28s)\n");
160 fprintf(f
, "\t-m\tspecify (remote) device address\n");
161 fprintf(f
, "\t-R\tconnect to this channel of an RFCOMM server\n");
162 fprintf(f
, "\t-r, -w\tspecify read/write handle\n");
163 fprintf(f
, "\t-W\tspecify write value\n");
164 fprintf(f
, "\t-b\tdump raw bytes to output (text by default)\n");
165 fprintf(f
, "\t-d\tdelay between reads for this many msecs\n");
168 int main(int argc
, char **argv
)
172 const char *local_mac
;
173 const char *remote_mac
;
174 size_t rfcomm_channel
;
175 uint16_t read_handle
;
176 uint16_t write_handle
, write_value
;
178 struct ble_desc
*desc
;
181 /* Preset defaults. */
182 progname
= basename(argv
[0]);
183 ble_log_setup(verbose
);
186 remote_mac
= DEFAULT_MAC_ADDR
;
188 read_handle
= DEFAULT_READ_HANDLE
;
189 write_handle
= DEFAULT_WRITE_HANDLE
;
190 write_value
= DEFAULT_WRITE_VALUE
;
192 /* Scan command line arguments. */
193 while ((c
= getopt(argc
, argv
, "bd:hi:I:m:qr:R:s:vw:W:")) != EOF
) {
199 read_delay
= strtol(optarg
, NULL
, 0);
206 free((void *)local_mac
);
207 local_mac
= strdup(optarg
);
211 free((void *)local_mac
);
212 num
= strtol(optarg
, NULL
, 0);
213 local_mac
= ble_adapter_get_address(num
);
215 ble_log_append(0, "cannot get address for HCI dev %d\n", num
);
226 read_handle
= strtol(optarg
, NULL
, 0);
229 rfcomm_channel
= strtol(optarg
, NULL
, 0);
232 scan_time
= strtol(optarg
, NULL
, 0);
238 write_handle
= strtol(optarg
, NULL
, 0);
241 write_value
= strtol(optarg
, NULL
, 0);
250 ble_log_setup(verbose
);
253 ble_log_append(2, "local addr '%s'\n", local_mac
);
255 ble_log_append(2, "device addr '%s'\n", remote_mac
);
256 ble_log_append(3, "Preparing.\n");
257 desc
= ble_desc_new(local_mac
, remote_mac
);
259 ble_log_append(0, "Failed to create BLE descriptor.\n");
264 ble_log_append(2, "scanning for devices\n");
265 rc
= do_scan(desc
, scan_time
);
266 } else if (rfcomm_channel
) {
267 ble_log_append(2, "RFCOMM client, channel %d\n", rfcomm_channel
);
268 rc
= do_rfcomm(desc
, rfcomm_channel
, read_delay
);
270 ble_log_append(2, "indications/notifications\n");
271 ble_log_append(2, "read/write handles %u/%u\n", read_handle
, write_handle
);
272 ble_log_append(2, "write value %u\n", write_value
);
273 rc
= do_ble_indnot(desc
, read_handle
, write_handle
, write_value
, read_delay
);