- Add bluetooth kernel module intented to manage all internal data structures
-Managing for HCI connections
-Managing of L2cap Channels
-Pending frames
-Interface with KDL
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28726 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel bluetooth ;
|
||||||
|
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel bluetooth btCoreData ;
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#include "ConnectionInterface.h"
|
||||||
|
#include "ChannelInterface.h"
|
||||||
|
#include "FrameInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <bluetooth/bdaddrUtils.h>
|
||||||
|
#include <bluetooth/HCI/btHCI_transport.h>
|
||||||
|
#include <bluetooth/HCI/btHCI_event.h>
|
||||||
|
|
||||||
|
#define BT_DEBUG_THIS_MODULE
|
||||||
|
#include <btDebug.h>
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection> sConnectionList;
|
||||||
|
net_buffer_module_info *gBufferModule = NULL;
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
ExistConnectionByDestination(bdaddr_t *destination, hci_id hid = -1)
|
||||||
|
{
|
||||||
|
return (ConnectionByDestination(destination, hid) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
ExistConnectionByHandle(uint16 handle, hci_id hid)
|
||||||
|
{
|
||||||
|
return (ConnectionByHandle(handle,hid));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
DumpHciConnections(int argc, char** argv)
|
||||||
|
{
|
||||||
|
HciConnection* conn;
|
||||||
|
L2capChannel* chan;
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
conn = iterator.Next();
|
||||||
|
kprintf("\tLocalDevice=%lx Destination=%s handle=%#x type=%d outqueue=%ld expected=%ld\n",
|
||||||
|
conn->Hid, bdaddrUtils::ToString(conn->destination),
|
||||||
|
conn->handle, conn->type, conn->OutGoingFrames.Size() , conn->ExpectedResponses.Size());
|
||||||
|
|
||||||
|
// each channel
|
||||||
|
DoublyLinkedList<L2capChannel>::Iterator channelIterator = conn->ChannelList.GetIterator();
|
||||||
|
while (channelIterator.HasNext()) {
|
||||||
|
chan = channelIterator.Next();
|
||||||
|
kprintf("\t\tscid=%x dcid=%x state=%x cfg=%x\n", chan->scid,
|
||||||
|
chan->dcid, chan->state, chan->cfgState);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PostEvent(net_device* ndev, void* event, size_t size)
|
||||||
|
{
|
||||||
|
struct hci_event_header* outgoingEvent = (struct hci_event_header*) event;
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
// Take actions on certain type of events.
|
||||||
|
switch (outgoingEvent->ecode) {
|
||||||
|
case HCI_EVENT_CONN_COMPLETE:
|
||||||
|
{
|
||||||
|
struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent+1);
|
||||||
|
//TODO: XXX parse handle field
|
||||||
|
HciConnection* conn = AddConnection(data->handle, BT_ACL, &data->bdaddr, ndev->index);
|
||||||
|
if (conn == NULL)
|
||||||
|
panic("no mem for conn desc");
|
||||||
|
conn->ndevice = ndev;
|
||||||
|
debugf("Registered connection handle=%#x\n",data->handle);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
|
{
|
||||||
|
struct hci_ev_disconnection_complete_reply* data =
|
||||||
|
(struct hci_ev_disconnection_complete_reply*)(outgoingEvent+1);
|
||||||
|
RemoveConnection(data->handle, ndev->index);
|
||||||
|
debugf("unRegistered connection handle=%#x\n",data->handle);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// forward to bluetooth server
|
||||||
|
port_id port = find_port(BT_USERLAND_PORT_NAME);
|
||||||
|
if (port != B_NAME_NOT_FOUND) {
|
||||||
|
|
||||||
|
err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1),
|
||||||
|
event, size, B_TIMEOUT, 1*1000*1000);
|
||||||
|
|
||||||
|
if (err != B_OK)
|
||||||
|
debugf("Error posting userland %s\n", strerror(err));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
flowf("ERROR:bluetooth_server not found for posting\n");
|
||||||
|
err = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
bcd_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
new (&sConnectionList) DoublyLinkedList<HciConnection>;
|
||||||
|
add_debugger_command("btConnections", &DumpHciConnections,
|
||||||
|
"Lists Bluetooth Connections with RemoteDevices & channels");
|
||||||
|
|
||||||
|
status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
|
||||||
|
if (status < B_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
|
||||||
|
remove_debugger_command("btConnections", &DumpHciConnections);
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bluetooth_core_data_module_info sBCDModule = {
|
||||||
|
{
|
||||||
|
BT_CORE_DATA_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
bcd_std_ops
|
||||||
|
},
|
||||||
|
PostEvent,
|
||||||
|
AddConnection,
|
||||||
|
/* RemoveConnection,*/
|
||||||
|
RemoveConnection,
|
||||||
|
|
||||||
|
RouteConnection,
|
||||||
|
|
||||||
|
SetAclBuffer,
|
||||||
|
SetAclExpectedSize,
|
||||||
|
AclPutting,
|
||||||
|
AclComplete,
|
||||||
|
AclOverFlowed,
|
||||||
|
|
||||||
|
ConnectionByHandle,
|
||||||
|
ConnectionByDestination,
|
||||||
|
|
||||||
|
AddChannel,
|
||||||
|
RemoveChannel,
|
||||||
|
ChannelBySourceID,
|
||||||
|
ChannelAllocateCid,
|
||||||
|
ChannelAllocateIdent,
|
||||||
|
|
||||||
|
SignalByIdent,
|
||||||
|
TimeoutSignal,
|
||||||
|
unTimeoutSignal,
|
||||||
|
SpawmFrame,
|
||||||
|
SpawmSignal,
|
||||||
|
AcknowledgeSignal
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info *modules[] = {
|
||||||
|
(module_info *)&sBCDModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <l2cap.h>
|
||||||
|
#include <bluetooth/HCI/btHCI_command.h>
|
||||||
|
|
||||||
|
#define BT_DEBUG_THIS_MODULE
|
||||||
|
#define SUBMODULE_NAME "Channel"
|
||||||
|
#define SUBMODULE_COLOR 31
|
||||||
|
#include <btDebug.h>
|
||||||
|
|
||||||
|
#include "ChannelInterface.h"
|
||||||
|
#include "FrameInterface.h"
|
||||||
|
|
||||||
|
L2capChannel*
|
||||||
|
ChannelBySourceID(HciConnection *conn, uint16 scid)
|
||||||
|
{
|
||||||
|
L2capChannel* channel = NULL;
|
||||||
|
|
||||||
|
DoublyLinkedList<L2capChannel>::Iterator iterator = conn->ChannelList.GetIterator();
|
||||||
|
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
channel = iterator.Next();
|
||||||
|
if (channel->scid == scid)
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16
|
||||||
|
ChannelAllocateCid(HciConnection* conn)
|
||||||
|
{
|
||||||
|
uint16 cid = conn->lastCid ;
|
||||||
|
debugf("Starting search cid %d\n",cid);
|
||||||
|
do {
|
||||||
|
cid = (cid == L2CAP_LAST_CID)?L2CAP_FIRST_CID : cid + 1;
|
||||||
|
|
||||||
|
if(ChannelBySourceID(conn, cid) == NULL) {
|
||||||
|
conn->lastCid = cid;
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (cid != conn->lastCid);
|
||||||
|
|
||||||
|
return L2CAP_NULL_CID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16
|
||||||
|
ChannelAllocateIdent(HciConnection* conn)
|
||||||
|
{
|
||||||
|
uint8 ident = conn->lastIdent + 1;
|
||||||
|
|
||||||
|
if (ident < L2CAP_FIRST_IDENT)
|
||||||
|
ident = L2CAP_FIRST_IDENT;
|
||||||
|
|
||||||
|
while (ident != conn->lastIdent) {
|
||||||
|
if (SignalByIdent(conn, ident) == NULL) {
|
||||||
|
conn->lastIdent = ident;
|
||||||
|
|
||||||
|
return ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
ident ++;
|
||||||
|
if (ident < L2CAP_FIRST_IDENT)
|
||||||
|
ident = L2CAP_FIRST_IDENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return L2CAP_NULL_IDENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
L2capChannel*
|
||||||
|
AddChannel(HciConnection* conn, uint16 psm)
|
||||||
|
{
|
||||||
|
L2capChannel* channel = new (std::nothrow) L2capChannel;
|
||||||
|
|
||||||
|
if (channel == NULL) {
|
||||||
|
flowf ("no mem for channel");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a new Source CID */
|
||||||
|
channel->scid = ChannelAllocateCid(conn);
|
||||||
|
|
||||||
|
if (channel->scid != L2CAP_NULL_CID) {
|
||||||
|
/* Initialize channel */
|
||||||
|
channel->psm = psm;
|
||||||
|
channel->conn = conn;
|
||||||
|
channel->state = L2CAP_CHAN_CLOSED;
|
||||||
|
channel->cfgState = 0;
|
||||||
|
channel->endpoint = NULL;
|
||||||
|
|
||||||
|
// the last assigned CID should be the last in the list
|
||||||
|
// Think if keeping an ordered list will improve the search method
|
||||||
|
// as it is called in every reception
|
||||||
|
conn->ChannelList.Add(channel);
|
||||||
|
//conn->num_channels++;
|
||||||
|
|
||||||
|
// Any constance of the new channel created ...? ng_l2cap_con_ref(con);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
flowf("no CID available\n");
|
||||||
|
delete channel;
|
||||||
|
channel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoveChannel(HciConnection* conn, uint16 scid)
|
||||||
|
{
|
||||||
|
//TODO make it safer
|
||||||
|
conn->ChannelList.Remove(ChannelBySourceID(conn, scid));
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _CHANNEL_INTERFACE_H
|
||||||
|
#define _CHANNEL_INTERFACE_H
|
||||||
|
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include <l2cap.h>
|
||||||
|
#include <btCoreData.h>
|
||||||
|
|
||||||
|
L2capChannel* AddChannel(HciConnection* conn, uint16 psm);
|
||||||
|
void RemoveChannel(HciConnection* conn, uint16 scid);
|
||||||
|
|
||||||
|
L2capChannel* ChannelBySourceID(HciConnection* conn, uint16 scid);
|
||||||
|
uint16 ChannelAllocateCid(HciConnection* conn);
|
||||||
|
uint16 ChannelAllocateIdent(HciConnection* conn);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _CHANNELINTERFACE_H
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/bluetooth_util.h>
|
||||||
|
|
||||||
|
#define BT_DEBUG_THIS_MODULE
|
||||||
|
#define SUBMODULE_NAME "Connection"
|
||||||
|
#define SUBMODULE_COLOR 31
|
||||||
|
#include <btDebug.h>
|
||||||
|
|
||||||
|
#include <l2cap.h>
|
||||||
|
|
||||||
|
#include "ConnectionInterface.h"
|
||||||
|
|
||||||
|
void PurgeChannels(HciConnection* conn);
|
||||||
|
|
||||||
|
HciConnection*
|
||||||
|
AddConnection(uint16 handle, int type, bdaddr_t* dst, hci_id hid)
|
||||||
|
{
|
||||||
|
// Create connection descriptor
|
||||||
|
|
||||||
|
HciConnection* conn = ConnectionByHandle(handle, hid);
|
||||||
|
if (conn != NULL)
|
||||||
|
goto update;
|
||||||
|
|
||||||
|
conn = new (std::nothrow) HciConnection;
|
||||||
|
if (conn == NULL)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
memset(conn, 0, sizeof(HciConnection));
|
||||||
|
|
||||||
|
conn->currentRxPacket = NULL;
|
||||||
|
conn->currentRxExpectedLength = 0;
|
||||||
|
update:
|
||||||
|
// fill values
|
||||||
|
bacpy(&conn->destination, dst);
|
||||||
|
conn->type = type;
|
||||||
|
conn->handle = handle;
|
||||||
|
conn->Hid = hid;
|
||||||
|
conn->status = HCI_CONN_OPEN;
|
||||||
|
conn->mtu = L2CAP_MTU_MINIMUM; // TODO: give the mtu to the connection
|
||||||
|
conn->lastCid = L2CAP_FIRST_CID;
|
||||||
|
conn->lastIdent = L2CAP_FIRST_IDENT;
|
||||||
|
|
||||||
|
sConnectionList.Add(conn);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RemoveConnection(bdaddr_t* destination, hci_id hid)
|
||||||
|
{
|
||||||
|
HciConnection* conn;
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
conn = iterator.Next();
|
||||||
|
if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
|
||||||
|
|
||||||
|
// if the device is still part of the list, remove it
|
||||||
|
if (conn->GetDoublyLinkedListLink()->next != NULL
|
||||||
|
|| conn->GetDoublyLinkedListLink()->previous != NULL
|
||||||
|
|| conn == sConnectionList.Head()) {
|
||||||
|
sConnectionList.Remove(conn);
|
||||||
|
|
||||||
|
delete conn;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RemoveConnection(uint16 handle, hci_id hid)
|
||||||
|
{
|
||||||
|
HciConnection* conn;
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
conn = iterator.Next();
|
||||||
|
if (conn->Hid == hid && conn->handle == handle) {
|
||||||
|
|
||||||
|
// if the device is still part of the list, remove it
|
||||||
|
if (conn->GetDoublyLinkedListLink()->next != NULL
|
||||||
|
|| conn->GetDoublyLinkedListLink()->previous != NULL
|
||||||
|
|| conn == sConnectionList.Head()) {
|
||||||
|
sConnectionList.Remove(conn);
|
||||||
|
|
||||||
|
PurgeChannels(conn);
|
||||||
|
delete conn;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hci_id
|
||||||
|
RouteConnection(bdaddr_t* destination) {
|
||||||
|
|
||||||
|
HciConnection* conn;
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
conn = iterator.Next();
|
||||||
|
if (bacmp(&conn->destination, destination)==0) {
|
||||||
|
return conn->Hid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HciConnection*
|
||||||
|
ConnectionByHandle(uint16 handle, hci_id hid)
|
||||||
|
{
|
||||||
|
HciConnection* conn;
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
conn = iterator.Next();
|
||||||
|
if (conn->Hid == hid && conn->handle==handle) {
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HciConnection*
|
||||||
|
ConnectionByDestination(bdaddr_t* destination, hci_id hid)
|
||||||
|
{
|
||||||
|
HciConnection* conn;
|
||||||
|
|
||||||
|
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
conn = iterator.Next();
|
||||||
|
if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#pragma mark - ACL helper funcs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SetAclBuffer(HciConnection* conn, net_buffer* nbuf)
|
||||||
|
{
|
||||||
|
conn->currentRxPacket = nbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SetAclExpectedSize(HciConnection* conn, size_t size)
|
||||||
|
{
|
||||||
|
conn->currentRxExpectedLength = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AclPutting(HciConnection* conn, size_t size)
|
||||||
|
{
|
||||||
|
conn->currentRxExpectedLength -= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AclComplete(HciConnection* conn)
|
||||||
|
{
|
||||||
|
return conn->currentRxExpectedLength == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AclOverFlowed(HciConnection* conn)
|
||||||
|
{
|
||||||
|
return conn->currentRxExpectedLength < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#pragma mark - private funcs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
PurgeChannels(HciConnection* conn)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _CONNECTION_INTERFACE_H
|
||||||
|
#define _CONNECTION_INTERFACE_H
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/HCI/btHCI.h>
|
||||||
|
|
||||||
|
#include <btCoreData.h>
|
||||||
|
|
||||||
|
extern DoublyLinkedList<HciConnection> sConnectionList;
|
||||||
|
|
||||||
|
HciConnection* ConnectionByHandle(uint16 handle, hci_id hid);
|
||||||
|
HciConnection* ConnectionByDestination(bdaddr_t *destination, hci_id hid);
|
||||||
|
|
||||||
|
|
||||||
|
HciConnection* AddConnection(uint16 handle, int type, bdaddr_t *dst, hci_id hid);
|
||||||
|
status_t RemoveConnection(bdaddr_t *destination, hci_id hid);
|
||||||
|
status_t RemoveConnection(uint16 handle, hci_id hid);
|
||||||
|
|
||||||
|
hci_id RouteConnection(bdaddr_t *destination);
|
||||||
|
|
||||||
|
void SetAclBuffer(HciConnection* conn, net_buffer* nbuf);
|
||||||
|
void SetAclExpectedSize(HciConnection* conn, size_t size);
|
||||||
|
void AclPutting(HciConnection* conn, size_t size);
|
||||||
|
bool AclComplete(HciConnection* conn);
|
||||||
|
bool AclOverFlowed(HciConnection* conn);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _CONNECTION_INTERFACE_H
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#include "FrameInterface.h"
|
||||||
|
|
||||||
|
#define BT_DEBUG_THIS_MODULE
|
||||||
|
#define SUBMODULE_NAME "Frame"
|
||||||
|
#define SUBMODULE_COLOR 31
|
||||||
|
#include <btDebug.h>
|
||||||
|
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SignalByIdent(HciConnection* conn, uint8 ident)
|
||||||
|
{
|
||||||
|
L2capFrame* frame;
|
||||||
|
|
||||||
|
DoublyLinkedList<L2capFrame>::Iterator iterator = conn->ExpectedResponses.GetIterator();
|
||||||
|
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
|
||||||
|
frame = iterator.Next();
|
||||||
|
if (frame->type == L2CAP_C_FRAME && frame->ident == ident) {
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TimeoutSignal(L2capFrame* frame, uint32 timeo)
|
||||||
|
{
|
||||||
|
if (frame != NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
unTimeoutSignal(L2capFrame* frame)
|
||||||
|
{
|
||||||
|
if (frame != NULL)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SpawmFrame(HciConnection* conn, net_buffer* buffer, frame_type type)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
panic("Null Buffer to outgoing queue");
|
||||||
|
|
||||||
|
L2capFrame* frame = new (std::nothrow) L2capFrame;
|
||||||
|
|
||||||
|
frame->conn = conn;
|
||||||
|
frame->channel = NULL; // TODO: needed?
|
||||||
|
|
||||||
|
frame->buffer = buffer;
|
||||||
|
frame->type = type;
|
||||||
|
|
||||||
|
conn->OutGoingFrames.Add(frame, true);
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SpawmSignal(HciConnection* conn, L2capChannel* channel, net_buffer* buffer, uint8 ident, uint8 code)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
panic("Null Buffer to outgoing queue");
|
||||||
|
|
||||||
|
L2capFrame* frame = new (std::nothrow) L2capFrame;
|
||||||
|
|
||||||
|
frame->conn = conn;
|
||||||
|
frame->channel = channel; // TODO: needed?
|
||||||
|
|
||||||
|
frame->buffer = buffer;
|
||||||
|
frame->type = L2CAP_C_FRAME;
|
||||||
|
frame->ident = ident;
|
||||||
|
frame->code = code;
|
||||||
|
|
||||||
|
conn->OutGoingFrames.Add(frame, true);
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AcknowledgeSignal(L2capFrame* frame)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (frame != NULL) {
|
||||||
|
|
||||||
|
if (frame->type == L2CAP_C_FRAME) {
|
||||||
|
unTimeoutSignal(frame);
|
||||||
|
frame->conn->ExpectedResponses.Remove(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
gBufferModule->free(frame->buffer);
|
||||||
|
delete frame;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _FRAME_INTERFACE_H
|
||||||
|
#define _FRAME_INTERFACE_H
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
|
#include <btCoreData.h>
|
||||||
|
|
||||||
|
extern net_buffer_module_info* gBufferModule;
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SignalByIdent(HciConnection* conn, uint8 ident);
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TimeoutSignal(L2capFrame* frame, uint32 timeo);
|
||||||
|
|
||||||
|
status_t
|
||||||
|
unTimeoutSignal(L2capFrame* frame);
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SpawmFrame(HciConnection* conn, net_buffer* buffer, frame_type frame);
|
||||||
|
|
||||||
|
L2capFrame*
|
||||||
|
SpawmSignal(HciConnection* conn, L2capChannel* channel, net_buffer* buffer, uint8 ident, uint8 code);
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AcknowledgeSignal(L2capFrame* frame);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel bluetooth btCoreData ;
|
||||||
|
|
||||||
|
UsePrivateHeaders kernel net bluetooth ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ;
|
||||||
|
|
||||||
|
# disable debug output, if debugging is disabled
|
||||||
|
if $(DEBUG) = 0 {
|
||||||
|
SubDirCcFlags [ FDefines DEBUG_MAX_LEVEL_FLOW=0 DEBUG_MAX_LEVEL_INFO=0 ] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
KernelAddon btCoreData :
|
||||||
|
ConnectionInterface.cpp
|
||||||
|
ChannelInterface.cpp
|
||||||
|
FrameInterface.cpp
|
||||||
|
BTCoreData.cpp
|
||||||
|
;
|
||||||
|
|
||||||
Reference in New Issue
Block a user