- Implement ACL Segmentation and Reassembly
- Kernel traces for bluetooth devices - Register connections helper funcs git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28739 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7cc7cada6a
commit
d8de43897a
@ -15,6 +15,7 @@ UsePrivateHeaders net bluetooth ;
|
||||
|
||||
KernelAddon bluetooth :
|
||||
bluetooth.cpp
|
||||
acl.cpp
|
||||
;
|
||||
|
||||
# Installation
|
||||
|
174
src/add-ons/kernel/network/devices/bluetooth/acl.cpp
Normal file
174
src/add-ons/kernel/network/devices/bluetooth/acl.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <NetBufferUtilities.h>
|
||||
#include <net_protocol.h>
|
||||
|
||||
#include <bluetooth/HCI/btHCI_acl.h>
|
||||
#include <bluetooth/HCI/btHCI_transport.h>
|
||||
#include <bluetooth/HCI/btHCI_event.h>
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
|
||||
//#define BT_DEBUG_THIS_MODULE
|
||||
#define SUBMODULE_NAME "ACL"
|
||||
#define SUBMODULE_COLOR 34
|
||||
#include <btDebug.h>
|
||||
#include <btCoreData.h>
|
||||
#include <btModules.h>
|
||||
#include <l2cap.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
extern struct bluetooth_core_data_module_info* btCoreData;
|
||||
|
||||
struct net_protocol_module_info* L2cap = NULL;
|
||||
|
||||
extern void RegisterConnection(hci_id hid, uint16 handle);
|
||||
extern void unRegisterConnection(hci_id hid, uint16 handle);
|
||||
|
||||
status_t PostToUpper(HciConnection* conn, net_buffer* buf);
|
||||
|
||||
status_t
|
||||
AclAssembly(net_buffer* nbuf, hci_id hid)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
|
||||
/* Check ACL data packet. Driver should ensure report complete ACL packets */
|
||||
if (nbuf->size < sizeof(struct hci_acl_header)) {
|
||||
debugf("Transport driver has reported invalid ACL data packet, too small, length=%ld\n", nbuf->size);
|
||||
gBufferModule->free(nbuf);
|
||||
return (EMSGSIZE);
|
||||
}
|
||||
|
||||
/* Strip ACL data packet header */
|
||||
NetBufferHeaderReader<struct hci_acl_header> aclHeader(nbuf);
|
||||
status_t status = aclHeader.Status();
|
||||
if (status < B_OK) {
|
||||
gBufferModule->free(nbuf);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
|
||||
/* Get ACL connection handle, PB flag and payload length */
|
||||
aclHeader->handle = le16toh(aclHeader->handle);
|
||||
|
||||
uint16 con_handle = get_acl_handle(aclHeader->handle);
|
||||
uint16 pb = get_acl_pb_flag(aclHeader->handle);
|
||||
uint16 length = le16toh(aclHeader->alen);
|
||||
|
||||
aclHeader.Remove();
|
||||
|
||||
debugf("got ACL data packet, con_handle=%#x, PB=%#x, length=%d\n", con_handle, pb, length);
|
||||
|
||||
/* a) Ensure there is HCI connection
|
||||
b) Get connection descriptor
|
||||
c) veryfy the status of the connection
|
||||
*/
|
||||
|
||||
HciConnection* conn = btCoreData->ConnectionByHandle(con_handle, hid);
|
||||
if (conn == NULL) {
|
||||
//debugf("unexpected ACL!Connection does not exist!schedule! con_handle=%#x\n", con_handle);
|
||||
panic("unexpected ACL!Connection does not exist!schedule!\n");
|
||||
conn = btCoreData->AddConnection(con_handle, BT_ACL, BDADDR_NULL, hid);
|
||||
}
|
||||
|
||||
// Verify connection state
|
||||
if (conn->status!= HCI_CONN_OPEN) {
|
||||
flowf("unexpected ACL data packet. Connection not open\n");
|
||||
gBufferModule->free(nbuf);
|
||||
return EHOSTDOWN;
|
||||
}
|
||||
|
||||
|
||||
/* Process packet */
|
||||
if (pb == HCI_ACL_PACKET_START) {
|
||||
if (conn->currentRxPacket != NULL) {
|
||||
debugf("dropping incomplete L2CAP packet, got %ld bytes, want %d bytes\n", conn->currentRxPacket->size, length );
|
||||
gBufferModule->free(conn->currentRxPacket);
|
||||
conn->currentRxPacket = NULL;
|
||||
conn->currentRxExpectedLength = 0;
|
||||
}
|
||||
|
||||
// Get L2CAP header, ACL header was dimissed
|
||||
if (nbuf->size < sizeof(l2cap_hdr_t)) {
|
||||
debugf("invalid L2CAP packet start fragment. Packet too small, length=%ld\n", nbuf->size);
|
||||
gBufferModule->free(nbuf);
|
||||
return (EMSGSIZE);
|
||||
}
|
||||
|
||||
|
||||
NetBufferHeaderReader<l2cap_hdr_t> l2capHeader(nbuf);
|
||||
status_t status = l2capHeader.Status();
|
||||
if (status < B_OK) {
|
||||
gBufferModule->free(nbuf);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
l2capHeader->length = le16toh(l2capHeader->length);
|
||||
l2capHeader->dcid = le16toh(l2capHeader->dcid);
|
||||
|
||||
debugf("staring new L2CAP packet, con_handle=%#x, length=%d\n", con_handle, le16toh(l2capHeader->length));
|
||||
|
||||
/* Start new L2CAP packet */
|
||||
conn->currentRxPacket = nbuf;
|
||||
conn->currentRxExpectedLength = l2capHeader->length + sizeof(l2cap_hdr_t);
|
||||
|
||||
|
||||
} else if (pb == HCI_ACL_PACKET_FRAGMENT) {
|
||||
if (conn->currentRxPacket == NULL) {
|
||||
gBufferModule->free(nbuf);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Add fragment to the L2CAP packet */
|
||||
gBufferModule->merge(conn->currentRxPacket, nbuf, true);
|
||||
|
||||
} else {
|
||||
debugf("invalid ACL data packet. Invalid PB flag=%#x\n", pb);
|
||||
gBufferModule->free(nbuf);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
conn->currentRxExpectedLength -= length; /* substract the length of content of the ACL packet*/
|
||||
|
||||
if (conn->currentRxExpectedLength < 0) {
|
||||
|
||||
debugf("packet length mismatch. Got %ld bytes, expected %ld bytes\n", conn->currentRxPacket->size,
|
||||
conn->currentRxExpectedLength);
|
||||
gBufferModule->free(conn->currentRxPacket);
|
||||
conn->currentRxPacket = NULL;
|
||||
conn->currentRxExpectedLength = 0;
|
||||
|
||||
} else if (conn->currentRxExpectedLength == 0) {
|
||||
// OK, we have got complete L2CAP packet, so process it
|
||||
debugf("L2cap packet ready %ld bytes\n", conn->currentRxPacket->size);
|
||||
error = PostToUpper(conn, conn->currentRxPacket);
|
||||
// clean
|
||||
conn->currentRxPacket = NULL;
|
||||
conn->currentRxExpectedLength = 0;
|
||||
} else {
|
||||
debugf("Expected %ld current acl apports %d\n", conn->currentRxExpectedLength, length);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PostToUpper(HciConnection* conn, net_buffer* buf)
|
||||
{
|
||||
if (L2cap == NULL)
|
||||
|
||||
if (get_module(NET_BLUETOOTH_L2CAP_NAME,(module_info**)&L2cap) != B_OK) {
|
||||
debugf("cannot get module \"%s\"\n", NET_BLUETOOTH_L2CAP_NAME);
|
||||
return B_ERROR;
|
||||
} // TODO: someone put it
|
||||
|
||||
return L2cap->receive_data((net_buffer*)conn);// XXX:HACK -> pass handle in type
|
||||
|
||||
}
|
17
src/add-ons/kernel/network/devices/bluetooth/acl.h
Normal file
17
src/add-ons/kernel/network/devices/bluetooth/acl.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACL_PROC_H_
|
||||
#define _ACL_PROC_H_
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
#include <bluetooth/HCI/btHCI.h>
|
||||
|
||||
status_t AclAssembly(net_buffer* buffer, hci_id hid);
|
||||
|
||||
status_t InitializeAclConnectionThread();
|
||||
status_t QuitAclConnectionThread();
|
||||
|
||||
#endif
|
@ -6,7 +6,6 @@
|
||||
* Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_device.h>
|
||||
#include <net_stack.h>
|
||||
@ -18,53 +17,109 @@
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <new>
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
|
||||
#include <bluetooth/HCI/btHCI.h>
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
|
||||
#define BT_DEBUG_THIS_MODULE
|
||||
#define SUBMODULE_NAME "bluetooth_device"
|
||||
#define SUBMODULE_COLOR 34
|
||||
#include <btDebug.h>
|
||||
#include <btCoreData.h>
|
||||
#include <btModules.h>
|
||||
|
||||
#include <bluetooth/HCI/btHCI_acl.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
|
||||
#include <bluetooth/HCI/btHCI.h>
|
||||
|
||||
struct bluetooth_device : net_device, DoublyLinkedListLinkImpl<bluetooth_device> {
|
||||
DoublyLinkedList<HciConnection> sConnectionList;
|
||||
int fd;
|
||||
uint16 frame_size;
|
||||
uint16 mtu;
|
||||
};
|
||||
|
||||
/* Modules references */
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
static net_stack_module_info *sStackModule = NULL;
|
||||
net_buffer_module_info* gBufferModule = NULL;
|
||||
static net_stack_module_info* sStackModule = NULL;
|
||||
struct bluetooth_core_data_module_info* btCoreData = NULL;
|
||||
|
||||
|
||||
static mutex sListLock;
|
||||
static DoublyLinkedList<bluetooth_device> sDeviceList;
|
||||
static sem_id sLinkChangeSemaphore;
|
||||
|
||||
|
||||
bluetooth_device*
|
||||
FindDeviceByID(hci_id hid)
|
||||
{
|
||||
|
||||
bluetooth_device* device;
|
||||
|
||||
DoublyLinkedList<bluetooth_device>::Iterator iterator = sDeviceList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
device = iterator.Next();
|
||||
if (device->index == (uint32 )hid)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: keeping this list might not be strictily needed
|
||||
void
|
||||
RegisterConnection(hci_id hid, uint16 handle)
|
||||
{
|
||||
bluetooth_device* device = FindDeviceByID(hid);
|
||||
HciConnection* conn = btCoreData->ConnectionByHandle(handle, hid);
|
||||
|
||||
if (device != NULL && conn != NULL) {
|
||||
conn->ndevice = (struct net_device*)device;
|
||||
device->sConnectionList.Add(conn);
|
||||
} else {
|
||||
panic("problem registering connection");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
unRegisterConnection(hci_id hid, uint16 handle)
|
||||
{
|
||||
|
||||
bluetooth_device* device;
|
||||
device = FindDeviceByID(hid);
|
||||
|
||||
if (device != NULL) {
|
||||
device->sConnectionList.Remove(btCoreData->ConnectionByHandle(handle, hid));
|
||||
}
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
status_t
|
||||
bluetooth_init(const char *name, net_device **_device)
|
||||
bluetooth_init(const char* name, net_device** _device)
|
||||
{
|
||||
debugf("Initializing bluetooth device %s\n",name);
|
||||
|
||||
|
||||
// TODO: make sure this is a device in /dev/bluetooth
|
||||
if (strncmp(name, "bluetooth/h", 11))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (gBufferModule == NULL) { // lazy allocation
|
||||
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
|
||||
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
bluetooth_device *device = new (std::nothrow) bluetooth_device;
|
||||
bluetooth_device* device = new (std::nothrow) bluetooth_device;
|
||||
if (device == NULL) {
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
return B_NO_MEMORY;
|
||||
@ -76,7 +131,7 @@ bluetooth_init(const char *name, net_device **_device)
|
||||
strcpy(device->name, name);
|
||||
|
||||
MutexLocker _(&sListLock);
|
||||
|
||||
|
||||
if (sDeviceList.IsEmpty())
|
||||
device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index
|
||||
else
|
||||
@ -93,9 +148,9 @@ bluetooth_init(const char *name, net_device **_device)
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_uninit(net_device *_device)
|
||||
bluetooth_uninit(net_device* _device)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device *)_device;
|
||||
|
||||
debugf("index %lx\n",device->index);
|
||||
|
||||
@ -113,9 +168,9 @@ bluetooth_uninit(net_device *_device)
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_up(net_device *_device)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_up(net_device* _device)
|
||||
{
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld\n",device->index);
|
||||
|
||||
@ -133,9 +188,9 @@ err:
|
||||
|
||||
|
||||
void
|
||||
bluetooth_down(net_device *_device)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_down(net_device* _device)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld\n",device->index);
|
||||
|
||||
@ -145,60 +200,94 @@ bluetooth_down(net_device *_device)
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_control(net_device *_device, int32 op, void *argument,
|
||||
bluetooth_control(net_device* _device, int32 op, void* argument,
|
||||
size_t length)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
{
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld\n",device->index);
|
||||
|
||||
|
||||
// Forward the call to the driver
|
||||
return ioctl(device->fd, op, argument, length);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_send_data(net_device *_device, net_buffer *buffer)
|
||||
bluetooth_send_data(net_device *_device, net_buffer* buffer)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
net_buffer* curr_frame = NULL;
|
||||
net_buffer* next_frame = buffer;
|
||||
uint16 handle = buffer->type; //TODO: net_routes??
|
||||
uint8 flag = HCI_ACL_PACKET_START;
|
||||
|
||||
debugf("index %ld try to send bt packet of %lu bytes (flags %ld):\n",device->index, buffer->size, buffer->flags);
|
||||
|
||||
/* TODO:
|
||||
|
||||
*/
|
||||
//TODO: ATOMIC!!! any other thread should stop here
|
||||
do {
|
||||
// Divide packet if big enough
|
||||
curr_frame = next_frame;
|
||||
|
||||
// MTU and size possiblities to be checked in l2cap....
|
||||
// if (buffer->size > device->frame_size)
|
||||
// return B_BAD_VALUE;
|
||||
if (next_frame->size > device->mtu) {
|
||||
next_frame = gBufferModule->split(curr_frame, device->mtu);
|
||||
} else {
|
||||
next_frame = NULL;
|
||||
}
|
||||
|
||||
// Attach acl header
|
||||
NetBufferPrepend<struct hci_acl_header> bufferHeader(curr_frame);
|
||||
status_t status = bufferHeader.Status();
|
||||
if (status < B_OK) {
|
||||
// free the buffer
|
||||
continue;
|
||||
}
|
||||
|
||||
bufferHeader->handle = pack_acl_handle_flags(handle, flag, 0); /* Handle & Flags(PB, BC) */
|
||||
bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header);
|
||||
|
||||
bufferHeader.Sync();
|
||||
|
||||
// Send to driver XXX: another inter-layer trick
|
||||
debugf("tolower nbuf %p\n",curr_frame);
|
||||
curr_frame->protocol = BT_ACL;
|
||||
((status_t(*)(hci_id id, net_buffer* nbuf))device->media)(device->index, curr_frame);
|
||||
|
||||
flag = HCI_ACL_PACKET_FRAGMENT;
|
||||
|
||||
} while (next_frame == NULL);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_receive_data(net_device *_device, net_buffer **_buffer)
|
||||
bluetooth_receive_data(net_device* _device, net_buffer** _buffer)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
status_t status = B_OK;
|
||||
|
||||
debugf("index %ld try to send bt packet of %lu bytes (flags %ld):\n", device->index, (*_buffer)->size, (*_buffer)->flags);
|
||||
debugf("index %ld packet of %lu bytes (flags %ld):\n", device->index, (*_buffer)->size, (*_buffer)->flags);
|
||||
|
||||
if (device->fd == -1)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
/* TODO:
|
||||
|
||||
*/
|
||||
switch ((*_buffer)->protocol) {
|
||||
case BT_ACL:
|
||||
status = AclAssembly(*_buffer, device->index);
|
||||
break;
|
||||
default:
|
||||
panic("Protocol not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_set_mtu(net_device *_device, size_t mtu)
|
||||
bluetooth_set_mtu(net_device* _device, size_t mtu)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld mtu %ld\n",device->index, mtu);
|
||||
|
||||
@ -209,9 +298,9 @@ bluetooth_set_mtu(net_device *_device, size_t mtu)
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_set_promiscuous(net_device *_device, bool promiscuous)
|
||||
bluetooth_set_promiscuous(net_device* _device, bool promiscuous)
|
||||
{
|
||||
bluetooth_device *device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld promiscuous %d\n",device->index, promiscuous);
|
||||
|
||||
@ -220,18 +309,18 @@ bluetooth_set_promiscuous(net_device *_device, bool promiscuous)
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_set_media(net_device *device, uint32 media)
|
||||
bluetooth_set_media(net_device* device, uint32 media)
|
||||
{
|
||||
debugf("index %ld media %ld\n",device->index, media);
|
||||
|
||||
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
bluetooth_add_multicast(struct net_device *_device, const sockaddr *_address)
|
||||
bluetooth_add_multicast(struct net_device* _device, const sockaddr* _address)
|
||||
{
|
||||
bluetooth_device* device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld\n",device->index);
|
||||
|
||||
@ -239,9 +328,9 @@ bluetooth_add_multicast(struct net_device *_device, const sockaddr *_address)
|
||||
}
|
||||
|
||||
status_t
|
||||
bluetooth_remove_multicast(struct net_device *_device, const sockaddr *_address)
|
||||
bluetooth_remove_multicast(struct net_device* _device, const sockaddr* _address)
|
||||
{
|
||||
bluetooth_device* device = (bluetooth_device *)_device;
|
||||
bluetooth_device* device = (bluetooth_device*)_device;
|
||||
|
||||
debugf("index %ld\n",device->index);
|
||||
|
||||
@ -259,9 +348,14 @@ dump_bluetooth_devices(int argc, char** argv)
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
device = iterator.Next();
|
||||
kprintf("\tname=%s index=%#lx\n",device->name, device->index);
|
||||
kprintf("\tname=%s index=%#lx @%p\n",device->name, device->index, device);
|
||||
DoublyLinkedList<HciConnection>::Iterator connIterator = device->sConnectionList.GetIterator();
|
||||
while (connIterator.HasNext()) {
|
||||
HciConnection* conn = connIterator.Next();
|
||||
kprintf("\t\t handle=%#x destination=%s @%p\n", conn->handle, bdaddrUtils::ToString(conn->destination), conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -271,14 +365,23 @@ bluetooth_std_ops(int32 op, ...)
|
||||
{
|
||||
|
||||
flowf("\n");
|
||||
|
||||
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
status_t status = get_module(NET_STACK_MODULE_NAME,
|
||||
(module_info **)&sStackModule);
|
||||
if (status < B_OK)
|
||||
status_t status;
|
||||
|
||||
status = get_module(NET_STACK_MODULE_NAME,(module_info**)&sStackModule);
|
||||
if (status < B_OK) {
|
||||
flowf("problem getting netstack module\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = get_module(BT_CORE_DATA_MODULE_NAME,(module_info**)&btCoreData);
|
||||
if (status < B_OK) {
|
||||
flowf("problem getting datacore\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
new (&sDeviceList) DoublyLinkedList<bluetooth_device>;
|
||||
// static C++ objects are not initialized in the module startup
|
||||
@ -286,11 +389,15 @@ bluetooth_std_ops(int32 op, ...)
|
||||
sLinkChangeSemaphore = create_sem(0, "bt sem");
|
||||
if (sLinkChangeSemaphore < B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
flowf("sem failed\n");
|
||||
return sLinkChangeSemaphore;
|
||||
}
|
||||
|
||||
mutex_init(&sListLock, "bluetooth devices");
|
||||
|
||||
//status = InitializeAclConnectionThread();
|
||||
debugf("Connection Thread error=%lx\n", status);
|
||||
|
||||
add_debugger_command("btLocalDevices", &dump_bluetooth_devices, "Lists Bluetooth LocalDevices registered in the Stack");
|
||||
|
||||
return B_OK;
|
||||
@ -302,9 +409,10 @@ bluetooth_std_ops(int32 op, ...)
|
||||
|
||||
mutex_destroy(&sListLock);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
|
||||
put_module(BT_CORE_DATA_MODULE_NAME);
|
||||
remove_debugger_command("btLocalDevices", &dump_bluetooth_devices);
|
||||
|
||||
//status_t status = QuitAclConnectionThread();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -316,8 +424,8 @@ bluetooth_std_ops(int32 op, ...)
|
||||
|
||||
net_device_module_info sBluetoothModule = {
|
||||
{
|
||||
"network/devices/bluetooth/v1",
|
||||
0,
|
||||
NET_BLUETOOTH_DEVICE_NAME,
|
||||
B_KEEP_LOADED,
|
||||
bluetooth_std_ops
|
||||
},
|
||||
bluetooth_init,
|
||||
@ -334,8 +442,9 @@ net_device_module_info sBluetoothModule = {
|
||||
bluetooth_remove_multicast,
|
||||
};
|
||||
|
||||
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sBluetoothModule,
|
||||
|
||||
NULL
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user