1 #include <stdlib.h>
2 #include <time.h>
3 #include <unistd.h>
4 
5 #include "base.h"
6 #include "support/gatt.h"
7 #include "support/callbacks.h"
8 
9 #define DEFAULT_RANDOM_SEED 42
10 
create_random_uuid(bt_uuid_t * uuid,int seed)11 static void create_random_uuid(bt_uuid_t *uuid, int seed) {
12   srand(seed < 0 ? time(NULL) : seed);
13   for (int i = 0; i < 16; ++i) {
14     uuid->uu[i] = (uint8_t) (rand() % 256);
15   }
16 }
17 
gatt_client_register()18 bool gatt_client_register() {
19   TASSERT(gatt_interface != NULL, "Null GATT interface.");
20 
21   // Registers gatt client.
22   bt_uuid_t gatt_client_uuid;
23   create_random_uuid(&gatt_client_uuid, DEFAULT_RANDOM_SEED);
24   CALL_AND_WAIT(gatt_interface->client->register_client(&gatt_client_uuid), btgattc_register_app_cb);
25   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT client app callback.");
26 
27   // Unregisters gatt client. No callback is expected.
28   gatt_interface->client->unregister_client(gatt_get_client_interface());
29 
30   return true;
31 }
32 
gatt_client_scan()33 bool gatt_client_scan() {
34   TASSERT(gatt_interface != NULL, "Null GATT interface.");
35 
36   // Starts BLE scan. NB: This test assumes there is a BLE beacon advertising nearby.
37   CALL_AND_WAIT(gatt_interface->client->scan(true), btgattc_scan_result_cb);
38 
39   // Ends BLE scan. No callback is expected.
40   gatt_interface->client->scan(false);
41 
42   return true;
43 }
44 
gatt_client_advertise()45 bool gatt_client_advertise() {
46   TASSERT(gatt_interface != NULL, "Null GATT interface.");
47 
48   // Registers a new client app.
49   bt_uuid_t gatt_client_uuid;
50   create_random_uuid(&gatt_client_uuid, DEFAULT_RANDOM_SEED);
51   CALL_AND_WAIT(gatt_interface->client->register_client(&gatt_client_uuid), btgattc_register_app_cb);
52   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT client app callback.");
53 
54   // Starts advertising.
55   CALL_AND_WAIT(gatt_interface->client->listen(gatt_get_client_interface(), true), btgattc_advertise_cb);
56   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error starting BLE advertisement.");
57 
58   // Stops advertising.
59   CALL_AND_WAIT(gatt_interface->client->listen(gatt_get_client_interface(), false), btgattc_advertise_cb);
60   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error stopping BLE advertisement.");
61 
62   // Unregisters gatt server. No callback is expected.
63   gatt_interface->client->unregister_client(gatt_get_client_interface());
64 
65   return true;
66 }
67 
gatt_server_register()68 bool gatt_server_register() {
69   TASSERT(gatt_interface != NULL, "Null GATT interface.");
70 
71   // Registers gatt server.
72   bt_uuid_t gatt_server_uuid;
73   create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
74   CALL_AND_WAIT(gatt_interface->server->register_server(&gatt_server_uuid), btgatts_register_app_cb);
75   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT server app callback.");
76 
77   // Unregisters gatt server. No callback is expected.
78   gatt_interface->server->unregister_server(gatt_get_server_interface());
79   return true;
80 }
81 
gatt_server_build()82 bool gatt_server_build() {
83   TASSERT(gatt_interface != NULL, "Null GATT interface.");
84 
85   // Registers gatt server.
86   bt_uuid_t gatt_server_uuid;
87   create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
88   CALL_AND_WAIT(gatt_interface->server->register_server(&gatt_server_uuid), btgatts_register_app_cb);
89   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error registering GATT server app callback.");
90 
91   // Service UUID.
92   btgatt_srvc_id_t srvc_id;
93   srvc_id.id.inst_id = 0;   // there is only one instance of this service.
94   srvc_id.is_primary = 1;   // this service is primary.
95   create_random_uuid(&srvc_id.id.uuid, -1);
96 
97   // Characteristics UUID.
98   bt_uuid_t char_uuid;
99   create_random_uuid(&char_uuid, -1);
100 
101   // Descriptor UUID.
102   bt_uuid_t desc_uuid;
103   create_random_uuid(&desc_uuid, -1);
104 
105   // Adds service.
106   int server_if = gatt_get_server_interface();
107   CALL_AND_WAIT(gatt_interface->server->add_service(server_if, &srvc_id, 4 /* # handles */), btgatts_service_added_cb);
108   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding service.");
109 
110   // Adds characteristics.
111   int srvc_handle = gatt_get_service_handle();
112   CALL_AND_WAIT(gatt_interface->server->add_characteristic(server_if, srvc_handle, &char_uuid, 0x10 /* notification */, 0x01 /* read only */), btgatts_characteristic_added_cb);
113   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding characteristics.");
114 
115   // Adds descriptor.
116   CALL_AND_WAIT(gatt_interface->server->add_descriptor(server_if, srvc_handle, &desc_uuid, 0x01), btgatts_descriptor_added_cb);
117   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error adding descriptor.");
118 
119   // Starts server.
120   CALL_AND_WAIT(gatt_interface->server->start_service(server_if, srvc_handle, 2 /*BREDR/LE*/), btgatts_service_started_cb);
121   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error starting server.");
122 
123   // Stops server.
124   CALL_AND_WAIT(gatt_interface->server->stop_service(server_if, srvc_handle), btgatts_service_stopped_cb);
125   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error stopping server.");
126 
127   // Deletes service.
128   CALL_AND_WAIT(gatt_interface->server->delete_service(server_if, srvc_handle), btgatts_service_deleted_cb);
129   TASSERT(gatt_get_status() == BT_STATUS_SUCCESS, "Error deleting service.");
130 
131   // Unregisters gatt server. No callback is expected.
132   gatt_interface->server->unregister_server(server_if);
133 
134   return true;
135 }
136