1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "btm_inq_db.h"
17 
18 #include "platform/include/allocator.h"
19 #include "platform/include/list.h"
20 #include "platform/include/mutex.h"
21 
22 #define INQUIRY_DB_MAX 40
23 
24 typedef struct {
25     BtAddr addr;
26     BtmInquiryInfo inquiryInfo;
27 } BtmInquiryDBEntity;
28 
29 static List *g_inquiryDb = NULL;
30 static Mutex *g_inquiryDbLock = NULL;
31 
BtmAllocInquiryDBEntity(const BtAddr * addr,const BtmInquiryInfo * info)32 static BtmInquiryDBEntity *BtmAllocInquiryDBEntity(const BtAddr *addr, const BtmInquiryInfo *info)
33 {
34     BtmInquiryDBEntity *entity = MEM_MALLOC.alloc(sizeof(BtmInquiryDBEntity));
35     if (entity != NULL) {
36         entity->addr = *addr;
37         entity->inquiryInfo = *info;
38     }
39     return entity;
40 }
41 
BtmFreeInquiryDBEntiry(void * entity)42 static void BtmFreeInquiryDBEntiry(void *entity)
43 {
44     MEM_MALLOC.free(entity);
45 }
46 
BtmIsSameAddress(const BtAddr * addr1,const BtAddr * addr2)47 static bool BtmIsSameAddress(const BtAddr *addr1, const BtAddr *addr2)
48 {
49     bool isSame = true;
50 
51     for (uint8_t i = 0; i < BT_ADDRESS_SIZE; i++) {
52         if (addr1->addr[i] != addr2->addr[i]) {
53             isSame = false;
54             break;
55         }
56     }
57 
58     return isSame;
59 }
60 
BtmFindInquiryEntiryByAddress(const BtAddr * addr)61 static BtmInquiryDBEntity *BtmFindInquiryEntiryByAddress(const BtAddr *addr)
62 {
63     BtmInquiryDBEntity *entity = NULL;
64     ListNode *node = ListGetFirstNode(g_inquiryDb);
65     while (node != NULL) {
66         entity = ListGetNodeData(node);
67         if (entity != NULL) {
68             if (BtmIsSameAddress(addr, &entity->addr)) {
69                 break;
70             }
71             entity = NULL;
72         }
73         node = ListGetNextNode(node);
74     }
75     return entity;
76 }
77 
BtmAssignOrUpdateInquiryInfo(const BtAddr * addr,const BtmInquiryInfo * info)78 int BtmAssignOrUpdateInquiryInfo(const BtAddr *addr, const BtmInquiryInfo *info)
79 {
80     int result = BT_SUCCESS;
81 
82     MutexLock(g_inquiryDbLock);
83 
84     BtmInquiryDBEntity *entity = BtmFindInquiryEntiryByAddress(addr);
85     if (entity != NULL) {
86         entity->inquiryInfo = *info;
87     } else {
88         entity = BtmAllocInquiryDBEntity(addr, info);
89         if (entity != NULL) {
90             if (ListGetSize(g_inquiryDb) >= INQUIRY_DB_MAX) {
91                 ListRemoveFirst(g_inquiryDb);
92             }
93 
94             ListAddLast(g_inquiryDb, entity);
95         }
96     }
97 
98     MutexUnlock(g_inquiryDbLock);
99 
100     return result;
101 }
102 
BtmQueryInquiryInfoByAddr(const BtAddr * addr,BtmInquiryInfo * info)103 int BtmQueryInquiryInfoByAddr(const BtAddr *addr, BtmInquiryInfo *info)
104 {
105     if ((addr == NULL) || (info == NULL)) {
106         return BT_BAD_PARAM;
107     }
108 
109     int result = BT_SUCCESS;
110 
111     MutexLock(g_inquiryDbLock);
112 
113     BtmInquiryDBEntity *entity = BtmFindInquiryEntiryByAddress(addr);
114     if (entity != NULL) {
115         *info = entity->inquiryInfo;
116     } else {
117         result = BT_OPERATION_FAILED;
118     }
119 
120     MutexUnlock(g_inquiryDbLock);
121 
122     return result;
123 }
124 
BtmClearInquiryDb()125 void BtmClearInquiryDb()
126 {
127     MutexLock(g_inquiryDbLock);
128 
129     ListClear(g_inquiryDb);
130 
131     MutexUnlock(g_inquiryDbLock);
132 }
133 
BtmInitInquiryDb()134 void BtmInitInquiryDb()
135 {
136     g_inquiryDb = ListCreate(BtmFreeInquiryDBEntiry);
137     g_inquiryDbLock = MutexCreate();
138 }
139 
BtmCloseInquiryDb()140 void BtmCloseInquiryDb()
141 {
142     if (g_inquiryDbLock != NULL) {
143         MutexDelete(g_inquiryDbLock);
144         g_inquiryDbLock = NULL;
145     }
146 
147     if (g_inquiryDb != NULL) {
148         ListDelete(g_inquiryDb);
149         g_inquiryDb = NULL;
150     }
151 }