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