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 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 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 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 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 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 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