1/* 2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5#include <string.h> 6 7#include <l2cap.h> 8#include <bluetooth/HCI/btHCI_command.h> 9 10#include <btDebug.h> 11 12#include "ChannelInterface.h" 13#include "FrameInterface.h" 14 15 16L2capChannel* 17ChannelBySourceID(HciConnection *conn, uint16 scid) 18{ 19 L2capChannel* channel = NULL; 20 21 DoublyLinkedList<L2capChannel>::Iterator iterator = conn->ChannelList.GetIterator(); 22 23 while (iterator.HasNext()) { 24 channel = iterator.Next(); 25 if (channel->scid == scid) 26 return channel; 27 } 28 29 return NULL; 30} 31 32 33uint16 34ChannelAllocateCid(HciConnection* conn) 35{ 36 uint16 cid = conn->lastCid; 37 TRACE("%s: Starting search cid %d\n", __func__, cid); 38 do { 39 cid = (cid == L2CAP_LAST_CID) ? L2CAP_FIRST_CID : cid + 1; 40 41 if (ChannelBySourceID(conn, cid) == NULL) { 42 conn->lastCid = cid; 43 return cid; 44 } 45 46 } while (cid != conn->lastCid); 47 48 return L2CAP_NULL_CID; 49} 50 51 52uint16 53ChannelAllocateIdent(HciConnection* conn) 54{ 55 uint8 ident = conn->lastIdent + 1; 56 57 if (ident < L2CAP_FIRST_IDENT) 58 ident = L2CAP_FIRST_IDENT; 59 60 while (ident != conn->lastIdent) { 61 if (SignalByIdent(conn, ident) == NULL) { 62 conn->lastIdent = ident; 63 64 return ident; 65 } 66 67 ident++; 68 if (ident < L2CAP_FIRST_IDENT) 69 ident = L2CAP_FIRST_IDENT; 70 } 71 72 return L2CAP_NULL_IDENT; 73} 74 75 76L2capChannel* 77AddChannel(HciConnection* conn, uint16 psm) 78{ 79 L2capChannel* channel = new (std::nothrow) L2capChannel; 80 81 if (channel == NULL) { 82 ERROR("%s: Unable to allocate memory for channel!\n", __func__); 83 return NULL; 84 } 85 86 /* Get a new Source CID */ 87 channel->scid = ChannelAllocateCid(conn); 88 89 if (channel->scid != L2CAP_NULL_CID) { 90 /* Initialize channel */ 91 channel->psm = psm; 92 channel->conn = conn; 93 channel->state = L2CAP_CHAN_CLOSED; 94 channel->cfgState = 0; 95 channel->endpoint = NULL; 96 97 // the last assigned CID should be the last in the list 98 // Think if keeping an ordered list will improve the search method 99 // as it is called in every reception 100 conn->ChannelList.Add(channel); 101 //conn->num_channels++; 102 103 // Any constance of the new channel created ...? ng_l2cap_con_ref(con); 104 105 } else { 106 ERROR("%s: no CID available\n", __func__); 107 delete channel; 108 channel = NULL; 109 } 110 111 return channel; 112} 113 114 115void 116RemoveChannel(HciConnection* conn, uint16 scid) 117{ 118 //TODO make it safer 119 conn->ChannelList.Remove(ChannelBySourceID(conn, scid)); 120} 121