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 "l2cap_inst.h"
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include "log.h"
23 
24 #include "l2cap_cmn.h"
25 
26 static L2capInstance g_l2capInst;
27 
L2capGetInstance()28 L2capInstance *L2capGetInstance()
29 {
30     return &g_l2capInst;
31 }
32 
L2capInitialized()33 int L2capInitialized()
34 {
35     L2capInstance *inst = L2capGetInstance();
36 
37     if (inst->connList != NULL) {
38         return BT_SUCCESS;
39     }
40 
41     return BT_BAD_STATUS;
42 }
43 
L2capGetPsm(uint16_t lpsm)44 L2capPsm *L2capGetPsm(uint16_t lpsm)
45 {
46     L2capInstance *inst = L2capGetInstance();
47     L2capPsm *psm = NULL;
48     ListNode *node = NULL;
49 
50     node = ListGetFirstNode(inst->psmList);
51     while (node != NULL) {
52         psm = ListGetNodeData(node);
53         if (psm->lpsm == lpsm) {
54             return psm;
55         }
56 
57         node = ListGetNextNode(node);
58     }
59 
60     return NULL;
61 }
62 
L2capGetConnection(uint16_t aclHandle)63 L2capConnection *L2capGetConnection(uint16_t aclHandle)
64 {
65     L2capInstance *inst = L2capGetInstance();
66     L2capConnection *conn = NULL;
67     ListNode *node = NULL;
68 
69     node = ListGetFirstNode(inst->connList);
70     while (node != NULL) {
71         conn = ListGetNodeData(node);
72         if (conn->aclHandle == aclHandle) {
73             return conn;
74         }
75 
76         node = ListGetNextNode(node);
77     }
78 
79     return NULL;
80 }
81 
L2capGetConnection2(const BtAddr * addr)82 L2capConnection *L2capGetConnection2(const BtAddr *addr)
83 {
84     L2capInstance *inst = L2capGetInstance();
85     L2capConnection *conn = NULL;
86     ListNode *node = NULL;
87 
88     node = ListGetFirstNode(inst->connList);
89     while (node != NULL) {
90         conn = ListGetNodeData(node);
91         if (memcmp(conn->addr.addr, addr->addr, sizeof(addr->addr)) == 0) {
92             return conn;
93         }
94 
95         node = ListGetNextNode(node);
96     }
97 
98     return NULL;
99 }
100 
L2capGetConnection3(const L2capChannel * chan)101 L2capConnection *L2capGetConnection3(const L2capChannel *chan)
102 {
103     L2capInstance *inst = L2capGetInstance();
104     L2capConnection *conn = NULL;
105     ListNode *node = NULL;
106     ListNode *nodeChan = NULL;
107 
108     node = ListGetFirstNode(inst->connList);
109     while (node != NULL) {
110         conn = ListGetNodeData(node);
111 
112         nodeChan = ListGetFirstNode(conn->chanList);
113         while (nodeChan != NULL) {
114             if (ListGetNodeData(nodeChan) == chan) {
115                 return conn;
116             }
117 
118             nodeChan = ListGetNextNode(nodeChan);
119         }
120 
121         node = ListGetNextNode(node);
122     }
123 
124     return conn;
125 }
126 
L2capGetChannel(const L2capConnection * conn,int16_t lcid)127 L2capChannel *L2capGetChannel(const L2capConnection *conn, int16_t lcid)
128 {
129     L2capChannel *chan = NULL;
130     ListNode *node = NULL;
131 
132     node = ListGetFirstNode(conn->chanList);
133     while (node != NULL) {
134         chan = ListGetNodeData(node);
135         if (chan->lcid == lcid) {
136             return chan;
137         }
138 
139         node = ListGetNextNode(node);
140     }
141 
142     return NULL;
143 }
144 
L2capGetChannel2(uint16_t lcid,L2capConnection ** conn,L2capChannel ** chan)145 void L2capGetChannel2(uint16_t lcid, L2capConnection **conn, L2capChannel **chan)
146 {
147     L2capInstance *inst = L2capGetInstance();
148     ListNode *node = NULL;
149 
150     node = ListGetFirstNode(inst->connList);
151     while (node != NULL) {
152         *conn = ListGetNodeData(node);
153         *chan = L2capGetChannel(*conn, lcid);
154         if ((*chan) != NULL) {
155             break;
156         }
157 
158         node = ListGetNextNode(node);
159     }
160 
161     return;
162 }
163 
L2capGetChannel3(uint16_t aclHandle,uint16_t lcid,L2capConnection ** conn,L2capChannel ** chan)164 void L2capGetChannel3(uint16_t aclHandle, uint16_t lcid, L2capConnection **conn, L2capChannel **chan)
165 {
166     *conn = L2capGetConnection(aclHandle);
167     if ((*conn) == NULL) {
168         return;
169     }
170 
171     *chan = L2capGetChannel(*conn, lcid);
172     return;
173 }
174 
L2capGetNewLcid()175 static uint16_t L2capGetNewLcid()
176 {
177     L2capInstance *inst = L2capGetInstance();
178     uint16_t lcid = L2CAP_MIN_CID;
179 
180     if (inst->nextLcid == 0) {
181         L2capConnection *conn = NULL;
182         L2capChannel *chan = NULL;
183 
184         while (1) {
185             L2capGetChannel2(lcid, &conn, &chan);
186             if (chan == NULL) {
187                 break;
188             }
189 
190             lcid += 1;
191         }
192     } else {
193         lcid = inst->nextLcid;
194 
195         if (lcid == L2CAP_MAX_CID) {
196             inst->nextLcid = 0;
197         } else {
198             inst->nextLcid += 1;
199         }
200     }
201 
202     return lcid;
203 }
204 
L2capSetDefaultConfigOptions(L2capConfigInfo * cfg)205 static void L2capSetDefaultConfigOptions(L2capConfigInfo *cfg)
206 {
207     cfg->mtu = L2CAP_DEFAULT_MTU;
208     cfg->flushTimeout = L2CAP_NONE_FLUSH_PACKET;
209     cfg->rfc.mode = L2CAP_BASIC_MODE;
210     cfg->rfc.maxTransmit = L2CAP_DEFAULT_MAX_TRANSMIT;
211     cfg->rfc.txWindowSize = L2CAP_DEFAULT_TX_WINDOW;
212     cfg->rfc.rxWindowSize = L2CAP_DEFAULT_TX_WINDOW;
213     cfg->rfc.retransmissionTimeout = 0;
214     cfg->rfc.monitorTimeout = 0;
215     cfg->rfc.mps = L2capGetRxBufferSize() - L2CAP_SIZE_10;
216     cfg->fcs = 0x01;
217 
218     return;
219 }
220 
L2capNewChannel(L2capConnection * conn,uint16_t lpsm,uint16_t rpsm)221 L2capChannel *L2capNewChannel(L2capConnection *conn, uint16_t lpsm, uint16_t rpsm)
222 {
223     L2capChannel *chan = NULL;
224 
225     chan = L2capAlloc(sizeof(L2capChannel));
226     if (chan == NULL) {
227         return NULL;
228     }
229 
230     if (conn->discTimer != NULL) {
231         AlarmCancel(conn->discTimer);
232         AlarmDelete(conn->discTimer);
233         conn->discTimer = NULL;
234     } else {
235         if ((conn->state == L2CAP_CONNECTION_CONNECTED) && (ListGetFirstNode(conn->chanList) == NULL)) {
236             if (L2capAddConnectionRef(conn->aclHandle) != BT_SUCCESS) {
237                 conn->state = L2CAP_CONNECTION_DISCONNECTING;
238             }
239         }
240     }
241 
242     chan->lcid = L2capGetNewLcid();
243     chan->lpsm = lpsm;
244     chan->rpsm = rpsm;
245     chan->state = L2CAP_CHANNEL_IDLE;
246     chan->cfgState = 0;
247 
248     chan->part.options = NULL;
249     chan->part.length = 0;
250 
251     L2capSetDefaultConfigOptions(&(chan->lcfg));
252     L2capSetDefaultConfigOptions(&(chan->rcfg));
253 
254     ListAddLast(conn->chanList, chan);
255     return chan;
256 }
257 
L2capDestroyChannelTx(L2capChannel * chan)258 static void L2capDestroyChannelTx(L2capChannel *chan)
259 {
260     ListNode *node = NULL;
261 
262     if (chan->lcfg.rfc.mode == L2CAP_STREAM_MODE) {
263         Packet *pkt = NULL;
264 
265         while (1) {
266             node = ListGetFirstNode(chan->erfc.txList);
267             if (node == NULL) {
268                 break;
269             }
270 
271             pkt = ListGetNodeData(node);
272             ListRemoveNode(chan->erfc.txList, pkt);
273             PacketFree(pkt);
274         }
275     } else {
276         L2capErfcTxPacket *tx = NULL;
277 
278         while (1) {
279             node = ListGetFirstNode(chan->erfc.txList);
280             if (node == NULL) {
281                 break;
282             }
283 
284             tx = ListGetNodeData(node);
285             ListRemoveNode(chan->erfc.txList, tx);
286             PacketFree(tx->pkt);
287             L2capFree(tx);
288         }
289     }
290 
291     ListDelete(chan->erfc.txList);
292     return;
293 }
294 
L2capDestroyChannel(L2capChannel * chan)295 void L2capDestroyChannel(L2capChannel *chan)
296 {
297     if (chan->erfc.monitorTimer != NULL) {
298         AlarmCancel(chan->erfc.monitorTimer);
299         AlarmDelete(chan->erfc.monitorTimer);
300     }
301 
302     if (chan->erfc.retransmissionTimer != NULL) {
303         AlarmCancel(chan->erfc.retransmissionTimer);
304         AlarmDelete(chan->erfc.retransmissionTimer);
305     }
306 
307     if (chan->part.options != NULL) {
308         L2capFree(chan->part.options);
309     }
310 
311     if (chan->erfc.txList != NULL) {
312         L2capDestroyChannelTx(chan);
313     }
314 
315     if (chan->erfc.rxSarPacket != NULL) {
316         PacketFree(chan->erfc.rxSarPacket);
317     }
318 
319     L2capFree(chan);
320     return;
321 }
322 
L2capDisconnectTimeout(const void * parameter)323 static void L2capDisconnectTimeout(const void *parameter)
324 {
325     L2capInstance *inst = L2capGetInstance();
326     L2capConnection *conn = NULL;
327     ListNode *node = NULL;
328 
329     if (inst->connList == NULL) {
330         return;
331     }
332 
333     node = ListGetFirstNode(inst->connList);
334     while (node != NULL) {
335         conn = ListGetNodeData(node);
336         if (conn == parameter) {
337             if (ListGetFirstNode(conn->chanList) != NULL) {
338                 break;
339             }
340 
341             AlarmDelete(conn->discTimer);
342             conn->discTimer = NULL;
343             // Reason: REMOTE USER TERMINATED CONNECTION
344             L2capDisconnect(conn->aclHandle, 0x13);
345             break;
346         }
347 
348         node = ListGetNextNode(node);
349     }
350 
351     return;
352 }
353 
L2capDisconnectTimeoutCallback(void * parameter)354 static void L2capDisconnectTimeoutCallback(void *parameter)
355 {
356     L2capAsynchronousProcess(L2capDisconnectTimeout, NULL, parameter);
357     return;
358 }
359 
L2capDeleteChannel(L2capConnection * conn,L2capChannel * chan,uint16_t removeAcl)360 void L2capDeleteChannel(L2capConnection *conn, L2capChannel *chan, uint16_t removeAcl)
361 {
362     ListRemoveNode(conn->chanList, chan);
363     L2capDestroyChannel(chan);
364 
365     if (removeAcl) {
366         if (ListGetFirstNode(conn->chanList) == NULL) {
367             // Reason: REMOTE USER TERMINATED CONNECTION
368             L2capDisconnect(conn->aclHandle, 0x13);
369         }
370     } else {
371         if (ListGetFirstNode(conn->chanList) == NULL) {
372             if (conn->discTimer != NULL) {
373                 AlarmCancel(conn->discTimer);
374             } else {
375                 conn->discTimer = AlarmCreate("", false);
376             }
377 
378             AlarmSet(conn->discTimer, L2CAP_DISCONNECTION_TIME_OUT, L2capDisconnectTimeoutCallback, conn);
379         }
380     }
381 
382     return;
383 }
384 
L2capNewConnection(const BtAddr * addr,uint16_t aclHandle)385 L2capConnection *L2capNewConnection(const BtAddr *addr, uint16_t aclHandle)
386 {
387     L2capInstance *inst = L2capGetInstance();
388     L2capConnection *conn = NULL;
389 
390     conn = L2capAlloc(sizeof(L2capConnection));
391     if (conn == NULL) {
392         return NULL;
393     }
394 
395     (void)memcpy_s(&(conn->addr), sizeof(BtAddr), addr, sizeof(BtAddr));
396     conn->aclHandle = aclHandle;
397     conn->state = L2CAP_CONNECTION_IDLE;
398     conn->info.state = L2CAP_INFO_STATE_NONE;
399     conn->nextIdentifier = L2CAP_MIN_IDENTIFIER;
400 
401     conn->chanList = ListCreate(NULL);
402     conn->pendingList = ListCreate(NULL);
403     conn->discTimer = NULL;
404 
405     ListAddFirst(inst->connList, conn);
406     return conn;
407 }
408 
L2capDeleteConnection(L2capConnection * conn)409 void L2capDeleteConnection(L2capConnection *conn)
410 {
411     L2capInstance *inst = L2capGetInstance();
412     ListNode *node = NULL;
413 
414     if (conn->chanList != NULL) {
415         L2capChannel *chan = NULL;
416 
417         while (1) {
418             node = ListGetFirstNode(conn->chanList);
419             if (node == NULL) {
420                 break;
421             }
422 
423             chan = ListGetNodeData(node);
424             ListRemoveNode(conn->chanList, chan);
425 
426             L2capDestroyChannel(chan);
427         }
428 
429         ListDelete(conn->chanList);
430     }
431 
432     if (conn->pendingList != NULL) {
433         L2capClearPendingRequest(conn->pendingList);
434         ListDelete(conn->pendingList);
435     }
436 
437     if (conn->discTimer != NULL) {
438         AlarmCancel(conn->discTimer);
439         AlarmDelete(conn->discTimer);
440         conn->discTimer = NULL;
441     }
442 
443     ListRemoveNode(inst->connList, conn);
444     L2capFree(conn);
445 
446     // if no connection exists, reset nextLcid value
447     if (ListGetFirstNode(inst->connList) == NULL) {
448         inst->nextLcid = L2CAP_MIN_CID;
449     }
450 
451     return;
452 }