1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 #include <string.h>
19 
20 #include <cstdint>
21 #include <map>
22 #include <memory>
23 #include <string>
24 
25 #include "common/message_loop_thread.h"
26 #include "common/strings.h"
27 #include "stack/gatt/gatt_int.h"
28 #include "stack/include/gatt_api.h"
29 
30 std::map<std::string, int> mock_function_count_map;
31 
LogMsg(uint32_t trace_set_mask,const char * fmt_str,...)32 void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
33 
get_main_thread()34 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
35 
36 class StackGattTest : public ::testing::Test {};
37 
38 namespace {
39 
40 // Actual size of structure without compiler padding
actual_sizeof_tGATT_REG()41 size_t actual_sizeof_tGATT_REG() {
42   return sizeof(bluetooth::Uuid) + sizeof(tGATT_CBACK) + sizeof(tGATT_IF) +
43          sizeof(bool) + sizeof(uint8_t) + sizeof(bool);
44 }
45 
tGATT_DISC_RES_CB(uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_DISC_RES * p_data)46 void tGATT_DISC_RES_CB(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
47                        tGATT_DISC_RES* p_data) {}
tGATT_DISC_CMPL_CB(uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_STATUS status)48 void tGATT_DISC_CMPL_CB(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
49                         tGATT_STATUS status) {}
tGATT_CMPL_CBACK(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)50 void tGATT_CMPL_CBACK(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
51                       tGATT_CL_COMPLETE* p_data) {}
tGATT_CONN_CBACK(tGATT_IF gatt_if,const RawAddress & bda,uint16_t conn_id,bool connected,tGATT_DISCONN_REASON reason,tBT_TRANSPORT transport)52 void tGATT_CONN_CBACK(tGATT_IF gatt_if, const RawAddress& bda, uint16_t conn_id,
53                       bool connected, tGATT_DISCONN_REASON reason,
54                       tBT_TRANSPORT transport) {}
tGATT_REQ_CBACK(uint16_t conn_id,uint32_t trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)55 void tGATT_REQ_CBACK(uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type,
56                      tGATTS_DATA* p_data) {}
tGATT_CONGESTION_CBACK(uint16_t conn_id,bool congested)57 void tGATT_CONGESTION_CBACK(uint16_t conn_id, bool congested) {}
tGATT_ENC_CMPL_CB(tGATT_IF gatt_if,const RawAddress & bda)58 void tGATT_ENC_CMPL_CB(tGATT_IF gatt_if, const RawAddress& bda) {}
tGATT_PHY_UPDATE_CB(tGATT_IF gatt_if,uint16_t conn_id,uint8_t tx_phy,uint8_t rx_phy,tGATT_STATUS status)59 void tGATT_PHY_UPDATE_CB(tGATT_IF gatt_if, uint16_t conn_id, uint8_t tx_phy,
60                          uint8_t rx_phy, tGATT_STATUS status) {}
tGATT_CONN_UPDATE_CB(tGATT_IF gatt_if,uint16_t conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,tGATT_STATUS status)61 void tGATT_CONN_UPDATE_CB(tGATT_IF gatt_if, uint16_t conn_id, uint16_t interval,
62                           uint16_t latency, uint16_t timeout,
63                           tGATT_STATUS status) {}
64 
65 tGATT_CBACK gatt_callbacks = {
66     .p_conn_cb = tGATT_CONN_CBACK,
67     .p_cmpl_cb = tGATT_CMPL_CBACK,
68     .p_disc_res_cb = tGATT_DISC_RES_CB,
69     .p_disc_cmpl_cb = tGATT_DISC_CMPL_CB,
70     .p_req_cb = tGATT_REQ_CBACK,
71     .p_enc_cmpl_cb = tGATT_ENC_CMPL_CB,
72     .p_congestion_cb = tGATT_CONGESTION_CBACK,
73     .p_phy_update_cb = tGATT_PHY_UPDATE_CB,
74     .p_conn_update_cb = tGATT_CONN_UPDATE_CB,
75 };
76 
77 }  // namespace
78 
TEST_F(StackGattTest,lifecycle_tGATT_REG)79 TEST_F(StackGattTest, lifecycle_tGATT_REG) {
80   {
81     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
82     std::unique_ptr<tGATT_REG> reg1 = std::make_unique<tGATT_REG>();
83     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
84     memset(reg1.get(), 0xff, sizeof(tGATT_REG));
85     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
86 
87     memset(reg0.get(), 0x0, sizeof(tGATT_REG));
88     memset(reg1.get(), 0x0, sizeof(tGATT_REG));
89     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
90   }
91 
92   {
93     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
94     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
95 
96     tGATT_REG reg1;
97     memset(&reg1, 0xff, sizeof(tGATT_REG));
98 
99     // Clear the structures
100     memset(reg0.get(), 0, sizeof(tGATT_REG));
101     // Restore the complex structure after memset
102     memset(&reg1.name, 0, sizeof(std::string));
103     reg1 = {};
104     ASSERT_EQ(0, memcmp(reg0.get(), &reg1, actual_sizeof_tGATT_REG()));
105   }
106 
107   {
108     tGATT_REG* reg0 = new tGATT_REG();
109     tGATT_REG* reg1 = new tGATT_REG();
110     memset(reg0, 0, sizeof(tGATT_REG));
111     *reg1 = {};
112     reg0->in_use = true;
113     ASSERT_NE(0, memcmp(reg0, reg1, sizeof(tGATT_REG)));
114     delete reg1;
115     delete reg0;
116   }
117 }
118 
TEST_F(StackGattTest,gatt_init_free)119 TEST_F(StackGattTest, gatt_init_free) {
120   gatt_init();
121   gatt_free();
122 }
123 
TEST_F(StackGattTest,GATT_Register_Deregister)124 TEST_F(StackGattTest, GATT_Register_Deregister) {
125   gatt_init();
126 
127   // Gatt db profile always takes the first slot
128   tGATT_IF apps[GATT_MAX_APPS - 1];
129 
130   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
131     std::string name = bluetooth::common::StringFormat("name%02d", i);
132     apps[i] = GATT_Register(bluetooth::Uuid::GetRandom(), name, &gatt_callbacks,
133                             false);
134   }
135 
136   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
137     GATT_Deregister(apps[i]);
138   }
139 
140   gatt_free();
141 }
142