• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "test/common/mock_functions.h"
30 #include "types/bluetooth/uuid.h"
31 #include "types/raw_address.h"
32 
33 class StackGattTest : public ::testing::Test {};
34 
35 namespace {
36 
37 // Actual size of structure without compiler padding
actual_sizeof_tGATT_REG()38 size_t actual_sizeof_tGATT_REG() {
39   return sizeof(bluetooth::Uuid) + sizeof(tGATT_CBACK) + sizeof(tGATT_IF) +
40          sizeof(bool) + sizeof(uint8_t) + sizeof(bool);
41 }
42 
tGATT_DISC_RES_CB(uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_DISC_RES * p_data)43 void tGATT_DISC_RES_CB(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
44                        tGATT_DISC_RES* p_data) {}
tGATT_DISC_CMPL_CB(uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_STATUS status)45 void tGATT_DISC_CMPL_CB(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
46                         tGATT_STATUS status) {}
tGATT_CMPL_CBACK(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)47 void tGATT_CMPL_CBACK(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
48                       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)49 void tGATT_CONN_CBACK(tGATT_IF gatt_if, const RawAddress& bda, uint16_t conn_id,
50                       bool connected, tGATT_DISCONN_REASON reason,
51                       tBT_TRANSPORT transport) {}
tGATT_REQ_CBACK(uint16_t conn_id,uint32_t trans_id,tGATTS_REQ_TYPE type,tGATTS_DATA * p_data)52 void tGATT_REQ_CBACK(uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type,
53                      tGATTS_DATA* p_data) {}
tGATT_CONGESTION_CBACK(uint16_t conn_id,bool congested)54 void tGATT_CONGESTION_CBACK(uint16_t conn_id, bool congested) {}
tGATT_ENC_CMPL_CB(tGATT_IF gatt_if,const RawAddress & bda)55 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)56 void tGATT_PHY_UPDATE_CB(tGATT_IF gatt_if, uint16_t conn_id, uint8_t tx_phy,
57                          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)58 void tGATT_CONN_UPDATE_CB(tGATT_IF gatt_if, uint16_t conn_id, uint16_t interval,
59                           uint16_t latency, uint16_t timeout,
60                           tGATT_STATUS status) {}
61 
62 tGATT_CBACK gatt_callbacks = {
63     .p_conn_cb = tGATT_CONN_CBACK,
64     .p_cmpl_cb = tGATT_CMPL_CBACK,
65     .p_disc_res_cb = tGATT_DISC_RES_CB,
66     .p_disc_cmpl_cb = tGATT_DISC_CMPL_CB,
67     .p_req_cb = tGATT_REQ_CBACK,
68     .p_enc_cmpl_cb = tGATT_ENC_CMPL_CB,
69     .p_congestion_cb = tGATT_CONGESTION_CBACK,
70     .p_phy_update_cb = tGATT_PHY_UPDATE_CB,
71     .p_conn_update_cb = tGATT_CONN_UPDATE_CB,
72 };
73 
74 }  // namespace
75 
TEST_F(StackGattTest,lifecycle_tGATT_REG)76 TEST_F(StackGattTest, lifecycle_tGATT_REG) {
77   {
78     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
79     std::unique_ptr<tGATT_REG> reg1 = std::make_unique<tGATT_REG>();
80     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
81     memset(reg1.get(), 0xff, sizeof(tGATT_REG));
82     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
83 
84     memset(reg0.get(), 0x0, sizeof(tGATT_REG));
85     memset(reg1.get(), 0x0, sizeof(tGATT_REG));
86     ASSERT_EQ(0, memcmp(reg0.get(), reg1.get(), sizeof(tGATT_REG)));
87   }
88 
89   {
90     std::unique_ptr<tGATT_REG> reg0 = std::make_unique<tGATT_REG>();
91     memset(reg0.get(), 0xff, sizeof(tGATT_REG));
92 
93     tGATT_REG reg1;
94     memset(&reg1, 0xff, sizeof(tGATT_REG));
95 
96     // Clear the structures
97     memset(reg0.get(), 0, sizeof(tGATT_REG));
98     // Restore the complex structure after memset
99     memset(&reg1.name, 0, sizeof(std::string));
100     reg1 = {};
101     ASSERT_EQ(0, memcmp(reg0.get(), &reg1, actual_sizeof_tGATT_REG()));
102   }
103 
104   {
105     tGATT_REG* reg0 = new tGATT_REG();
106     tGATT_REG* reg1 = new tGATT_REG();
107     memset(reg0, 0, sizeof(tGATT_REG));
108     *reg1 = {};
109     reg0->in_use = true;
110     ASSERT_NE(0, memcmp(reg0, reg1, sizeof(tGATT_REG)));
111     delete reg1;
112     delete reg0;
113   }
114 }
115 
TEST_F(StackGattTest,gatt_init_free)116 TEST_F(StackGattTest, gatt_init_free) {
117   gatt_init();
118   gatt_free();
119 }
120 
TEST_F(StackGattTest,GATT_Register_Deregister)121 TEST_F(StackGattTest, GATT_Register_Deregister) {
122   gatt_init();
123 
124   // Gatt db profile always takes the first slot
125   tGATT_IF apps[GATT_MAX_APPS - 1];
126 
127   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
128     std::string name = bluetooth::common::StringFormat("name%02d", i);
129     apps[i] = GATT_Register(bluetooth::Uuid::GetRandom(), name, &gatt_callbacks,
130                             false);
131   }
132 
133   for (int i = 0; i < GATT_MAX_APPS - 1; i++) {
134     GATT_Deregister(apps[i]);
135   }
136 
137   gatt_free();
138 }
139 
TEST_F(StackGattTest,gatt_status_text)140 TEST_F(StackGattTest, gatt_status_text) {
141   std::vector<std::pair<tGATT_STATUS, std::string>> statuses = {
142       std::make_pair(GATT_SUCCESS, "GATT_SUCCESS"),  // Also GATT_ENCRYPED_MITM
143       std::make_pair(GATT_INVALID_HANDLE, "GATT_INVALID_HANDLE"),
144       std::make_pair(GATT_READ_NOT_PERMIT, "GATT_READ_NOT_PERMIT"),
145       std::make_pair(GATT_WRITE_NOT_PERMIT, "GATT_WRITE_NOT_PERMIT"),
146       std::make_pair(GATT_INVALID_PDU, "GATT_INVALID_PDU"),
147       std::make_pair(GATT_INSUF_AUTHENTICATION, "GATT_INSUF_AUTHENTICATION"),
148       std::make_pair(GATT_REQ_NOT_SUPPORTED, "GATT_REQ_NOT_SUPPORTED"),
149       std::make_pair(GATT_INVALID_OFFSET, "GATT_INVALID_OFFSET"),
150       std::make_pair(GATT_INSUF_AUTHORIZATION, "GATT_INSUF_AUTHORIZATION"),
151       std::make_pair(GATT_PREPARE_Q_FULL, "GATT_PREPARE_Q_FULL"),
152       std::make_pair(GATT_NOT_FOUND, "GATT_NOT_FOUND"),
153       std::make_pair(GATT_NOT_LONG, "GATT_NOT_LONG"),
154       std::make_pair(GATT_INSUF_KEY_SIZE, "GATT_INSUF_KEY_SIZE"),
155       std::make_pair(GATT_INVALID_ATTR_LEN, "GATT_INVALID_ATTR_LEN"),
156       std::make_pair(GATT_ERR_UNLIKELY, "GATT_ERR_UNLIKELY"),
157       std::make_pair(GATT_INSUF_ENCRYPTION, "GATT_INSUF_ENCRYPTION"),
158       std::make_pair(GATT_UNSUPPORT_GRP_TYPE, "GATT_UNSUPPORT_GRP_TYPE"),
159       std::make_pair(GATT_INSUF_RESOURCE, "GATT_INSUF_RESOURCE"),
160       std::make_pair(GATT_DATABASE_OUT_OF_SYNC, "GATT_DATABASE_OUT_OF_SYNC"),
161       std::make_pair(GATT_VALUE_NOT_ALLOWED, "GATT_VALUE_NOT_ALLOWED"),
162       std::make_pair(GATT_ILLEGAL_PARAMETER, "GATT_ILLEGAL_PARAMETER"),
163       std::make_pair(GATT_TOO_SHORT, "GATT_TOO_SHORT"),
164       std::make_pair(GATT_NO_RESOURCES, "GATT_NO_RESOURCES"),
165       std::make_pair(GATT_INTERNAL_ERROR, "GATT_INTERNAL_ERROR"),
166       std::make_pair(GATT_WRONG_STATE, "GATT_WRONG_STATE"),
167       std::make_pair(GATT_DB_FULL, "GATT_DB_FULL"),
168       std::make_pair(GATT_BUSY, "GATT_BUSY"),
169       std::make_pair(GATT_ERROR, "GATT_ERROR"),
170       std::make_pair(GATT_CMD_STARTED, "GATT_CMD_STARTED"),
171       std::make_pair(GATT_PENDING, "GATT_PENDING"),
172       std::make_pair(GATT_AUTH_FAIL, "GATT_AUTH_FAIL"),
173       std::make_pair(GATT_MORE, "GATT_MORE"),
174       std::make_pair(GATT_INVALID_CFG, "GATT_INVALID_CFG"),
175       std::make_pair(GATT_SERVICE_STARTED, "GATT_SERVICE_STARTED"),
176       std::make_pair(GATT_ENCRYPED_NO_MITM, "GATT_ENCRYPED_NO_MITM"),
177       std::make_pair(GATT_NOT_ENCRYPTED, "GATT_NOT_ENCRYPTED"),
178       std::make_pair(GATT_CONGESTED, "GATT_CONGESTED"),
179       std::make_pair(GATT_DUP_REG, "GATT_DUP_REG"),
180       std::make_pair(GATT_ALREADY_OPEN, "GATT_ALREADY_OPEN"),
181       std::make_pair(GATT_CANCEL, "GATT_CANCEL"),
182       std::make_pair(GATT_CCC_CFG_ERR, "GATT_CCC_CFG_ERR"),
183       std::make_pair(GATT_PRC_IN_PROGRESS, "GATT_PRC_IN_PROGRESS"),
184       std::make_pair(GATT_OUT_OF_RANGE, "GATT_OUT_OF_RANGE"),
185   };
186   for (const auto& status : statuses) {
187     ASSERT_STREQ(status.second.c_str(), gatt_status_text(status.first).c_str());
188   }
189   // Typical max value is already classified so use arbitrary unused one.
190   auto unknown = base::StringPrintf("UNKNOWN[%hhu]", 0xfc);
191   ASSERT_STREQ(unknown.c_str(),
192                gatt_status_text(static_cast<tGATT_STATUS>(0xfc)).c_str());
193 }
194