*Incorrect endianess handling from bdaddr at parsing from string.
*Remove bluetooth_util deprecated header *Issue conn_req for socket connect() call git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37132 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,9 +7,9 @@
|
||||
#define _BDADDR_UTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
|
||||
namespace Bluetooth {
|
||||
|
||||
@@ -34,12 +34,17 @@ public:
|
||||
}
|
||||
|
||||
|
||||
static bool Compare(bdaddr_t *ba1, bdaddr_t *ba2)
|
||||
static bool Compare(const bdaddr_t* ba1, const bdaddr_t* ba2)
|
||||
{
|
||||
return (bacmp(ba1, ba2) == 0);
|
||||
return (memcmp(ba1, ba2, sizeof(bdaddr_t)) == 0);
|
||||
}
|
||||
|
||||
|
||||
static void Copy(bdaddr_t* dst, const bdaddr_t* src)
|
||||
{
|
||||
memcpy(dst, src, sizeof(bdaddr_t));
|
||||
}
|
||||
|
||||
static char* ToString(const bdaddr_t bdaddr)
|
||||
{
|
||||
// TODO: not safe
|
||||
@@ -58,7 +63,7 @@ public:
|
||||
|
||||
if (addr != NULL) {
|
||||
size_t count = sscanf(addr, "%2X:%2X:%2X:%2X:%2X:%2X",
|
||||
&b0, &b1, &b2, &b3, &b4, &b5);
|
||||
&b5, &b4, &b3, &b2, &b1, &b0);
|
||||
|
||||
if (count == 6)
|
||||
return ((bdaddr_t) {{b0, b1, b2, b3, b4, b5}});
|
||||
@@ -71,6 +76,7 @@ public:
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef _BT_USE_EXPLICIT_NAMESPACE
|
||||
using Bluetooth::bdaddrUtils;
|
||||
#endif
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BLUETOOTH_UTIL_H
|
||||
#define _BLUETOOTH_UTIL_H
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <string.h>
|
||||
|
||||
/* BD Address management */
|
||||
static inline int bacmp(bdaddr_t* ba1, bdaddr_t* ba2)
|
||||
{
|
||||
return memcmp(ba1, ba2, sizeof(bdaddr_t));
|
||||
}
|
||||
|
||||
|
||||
static inline void bacpy(bdaddr_t* dst, bdaddr_t* src)
|
||||
{
|
||||
memcpy(dst, src, sizeof(bdaddr_t));
|
||||
}
|
||||
|
||||
|
||||
static inline void baswap(bdaddr_t* dst, bdaddr_t* src)
|
||||
{
|
||||
register uint8* d = (uint8*)dst;
|
||||
register uint8* s = (uint8*)src;
|
||||
register int i;
|
||||
|
||||
for(i = 0; i < 6; i++)
|
||||
d[i] = s[5 - i];
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Bluetooth Errors */
|
||||
static inline char* btstrerror(int error_code)
|
||||
{
|
||||
return "Unknown Bluetooth error";
|
||||
}
|
||||
|
||||
|
||||
#endif // _BLUETOOTH_UTIL_H
|
||||
@@ -143,7 +143,7 @@ struct bluetooth_core_data_module_info {
|
||||
// status_t (*RemoveConnection)(bdaddr_t destination, hci_id hid);
|
||||
status_t (*RemoveConnection)(uint16 handle, hci_id hid);
|
||||
|
||||
hci_id (*RouteConnection)(bdaddr_t* destination);
|
||||
hci_id (*RouteConnection)(const bdaddr_t* destination);
|
||||
|
||||
void (*SetAclBuffer)(struct HciConnection* conn,
|
||||
net_buffer* nbuf);
|
||||
@@ -155,7 +155,7 @@ struct bluetooth_core_data_module_info {
|
||||
bool (*AclOverFlowed)(struct HciConnection* conn);
|
||||
|
||||
struct HciConnection* (*ConnectionByHandle)(uint16 handle, hci_id hid);
|
||||
struct HciConnection* (*ConnectionByDestination)(bdaddr_t* destination,
|
||||
struct HciConnection* (*ConnectionByDestination)(const bdaddr_t* destination,
|
||||
hci_id hid);
|
||||
|
||||
struct L2capChannel* (*AddChannel)(struct HciConnection* conn,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
|
||||
#define BT_DEBUG_THIS_MODULE
|
||||
#define SUBMODULE_NAME "Connection"
|
||||
@@ -49,19 +49,19 @@ AddConnection(uint16 handle, int type, bdaddr_t* dst, hci_id hid)
|
||||
if (conn == NULL)
|
||||
goto bail;
|
||||
|
||||
//memset(conn, 0, sizeof(HciConnection));
|
||||
// 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;
|
||||
bdaddrUtils::Copy(&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);
|
||||
@@ -76,11 +76,14 @@ RemoveConnection(bdaddr_t* destination, hci_id hid)
|
||||
{
|
||||
HciConnection* conn;
|
||||
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator
|
||||
= sConnectionList.GetIterator();
|
||||
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
conn = iterator.Next();
|
||||
if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
|
||||
if (conn->Hid == hid
|
||||
&& bdaddrUtils::Compare(&conn->destination, destination)) {
|
||||
|
||||
// if the device is still part of the list, remove it
|
||||
if (conn->GetDoublyLinkedListLink()->next != NULL
|
||||
@@ -102,7 +105,8 @@ RemoveConnection(uint16 handle, hci_id hid)
|
||||
{
|
||||
HciConnection* conn;
|
||||
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator
|
||||
= sConnectionList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
conn = iterator.Next();
|
||||
@@ -125,15 +129,16 @@ RemoveConnection(uint16 handle, hci_id hid)
|
||||
|
||||
|
||||
hci_id
|
||||
RouteConnection(bdaddr_t* destination) {
|
||||
RouteConnection(const bdaddr_t* destination) {
|
||||
|
||||
HciConnection* conn;
|
||||
HciConnection* conn;
|
||||
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator
|
||||
= sConnectionList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
conn = iterator.Next();
|
||||
if (bacmp(&conn->destination, destination)==0) {
|
||||
if (bdaddrUtils::Compare(&conn->destination, destination)) {
|
||||
return conn->Hid;
|
||||
}
|
||||
}
|
||||
@@ -147,11 +152,12 @@ ConnectionByHandle(uint16 handle, hci_id hid)
|
||||
{
|
||||
HciConnection* conn;
|
||||
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator
|
||||
= sConnectionList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
conn = iterator.Next();
|
||||
if (conn->Hid == hid && conn->handle==handle) {
|
||||
if (conn->Hid == hid && conn->handle == handle) {
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@@ -161,15 +167,17 @@ ConnectionByHandle(uint16 handle, hci_id hid)
|
||||
|
||||
|
||||
HciConnection*
|
||||
ConnectionByDestination(bdaddr_t* destination, hci_id hid)
|
||||
ConnectionByDestination(const bdaddr_t* destination, hci_id hid)
|
||||
{
|
||||
HciConnection* conn;
|
||||
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator();
|
||||
DoublyLinkedList<HciConnection>::Iterator iterator
|
||||
= sConnectionList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
conn = iterator.Next();
|
||||
if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) {
|
||||
if (conn->Hid == hid
|
||||
&& bdaddrUtils::Compare(&conn->destination, destination)) {
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@@ -177,6 +185,7 @@ ConnectionByDestination(bdaddr_t* destination, hci_id hid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark - ACL helper funcs
|
||||
#endif
|
||||
@@ -215,6 +224,7 @@ AclOverFlowed(HciConnection* conn)
|
||||
return conn->currentRxExpectedLength < 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark - private funcs
|
||||
#endif
|
||||
|
||||
@@ -15,14 +15,16 @@
|
||||
extern DoublyLinkedList<HciConnection> sConnectionList;
|
||||
|
||||
HciConnection* ConnectionByHandle(uint16 handle, hci_id hid);
|
||||
HciConnection* ConnectionByDestination(bdaddr_t *destination, hci_id hid);
|
||||
HciConnection* ConnectionByDestination(const 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);
|
||||
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);
|
||||
hci_id RouteConnection(const bdaddr_t* destination);
|
||||
|
||||
void SetAclBuffer(HciConnection* conn, net_buffer* nbuf);
|
||||
void SetAclExpectedSize(HciConnection* conn, size_t size);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#include "snet_buffer.h"
|
||||
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
|
||||
#define BT_DEBUG_THIS_MODULE
|
||||
#define SUBMODULE_NAME BLUETOOTH_DEVICE_DEVFS_NAME
|
||||
#define SUBMODULE_COLOR 35
|
||||
@@ -278,7 +276,7 @@ device_added(usb_device* dev, void** cookie)
|
||||
/*
|
||||
else if ( desc->vendor_id == YOUR_VENDOR_HERE
|
||||
&& desc->product_id == YOUR_PRODUCT_HERE ) {
|
||||
YOUR_SPECIAL_FLAGS_HERE
|
||||
YOUR_SPECIAL_FLAGS_HERE
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -10,8 +10,9 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
#include <bluetooth/L2CAP/btL2CAP.h>
|
||||
|
||||
#define BT_DEBUG_THIS_MODULE
|
||||
#define MODULE_NAME "l2cap"
|
||||
#define SUBMODULE_NAME "Endpoint"
|
||||
@@ -100,18 +101,18 @@ L2capEndpoint::Close()
|
||||
|
||||
if (fAcceptSemaphore != -1) {
|
||||
debugf("server socket not handling any channel %p\n", this);
|
||||
|
||||
|
||||
delete_sem(fAcceptSemaphore);
|
||||
// TODO: Clean needed stuff
|
||||
// Unbind?
|
||||
return B_OK;
|
||||
|
||||
|
||||
} else {
|
||||
// Client endpoint
|
||||
if (fState == CLOSING) {
|
||||
debugf("Already closed by peer %p\n", this);
|
||||
// TODO: Clean needed stuff
|
||||
|
||||
|
||||
return B_OK;
|
||||
} else {
|
||||
// Issue Disconnection request over the channel
|
||||
@@ -119,7 +120,7 @@ L2capEndpoint::Close()
|
||||
return l2cap_upper_dis_req(fChannel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -133,16 +134,19 @@ L2capEndpoint::Free()
|
||||
|
||||
|
||||
status_t
|
||||
L2capEndpoint::Bind(const struct sockaddr *_address)
|
||||
L2capEndpoint::Bind(const struct sockaddr* _address)
|
||||
{
|
||||
if (_address == NULL)
|
||||
const sockaddr_l2cap* address
|
||||
= reinterpret_cast<const sockaddr_l2cap*>(_address);
|
||||
|
||||
if (_address == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
if (_address->sa_family != AF_BLUETOOTH )
|
||||
|
||||
if (address->l2cap_family != AF_BLUETOOTH )
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
//if (_address->sa_len != sizeof(struct sockaddr_l2cap))
|
||||
// return EAFNOSUPPORT;
|
||||
if (address->l2cap_len != sizeof(struct sockaddr_l2cap))
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
// TODO: Check if that PSM is already bound
|
||||
// return EADDRINUSE;
|
||||
@@ -150,16 +154,18 @@ L2capEndpoint::Bind(const struct sockaddr *_address)
|
||||
// TODO: Check if the PSM is valid, check assigned numbers document for valid
|
||||
// psm available to applications.
|
||||
// All PSM values shall be ODD, that is, the least significant bit of the least
|
||||
// significant octet must be ’1’. Also, all PSM values shall have the least
|
||||
// significant bit of the most significant octet equal to ’0’. This allows the
|
||||
// PSM field to be extended beyond 16 bits.
|
||||
if ((((struct sockaddr_l2cap*)_address)->l2cap_psm & 1) == 0)
|
||||
// significant octet must be ’1’. Also, all PSM values shall have the least
|
||||
// significant bit of the most significant octet equal to ’0’. This allows
|
||||
// the PSM field to be extended beyond 16 bits.
|
||||
if ((address->l2cap_psm & 1) == 0)
|
||||
return B_ERROR;
|
||||
|
||||
flowf("\n")
|
||||
|
||||
memcpy(&socket->address, _address, sizeof(struct sockaddr_l2cap));
|
||||
socket->address.ss_len = sizeof(struct sockaddr_l2cap);
|
||||
|
||||
debugf("for %s psm=%d\n", bdaddrUtils::ToString(address->l2cap_bdaddr),
|
||||
address->l2cap_psm);
|
||||
|
||||
fState = BOUND;
|
||||
|
||||
return B_OK;
|
||||
@@ -179,7 +185,7 @@ status_t
|
||||
L2capEndpoint::Listen(int backlog)
|
||||
{
|
||||
debugf("[%ld] %p\n", find_thread(NULL), this);
|
||||
|
||||
|
||||
if (fState != BOUND) {
|
||||
debugf("Invalid State %p\n", this);
|
||||
return B_BAD_VALUE;
|
||||
@@ -200,32 +206,66 @@ L2capEndpoint::Listen(int backlog)
|
||||
|
||||
|
||||
status_t
|
||||
L2capEndpoint::Connect(const struct sockaddr *_address)
|
||||
L2capEndpoint::Connect(const struct sockaddr* _address)
|
||||
{
|
||||
if (_address->sa_family != AF_BLUETOOTH)
|
||||
return EAFNOSUPPORT;
|
||||
const sockaddr_l2cap* address
|
||||
= reinterpret_cast<const sockaddr_l2cap*>(_address);
|
||||
|
||||
debugf("[%ld] %p->L2capEndpoint::Connect(\"%s\")\n", find_thread(NULL), this,
|
||||
ConstSocketAddress(&gL2cap4AddressModule, _address).AsString().Data());
|
||||
if (address->l2cap_len != sizeof(*address))
|
||||
return EINVAL;
|
||||
|
||||
const sockaddr_l2cap* address = (const sockaddr_l2cap*)_address;
|
||||
// Check for any specific status?
|
||||
if (fState == CONNECTING) {
|
||||
return EINPROGRESS;
|
||||
}
|
||||
|
||||
/**/
|
||||
TOUCH(address);
|
||||
// TODO: should not be in the BOUND status first?
|
||||
|
||||
return B_OK;
|
||||
debugf("[%ld] %p->L2capEndpoint::Connect(\"%s\")\n", find_thread(NULL),
|
||||
this, ConstSocketAddress(&gL2cap4AddressModule, _address)
|
||||
.AsString().Data());
|
||||
|
||||
// TODO: If we were bound to a specific source address
|
||||
|
||||
// Route, we must find a Connection descriptor with address->l2cap_address
|
||||
hci_id hid = btCoreData->RouteConnection(&address->l2cap_bdaddr);
|
||||
|
||||
debugf("%lx for route %s\n", hid,
|
||||
bdaddrUtils::ToString(address->l2cap_bdaddr));
|
||||
|
||||
if (hid > 0) {
|
||||
HciConnection* connection = btCoreData->ConnectionByDestination(
|
||||
&address->l2cap_bdaddr, hid);
|
||||
|
||||
L2capChannel* channel = btCoreData->AddChannel(connection,
|
||||
address->l2cap_psm);
|
||||
|
||||
if (channel == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
// Send connection request
|
||||
if (l2cap_upper_con_req(channel) == B_OK) {
|
||||
fState = CONNECTING;
|
||||
|
||||
return B_OK;
|
||||
} else {
|
||||
return ECONNREFUSED;
|
||||
}
|
||||
}
|
||||
|
||||
return ENETUNREACH;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
L2capEndpoint::Accept(net_socket **_acceptedSocket)
|
||||
L2capEndpoint::Accept(net_socket** _acceptedSocket)
|
||||
{
|
||||
debugf("[%ld]\n", find_thread(NULL));
|
||||
|
||||
// MutexLocker locker(fLock);
|
||||
|
||||
status_t status;
|
||||
bigtime_t timeout = absolute_timeout(300*1000*1000);
|
||||
bigtime_t timeout = absolute_timeout(300 * 1000 * 1000);
|
||||
|
||||
do {
|
||||
// locker.Unlock();
|
||||
@@ -238,18 +278,18 @@ L2capEndpoint::Accept(net_socket **_acceptedSocket)
|
||||
|
||||
// locker.Lock();
|
||||
status = gSocketModule->dequeue_connected(socket, _acceptedSocket);
|
||||
|
||||
|
||||
if (status != B_OK) {
|
||||
debugf("Could not dequeue socket %s\n", strerror(status));
|
||||
} else {
|
||||
|
||||
|
||||
((L2capEndpoint*)((*_acceptedSocket)->first_protocol))->fState = ESTABLISHED;
|
||||
// unassign any channel for the parent endpoint
|
||||
fChannel = NULL;
|
||||
// we are listening again
|
||||
fState = LISTEN;
|
||||
}
|
||||
|
||||
|
||||
} while (status != B_OK);
|
||||
|
||||
return status;
|
||||
@@ -257,8 +297,8 @@ L2capEndpoint::Accept(net_socket **_acceptedSocket)
|
||||
|
||||
|
||||
ssize_t
|
||||
L2capEndpoint::Send(const iovec *vecs, size_t vecCount,
|
||||
ancillary_data_container *ancillaryData)
|
||||
L2capEndpoint::Send(const iovec* vecs, size_t vecCount,
|
||||
ancillary_data_container* ancillaryData)
|
||||
{
|
||||
debugf("[%ld] %p Send(%p, %ld, %p)\n", find_thread(NULL),
|
||||
this, vecs, vecCount, ancillaryData);
|
||||
@@ -268,9 +308,9 @@ L2capEndpoint::Send(const iovec *vecs, size_t vecCount,
|
||||
|
||||
|
||||
ssize_t
|
||||
L2capEndpoint::Receive(const iovec *vecs, size_t vecCount,
|
||||
ancillary_data_container **_ancillaryData, struct sockaddr *_address,
|
||||
socklen_t *_addressLength)
|
||||
L2capEndpoint::Receive(const iovec* vecs, size_t vecCount,
|
||||
ancillary_data_container** _ancillaryData, struct sockaddr* _address,
|
||||
socklen_t* _addressLength)
|
||||
{
|
||||
debugf("[%ld] %p Receive(%p, %ld)\n", find_thread(NULL),
|
||||
this, vecs, vecCount);
|
||||
@@ -292,7 +332,7 @@ L2capEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer)
|
||||
if (fState != ESTABLISHED) {
|
||||
debugf("Invalid State %p\n", this);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return gStackModule->fifo_dequeue_buffer(&fReceivingFifo, flags,
|
||||
B_INFINITE_TIMEOUT, _buffer);
|
||||
@@ -322,7 +362,8 @@ L2capEndpoint::ForPsm(uint16 psm)
|
||||
{
|
||||
L2capEndpoint* endpoint;
|
||||
|
||||
DoublyLinkedList<L2capEndpoint>::Iterator iterator = EndpointList.GetIterator();
|
||||
DoublyLinkedList<L2capEndpoint>::Iterator iterator
|
||||
= EndpointList.GetIterator();
|
||||
|
||||
while (iterator.HasNext()) {
|
||||
|
||||
@@ -346,25 +387,26 @@ L2capEndpoint::BindToChannel(L2capChannel* channel)
|
||||
if (error != B_OK) {
|
||||
debugf("Could not spawn child for Endpoint %p\n", this);
|
||||
// TODO: Handle situation
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
L2capEndpoint* endpoint = (L2capEndpoint*)newSocket->first_protocol;
|
||||
|
||||
|
||||
endpoint->fChannel = channel;
|
||||
endpoint->fPeerEndpoint = this;
|
||||
|
||||
|
||||
channel->endpoint = endpoint;
|
||||
|
||||
debugf("new socket %p/e->%p from parent %p/e->%p\n", newSocket, endpoint, socket, this);
|
||||
debugf("new socket %p/e->%p from parent %p/e->%p\n",
|
||||
newSocket, endpoint, socket, this);
|
||||
|
||||
// Provide the channel the configuration set by the user socket
|
||||
channel->configuration = &fConfiguration;
|
||||
|
||||
|
||||
// It might be used keep the last negotiated channel
|
||||
// fChannel = channel;
|
||||
|
||||
debugf("New endpoint %p for psm %d, schannel %x dchannel %x\n", endpoint,
|
||||
debugf("New endpoint %p for psm %d, schannel %x dchannel %x\n", endpoint,
|
||||
channel->psm, channel->scid, channel->dcid);
|
||||
}
|
||||
|
||||
@@ -372,16 +414,16 @@ L2capEndpoint::BindToChannel(L2capChannel* channel)
|
||||
status_t
|
||||
L2capEndpoint::MarkEstablished()
|
||||
{
|
||||
debugf("Endpoint %p for psm %d, schannel %x dchannel %x\n", this,
|
||||
fChannel->psm, fChannel->scid, fChannel->dcid);
|
||||
|
||||
debugf("Endpoint %p for psm %d, schannel %x dchannel %x\n", this,
|
||||
fChannel->psm, fChannel->scid, fChannel->dcid);
|
||||
|
||||
status_t error = gSocketModule->set_connected(socket);
|
||||
if (error == B_OK) {
|
||||
release_sem(fPeerEndpoint->fAcceptSemaphore);
|
||||
} else {
|
||||
debugf("Could not set child Endpoint %p %s\n", this, strerror(error));
|
||||
}
|
||||
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -391,7 +433,7 @@ L2capEndpoint::MarkClosed()
|
||||
{
|
||||
flowf("\n");
|
||||
fState = CLOSED;
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
extern net_stack_module_info* gStackModule;
|
||||
|
||||
class L2capEndpoint : public net_protocol,
|
||||
public ProtocolSocket,
|
||||
public DoublyLinkedListLinkImpl<L2capEndpoint> {
|
||||
class L2capEndpoint : public net_protocol,
|
||||
public ProtocolSocket,
|
||||
public DoublyLinkedListLinkImpl<L2capEndpoint> {
|
||||
|
||||
public:
|
||||
L2capEndpoint(net_socket* socket);
|
||||
@@ -44,17 +44,17 @@ public:
|
||||
mutex_unlock(&fLock);
|
||||
}
|
||||
|
||||
status_t Bind(const struct sockaddr *_address);
|
||||
status_t Bind(const struct sockaddr* _address);
|
||||
status_t Unbind();
|
||||
status_t Listen(int backlog);
|
||||
status_t Connect(const struct sockaddr *address);
|
||||
status_t Accept(net_socket **_acceptedSocket);
|
||||
status_t Connect(const struct sockaddr* address);
|
||||
status_t Accept(net_socket** _acceptedSocket);
|
||||
|
||||
ssize_t Send(const iovec *vecs, size_t vecCount,
|
||||
ancillary_data_container *ancillaryData);
|
||||
ssize_t Receive(const iovec *vecs, size_t vecCount,
|
||||
ancillary_data_container **_ancillaryData,
|
||||
struct sockaddr *_address, socklen_t *_addressLength);
|
||||
ssize_t Send(const iovec* vecs, size_t vecCount,
|
||||
ancillary_data_container* ancillaryData);
|
||||
ssize_t Receive(const iovec* vecs, size_t vecCount,
|
||||
ancillary_data_container** _ancillaryData,
|
||||
struct sockaddr* _address, socklen_t* _addressLength);
|
||||
|
||||
ssize_t ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer);
|
||||
ssize_t Sendable();
|
||||
@@ -68,24 +68,25 @@ public:
|
||||
void BindToChannel(L2capChannel* channel);
|
||||
status_t MarkEstablished();
|
||||
status_t MarkClosed();
|
||||
|
||||
|
||||
static L2capEndpoint* ForPsm(uint16 psm);
|
||||
|
||||
|
||||
bool RequiresConfiguration()
|
||||
{
|
||||
return fConfigurationSet;
|
||||
}
|
||||
|
||||
ChannelConfiguration fConfiguration;
|
||||
|
||||
ChannelConfiguration fConfiguration;
|
||||
bool fConfigurationSet;
|
||||
net_fifo fReceivingFifo;
|
||||
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
// establishing a connection
|
||||
CLOSED,
|
||||
BOUND,
|
||||
LISTEN,
|
||||
CONNECTING,
|
||||
ESTABLISHED,
|
||||
|
||||
// peer closes the connection
|
||||
|
||||
@@ -62,13 +62,12 @@ static struct net_domain* sDomain;
|
||||
net_protocol*
|
||||
l2cap_init_protocol(net_socket* socket)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket);
|
||||
if (protocol == NULL)
|
||||
return NULL;
|
||||
|
||||
EndpointList.Add(protocol);
|
||||
debugf("Prococol created %p\n", protocol);
|
||||
|
||||
return protocol;
|
||||
}
|
||||
@@ -78,12 +77,12 @@ status_t
|
||||
l2cap_uninit_protocol(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol);
|
||||
|
||||
|
||||
// TODO: Some more checkins / uninit
|
||||
EndpointList.Remove(endpoint);
|
||||
|
||||
|
||||
delete endpoint;
|
||||
|
||||
return B_OK;
|
||||
@@ -94,7 +93,7 @@ status_t
|
||||
l2cap_open(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -103,7 +102,7 @@ status_t
|
||||
l2cap_close(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ status_t
|
||||
l2cap_free(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -120,9 +119,16 @@ l2cap_free(net_protocol* protocol)
|
||||
status_t
|
||||
l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
return B_ERROR;
|
||||
debugf("from %p, with %p\n", protocol, address);
|
||||
|
||||
if (address == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (address->sa_family != AF_BLUETOOTH)
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
|
||||
return ((L2capEndpoint*)protocol)->Connect(address);;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,9 +144,8 @@ l2cap_control(net_protocol* protocol, int level, int option, void* value,
|
||||
size_t* _length)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
/* return protocol->next->module->control(protocol->next, level, option, value, _length); */
|
||||
return B_OK;
|
||||
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,9 +154,8 @@ l2cap_getsockopt(net_protocol* protocol, int level, int option,
|
||||
void* value, int* length)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
/* return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */
|
||||
return B_OK;
|
||||
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +167,6 @@ l2cap_setsockopt(net_protocol* protocol, int level, int option,
|
||||
|
||||
((L2capEndpoint*)protocol)->fConfigurationSet = true;
|
||||
|
||||
/* return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -171,6 +174,8 @@ l2cap_setsockopt(net_protocol* protocol, int level, int option,
|
||||
status_t
|
||||
l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
|
||||
{
|
||||
debugf("from %p, with %p\n", protocol, address);
|
||||
|
||||
return ((L2capEndpoint*)protocol)->Bind(address);
|
||||
}
|
||||
|
||||
@@ -179,7 +184,7 @@ status_t
|
||||
l2cap_unbind(net_protocol* protocol, struct sockaddr* address)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -195,7 +200,7 @@ status_t
|
||||
l2cap_shutdown(net_protocol* protocol, int direction)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -204,7 +209,7 @@ status_t
|
||||
l2cap_send_data(net_protocol* protocol, net_buffer* buffer)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return protocol->next->module->send_data(protocol->next, buffer);
|
||||
}
|
||||
|
||||
@@ -214,7 +219,7 @@ l2cap_send_routed_data(net_protocol* protocol, struct net_route* route,
|
||||
net_buffer* buffer)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return protocol->next->module->send_routed_data(protocol->next, route, buffer);
|
||||
}
|
||||
|
||||
@@ -223,7 +228,7 @@ ssize_t
|
||||
l2cap_send_avail(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -242,7 +247,7 @@ ssize_t
|
||||
l2cap_read_avail(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -251,7 +256,7 @@ struct net_domain*
|
||||
l2cap_get_domain(net_protocol* protocol)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return sDomain;
|
||||
}
|
||||
|
||||
@@ -260,7 +265,7 @@ size_t
|
||||
l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return protocol->next->module->get_mtu(protocol->next, address);
|
||||
}
|
||||
|
||||
@@ -270,7 +275,7 @@ l2cap_receive_data(net_buffer* buffer)
|
||||
{
|
||||
HciConnection* conn = (HciConnection*)buffer;
|
||||
debugf("received some data, buffer length %lu\n", conn->currentRxPacket->size);
|
||||
|
||||
|
||||
l2cap_receive(conn, conn->currentRxPacket);
|
||||
|
||||
return B_OK;
|
||||
@@ -281,7 +286,7 @@ status_t
|
||||
l2cap_error(uint32 code, net_buffer* data)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -291,7 +296,7 @@ l2cap_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
|
||||
void* errorData)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -303,31 +308,30 @@ l2cap_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
|
||||
static status_t
|
||||
l2cap_std_ops(int32 op, ...)
|
||||
{
|
||||
status_t error;
|
||||
status_t error;
|
||||
|
||||
flowf("\n");
|
||||
|
||||
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
error = gStackModule->register_domain_protocols(AF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
|
||||
error = gStackModule->register_domain_protocols(AF_BLUETOOTH,
|
||||
SOCK_STREAM, BLUETOOTH_PROTO_L2CAP,
|
||||
"network/protocols/l2cap/v1",
|
||||
NULL);
|
||||
if (error != B_OK) {
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = gStackModule->register_domain_receiving_protocol(AF_BLUETOOTH, BLUETOOTH_PROTO_L2CAP,
|
||||
error = gStackModule->register_domain_receiving_protocol(AF_BLUETOOTH,
|
||||
BLUETOOTH_PROTO_L2CAP,
|
||||
"network/protocols/l2cap/v1");
|
||||
if (error != B_OK) {
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule,
|
||||
&gL2cap4AddressModule, &sDomain);
|
||||
if (error != B_OK) {
|
||||
&gL2cap4AddressModule, &sDomain);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
new (&EndpointList) DoublyLinkedList<L2capEndpoint>;
|
||||
|
||||
@@ -337,10 +341,10 @@ l2cap_std_ops(int32 op, ...)
|
||||
}
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
|
||||
|
||||
error = QuitConnectionPurgeThread();
|
||||
gStackModule->unregister_domain(sDomain);
|
||||
|
||||
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include <net_datalink.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
@@ -18,15 +17,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
#include <bluetooth/bdaddrUtils.h>
|
||||
#include <bluetooth/L2CAP/btL2CAP.h>
|
||||
|
||||
#define L2CAP_CHECKSUM(address) (address.b[0]+\
|
||||
address.b[1]+\
|
||||
address.b[2]+\
|
||||
address.b[3]+\
|
||||
address.b[4]+\
|
||||
address.b[5])
|
||||
address.b[1]+\
|
||||
address.b[2]+\
|
||||
address.b[3]+\
|
||||
address.b[4]+\
|
||||
address.b[5])
|
||||
|
||||
/*!
|
||||
Routing utility function: copies address \a from into a new address
|
||||
@@ -75,7 +74,8 @@ l2cap_copy_address(const sockaddr *from, sockaddr **to,
|
||||
\return B_BAD_VALUE if \a address or \a mask is NULL
|
||||
*/
|
||||
static status_t
|
||||
l2cap_mask_address(const sockaddr *address, const sockaddr *mask, sockaddr *result)
|
||||
l2cap_mask_address(const sockaddr *address, const sockaddr *mask,
|
||||
sockaddr *result)
|
||||
{
|
||||
if (address == NULL || result == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -96,10 +96,12 @@ l2cap_is_empty_address(const sockaddr *address, bool checkPort)
|
||||
if (address == NULL || address->sa_len == 0)
|
||||
return true;
|
||||
|
||||
return ((bacmp(&((sockaddr_l2cap *)address)->l2cap_bdaddr, BDADDR_NULL)==0)
|
||||
&& (!checkPort || ((sockaddr_l2cap *)address)->l2cap_psm == 0) );
|
||||
return ((bdaddrUtils::Compare(
|
||||
&((const sockaddr_l2cap *)address)->l2cap_bdaddr, BDADDR_NULL)==0)
|
||||
&& (!checkPort || ((sockaddr_l2cap *)address)->l2cap_psm == 0));
|
||||
}
|
||||
|
||||
|
||||
/*! Checks if the given \a address is L2CAP address.
|
||||
\return false if \a address is NULL, or with family different from AF_BLUETOOTH
|
||||
true if it has AF_BLUETOOTH address family
|
||||
@@ -127,8 +129,8 @@ l2cap_equal_addresses(const sockaddr *a, const sockaddr *b)
|
||||
if (a == NULL && b != NULL)
|
||||
return l2cap_is_empty_address(b, false);
|
||||
|
||||
return (bacmp(&((sockaddr_l2cap*)a)->l2cap_bdaddr,
|
||||
&((sockaddr_l2cap*)b)->l2cap_bdaddr)==0);
|
||||
return bdaddrUtils::Compare(&((const sockaddr_l2cap*)a)->l2cap_bdaddr,
|
||||
&((sockaddr_l2cap*)b)->l2cap_bdaddr);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +162,8 @@ l2cap_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
|
||||
if (a == NULL && b != NULL)
|
||||
return l2cap_is_empty_address(b, true);
|
||||
|
||||
return (bacmp(&((sockaddr_l2cap*)a)->l2cap_bdaddr,&((sockaddr_l2cap *)b)->l2cap_bdaddr)==0)
|
||||
return (bdaddrUtils::Compare(&((const sockaddr_l2cap *)a)->l2cap_bdaddr,
|
||||
&((const sockaddr_l2cap *)b)->l2cap_bdaddr))
|
||||
&& ((sockaddr_l2cap *)a)->l2cap_psm == ((sockaddr_l2cap *)b)->l2cap_psm;
|
||||
}
|
||||
|
||||
@@ -232,15 +235,18 @@ l2cap_print_address_buffer(const sockaddr *_address, char *buffer,
|
||||
if (address == NULL)
|
||||
strlcpy(buffer, "<none>", bufferSize);
|
||||
else {
|
||||
bdaddr_t addr = address->l2cap_bdaddr;
|
||||
bdaddr_t addr = address->l2cap_bdaddr;
|
||||
if (printPort) {
|
||||
snprintf(buffer, bufferSize, "%2X:%2X:%2X:%2X:%2X:%2X|%u", addr.b[0],
|
||||
addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5],address->l2cap_psm);
|
||||
}
|
||||
snprintf(buffer, bufferSize,
|
||||
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X|%u", addr.b[0],
|
||||
addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5],
|
||||
address->l2cap_psm);
|
||||
}
|
||||
else {
|
||||
snprintf(buffer, bufferSize, "%2X:%2X:%2X:%2X:%2X:%2X",addr.b[0],
|
||||
addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5]);
|
||||
}
|
||||
snprintf(buffer, bufferSize,
|
||||
"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",addr.b[0],
|
||||
addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5]);
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@@ -333,7 +339,7 @@ l2cap_update_to(sockaddr *_address, const sockaddr *_from)
|
||||
if (address->l2cap_psm == 0)
|
||||
address->l2cap_psm = from->l2cap_psm;
|
||||
|
||||
if (bacmp(&address->l2cap_bdaddr, BDADDR_BROADCAST)==0)
|
||||
if (bdaddrUtils::Compare(&address->l2cap_bdaddr, BDADDR_BROADCAST))
|
||||
address->l2cap_bdaddr = from->l2cap_bdaddr;
|
||||
|
||||
return B_OK;
|
||||
@@ -378,7 +384,8 @@ l2cap_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress)
|
||||
const sockaddr_l2cap *peer = (const sockaddr_l2cap *)peerAddress;
|
||||
|
||||
return ((our ? our->l2cap_psm : 0) | ((peer ? peer->l2cap_psm : 0) << 16))
|
||||
^ (our ? L2CAP_CHECKSUM(our->l2cap_bdaddr) : 0) ^ (peer ? L2CAP_CHECKSUM(peer->l2cap_bdaddr) : 0);
|
||||
^ (our ? L2CAP_CHECKSUM(our->l2cap_bdaddr) : 0)
|
||||
^ (peer ? L2CAP_CHECKSUM(peer->l2cap_bdaddr) : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ status_t
|
||||
l2cap_process_signal_cmd(HciConnection* conn, net_buffer* buffer)
|
||||
{
|
||||
net_buffer* m = buffer;
|
||||
|
||||
|
||||
debugf("Signal size=%ld\n", buffer->size);
|
||||
|
||||
while (m != NULL) {
|
||||
@@ -317,9 +317,10 @@ l2cap_process_con_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer)
|
||||
cmd->channel->dcid = dcid;
|
||||
btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_ertx_timeout);
|
||||
|
||||
//INDICATION error = ng_l2cap_l2ca_con_rsp(cmd->channel, cmd->token, result, status);
|
||||
if (error != B_OK)
|
||||
btCoreData->RemoveChannel(conn, cmd->channel->scid);
|
||||
// TODO:
|
||||
// INDICATION error = ng_l2cap_l2ca_con_rsp(cmd->channel, cmd->token, result, status);
|
||||
// if (error != B_OK)
|
||||
// btCoreData->RemoveChannel(conn, cmd->channel->scid);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -333,16 +334,15 @@ l2cap_process_con_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer)
|
||||
|
||||
cmd->channel->dcid = dcid;
|
||||
cmd->channel->state = L2CAP_CHAN_CONFIG;
|
||||
} else {
|
||||
/* There was an error, so close the channel */
|
||||
debugf("failed to open L2CAP channel, result=%d, status=%d\n", result, status);
|
||||
}
|
||||
|
||||
error = l2cap_upper_con_rsp(conn, cmd->channel);
|
||||
error = l2cap_con_rsp_ind(conn, cmd->channel);
|
||||
|
||||
/* XXX do we have to remove the channel on error? */
|
||||
if (error != 0 || result != L2CAP_SUCCESS)
|
||||
if (error != 0 || result != L2CAP_SUCCESS) {
|
||||
debugf("failed to open L2CAP channel, result=%d, status=%d\n", result, status);
|
||||
btCoreData->RemoveChannel(conn, cmd->channel->scid);
|
||||
}
|
||||
|
||||
btCoreData->AcknowledgeSignal(cmd);
|
||||
}
|
||||
@@ -534,7 +534,7 @@ l2cap_process_cfg_req(HciConnection* conn, uint8 ident, net_buffer* buffer)
|
||||
/* Send L2CA_ConfigInd event to the upper layer protocol */
|
||||
channel->cfgState |= L2CAP_CFG_IN;
|
||||
channel->ident = ident; // sent ident to reply
|
||||
error = l2cap_l2ca_cfg_rsp_ind(channel);
|
||||
error = l2cap_cfg_req_ind(channel);
|
||||
if (error != 0)
|
||||
btCoreData->RemoveChannel(conn, channel->scid);
|
||||
}
|
||||
@@ -656,7 +656,7 @@ l2cap_process_cfg_rsp(HciConnection *conn, uint8 ident, net_buffer *buffer)
|
||||
btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_rtx_timeout);
|
||||
else {
|
||||
/* Send L2CA_Config response to the upper layer protocol */
|
||||
error = l2cap_upper_cfg_rsp(cmd->channel /*, cmd->token, result*/);
|
||||
error = l2cap_cfg_rsp_ind(cmd->channel /*, cmd->token, result*/);
|
||||
if (error != 0) {
|
||||
/*
|
||||
* XXX FIXME what to do here? we were not able to send
|
||||
|
||||
@@ -19,12 +19,17 @@
|
||||
#include <l2cap.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark - Signals from the other pair
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_l2ca_con_ind(L2capChannel* channel)
|
||||
{
|
||||
L2capEndpoint* endpoint = L2capEndpoint::ForPsm(channel->psm);
|
||||
|
||||
if (endpoint == NULL) { //TODO: refuse connection no endpoint bound
|
||||
|
||||
if (endpoint == NULL) { // TODO: refuse connection no endpoint bound
|
||||
debugf("No endpoint bound for psm %d\n", channel->psm);
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -32,43 +37,70 @@ l2cap_l2ca_con_ind(L2capChannel* channel)
|
||||
// Pair Channel with endpoint
|
||||
endpoint->BindToChannel(channel);
|
||||
|
||||
net_buffer* buf = l2cap_con_rsp(channel->ident, channel->scid, channel->dcid,
|
||||
net_buffer* buf = l2cap_con_rsp(channel->ident, channel->scid, channel->dcid,
|
||||
L2CAP_SUCCESS, L2CAP_NO_INFO);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_CON_RSP);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_CON_RSP);
|
||||
if (cmd == NULL) {
|
||||
gBufferModule->free(buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
// we can move to configuration...
|
||||
channel->state = L2CAP_CHAN_CONFIG;
|
||||
|
||||
/* Link command to the queue */
|
||||
// Link command to the queue
|
||||
SchedConnectionPurgeThread(channel->conn);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel)
|
||||
l2cap_con_rsp_ind(HciConnection* conn, L2capChannel* channel)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
// We received a configuration response, connection process
|
||||
// is a step further but still configuration pending
|
||||
|
||||
// Send Configuration Request
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_cfg_rsp_ind(L2capChannel* channel)
|
||||
{
|
||||
channel->cfgState |= L2CAP_CFG_OUT;
|
||||
if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) {
|
||||
channel->state = L2CAP_CHAN_OPEN;
|
||||
return channel->endpoint->MarkEstablished();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_cfg_req_ind(L2capChannel* channel)
|
||||
{
|
||||
// if our configuration has not been yet sent ...
|
||||
if(!(channel->cfgState & L2CAP_CFG_OUT_SENT)) {
|
||||
|
||||
if (!(channel->cfgState & L2CAP_CFG_OUT_SENT)) {
|
||||
|
||||
// TODO: check if we can handle this conf
|
||||
|
||||
|
||||
// send config_rsp
|
||||
net_buffer* buf = l2cap_cfg_rsp(channel->ident, channel->dcid, 0,
|
||||
L2CAP_SUCCESS, NULL);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_CFG_RSP);
|
||||
if (cmd == NULL) {
|
||||
gBufferModule->free(buf);
|
||||
gBufferModule->free(buf);
|
||||
channel->state = L2CAP_CHAN_CLOSED;
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
flowf("Sending cfg resp\n");
|
||||
// Link command to the queue
|
||||
SchedConnectionPurgeThread(channel->conn);
|
||||
@@ -77,7 +109,7 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel)
|
||||
channel->cfgState |= L2CAP_CFG_OUT_SENT;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -86,7 +118,7 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel)
|
||||
// Channel can be declared open
|
||||
channel->state = L2CAP_CHAN_OPEN;
|
||||
channel->endpoint->MarkEstablished();
|
||||
|
||||
|
||||
} else {
|
||||
// send configuration Request by our side
|
||||
if (channel->endpoint->RequiresConfiguration()) {
|
||||
@@ -96,7 +128,7 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel)
|
||||
// nothing special requested
|
||||
channel->ident = btCoreData->ChannelAllocateIdent(channel->conn);
|
||||
net_buffer* buf = l2cap_cfg_req(channel->ident, channel->dcid, 0, NULL);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_CFG_REQ);
|
||||
if (cmd == NULL) {
|
||||
gBufferModule->free(buf);
|
||||
@@ -109,8 +141,8 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel)
|
||||
// Link command to the queue
|
||||
SchedConnectionPurgeThread(channel->conn);
|
||||
|
||||
}
|
||||
channel->cfgState |= L2CAP_CFG_IN_SENT;
|
||||
}
|
||||
channel->cfgState |= L2CAP_CFG_IN_SENT;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
@@ -124,36 +156,42 @@ l2cap_l2ca_discon_ind(L2capChannel* channel)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#pragma mark - Signals from Upper Layer
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_upper_cfg_rsp(L2capChannel* channel)
|
||||
l2cap_upper_con_req(L2capChannel* channel)
|
||||
{
|
||||
channel->cfgState |= L2CAP_CFG_OUT;
|
||||
if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) {
|
||||
channel->state = L2CAP_CHAN_OPEN;
|
||||
return channel->endpoint->MarkEstablished();
|
||||
channel->ident = btCoreData->ChannelAllocateIdent(channel->conn);
|
||||
|
||||
net_buffer* buf = l2cap_con_req(channel->ident, channel->psm, channel->scid);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_CON_REQ);
|
||||
|
||||
if (cmd == NULL) {
|
||||
gBufferModule->free(buf);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
channel->state = L2CAP_CHAN_W4_L2CAP_CON_RSP;
|
||||
|
||||
// Link command to the queue
|
||||
SchedConnectionPurgeThread(channel->conn);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel)
|
||||
{
|
||||
flowf("\n");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
l2cap_upper_dis_req(L2capChannel* channel)
|
||||
{
|
||||
|
||||
channel->ident = btCoreData->ChannelAllocateIdent(channel->conn);
|
||||
|
||||
net_buffer* buf = l2cap_discon_req(channel->ident, channel->scid, channel->dcid);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_DISCON_REQ);
|
||||
|
||||
net_buffer* buf = l2cap_discon_req(channel->ident, channel->scid,
|
||||
channel->dcid);
|
||||
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
|
||||
channel->ident, L2CAP_DISCON_REQ);
|
||||
if (cmd == NULL) {
|
||||
gBufferModule->free(buf);
|
||||
return ENOMEM;
|
||||
@@ -161,7 +199,7 @@ l2cap_upper_dis_req(L2capChannel* channel)
|
||||
|
||||
channel->state = L2CAP_CHAN_W4_L2CA_DISCON_RSP;
|
||||
|
||||
/* Link command to the queue */
|
||||
// Link command to the queue
|
||||
SchedConnectionPurgeThread(channel->conn);
|
||||
return B_OK;
|
||||
|
||||
@@ -181,31 +219,31 @@ l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid)
|
||||
L2capChannel* channel = btCoreData->ChannelBySourceID(conn, dcid);
|
||||
|
||||
if (channel == NULL) {
|
||||
debugf("dcid %d does not exist for handle %d\n", dcid, conn->handle);
|
||||
debugf("dcid %d does not exist for handle %d\n", dcid, conn->handle);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (channel->endpoint == NULL) {
|
||||
debugf("dcid %d not bound to endpoint\n", dcid);
|
||||
return B_ERROR;
|
||||
debugf("dcid %d not bound to endpoint\n", dcid);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return gStackModule->fifo_enqueue_buffer(&channel->endpoint->fReceivingFifo, buffer);
|
||||
return gStackModule->fifo_enqueue_buffer(
|
||||
&channel->endpoint->fReceivingFifo, buffer);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm)
|
||||
{
|
||||
|
||||
L2capEndpoint* endpoint = L2capEndpoint::ForPsm(psm);
|
||||
|
||||
if (endpoint == NULL) {
|
||||
debugf("no enpoint bound with psm %d\n", psm);
|
||||
return B_ERROR;
|
||||
debugf("no enpoint bound with psm %d\n", psm);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
flowf("Enqueue to fifo\n");
|
||||
return gStackModule->fifo_enqueue_buffer(&endpoint->fReceivingFifo, buffer);
|
||||
|
||||
flowf("Enqueue to fifo\n");
|
||||
return gStackModule->fifo_enqueue_buffer(
|
||||
&endpoint->fReceivingFifo, buffer);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -8,13 +8,13 @@
|
||||
#include "l2cap_internal.h"
|
||||
|
||||
status_t l2cap_l2ca_con_ind(L2capChannel* channel);
|
||||
status_t l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel);
|
||||
status_t l2cap_cfg_req_ind(L2capChannel* channel);
|
||||
status_t l2cap_l2ca_discon_ind(L2capChannel* channel);
|
||||
status_t l2cap_con_rsp_ind(HciConnection* conn, L2capChannel* channel);
|
||||
status_t l2cap_cfg_rsp_ind(L2capChannel* channel);
|
||||
|
||||
|
||||
status_t l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel);
|
||||
status_t l2cap_upper_cfg_rsp(L2capChannel* channel);
|
||||
status_t l2cap_upper_dis_req(L2capChannel* channel);
|
||||
status_t l2cap_upper_con_req(L2capChannel* channel);
|
||||
status_t l2cap_upper_dis_req(L2capChannel* channel);
|
||||
|
||||
|
||||
status_t l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid);
|
||||
|
||||
@@ -130,7 +130,7 @@ RemoteDevice::Authenticate()
|
||||
BluetoothCommand<typed_command(hci_cp_create_conn)>
|
||||
createConnection(OGF_LINK_CONTROL, OCF_CREATE_CONN);
|
||||
|
||||
bacpy(&createConnection->bdaddr, &fBdaddr);
|
||||
bdaddrUtils::Copy(&createConnection->bdaddr, &fBdaddr);
|
||||
createConnection->pscan_rep_mode = fPageRepetitionMode;
|
||||
createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1
|
||||
createConnection->clock_offset = fClockOffset | 0x8000; // substract!
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <bluetooth/HCI/btHCI_command.h>
|
||||
#include <bluetooth/L2CAP/btL2CAP.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/bluetooth_util.h>
|
||||
|
||||
#include "BluetoothServer.h"
|
||||
#include "DeskbarReplicant.h"
|
||||
|
||||
@@ -975,7 +975,7 @@ LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
|
||||
BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
|
||||
linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_LINK_KEY_NEG_REPLY);
|
||||
|
||||
bacpy(&linkKeyNegativeReply->bdaddr, &keyRequested->bdaddr);
|
||||
bdaddrUtils::Copy(&linkKeyNegativeReply->bdaddr, &keyRequested->bdaddr);
|
||||
|
||||
if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
|
||||
linkKeyNegativeReply.Size()) == B_ERROR) {
|
||||
|
||||
Reference in New Issue
Block a user