*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:
Oliver Ruiz Dorantes
2010-06-14 20:04:10 +00:00
parent a8ad734f1c
commit a5bf12376d
16 changed files with 343 additions and 278 deletions
+10 -4
View File
@@ -7,9 +7,9 @@
#define _BDADDR_UTILS_H #define _BDADDR_UTILS_H
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/bluetooth_util.h>
namespace Bluetooth { 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) static char* ToString(const bdaddr_t bdaddr)
{ {
// TODO: not safe // TODO: not safe
@@ -58,7 +63,7 @@ public:
if (addr != NULL) { if (addr != NULL) {
size_t count = sscanf(addr, "%2X:%2X:%2X:%2X:%2X:%2X", 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) if (count == 6)
return ((bdaddr_t) {{b0, b1, b2, b3, b4, b5}}); return ((bdaddr_t) {{b0, b1, b2, b3, b4, b5}});
@@ -71,6 +76,7 @@ public:
} }
#ifndef _BT_USE_EXPLICIT_NAMESPACE #ifndef _BT_USE_EXPLICIT_NAMESPACE
using Bluetooth::bdaddrUtils; using Bluetooth::bdaddrUtils;
#endif #endif
-42
View File
@@ -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
+2 -2
View File
@@ -143,7 +143,7 @@ struct bluetooth_core_data_module_info {
// status_t (*RemoveConnection)(bdaddr_t destination, hci_id hid); // status_t (*RemoveConnection)(bdaddr_t destination, hci_id hid);
status_t (*RemoveConnection)(uint16 handle, 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, void (*SetAclBuffer)(struct HciConnection* conn,
net_buffer* nbuf); net_buffer* nbuf);
@@ -155,7 +155,7 @@ struct bluetooth_core_data_module_info {
bool (*AclOverFlowed)(struct HciConnection* conn); bool (*AclOverFlowed)(struct HciConnection* conn);
struct HciConnection* (*ConnectionByHandle)(uint16 handle, hci_id hid); struct HciConnection* (*ConnectionByHandle)(uint16 handle, hci_id hid);
struct HciConnection* (*ConnectionByDestination)(bdaddr_t* destination, struct HciConnection* (*ConnectionByDestination)(const bdaddr_t* destination,
hci_id hid); hci_id hid);
struct L2capChannel* (*AddChannel)(struct HciConnection* conn, struct L2capChannel* (*AddChannel)(struct HciConnection* conn,
@@ -8,7 +8,7 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/bluetooth_util.h> #include <bluetooth/bdaddrUtils.h>
#define BT_DEBUG_THIS_MODULE #define BT_DEBUG_THIS_MODULE
#define SUBMODULE_NAME "Connection" #define SUBMODULE_NAME "Connection"
@@ -49,13 +49,13 @@ AddConnection(uint16 handle, int type, bdaddr_t* dst, hci_id hid)
if (conn == NULL) if (conn == NULL)
goto bail; goto bail;
//memset(conn, 0, sizeof(HciConnection)); // memset(conn, 0, sizeof(HciConnection));
conn->currentRxPacket = NULL; conn->currentRxPacket = NULL;
conn->currentRxExpectedLength = 0; conn->currentRxExpectedLength = 0;
update: update:
// fill values // fill values
bacpy(&conn->destination, dst); bdaddrUtils::Copy(&conn->destination, dst);
conn->type = type; conn->type = type;
conn->handle = handle; conn->handle = handle;
conn->Hid = hid; conn->Hid = hid;
@@ -76,11 +76,14 @@ RemoveConnection(bdaddr_t* destination, hci_id hid)
{ {
HciConnection* conn; HciConnection* conn;
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator(); DoublyLinkedList<HciConnection>::Iterator iterator
= sConnectionList.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
conn = iterator.Next(); 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 the device is still part of the list, remove it
if (conn->GetDoublyLinkedListLink()->next != NULL if (conn->GetDoublyLinkedListLink()->next != NULL
@@ -102,7 +105,8 @@ RemoveConnection(uint16 handle, hci_id hid)
{ {
HciConnection* conn; HciConnection* conn;
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator(); DoublyLinkedList<HciConnection>::Iterator iterator
= sConnectionList.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
conn = iterator.Next(); conn = iterator.Next();
@@ -125,15 +129,16 @@ RemoveConnection(uint16 handle, hci_id hid)
hci_id 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()) { while (iterator.HasNext()) {
conn = iterator.Next(); conn = iterator.Next();
if (bacmp(&conn->destination, destination)==0) { if (bdaddrUtils::Compare(&conn->destination, destination)) {
return conn->Hid; return conn->Hid;
} }
} }
@@ -147,11 +152,12 @@ ConnectionByHandle(uint16 handle, hci_id hid)
{ {
HciConnection* conn; HciConnection* conn;
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator(); DoublyLinkedList<HciConnection>::Iterator iterator
= sConnectionList.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
conn = iterator.Next(); conn = iterator.Next();
if (conn->Hid == hid && conn->handle==handle) { if (conn->Hid == hid && conn->handle == handle) {
return conn; return conn;
} }
} }
@@ -161,15 +167,17 @@ ConnectionByHandle(uint16 handle, hci_id hid)
HciConnection* HciConnection*
ConnectionByDestination(bdaddr_t* destination, hci_id hid) ConnectionByDestination(const bdaddr_t* destination, hci_id hid)
{ {
HciConnection* conn; HciConnection* conn;
DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator(); DoublyLinkedList<HciConnection>::Iterator iterator
= sConnectionList.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
conn = iterator.Next(); conn = iterator.Next();
if (conn->Hid == hid && bacmp(&conn->destination, destination)==0) { if (conn->Hid == hid
&& bdaddrUtils::Compare(&conn->destination, destination)) {
return conn; return conn;
} }
} }
@@ -177,6 +185,7 @@ ConnectionByDestination(bdaddr_t* destination, hci_id hid)
return NULL; return NULL;
} }
#if 0 #if 0
#pragma mark - ACL helper funcs #pragma mark - ACL helper funcs
#endif #endif
@@ -215,6 +224,7 @@ AclOverFlowed(HciConnection* conn)
return conn->currentRxExpectedLength < 0; return conn->currentRxExpectedLength < 0;
} }
#if 0 #if 0
#pragma mark - private funcs #pragma mark - private funcs
#endif #endif
@@ -15,14 +15,16 @@
extern DoublyLinkedList<HciConnection> sConnectionList; extern DoublyLinkedList<HciConnection> sConnectionList;
HciConnection* ConnectionByHandle(uint16 handle, hci_id hid); 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); HciConnection* AddConnection(uint16 handle, int type, bdaddr_t* dst,
status_t RemoveConnection(bdaddr_t *destination, hci_id hid); hci_id hid);
status_t RemoveConnection(bdaddr_t* destination, hci_id hid);
status_t RemoveConnection(uint16 handle, 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 SetAclBuffer(HciConnection* conn, net_buffer* nbuf);
void SetAclExpectedSize(HciConnection* conn, size_t size); void SetAclExpectedSize(HciConnection* conn, size_t size);
@@ -16,8 +16,6 @@
#include "snet_buffer.h" #include "snet_buffer.h"
#include <bluetooth/bluetooth_util.h>
#define BT_DEBUG_THIS_MODULE #define BT_DEBUG_THIS_MODULE
#define SUBMODULE_NAME BLUETOOTH_DEVICE_DEVFS_NAME #define SUBMODULE_NAME BLUETOOTH_DEVICE_DEVFS_NAME
#define SUBMODULE_COLOR 35 #define SUBMODULE_COLOR 35
@@ -10,8 +10,9 @@
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <bluetooth/bdaddrUtils.h>
#include <bluetooth/L2CAP/btL2CAP.h> #include <bluetooth/L2CAP/btL2CAP.h>
#define BT_DEBUG_THIS_MODULE #define BT_DEBUG_THIS_MODULE
#define MODULE_NAME "l2cap" #define MODULE_NAME "l2cap"
#define SUBMODULE_NAME "Endpoint" #define SUBMODULE_NAME "Endpoint"
@@ -133,16 +134,19 @@ L2capEndpoint::Free()
status_t status_t
L2capEndpoint::Bind(const struct sockaddr *_address) L2capEndpoint::Bind(const struct sockaddr* _address)
{ {
const sockaddr_l2cap* address
= reinterpret_cast<const sockaddr_l2cap*>(_address);
if (_address == NULL) if (_address == NULL)
return B_ERROR; return B_ERROR;
if (_address->sa_family != AF_BLUETOOTH ) if (address->l2cap_family != AF_BLUETOOTH )
return EAFNOSUPPORT; return EAFNOSUPPORT;
//if (_address->sa_len != sizeof(struct sockaddr_l2cap)) if (address->l2cap_len != sizeof(struct sockaddr_l2cap))
// return EAFNOSUPPORT; return EAFNOSUPPORT;
// TODO: Check if that PSM is already bound // TODO: Check if that PSM is already bound
// return EADDRINUSE; // return EADDRINUSE;
@@ -151,15 +155,17 @@ L2capEndpoint::Bind(const struct sockaddr *_address)
// psm available to applications. // psm available to applications.
// All PSM values shall be ODD, that is, the least significant bit of the least // 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 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 // significant bit of the most significant octet equal to 0. This allows
// PSM field to be extended beyond 16 bits. // the PSM field to be extended beyond 16 bits.
if ((((struct sockaddr_l2cap*)_address)->l2cap_psm & 1) == 0) if ((address->l2cap_psm & 1) == 0)
return B_ERROR; return B_ERROR;
flowf("\n")
memcpy(&socket->address, _address, sizeof(struct sockaddr_l2cap)); memcpy(&socket->address, _address, sizeof(struct sockaddr_l2cap));
socket->address.ss_len = 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; fState = BOUND;
return B_OK; return B_OK;
@@ -200,32 +206,66 @@ L2capEndpoint::Listen(int backlog)
status_t status_t
L2capEndpoint::Connect(const struct sockaddr *_address) L2capEndpoint::Connect(const struct sockaddr* _address)
{ {
if (_address->sa_family != AF_BLUETOOTH) const sockaddr_l2cap* address
return EAFNOSUPPORT; = reinterpret_cast<const sockaddr_l2cap*>(_address);
debugf("[%ld] %p->L2capEndpoint::Connect(\"%s\")\n", find_thread(NULL), this, if (address->l2cap_len != sizeof(*address))
ConstSocketAddress(&gL2cap4AddressModule, _address).AsString().Data()); return EINVAL;
const sockaddr_l2cap* address = (const sockaddr_l2cap*)_address; // Check for any specific status?
if (fState == CONNECTING) {
return EINPROGRESS;
}
/**/ // TODO: should not be in the BOUND status first?
TOUCH(address);
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; return B_OK;
} else {
return ECONNREFUSED;
}
}
return ENETUNREACH;
} }
status_t status_t
L2capEndpoint::Accept(net_socket **_acceptedSocket) L2capEndpoint::Accept(net_socket** _acceptedSocket)
{ {
debugf("[%ld]\n", find_thread(NULL)); debugf("[%ld]\n", find_thread(NULL));
// MutexLocker locker(fLock); // MutexLocker locker(fLock);
status_t status; status_t status;
bigtime_t timeout = absolute_timeout(300*1000*1000); bigtime_t timeout = absolute_timeout(300 * 1000 * 1000);
do { do {
// locker.Unlock(); // locker.Unlock();
@@ -257,8 +297,8 @@ L2capEndpoint::Accept(net_socket **_acceptedSocket)
ssize_t ssize_t
L2capEndpoint::Send(const iovec *vecs, size_t vecCount, L2capEndpoint::Send(const iovec* vecs, size_t vecCount,
ancillary_data_container *ancillaryData) ancillary_data_container* ancillaryData)
{ {
debugf("[%ld] %p Send(%p, %ld, %p)\n", find_thread(NULL), debugf("[%ld] %p Send(%p, %ld, %p)\n", find_thread(NULL),
this, vecs, vecCount, ancillaryData); this, vecs, vecCount, ancillaryData);
@@ -268,9 +308,9 @@ L2capEndpoint::Send(const iovec *vecs, size_t vecCount,
ssize_t ssize_t
L2capEndpoint::Receive(const iovec *vecs, size_t vecCount, L2capEndpoint::Receive(const iovec* vecs, size_t vecCount,
ancillary_data_container **_ancillaryData, struct sockaddr *_address, ancillary_data_container** _ancillaryData, struct sockaddr* _address,
socklen_t *_addressLength) socklen_t* _addressLength)
{ {
debugf("[%ld] %p Receive(%p, %ld)\n", find_thread(NULL), debugf("[%ld] %p Receive(%p, %ld)\n", find_thread(NULL),
this, vecs, vecCount); this, vecs, vecCount);
@@ -322,7 +362,8 @@ L2capEndpoint::ForPsm(uint16 psm)
{ {
L2capEndpoint* endpoint; L2capEndpoint* endpoint;
DoublyLinkedList<L2capEndpoint>::Iterator iterator = EndpointList.GetIterator(); DoublyLinkedList<L2capEndpoint>::Iterator iterator
= EndpointList.GetIterator();
while (iterator.HasNext()) { while (iterator.HasNext()) {
@@ -356,7 +397,8 @@ L2capEndpoint::BindToChannel(L2capChannel* channel)
channel->endpoint = endpoint; 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 // Provide the channel the configuration set by the user socket
channel->configuration = &fConfiguration; channel->configuration = &fConfiguration;
@@ -44,17 +44,17 @@ public:
mutex_unlock(&fLock); mutex_unlock(&fLock);
} }
status_t Bind(const struct sockaddr *_address); status_t Bind(const struct sockaddr* _address);
status_t Unbind(); status_t Unbind();
status_t Listen(int backlog); status_t Listen(int backlog);
status_t Connect(const struct sockaddr *address); status_t Connect(const struct sockaddr* address);
status_t Accept(net_socket **_acceptedSocket); status_t Accept(net_socket** _acceptedSocket);
ssize_t Send(const iovec *vecs, size_t vecCount, ssize_t Send(const iovec* vecs, size_t vecCount,
ancillary_data_container *ancillaryData); ancillary_data_container* ancillaryData);
ssize_t Receive(const iovec *vecs, size_t vecCount, ssize_t Receive(const iovec* vecs, size_t vecCount,
ancillary_data_container **_ancillaryData, ancillary_data_container** _ancillaryData,
struct sockaddr *_address, socklen_t *_addressLength); struct sockaddr* _address, socklen_t* _addressLength);
ssize_t ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer); ssize_t ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer);
ssize_t Sendable(); ssize_t Sendable();
@@ -86,6 +86,7 @@ private:
CLOSED, CLOSED,
BOUND, BOUND,
LISTEN, LISTEN,
CONNECTING,
ESTABLISHED, ESTABLISHED,
// peer closes the connection // peer closes the connection
@@ -62,13 +62,12 @@ static struct net_domain* sDomain;
net_protocol* net_protocol*
l2cap_init_protocol(net_socket* socket) l2cap_init_protocol(net_socket* socket)
{ {
flowf("\n");
L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket); L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket);
if (protocol == NULL) if (protocol == NULL)
return NULL; return NULL;
EndpointList.Add(protocol); EndpointList.Add(protocol);
debugf("Prococol created %p\n", protocol);
return protocol; return protocol;
} }
@@ -120,9 +119,16 @@ l2cap_free(net_protocol* protocol)
status_t status_t
l2cap_connect(net_protocol* protocol, const struct sockaddr* address) l2cap_connect(net_protocol* protocol, const struct sockaddr* address)
{ {
flowf("\n"); debugf("from %p, with %p\n", protocol, address);
return B_ERROR; if (address == NULL)
return EINVAL;
if (address->sa_family != AF_BLUETOOTH)
return EAFNOSUPPORT;
return ((L2capEndpoint*)protocol)->Connect(address);;
} }
@@ -139,8 +145,7 @@ l2cap_control(net_protocol* protocol, int level, int option, void* value,
{ {
flowf("\n"); flowf("\n");
/* return protocol->next->module->control(protocol->next, level, option, value, _length); */ return EOPNOTSUPP;
return B_OK;
} }
@@ -150,8 +155,7 @@ l2cap_getsockopt(net_protocol* protocol, int level, int option,
{ {
flowf("\n"); flowf("\n");
/* return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */ return EOPNOTSUPP;
return B_OK;
} }
@@ -163,7 +167,6 @@ l2cap_setsockopt(net_protocol* protocol, int level, int option,
((L2capEndpoint*)protocol)->fConfigurationSet = true; ((L2capEndpoint*)protocol)->fConfigurationSet = true;
/* return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */
return EOPNOTSUPP; return EOPNOTSUPP;
} }
@@ -171,6 +174,8 @@ l2cap_setsockopt(net_protocol* protocol, int level, int option,
status_t status_t
l2cap_bind(net_protocol* protocol, const struct sockaddr* address) l2cap_bind(net_protocol* protocol, const struct sockaddr* address)
{ {
debugf("from %p, with %p\n", protocol, address);
return ((L2capEndpoint*)protocol)->Bind(address); return ((L2capEndpoint*)protocol)->Bind(address);
} }
@@ -310,24 +315,23 @@ l2cap_std_ops(int32 op, ...)
switch (op) { switch (op) {
case B_MODULE_INIT: 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", "network/protocols/l2cap/v1",
NULL); NULL);
if (error != B_OK) { if (error != B_OK)
return error; 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"); "network/protocols/l2cap/v1");
if (error != B_OK) { if (error != B_OK)
return error; return error;
}
error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule, error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule,
&gL2cap4AddressModule, &sDomain); &gL2cap4AddressModule, &sDomain);
if (error != B_OK) { if (error != B_OK)
return error; return error;
}
new (&EndpointList) DoublyLinkedList<L2capEndpoint>; new (&EndpointList) DoublyLinkedList<L2capEndpoint>;
@@ -6,7 +6,6 @@
* Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com * Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
*/ */
#include <net_datalink.h> #include <net_datalink.h>
#include <ByteOrder.h> #include <ByteOrder.h>
@@ -18,7 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <bluetooth/bluetooth_util.h> #include <bluetooth/bdaddrUtils.h>
#include <bluetooth/L2CAP/btL2CAP.h> #include <bluetooth/L2CAP/btL2CAP.h>
#define L2CAP_CHECKSUM(address) (address.b[0]+\ #define L2CAP_CHECKSUM(address) (address.b[0]+\
@@ -75,7 +74,8 @@ l2cap_copy_address(const sockaddr *from, sockaddr **to,
\return B_BAD_VALUE if \a address or \a mask is NULL \return B_BAD_VALUE if \a address or \a mask is NULL
*/ */
static status_t 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) if (address == NULL || result == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -96,10 +96,12 @@ l2cap_is_empty_address(const sockaddr *address, bool checkPort)
if (address == NULL || address->sa_len == 0) if (address == NULL || address->sa_len == 0)
return true; return true;
return ((bacmp(&((sockaddr_l2cap *)address)->l2cap_bdaddr, BDADDR_NULL)==0) return ((bdaddrUtils::Compare(
&& (!checkPort || ((sockaddr_l2cap *)address)->l2cap_psm == 0) ); &((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. /*! Checks if the given \a address is L2CAP address.
\return false if \a address is NULL, or with family different from AF_BLUETOOTH \return false if \a address is NULL, or with family different from AF_BLUETOOTH
true if it has AF_BLUETOOTH address family 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) if (a == NULL && b != NULL)
return l2cap_is_empty_address(b, false); return l2cap_is_empty_address(b, false);
return (bacmp(&((sockaddr_l2cap*)a)->l2cap_bdaddr, return bdaddrUtils::Compare(&((const sockaddr_l2cap*)a)->l2cap_bdaddr,
&((sockaddr_l2cap*)b)->l2cap_bdaddr)==0); &((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) if (a == NULL && b != NULL)
return l2cap_is_empty_address(b, true); 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; && ((sockaddr_l2cap *)a)->l2cap_psm == ((sockaddr_l2cap *)b)->l2cap_psm;
} }
@@ -234,11 +237,14 @@ l2cap_print_address_buffer(const sockaddr *_address, char *buffer,
else { else {
bdaddr_t addr = address->l2cap_bdaddr; bdaddr_t addr = address->l2cap_bdaddr;
if (printPort) { if (printPort) {
snprintf(buffer, bufferSize, "%2X:%2X:%2X:%2X:%2X:%2X|%u", addr.b[0], snprintf(buffer, bufferSize,
addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5],address->l2cap_psm); "%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 { else {
snprintf(buffer, bufferSize, "%2X:%2X:%2X:%2X:%2X:%2X",addr.b[0], 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]); addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5]);
} }
} }
@@ -333,7 +339,7 @@ l2cap_update_to(sockaddr *_address, const sockaddr *_from)
if (address->l2cap_psm == 0) if (address->l2cap_psm == 0)
address->l2cap_psm = from->l2cap_psm; 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; address->l2cap_bdaddr = from->l2cap_bdaddr;
return B_OK; 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; const sockaddr_l2cap *peer = (const sockaddr_l2cap *)peerAddress;
return ((our ? our->l2cap_psm : 0) | ((peer ? peer->l2cap_psm : 0) << 16)) 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);
} }
@@ -317,9 +317,10 @@ l2cap_process_con_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer)
cmd->channel->dcid = dcid; cmd->channel->dcid = dcid;
btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_ertx_timeout); btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_ertx_timeout);
//INDICATION error = ng_l2cap_l2ca_con_rsp(cmd->channel, cmd->token, result, status); // TODO:
if (error != B_OK) // INDICATION error = ng_l2cap_l2ca_con_rsp(cmd->channel, cmd->token, result, status);
btCoreData->RemoveChannel(conn, cmd->channel->scid); // if (error != B_OK)
// btCoreData->RemoveChannel(conn, cmd->channel->scid);
} else { } else {
@@ -333,16 +334,15 @@ l2cap_process_con_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer)
cmd->channel->dcid = dcid; cmd->channel->dcid = dcid;
cmd->channel->state = L2CAP_CHAN_CONFIG; 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? */ /* 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->RemoveChannel(conn, cmd->channel->scid);
}
btCoreData->AcknowledgeSignal(cmd); 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 */ /* Send L2CA_ConfigInd event to the upper layer protocol */
channel->cfgState |= L2CAP_CFG_IN; channel->cfgState |= L2CAP_CFG_IN;
channel->ident = ident; // sent ident to reply channel->ident = ident; // sent ident to reply
error = l2cap_l2ca_cfg_rsp_ind(channel); error = l2cap_cfg_req_ind(channel);
if (error != 0) if (error != 0)
btCoreData->RemoveChannel(conn, channel->scid); 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); btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_rtx_timeout);
else { else {
/* Send L2CA_Config response to the upper layer protocol */ /* 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) { if (error != 0) {
/* /*
* XXX FIXME what to do here? we were not able to send * XXX FIXME what to do here? we were not able to send
@@ -19,12 +19,17 @@
#include <l2cap.h> #include <l2cap.h>
#if 0
#pragma mark - Signals from the other pair
#endif
status_t status_t
l2cap_l2ca_con_ind(L2capChannel* channel) l2cap_l2ca_con_ind(L2capChannel* channel)
{ {
L2capEndpoint* endpoint = L2capEndpoint::ForPsm(channel->psm); 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); debugf("No endpoint bound for psm %d\n", channel->psm);
return B_ERROR; return B_ERROR;
} }
@@ -44,17 +49,44 @@ l2cap_l2ca_con_ind(L2capChannel* channel)
// we can move to configuration... // we can move to configuration...
channel->state = L2CAP_CHAN_CONFIG; channel->state = L2CAP_CHAN_CONFIG;
/* Link command to the queue */ // Link command to the queue
SchedConnectionPurgeThread(channel->conn); SchedConnectionPurgeThread(channel->conn);
return B_OK; return B_OK;
} }
status_t 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 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 // TODO: check if we can handle this conf
@@ -124,34 +156,40 @@ l2cap_l2ca_discon_ind(L2capChannel* channel)
} }
#if 0
#pragma mark - Signals from Upper Layer
#endif
status_t status_t
l2cap_upper_cfg_rsp(L2capChannel* channel) l2cap_upper_con_req(L2capChannel* channel)
{ {
channel->cfgState |= L2CAP_CFG_OUT; channel->ident = btCoreData->ChannelAllocateIdent(channel->conn);
if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) {
channel->state = L2CAP_CHAN_OPEN; net_buffer* buf = l2cap_con_req(channel->ident, channel->psm, channel->scid);
return channel->endpoint->MarkEstablished(); 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; return B_OK;
} }
status_t
l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel)
{
flowf("\n");
return B_OK;
}
status_t status_t
l2cap_upper_dis_req(L2capChannel* channel) l2cap_upper_dis_req(L2capChannel* channel)
{ {
channel->ident = btCoreData->ChannelAllocateIdent(channel->conn); channel->ident = btCoreData->ChannelAllocateIdent(channel->conn);
net_buffer* buf = l2cap_discon_req(channel->ident, channel->scid, channel->dcid); net_buffer* buf = l2cap_discon_req(channel->ident, channel->scid,
channel->dcid);
L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf,
channel->ident, L2CAP_DISCON_REQ); channel->ident, L2CAP_DISCON_REQ);
if (cmd == NULL) { if (cmd == NULL) {
@@ -161,7 +199,7 @@ l2cap_upper_dis_req(L2capChannel* channel)
channel->state = L2CAP_CHAN_W4_L2CA_DISCON_RSP; channel->state = L2CAP_CHAN_W4_L2CA_DISCON_RSP;
/* Link command to the queue */ // Link command to the queue
SchedConnectionPurgeThread(channel->conn); SchedConnectionPurgeThread(channel->conn);
return B_OK; return B_OK;
@@ -190,14 +228,14 @@ l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid)
return B_ERROR; return B_ERROR;
} }
return gStackModule->fifo_enqueue_buffer(&channel->endpoint->fReceivingFifo, buffer); return gStackModule->fifo_enqueue_buffer(
&channel->endpoint->fReceivingFifo, buffer);
} }
status_t status_t
l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm) l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm)
{ {
L2capEndpoint* endpoint = L2capEndpoint::ForPsm(psm); L2capEndpoint* endpoint = L2capEndpoint::ForPsm(psm);
if (endpoint == NULL) { if (endpoint == NULL) {
@@ -206,6 +244,6 @@ l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm)
} }
flowf("Enqueue to fifo\n"); flowf("Enqueue to fifo\n");
return gStackModule->fifo_enqueue_buffer(&endpoint->fReceivingFifo, buffer); return gStackModule->fifo_enqueue_buffer(
&endpoint->fReceivingFifo, buffer);
} }
@@ -8,12 +8,12 @@
#include "l2cap_internal.h" #include "l2cap_internal.h"
status_t l2cap_l2ca_con_ind(L2capChannel* channel); 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_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_req(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_dis_req(L2capChannel* channel);
+1 -1
View File
@@ -130,7 +130,7 @@ RemoteDevice::Authenticate()
BluetoothCommand<typed_command(hci_cp_create_conn)> BluetoothCommand<typed_command(hci_cp_create_conn)>
createConnection(OGF_LINK_CONTROL, OCF_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_rep_mode = fPageRepetitionMode;
createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1 createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1
createConnection->clock_offset = fClockOffset | 0x8000; // substract! createConnection->clock_offset = fClockOffset | 0x8000; // substract!
@@ -24,7 +24,6 @@
#include <bluetooth/HCI/btHCI_command.h> #include <bluetooth/HCI/btHCI_command.h>
#include <bluetooth/L2CAP/btL2CAP.h> #include <bluetooth/L2CAP/btL2CAP.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/bluetooth_util.h>
#include "BluetoothServer.h" #include "BluetoothServer.h"
#include "DeskbarReplicant.h" #include "DeskbarReplicant.h"
+1 -1
View File
@@ -975,7 +975,7 @@ LocalDeviceImpl::LinkKeyRequested(struct hci_ev_link_key_req* keyRequested,
BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)> BluetoothCommand<typed_command(hci_cp_link_key_neg_reply)>
linkKeyNegativeReply(OGF_LINK_CONTROL, OCF_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(), if ((fHCIDelegate)->IssueCommand(linkKeyNegativeReply.Data(),
linkKeyNegativeReply.Size()) == B_ERROR) { linkKeyNegativeReply.Size()) == B_ERROR) {