From 9760dcae2038d47442f4658c2575844c6cf92c40 Mon Sep 17 00:00:00 2001 From: Oliver Ruiz Dorantes Date: Sun, 17 Jan 2010 15:46:36 +0000 Subject: [PATCH] - Move bluetooth net_device module to a independent module HCI, remake API interfaces - Move functionality for assembling ACL/events packets of the driver to this module - Move h2generic driver to c++ (not style) - Pass checkstyle.py to all commited files. Fixes: - Wrong condition for finishing l2cap packet segmentation. - Place NetBuffersPrependers in a inner scope to avoid Sycing twice in destructor. - Avoid keeping trace of l2cap responses of any other kind of thread. - Do not free net_buffers of for Frame containers. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35117 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/bluetooth/HCI/btHCI_module.h | 35 -- headers/os/bluetooth/HCI/btHCI_transport.h | 167 +++++--- headers/private/bluetooth/btCoreData.h | 361 +++++++++--------- headers/private/bluetooth/btModules.h | 23 +- src/add-ons/kernel/bluetooth/Jamfile | 1 + .../bluetooth/btCoreData/BTCoreData.cpp | 94 +++-- src/add-ons/kernel/bluetooth/hci/Jamfile | 16 + .../bluetooth => bluetooth/hci}/acl.cpp | 57 +-- .../devices/bluetooth => bluetooth/hci}/acl.h | 0 .../bluetooth => bluetooth/hci}/bluetooth.cpp | 340 +++++++---------- .../drivers/bluetooth/h2/h2generic/Jamfile | 10 +- .../drivers/bluetooth/h2/h2generic/h2cfg.h | 23 +- .../h2generic/{h2generic.c => h2generic.cpp} | 334 ++++++++-------- .../bluetooth/h2/h2generic/h2generic.h | 49 +-- .../{h2transactions.c => h2transactions.cpp} | 189 ++------- .../bluetooth/h2/h2generic/h2transactions.h | 2 - .../drivers/bluetooth/h2/h2generic/h2upper.c | 187 --------- .../bluetooth/h2/h2generic/h2upper.cpp | 189 +++++++++ .../drivers/bluetooth/h2/h2generic/h2upper.h | 13 +- .../h2/h2generic/{h2util.c => h2util.cpp} | 32 +- .../drivers/bluetooth/h2/h2generic/h2util.h | 14 +- .../{snet_buffer.c => snet_buffer.cpp} | 102 ++--- .../bluetooth/h2/h2generic/snet_buffer.h | 34 +- src/add-ons/kernel/network/devices/Jamfile | 2 +- .../kernel/network/devices/bluetooth/Jamfile | 27 -- .../network/protocols/l2cap/l2cap_lower.cpp | 115 +++--- 26 files changed, 1157 insertions(+), 1259 deletions(-) delete mode 100644 headers/os/bluetooth/HCI/btHCI_module.h create mode 100644 src/add-ons/kernel/bluetooth/hci/Jamfile rename src/add-ons/kernel/{network/devices/bluetooth => bluetooth/hci}/acl.cpp (69%) rename src/add-ons/kernel/{network/devices/bluetooth => bluetooth/hci}/acl.h (100%) rename src/add-ons/kernel/{network/devices/bluetooth => bluetooth/hci}/bluetooth.cpp (55%) rename src/add-ons/kernel/drivers/bluetooth/h2/h2generic/{h2generic.c => h2generic.cpp} (69%) rename src/add-ons/kernel/drivers/bluetooth/h2/h2generic/{h2transactions.c => h2transactions.cpp} (58%) delete mode 100644 src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.c create mode 100644 src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.cpp rename src/add-ons/kernel/drivers/bluetooth/h2/h2generic/{h2util.c => h2util.cpp} (84%) rename src/add-ons/kernel/drivers/bluetooth/h2/h2generic/{snet_buffer.c => snet_buffer.cpp} (58%) delete mode 100644 src/add-ons/kernel/network/devices/bluetooth/Jamfile diff --git a/headers/os/bluetooth/HCI/btHCI_module.h b/headers/os/bluetooth/HCI/btHCI_module.h deleted file mode 100644 index af548ae3a2..0000000000 --- a/headers/os/bluetooth/HCI/btHCI_module.h +++ /dev/null @@ -1,35 +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 _BTHCI_MODULE_H_ -#define _BTHCI_MODULE_H_ - -/* includes */ - -#include -#include -#include - -/* defines */ -#define BT_HCI_MODULE_NAME "bus_managers/hci/v1" - -/* TODO: Possible definition of a bus manager of whatever is gonna be on the top */ -typedef struct bt_hci_module_info { - /* registration */ - status_t (*RegisterDriver)(bt_hci_transport* desc, hci_id *id /*out*/, - bt_hci_device* cookie /*out*/ ); - status_t (*UnregisterDriver)(hci_id id); - - /* Transferences to be called from drivers */ - - status_t (*PostACL)(hci_id id, net_buffer* nbuf); - status_t (*PostSCO)(hci_id id, net_buffer* nbuf); - - /* Management */ - bt_hci_device* (*GetHciDevice)(hci_id id); - -} bt_hci_module_info ; - - -#endif // _BTHCI_MODULE_H_ diff --git a/headers/os/bluetooth/HCI/btHCI_transport.h b/headers/os/bluetooth/HCI/btHCI_transport.h index 6960ce31e5..556078a77c 100644 --- a/headers/os/bluetooth/HCI/btHCI_transport.h +++ b/headers/os/bluetooth/HCI/btHCI_transport.h @@ -7,53 +7,46 @@ #include +#include + #include #include -typedef enum { ANCILLYANT = (1<<0), - RUNNING = (1<<1), - LEAVING = (1<<2), - SENDING = (1<<3), - PROCESSING = (1<<4) - } bt_transport_status_t; + +typedef enum { + ANCILLYANT = (1<<0), + RUNNING = (1<<1), + LEAVING = (1<<2), + SENDING = (1<<3), + PROCESSING = (1<<4) +} bt_transport_status_t; + typedef uint8 bt_stat_t; typedef struct bt_hci_statistics { - bt_stat_t acceptedTX; - bt_stat_t rejectedTX; - bt_stat_t successfulTX; - bt_stat_t errorTX; + bt_stat_t acceptedTX; + bt_stat_t rejectedTX; + bt_stat_t successfulTX; + bt_stat_t errorTX; - bt_stat_t acceptedRX; - bt_stat_t rejectedRX; - bt_stat_t successfulRX; - bt_stat_t errorRX; + bt_stat_t acceptedRX; + bt_stat_t rejectedRX; + bt_stat_t successfulRX; + bt_stat_t errorRX; - bt_stat_t commandTX; - bt_stat_t eventRX; - bt_stat_t aclTX; - bt_stat_t aclRX; - bt_stat_t scoTX; - bt_stat_t scoRX; - bt_stat_t escoTX; - bt_stat_t escoRX; + bt_stat_t commandTX; + bt_stat_t eventRX; + bt_stat_t aclTX; + bt_stat_t aclRX; + bt_stat_t scoTX; + bt_stat_t scoRX; + bt_stat_t escoTX; + bt_stat_t escoRX; - bt_stat_t bytesRX; - bt_stat_t bytesTX; + bt_stat_t bytesRX; + bt_stat_t bytesTX; } bt_hci_statistics; -/* TODO: Possible hooks which drivers will have to provide */ -typedef struct bt_hci_transport { - - status_t (*SendCommand)(hci_id hci_dev, net_buffer *snbuf); - status_t (*SendPacket)(hci_id hci_dev, net_buffer *nbuf ); - status_t (*SendSCO)(hci_id hci_dev, net_buffer *nbuf ); - status_t (*DeliverStatistics)(bt_hci_statistics *statistics); - - transport_type kind; - char name[B_OS_NAME_LENGTH]; - -} bt_hci_transport; typedef struct bt_hci_device { transport_type kind; @@ -61,35 +54,109 @@ typedef struct bt_hci_device { } bt_hci_device; -/* Here the transport driver have some flags that */ -/* can be used to inform the upper layer about some */ -/* special behaouvior to perform */ +/* Hooks which drivers will have to provide. + * The structure is meant to be allocated in driver side and + * provided to the HCI where it will fill the remaining fields + */ +typedef struct bt_hci_transport_hooks { -#define BT_IGNORE_THIS_DEVICE (1<<0) -#define BT_SCO_NOT_WORKING (1<<1) -#define BT_WILL_NEED_A_RESET (1<<2) -#define BT_DIGIANSWER (1<<4) + // to be filled by driver + status_t (*SendCommand)(hci_id hciId, void* command); + status_t (*SendACL)(hci_id hciId, net_buffer* nbuf ); + status_t (*SendSCO)(hci_id hciId, net_buffer* nbuf ); + status_t (*SendESCO)(hci_id hciId, net_buffer* nbuf ); -/* Mandatory IOCTLS to be */ + status_t (*DeliverStatistics)(hci_id hciId, bt_hci_statistics* statistics); + transport_type kind; + +} bt_hci_transport_hooks; + +typedef struct bt_hci_device_information { + + uint32 flags; + uint16 vendorId; + uint16 deviceId; + char name[B_OS_NAME_LENGTH]; + +} bt_hci_device_information; + + +#ifdef __cplusplus + +struct bluetooth_device : DoublyLinkedListLinkImpl { + + net_buffer* fBuffersRx[HCI_NUM_PACKET_TYPES]; + size_t fExpectedPacketSize[HCI_NUM_PACKET_TYPES]; + hci_id index; + + int fd; + + bt_hci_device_information* info; + bt_hci_transport_hooks* hooks; + uint16 mtu; + +}; + +#else + +struct bluetooth_device; + +#endif + + +#define BT_HCI_MODULE_NAME "bluetooth/hci/v1" + +// Possible definition of a bus manager +typedef struct bt_hci_module_info { + module_info info; + // Registration in Stack + status_t (*RegisterDriver)(bt_hci_transport_hooks* hooks, + bluetooth_device** device); + status_t (*UnregisterDriver)(hci_id id); + bluetooth_device* (*FindDeviceByID)(hci_id id); + + // to be called from transport driver + status_t (*PostTransportPacket)(hci_id hid, bt_packet_t type, + void* data, size_t count); + + // To be called from upper layers + status_t (*PostACL)(hci_id hciId, net_buffer* buffer); + status_t (*PostSCO)(hci_id hciId, net_buffer* buffer); + status_t (*PostESCO)(hci_id hciId, net_buffer* buffer); + +} bt_hci_module_info ; + + +/* Here the transport driver have some flags that + * can be used to inform the upper layer about some + * special behaouvior to perform */ + +#define BT_IGNORE_THIS_DEVICE (1 << 0) +#define BT_SCO_NOT_WORKING (1 << 1) +#define BT_WILL_NEED_A_RESET (1 << 2) +#define BT_DIGIANSWER (1 << 4) + +// Mandatory IOCTLS #define BT_IOCTLS_OFFSET 3000 enum { - ISSUE_BT_COMMAND = B_DEVICE_OP_CODES_END + BT_IOCTLS_OFFSET, //12999 + ISSUE_BT_COMMAND = B_DEVICE_OP_CODES_END + BT_IOCTLS_OFFSET, // 12999 GET_STATS, GET_NOTIFICATION_PORT, GET_HCI_ID, BT_UP }; -#define PACK_PORTCODE(type,hid,data) ((type&0xFF)<<24|(hid&0xFF)<<16|(data&0xFFFF)) -#define GET_PORTCODE_TYPE(code) ((code&0xFF000000)>>24) -#define GET_PORTCODE_HID(code) ((code&0x00FF0000)>>16) -#define GET_PORTCODE_DATA(code) ((code&0x0000FFFF)) +#define PACK_PORTCODE(type,hid,data) ((type & 0xFF) << 24 | (hid & 0xFF) << 16 | (data & 0xFFFF)) +#define GET_PORTCODE_TYPE(code) ((code & 0xFF000000) >> 24) +#define GET_PORTCODE_HID(code) ((code & 0x00FF0000) >> 16) +#define GET_PORTCODE_DATA(code) ((code & 0x0000FFFF)) /* Port drivers can use to send information (1 for all for at moment refer to ioctl GET_NOTIFICATION_PORT)*/ -#define BT_USERLAND_PORT_NAME "Kernel-User Event" +#define BT_USERLAND_PORT_NAME "BT Kernel-User Event" +#define BT_RX_PORT_NAME "BT Kernel RX assembly" #define BLUETOOTH_CONNECTION_PORT "bluetooth connection port" #define BLUETOOTH_CONNECTION_SCHED_PORT "bluetooth con sched port" diff --git a/headers/private/bluetooth/btCoreData.h b/headers/private/bluetooth/btCoreData.h index 8885807667..0ef4da4451 100644 --- a/headers/private/bluetooth/btCoreData.h +++ b/headers/private/bluetooth/btCoreData.h @@ -1,173 +1,188 @@ -/* - * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _BTCOREDATA_H -#define _BTCOREDATA_H - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define BT_CORE_DATA_MODULE_NAME "bluetooth/btCoreData/v1" - -struct L2capChannel; -struct L2capFrame; -struct L2capEndpoint; - -typedef enum _connection_status { - HCI_CONN_CLOSED, - HCI_CONN_OPEN, -} connection_status; - -#ifdef __cplusplus - -struct HciConnection : DoublyLinkedListLinkImpl { - HciConnection(); - virtual ~HciConnection(); - - hci_id Hid; - struct net_device* ndevice; - net_buffer* currentRxPacket; - ssize_t currentRxExpectedLength; - bdaddr_t destination; - uint16 handle; - int type; - uint16 mtu; - connection_status status; /* ACL connection state */ - uint16 lastCid; - uint8 lastIdent; - DoublyLinkedList ChannelList; - DoublyLinkedList ExpectedResponses; - DoublyLinkedList OutGoingFrames; - mutex fLock; - mutex fLockExpected; -}; - -#else - -struct HciConnection; - -#endif - -typedef enum _channel_status { - L2CAP_CHAN_CLOSED, /* channel closed */ - L2CAP_CHAN_W4_L2CAP_CON_RSP, /* wait for L2CAP resp. */ - L2CAP_CHAN_W4_L2CA_CON_RSP, /* wait for upper resp. */ - L2CAP_CHAN_CONFIG, /* L2CAP configuration */ - L2CAP_CHAN_OPEN, /* channel open */ - L2CAP_CHAN_W4_L2CAP_DISCON_RSP, /* wait for L2CAP discon. */ - L2CAP_CHAN_W4_L2CA_DISCON_RSP /* wait for upper discon. */ -} channel_status; - - -#ifdef __cplusplus - -typedef struct _ChannelConfiguration { - - uint16 imtu; /* incoming channel MTU */ - l2cap_flow_t iflow; /* incoming flow control */ - uint16 omtu; /* outgoing channel MTU */ - l2cap_flow_t oflow; /* outgoing flow control */ - - uint16 flush_timo; /* flush timeout */ - uint16 link_timo; /* link timeout */ - -} ChannelConfiguration; - -struct L2capChannel : DoublyLinkedListLinkImpl { - HciConnection* conn; - uint16 scid; - uint16 dcid; - uint16 psm; - uint8 ident; - uint8 cfgState; - - channel_status state; - ChannelConfiguration* configuration; - L2capEndpoint* endpoint; -}; - -#endif - - -typedef enum _frametype { - L2CAP_C_FRAME, // signals - L2CAP_G_FRAME, // CL packets - L2CAP_B_FRAME, // CO packets - - L2CAP_I_FRAME, - L2CAP_S_FRAME -} frame_type; - -#ifdef __cplusplus - -struct L2capFrame : DoublyLinkedListLinkImpl { - - HciConnection* conn; - L2capChannel* channel; - - uint16 flags; /* command flags */ - #define L2CAP_CMD_PENDING (1 << 0) /* command is pending */ - - uint8 code; /* L2CAP command opcode */ - uint8 ident; /* L2CAP command ident */ - - frame_type type; - - net_buffer* buffer; // contains 1 l2cap / mutliple acls - - //TODO :struct callout timo; /* RTX/ERTX timeout */ -}; - -#endif - - -struct bluetooth_core_data_module_info { - module_info info; - - status_t (*PostEvent)(struct net_device* ndev, void* event, size_t size); - struct HciConnection* (*AddConnection)(uint16 handle, int type, bdaddr_t* dst, hci_id hid); - - /*status_t (*RemoveConnection)(bdaddr_t destination, hci_id hid);*/ - status_t (*RemoveConnection)(uint16 handle, hci_id hid); - - hci_id (*RouteConnection)(bdaddr_t* destination); - - void (*SetAclBuffer)(struct HciConnection* conn, net_buffer* nbuf); - void (*SetAclExpectedSize)(struct HciConnection* conn, size_t size); - void (*AclPutting)(struct HciConnection* conn, size_t size); - bool (*AclComplete)(struct HciConnection* conn); - bool (*AclOverFlowed)(struct HciConnection* conn); - - struct HciConnection* (*ConnectionByHandle)(uint16 handle, hci_id hid); - struct HciConnection* (*ConnectionByDestination)(bdaddr_t* destination, hci_id hid); - - struct L2capChannel* (*AddChannel)(struct HciConnection* conn, uint16 psm); - void (*RemoveChannel)(struct HciConnection* conn, uint16 scid); - struct L2capChannel* (*ChannelBySourceID)(struct HciConnection* conn, uint16 sid); - uint16 (*ChannelAllocateCid)(struct HciConnection* conn); - uint16 (*ChannelAllocateIdent)(struct HciConnection* conn); - - struct L2capFrame* (*SignalByIdent)(struct HciConnection* conn, uint8 ident); - status_t (*TimeoutSignal)(struct L2capFrame* frame, uint32 timeo); - status_t (*UnTimeoutSignal)(struct L2capFrame* frame); - struct L2capFrame* (*SpawnFrame)(struct HciConnection* conn, struct L2capChannel* channel, net_buffer* buffer, frame_type frame); - struct L2capFrame* (*SpawnSignal)(struct HciConnection* conn, struct L2capChannel* channel, net_buffer* buffer, uint8 ident, uint8 code); - status_t (*AcknowledgeSignal)(struct L2capFrame* frame); - status_t (*QueueSignal)(struct L2capFrame* frame); - -}; - -inline bool ExistConnectionByDestination(bdaddr_t* destination, hci_id hid); -inline bool ExistConnectionByHandle(uint16 handle, hci_id hid); - -#endif // _BTCOREDATA_H +/* + * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _BTCOREDATA_H +#define _BTCOREDATA_H + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#define BT_CORE_DATA_MODULE_NAME "bluetooth/btCoreData/v1" + +struct L2capChannel; +struct L2capFrame; +struct L2capEndpoint; + +typedef enum _connection_status { + HCI_CONN_CLOSED, + HCI_CONN_OPEN, +} connection_status; + +#ifdef __cplusplus + +struct HciConnection : DoublyLinkedListLinkImpl { + HciConnection(); + virtual ~HciConnection(); + + hci_id Hid; + bluetooth_device* ndevice; + net_buffer* currentRxPacket; + ssize_t currentRxExpectedLength; + bdaddr_t destination; + uint16 handle; + int type; + uint16 mtu; + connection_status status; + uint16 lastCid; + uint8 lastIdent; + DoublyLinkedList ChannelList; + DoublyLinkedList ExpectedResponses; + DoublyLinkedList OutGoingFrames; + mutex fLock; + mutex fLockExpected; +}; + +#else + +struct HciConnection; + +#endif + +typedef enum _channel_status { + L2CAP_CHAN_CLOSED, /* channel closed */ + L2CAP_CHAN_W4_L2CAP_CON_RSP, /* wait for L2CAP resp. */ + L2CAP_CHAN_W4_L2CA_CON_RSP, /* wait for upper resp. */ + L2CAP_CHAN_CONFIG, /* L2CAP configuration */ + L2CAP_CHAN_OPEN, /* channel open */ + L2CAP_CHAN_W4_L2CAP_DISCON_RSP, /* wait for L2CAP discon. */ + L2CAP_CHAN_W4_L2CA_DISCON_RSP /* wait for upper discon. */ +} channel_status; + + +#ifdef __cplusplus + +typedef struct _ChannelConfiguration { + + uint16 imtu; /* incoming channel MTU */ + l2cap_flow_t iflow; /* incoming flow control */ + uint16 omtu; /* outgoing channel MTU */ + l2cap_flow_t oflow; /* outgoing flow control */ + + uint16 flush_timo; /* flush timeout */ + uint16 link_timo; /* link timeout */ + +} ChannelConfiguration; + +struct L2capChannel : DoublyLinkedListLinkImpl { + HciConnection* conn; + uint16 scid; + uint16 dcid; + uint16 psm; + uint8 ident; + uint8 cfgState; + + channel_status state; + ChannelConfiguration* configuration; + L2capEndpoint* endpoint; +}; + +#endif + + +typedef enum _frametype { + L2CAP_C_FRAME, // signals + L2CAP_G_FRAME, // CL packets + L2CAP_B_FRAME, // CO packets + + L2CAP_I_FRAME, + L2CAP_S_FRAME +} frame_type; + +#ifdef __cplusplus + +struct L2capFrame : DoublyLinkedListLinkImpl { + + HciConnection* conn; + L2capChannel* channel; + + uint16 flags; /* command flags */ + #define L2CAP_CMD_PENDING (1 << 0) /* command is pending */ + + uint8 code; /* L2CAP command opcode */ + uint8 ident; /* L2CAP command ident */ + + frame_type type; + + net_buffer* buffer; // contains 1 l2cap / mutliple acls + + // TODO :struct callout timo; /* RTX/ERTX timeout */ +}; + +#endif + + +struct bluetooth_core_data_module_info { + module_info info; + + status_t (*PostEvent)(bluetooth_device* ndev, void* event, + size_t size); + struct HciConnection* (*AddConnection)(uint16 handle, int type, + bdaddr_t* dst, hci_id hid); + + // status_t (*RemoveConnection)(bdaddr_t destination, hci_id hid); + status_t (*RemoveConnection)(uint16 handle, hci_id hid); + + hci_id (*RouteConnection)(bdaddr_t* destination); + + void (*SetAclBuffer)(struct HciConnection* conn, + net_buffer* nbuf); + void (*SetAclExpectedSize)(struct HciConnection* conn, + size_t size); + void (*AclPutting)(struct HciConnection* conn, + size_t size); + bool (*AclComplete)(struct HciConnection* conn); + bool (*AclOverFlowed)(struct HciConnection* conn); + + struct HciConnection* (*ConnectionByHandle)(uint16 handle, hci_id hid); + struct HciConnection* (*ConnectionByDestination)(bdaddr_t* destination, + hci_id hid); + + struct L2capChannel* (*AddChannel)(struct HciConnection* conn, + uint16 psm); + void (*RemoveChannel)(struct HciConnection* conn, + uint16 scid); + struct L2capChannel* (*ChannelBySourceID)(struct HciConnection* conn, + uint16 sid); + uint16 (*ChannelAllocateCid)(struct HciConnection* conn); + uint16 (*ChannelAllocateIdent)(struct HciConnection* conn); + + struct L2capFrame* (*SignalByIdent)(struct HciConnection* conn, + uint8 ident); + status_t (*TimeoutSignal)(struct L2capFrame* frame, uint32 timeo); + status_t (*UnTimeoutSignal)(struct L2capFrame* frame); + struct L2capFrame* (*SpawnFrame)(struct HciConnection* conn, + struct L2capChannel* channel, net_buffer* buffer, frame_type frame); + struct L2capFrame* (*SpawnSignal)(struct HciConnection* conn, + struct L2capChannel* channel, net_buffer* buffer, + uint8 ident, uint8 code); + status_t (*AcknowledgeSignal)(struct L2capFrame* frame); + status_t (*QueueSignal)(struct L2capFrame* frame); + +}; + + +inline bool ExistConnectionByDestination(bdaddr_t* destination, hci_id hid); +inline bool ExistConnectionByHandle(uint16 handle, hci_id hid); + +#endif // _BTCOREDATA_H diff --git a/headers/private/bluetooth/btModules.h b/headers/private/bluetooth/btModules.h index ffb43ff0af..bd02cf49d7 100644 --- a/headers/private/bluetooth/btModules.h +++ b/headers/private/bluetooth/btModules.h @@ -1,12 +1,11 @@ -/* - * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * All rights reserved. Distributed under the terms of the MIT License. - */ -#ifndef _BTMODULES_H -#define _BTMODULES_H - - -#define NET_BLUETOOTH_DEVICE_NAME "network/devices/bluetooth/v1" -#define NET_BLUETOOTH_L2CAP_NAME "network/protocols/l2cap/v1" - -#endif // _BCOREDATA_H +/* + * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef _BTMODULES_H +#define _BTMODULES_H + + +#define NET_BLUETOOTH_L2CAP_NAME "network/protocols/l2cap/v1" + +#endif // _BCOREDATA_H diff --git a/src/add-ons/kernel/bluetooth/Jamfile b/src/add-ons/kernel/bluetooth/Jamfile index 6e50736c62..b5b4bc97df 100644 --- a/src/add-ons/kernel/bluetooth/Jamfile +++ b/src/add-ons/kernel/bluetooth/Jamfile @@ -1,3 +1,4 @@ SubDir HAIKU_TOP src add-ons kernel bluetooth ; SubInclude HAIKU_TOP src add-ons kernel bluetooth btCoreData ; +SubInclude HAIKU_TOP src add-ons kernel bluetooth hci ; diff --git a/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp b/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp index 1c93fc4ac9..3b2f0deee7 100644 --- a/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp +++ b/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp @@ -15,10 +15,11 @@ #include DoublyLinkedList sConnectionList; -net_buffer_module_info *gBufferModule = NULL; +net_buffer_module_info* gBufferModule = NULL; + inline bool -ExistConnectionByDestination(bdaddr_t *destination, hci_id hid = -1) +ExistConnectionByDestination(bdaddr_t* destination, hci_id hid = -1) { return (ConnectionByDestination(destination, hid) != NULL); } @@ -27,7 +28,7 @@ ExistConnectionByDestination(bdaddr_t *destination, hci_id hid = -1) inline bool ExistConnectionByHandle(uint16 handle, hci_id hid) { - return (ConnectionByHandle(handle,hid)); + return (ConnectionByHandle(handle, hid)); } @@ -37,39 +38,48 @@ DumpHciConnections(int argc, char** argv) HciConnection* conn; L2capChannel* chan; L2capFrame* frame; - DoublyLinkedList::Iterator iterator = sConnectionList.GetIterator(); + DoublyLinkedList::Iterator iterator + = sConnectionList.GetIterator(); while (iterator.HasNext()) { conn = iterator.Next(); - kprintf("LocalDevice=%lx Destination=%s handle=%#x type=%d outqueue=%ld expected=%ld\n", - conn->Hid, bdaddrUtils::ToString(conn->destination), - conn->handle, conn->type, conn->OutGoingFrames.Count() , conn->ExpectedResponses.Count()); + kprintf("LocalDevice=%lx Destination=%s handle=%#x type=%d" + "outqueue=%ld expected=%ld\n", conn->Hid, + bdaddrUtils::ToString(conn->destination), conn->handle, conn->type, + conn->OutGoingFrames.Count() , conn->ExpectedResponses.Count()); // each channel kprintf("\tChannels\n"); - DoublyLinkedList::Iterator channelIterator = conn->ChannelList.GetIterator(); + DoublyLinkedList::Iterator channelIterator + = conn->ChannelList.GetIterator(); + while (channelIterator.HasNext()) { chan = channelIterator.Next(); kprintf("\t\tscid=%x dcid=%x state=%x cfg=%x\n", chan->scid, - chan->dcid, chan->state, chan->cfgState); + chan->dcid, chan->state, chan->cfgState); } // Each outgoing kprintf("\n\tOutGoingFrames\n"); - DoublyLinkedList::Iterator frameIterator = conn->OutGoingFrames.GetIterator(); + DoublyLinkedList::Iterator frameIterator + = conn->OutGoingFrames.GetIterator(); while (frameIterator.HasNext()) { frame = frameIterator.Next(); - kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", frame->channel->scid, - frame->code, frame->ident, frame->type, frame->buffer); + kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", + frame->channel->scid, frame->code, frame->ident, + frame->type, frame->buffer); } // Each expected kprintf("\n\tExpectedFrames\n"); - DoublyLinkedList::Iterator frameExpectedIterator = conn->ExpectedResponses.GetIterator(); + DoublyLinkedList::Iterator frameExpectedIterator + = conn->ExpectedResponses.GetIterator(); + while (frameExpectedIterator.HasNext()) { frame = frameExpectedIterator.Next(); - kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", frame->channel->scid, - frame->code, frame->ident, frame->type, frame->buffer); + kprintf("\t\tscid=%x code=%x ident=%x type=%x, buffer=%p\n", + frame->channel->scid, frame->code, frame->ident, + frame->type, frame->buffer); } } @@ -77,9 +87,8 @@ DumpHciConnections(int argc, char** argv) } - status_t -PostEvent(net_device* ndev, void* event, size_t size) +PostEvent(bluetooth_device* ndev, void* event, size_t size) { struct hci_event_header* outgoingEvent = (struct hci_event_header*) event; status_t err; @@ -88,41 +97,49 @@ PostEvent(net_device* ndev, void* event, size_t size) switch (outgoingEvent->ecode) { case HCI_EVENT_CONN_COMPLETE: { - struct hci_ev_conn_complete* data = (struct hci_ev_conn_complete*)(outgoingEvent+1); - //TODO: XXX parse handle field - HciConnection* conn = AddConnection(data->handle, BT_ACL, &data->bdaddr, ndev->index); + struct hci_ev_conn_complete* data + = (struct hci_ev_conn_complete*)(outgoingEvent + 1); + + // TODO: XXX parse handle field + HciConnection* conn = AddConnection(data->handle, BT_ACL, + &data->bdaddr, ndev->index); + if (conn == NULL) panic("no mem for conn desc"); conn->ndevice = ndev; debugf("Registered connection handle=%#x\n",data->handle); - - } break; + break; + } case HCI_EVENT_DISCONNECTION_COMPLETE: { - struct hci_ev_disconnection_complete_reply* data = - (struct hci_ev_disconnection_complete_reply*)(outgoingEvent+1); + struct hci_ev_disconnection_complete_reply* data; + + data = (struct hci_ev_disconnection_complete_reply*) + (outgoingEvent + 1); + RemoveConnection(data->handle, ndev->index); debugf("unRegistered connection handle=%#x\n",data->handle); - } break; + break; + } + } // forward to bluetooth server port_id port = find_port(BT_USERLAND_PORT_NAME); - if (port != B_NAME_NOT_FOUND) { + if (port != B_NAME_NOT_FOUND) { err = write_port_etc(port, PACK_PORTCODE(BT_EVENT, ndev->index, -1), - event, size, B_TIMEOUT, 1*1000*1000); + event, size, B_TIMEOUT, 1 * 1000 * 1000); if (err != B_OK) debugf("Error posting userland %s\n", strerror(err)); - } else { - flowf("ERROR:bluetooth_server not found for posting\n"); - err = B_NAME_NOT_FOUND; + } else { + flowf("ERROR:bluetooth_server not found for posting\n"); + err = B_NAME_NOT_FOUND; } - return err; } @@ -136,12 +153,12 @@ bcd_std_ops(int32 op, ...) case B_MODULE_INIT: new (&sConnectionList) DoublyLinkedList; add_debugger_command("btConnections", &DumpHciConnections, - "Lists Bluetooth Connections with RemoteDevices & channels"); + "Lists Bluetooth Connections with RemoteDevices & channels"); - status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule); - if (status < B_OK) { + status = get_module(NET_BUFFER_MODULE_NAME, + (module_info **)&gBufferModule); + if (status < B_OK) return status; - } return B_OK; @@ -159,6 +176,7 @@ bcd_std_ops(int32 op, ...) return B_ERROR; } + bluetooth_core_data_module_info sBCDModule = { { BT_CORE_DATA_MODULE_NAME, @@ -167,7 +185,7 @@ bluetooth_core_data_module_info sBCDModule = { }, PostEvent, AddConnection, -/* RemoveConnection,*/ + // RemoveConnection, RemoveConnection, RouteConnection, @@ -198,7 +216,7 @@ bluetooth_core_data_module_info sBCDModule = { }; -module_info *modules[] = { - (module_info *)&sBCDModule, +module_info* modules[] = { + (module_info*)&sBCDModule, NULL }; diff --git a/src/add-ons/kernel/bluetooth/hci/Jamfile b/src/add-ons/kernel/bluetooth/hci/Jamfile new file mode 100644 index 0000000000..5cf637f091 --- /dev/null +++ b/src/add-ons/kernel/bluetooth/hci/Jamfile @@ -0,0 +1,16 @@ +SubDir HAIKU_TOP src add-ons kernel bluetooth hci ; + +UsePrivateKernelHeaders ; +UsePrivateHeaders net bluetooth ; +UsePrivateHeaders [ FDirName kernel arch $(TARGET_ARCH) ] ; +UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; + +# disable debug output, if debugging is disabled +if $(DEBUG) = 0 { + SubDirCcFlags [ FDefines DEBUG_MAX_LEVEL_FLOW=0 DEBUG_MAX_LEVEL_INFO=0 ] ; +} + +KernelAddon hci : + bluetooth.cpp + acl.cpp +; diff --git a/src/add-ons/kernel/network/devices/bluetooth/acl.cpp b/src/add-ons/kernel/bluetooth/hci/acl.cpp similarity index 69% rename from src/add-ons/kernel/network/devices/bluetooth/acl.cpp rename to src/add-ons/kernel/bluetooth/hci/acl.cpp index c854d7ca7b..7db3941bef 100644 --- a/src/add-ons/kernel/network/devices/bluetooth/acl.cpp +++ b/src/add-ons/kernel/bluetooth/hci/acl.cpp @@ -38,14 +38,14 @@ AclAssembly(net_buffer* nbuf, hci_id hid) { status_t error = B_OK; - /* Check ACL data packet. Driver should ensure report complete ACL packets */ + // 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); + debugf("Invalid ACL data packet, small length=%ld\n", nbuf->size); gBufferModule->free(nbuf); return (EMSGSIZE); } - /* Strip ACL data packet header */ + // Strip ACL data packet header NetBufferHeaderReader aclHeader(nbuf); status_t status = aclHeader.Status(); if (status < B_OK) { @@ -54,26 +54,25 @@ AclAssembly(net_buffer* nbuf, hci_id hid) } - /* Get ACL connection handle, PB flag and payload length */ + // 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(); + aclHeader.Remove(); - debugf("got ACL data packet, con_handle=%#x, PB=%#x, length=%d\n", con_handle, pb, length); + debugf("ACL data packet, 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 - */ + // a) Ensure there is HCI connection + // b) Get connection descriptor + // c) veryfy the status of the connection - HciConnection* conn = btCoreData->ConnectionByHandle(con_handle, hid); + 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"); + debugf("Uexpected handle=%#x does not exist!\n", con_handle); conn = btCoreData->AddConnection(con_handle, BT_ACL, BDADDR_NULL, hid); } @@ -85,10 +84,11 @@ AclAssembly(net_buffer* nbuf, hci_id hid) } - /* Process packet */ + // 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 ); + debugf("Dropping incomplete L2CAP packet, got %ld want %d \n", + conn->currentRxPacket->size, length ); gBufferModule->free(conn->currentRxPacket); conn->currentRxPacket = NULL; conn->currentRxExpectedLength = 0; @@ -96,7 +96,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid) // 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); + debugf("Invalid L2CAP start fragment, small, length=%ld\n", + nbuf->size); gBufferModule->free(nbuf); return (EMSGSIZE); } @@ -112,9 +113,10 @@ AclAssembly(net_buffer* nbuf, hci_id hid) 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)); + debugf("New L2CAP, handle=%#x length=%d\n", con_handle, + le16toh(l2capHeader->length)); - /* Start new L2CAP packet */ + // Start new L2CAP packet conn->currentRxPacket = nbuf; conn->currentRxExpectedLength = l2capHeader->length + sizeof(l2cap_hdr_t); @@ -125,7 +127,7 @@ AclAssembly(net_buffer* nbuf, hci_id hid) return (EINVAL); } - /* Add fragment to the L2CAP packet */ + // Add fragment to the L2CAP packet gBufferModule->merge(conn->currentRxPacket, nbuf, true); } else { @@ -134,12 +136,14 @@ AclAssembly(net_buffer* nbuf, hci_id hid) return (EINVAL); } - conn->currentRxExpectedLength -= length; /* substract the length of content of the ACL packet*/ + // substract the length of content of the ACL packet + conn->currentRxExpectedLength -= length; if (conn->currentRxExpectedLength < 0) { - debugf("packet length mismatch. Got %ld bytes, expected %ld bytes\n", conn->currentRxPacket->size, - conn->currentRxExpectedLength); + debugf("Mismatch. Got %ld, expected %ld\n", + conn->currentRxPacket->size, conn->currentRxExpectedLength); + gBufferModule->free(conn->currentRxPacket); conn->currentRxPacket = NULL; conn->currentRxExpectedLength = 0; @@ -152,7 +156,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid) conn->currentRxPacket = NULL; conn->currentRxExpectedLength = 0; } else { - debugf("Expected %ld current acl apports %d\n", conn->currentRxExpectedLength, length); + debugf("Expected %ld current adds %d\n", + conn->currentRxExpectedLength, length); } return error; @@ -163,12 +168,12 @@ 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 + + return L2cap->receive_data((net_buffer*)conn);// XXX pass handle in type } diff --git a/src/add-ons/kernel/network/devices/bluetooth/acl.h b/src/add-ons/kernel/bluetooth/hci/acl.h similarity index 100% rename from src/add-ons/kernel/network/devices/bluetooth/acl.h rename to src/add-ons/kernel/bluetooth/hci/acl.h diff --git a/src/add-ons/kernel/network/devices/bluetooth/bluetooth.cpp b/src/add-ons/kernel/bluetooth/hci/bluetooth.cpp similarity index 55% rename from src/add-ons/kernel/network/devices/bluetooth/bluetooth.cpp rename to src/add-ons/kernel/bluetooth/hci/bluetooth.cpp index 2b4e137316..8a9cfba935 100644 --- a/src/add-ons/kernel/network/devices/bluetooth/bluetooth.cpp +++ b/src/add-ons/kernel/bluetooth/hci/bluetooth.cpp @@ -23,44 +23,45 @@ #include #define BT_DEBUG_THIS_MODULE -#define SUBMODULE_NAME "bluetooth_device" +#define SUBMODULE_NAME "hci" #define SUBMODULE_COLOR 34 #include #include #include #include +#define KERNEL_LAND +#include +#undef KERNEL_LAND #include #include #include #include +#include #include #include #include "acl.h" -struct bluetooth_device : net_device, DoublyLinkedListLinkImpl { - - net_buffer* fBuffersRx[HCI_NUM_PACKET_TYPES]; - size_t fExpectedPacketSize[HCI_NUM_PACKET_TYPES]; - int fd; - uint16 mtu; - -}; +typedef PortListener BluetoothRawDataPort; -/* Modules references */ +// Modules references 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 sDeviceList; static sem_id sLinkChangeSemaphore; +static DoublyLinkedList sDeviceList; + +BluetoothRawDataPort* BluetoothRXPort; // forward declarations -status_t bluetooth_receive_data(net_device* _device, net_buffer** _buffer); +status_t HciPacketHandler(void* data, int32 code, size_t size); bluetooth_device* @@ -68,11 +69,12 @@ FindDeviceByID(hci_id hid) { bluetooth_device* device; - DoublyLinkedList::Iterator iterator = sDeviceList.GetIterator(); - while (iterator.HasNext()) { + DoublyLinkedList::Iterator iterator + = sDeviceList.GetIterator(); + while (iterator.HasNext()) { device = iterator.Next(); - if (device->index == (uint32 )hid) + if (device->index == hid) return device; } @@ -81,9 +83,21 @@ FindDeviceByID(hci_id hid) status_t -Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) +PostTransportPacket(hci_id hid, bt_packet_t type, void* data, size_t count) +{ + uint32 code = 0; + + Bluetooth::CodeHandler::SetDevice(&code, hid); + Bluetooth::CodeHandler::SetProtocol(&code, type); + + return BluetoothRXPort->Trigger(code, data, count); +} + + +status_t +Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data, + size_t count) { - bluetooth_device* bluetoothDevice = (bluetooth_device*)netDevice; net_buffer* nbuf = bluetoothDevice->fBuffersRx[type]; size_t currentPacketLen = 0; @@ -95,15 +109,17 @@ Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) switch (type) { case BT_EVENT: if (count >= HCI_EVENT_HDR_SIZE) { - struct hci_event_header* headerPkt + struct hci_event_header* headerPacket = (struct hci_event_header*)data; bluetoothDevice->fExpectedPacketSize[type] - = HCI_EVENT_HDR_SIZE + headerPkt->elen; + = HCI_EVENT_HDR_SIZE + headerPacket->elen; - if (count > bluetoothDevice->fExpectedPacketSize[type]) { + if (count >= bluetoothDevice->fExpectedPacketSize[type]) { // the whole packet is here so it can be already posted. + flowf("EVENT posted in HCI!!!\n"); btCoreData->PostEvent(bluetoothDevice, data, bluetoothDevice->fExpectedPacketSize[type]); + } else { nbuf = gBufferModule->create( bluetoothDevice->fExpectedPacketSize[type]); @@ -113,7 +129,7 @@ Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) } } else { - flowf("EVENT frame corrupted\n"); + panic("EVENT frame corrupted\n"); return EILSEQ; } break; @@ -132,7 +148,7 @@ Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) nbuf->protocol = type; } else { - flowf("ACL frame corrupted\n"); + panic("ACL frame corrupted\n"); return EILSEQ; } break; @@ -152,22 +168,25 @@ Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) // Continuation of a packet currentPacketLen = bluetoothDevice->fExpectedPacketSize[type] - nbuf->size; } - if (nbuf != NULL) { - currentPacketLen = min_c(currentPacketLen, count); gBufferModule->append(nbuf, data, currentPacketLen); - if ((bluetoothDevice->fExpectedPacketSize[type] - nbuf->size) == 0 ) { + if ((bluetoothDevice->fExpectedPacketSize[type] - nbuf->size) == 0) { switch (nbuf->protocol) { case BT_EVENT: - btCoreData->PostEvent(netDevice, data, + panic("need to send full buffer to btdatacore!\n"); + btCoreData->PostEvent(bluetoothDevice, data, bluetoothDevice->fExpectedPacketSize[type]); + break; case BT_ACL: - bluetooth_receive_data(netDevice, &nbuf); + // TODO: device descriptor has been fetched better not + // pass id again + flowf("ACL parsed in ACL!\n"); + AclAssembly(nbuf, bluetoothDevice->index); break; default: @@ -197,12 +216,18 @@ Assemble(net_device* netDevice, bt_packet_t type, void* data, size_t count) status_t HciPacketHandler(void* data, int32 code, size_t size) { - bluetooth_device* bluetoothDevice - = FindDeviceByID(Bluetooth::CodeHandler::Device(code)); + hci_id deviceId = Bluetooth::CodeHandler::Device(code); + + bluetooth_device* bluetoothDevice = FindDeviceByID(deviceId); + + debugf("to assemble %ld bytes of %ld\n", size, deviceId); if (bluetoothDevice != NULL) return Assemble(bluetoothDevice, Bluetooth::CodeHandler::Protocol(code), data, size); + else { + debugf("Device %ld could not be matched\n", deviceId); + } return B_ERROR; } @@ -212,31 +237,22 @@ HciPacketHandler(void* data, int32 code, size_t size) status_t -bluetooth_init(const char* name, net_device** _device) +RegisterDriver(bt_hci_transport_hooks* hooks, bluetooth_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); - if (status < B_OK) - return status; - } bluetooth_device* device = new (std::nothrow) bluetooth_device; - if (device == NULL) { - put_module(NET_BUFFER_MODULE_NAME); + if (device == NULL) return B_NO_MEMORY; + + for (int index = 0; index < HCI_NUM_PACKET_TYPES; index++) { + device->fBuffersRx[index] = NULL; + device->fExpectedPacketSize[index] = 0; } - memset(device, 0, sizeof(bluetooth_device)); + device->info = NULL; // not yet used + device->hooks = hooks; - // Fill - strcpy(device->name, name); + device->mtu = L2CAP_MTU_MINIMUM; // TODO: ensure specs min value MutexLocker _(&sListLock); @@ -244,92 +260,58 @@ bluetooth_init(const char* name, net_device** _device) device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index else device->index = (sDeviceList.Tail())->index + 1; // REVIEW! + flowf("List not empty\n"); - // TODO: add to list whould be done in up hook sDeviceList.Add(device); - debugf("Device %s %lx\n", device->name, device->index ); + debugf("Device %lx\n", device->index ); *_device = device; + return B_OK; } status_t -bluetooth_uninit(net_device* _device) +UnregisterDriver(hci_id id) { - bluetooth_device* device = (bluetooth_device*)_device; + bluetooth_device* device = FindDeviceByID(id); - debugf("index %lx\n",device->index); + if (device == NULL) + return B_ERROR; - // if the device is still part of the list, remove it if (device->GetDoublyLinkedListLink()->next != NULL || device->GetDoublyLinkedListLink()->previous != NULL || device == sDeviceList.Head()) sDeviceList.Remove(device); - put_module(NET_BUFFER_MODULE_NAME); delete device; return B_OK; } +// PostACL status_t -bluetooth_up(net_device* _device) +PostACL(hci_id hciId, net_buffer* buffer) { - bluetooth_device* device = (bluetooth_device*)_device; - - debugf("index %ld\n",device->index); - - device->fd = open(device->name, O_RDWR); - if (device->fd < 0) - goto err; - - return B_OK; - -err: - close(device->fd); - device->fd = -1; - return errno; -} - - -void -bluetooth_down(net_device* _device) -{ - bluetooth_device* device = (bluetooth_device*)_device; - - debugf("index %ld\n",device->index); - - close(device->fd); - device->fd = -1; -} - - -status_t -bluetooth_control(net_device* _device, int32 op, void* argument, - size_t length) -{ - 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_device* device = (bluetooth_device*)_device; net_buffer* curr_frame = NULL; net_buffer* next_frame = buffer; - uint16 handle = buffer->type; // TODO: CodeHandler uint8 flag = HCI_ACL_PACKET_START; - debugf("index %ld try to send bt packet of %lu bytes (flags %ld):\n", + if (buffer == NULL) + panic("passing null buffer"); + + uint16 handle = buffer->type; // TODO: CodeHandler + + bluetooth_device* device = FindDeviceByID(hciId); + + if (device == NULL) { + debugf("No device %lx", hciId); + return B_ERROR; + } + + debugf("index %lx try to send bt packet of %lu bytes (flags %ld):\n", device->index, buffer->size, buffer->flags); // TODO: ATOMIC! any other thread should stop here @@ -337,116 +319,50 @@ bluetooth_send_data(net_device* _device, net_buffer* buffer) // Divide packet if big enough curr_frame = next_frame; - if (next_frame->size > device->mtu) { + if (curr_frame->size > device->mtu) { next_frame = gBufferModule->split(curr_frame, device->mtu); } else { next_frame = NULL; } // Attach acl header - NetBufferPrepend bufferHeader(curr_frame); - status_t status = bufferHeader.Status(); - if (status < B_OK) { - // free the buffer - continue; + { + NetBufferPrepend 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); + bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header); } - bufferHeader->handle = pack_acl_handle_flags(handle, flag, 0); - bufferHeader->alen = curr_frame->size - sizeof(struct hci_acl_header); - - bufferHeader.Sync(); - - // Send to driver XXX: another interlayer trick - debugf("tolower nbuf %p\n",curr_frame); + // Send to driver curr_frame->protocol = BT_ACL; - ((status_t(*)(hci_id id, net_buffer* nbuf))device->media)(device->index, - curr_frame); + debugf("Tolower nbuf %p!\n", curr_frame); + // We could pass a cookie and avoid the driver fetch the Id + device->hooks->SendACL(device->index, curr_frame); flag = HCI_ACL_PACKET_FRAGMENT; - } while (next_frame == NULL); + } while (next_frame != NULL); return B_OK; } status_t -bluetooth_receive_data(net_device* _device, net_buffer** _buffer) +PostSCO(hci_id hciId, net_buffer* buffer) { - bluetooth_device* device = (bluetooth_device*)_device; - status_t status = B_OK; - - debugf("index %ld packet of %lu bytes (flags %ld):\n", - device->index, (*_buffer)->size, (*_buffer)->flags); - - if (device->fd == -1) - return B_FILE_ERROR; - - switch ((*_buffer)->protocol) { - case BT_ACL: - status = AclAssembly(*_buffer, device->index); - break; - default: - panic("Protocol not supported"); - break; - } - - return status; + return B_ERROR; } status_t -bluetooth_set_mtu(net_device* _device, size_t mtu) +PostESCO(hci_id hciId, net_buffer* buffer) { - bluetooth_device* device = (bluetooth_device*)_device; - - debugf("index %ld mtu %ld\n",device->index, mtu); - - device->mtu = mtu; - - return B_OK; -} - - -status_t -bluetooth_set_promiscuous(net_device* _device, bool promiscuous) -{ - bluetooth_device* device = (bluetooth_device*)_device; - - debugf("index %ld promiscuous %d\n",device->index, promiscuous); - - return EOPNOTSUPP; -} - - -status_t -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_device* device = (bluetooth_device*)_device; - - debugf("index %ld\n",device->index); - - return EOPNOTSUPP; -} - - -status_t -bluetooth_remove_multicast(struct net_device* _device, const sockaddr* _address) -{ - bluetooth_device* device = (bluetooth_device*)_device; - - debugf("index %ld\n",device->index); - - return EOPNOTSUPP; + return B_ERROR; } @@ -455,11 +371,12 @@ dump_bluetooth_devices(int argc, char** argv) { bluetooth_device* device; - DoublyLinkedList::Iterator iterator = sDeviceList.GetIterator(); + DoublyLinkedList::Iterator iterator + = sDeviceList.GetIterator(); while (iterator.HasNext()) { device = iterator.Next(); - kprintf("\tname=%s index=%#lx @%p\n", device->name, device->index, device); + kprintf("\tindex=%#lx @%p hooks=%p\n",device->index, device, device->hooks); } return 0; @@ -477,9 +394,9 @@ bluetooth_std_ops(int32 op, ...) { status_t status; - status = get_module(NET_STACK_MODULE_NAME,(module_info**)&sStackModule); + status = get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule); if (status < B_OK) { - flowf("problem getting netstack module\n"); + panic("no way Dude we need that!"); return status; } @@ -492,6 +409,17 @@ bluetooth_std_ops(int32 op, ...) new (&sDeviceList) DoublyLinkedList; // static C++ objects are not initialized in the module startup + BluetoothRXPort = new BluetoothRawDataPort(BT_RX_PORT_NAME, + (BluetoothRawDataPort::port_listener_func)&HciPacketHandler); + + if (BluetoothRXPort->Launch() != B_OK) { + flowf("RX thread creation failed!\n"); + // we Cannot do much here ... avoid registering + + } else { + flowf("RX thread launched!\n"); + } + sLinkChangeSemaphore = create_sem(0, "bt sem"); if (sLinkChangeSemaphore < B_OK) { put_module(NET_STACK_MODULE_NAME); @@ -515,6 +443,7 @@ bluetooth_std_ops(int32 op, ...) delete_sem(sLinkChangeSemaphore); mutex_destroy(&sListLock); + put_module(NET_BUFFER_MODULE_NAME); put_module(NET_STACK_MODULE_NAME); put_module(BT_CORE_DATA_MODULE_NAME); remove_debugger_command("btLocalDevices", &dump_bluetooth_devices); @@ -529,24 +458,19 @@ bluetooth_std_ops(int32 op, ...) } -net_device_module_info sBluetoothModule = { +bt_hci_module_info sBluetoothModule = { { - NET_BLUETOOTH_DEVICE_NAME, + BT_HCI_MODULE_NAME, B_KEEP_LOADED, bluetooth_std_ops }, - bluetooth_init, - bluetooth_uninit, - bluetooth_up, - bluetooth_down, - bluetooth_control, - bluetooth_send_data, - bluetooth_receive_data, - bluetooth_set_mtu, - bluetooth_set_promiscuous, - bluetooth_set_media, - bluetooth_add_multicast, - bluetooth_remove_multicast, + RegisterDriver, + UnregisterDriver, + FindDeviceByID, + PostTransportPacket, + PostACL, + PostSCO, + PostESCO }; diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/Jamfile b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/Jamfile index 8e22ad4982..bc40eb37fd 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/Jamfile +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/Jamfile @@ -18,11 +18,11 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { } KernelAddon h2generic : - h2generic.c - h2transactions.c - h2upper.c - h2util.c - snet_buffer.c + h2generic.cpp + h2transactions.cpp + h2upper.cpp + h2util.cpp + snet_buffer.cpp $(r5_src) ; diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2cfg.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2cfg.h index 5cf00034ea..ef83ac6878 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2cfg.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2cfg.h @@ -1,10 +1,7 @@ /* * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * * All rights reserved. Distributed under the terms of the MIT License. - * */ - #ifndef _H2CFG_H_ #define _H2CFG_H_ @@ -16,20 +13,19 @@ #define BT_DRIVER_SUPPORTS_ESCO 0 +// TODO: move exclusive header for drivers +#define BT_DRIVER_RXCOVERAGE (BT_DRIVER_SUPPORTS_EVT + BT_DRIVER_SUPPORTS_ACL \ + + BT_DRIVER_SUPPORTS_SCO + BT_DRIVER_SUPPORTS_ESCO) +#define BT_DRIVER_TXCOVERAGE (BT_DRIVER_SUPPORTS_CMD + BT_DRIVER_SUPPORTS_ACL \ + + BT_DRIVER_SUPPORTS_SCO + BT_DRIVER_SUPPORTS_ESCO) -/* TODO: move exclusive header for drivers*/ -#define BT_DRIVER_RXCOVERAGE (BT_DRIVER_SUPPORTS_EVT+BT_DRIVER_SUPPORTS_ACL+BT_DRIVER_SUPPORTS_SCO+BT_DRIVER_SUPPORTS_ESCO) -#define BT_DRIVER_TXCOVERAGE (BT_DRIVER_SUPPORTS_CMD+BT_DRIVER_SUPPORTS_ACL+BT_DRIVER_SUPPORTS_SCO+BT_DRIVER_SUPPORTS_ESCO) - -#if BT_DRIVER_RXCOVERAGE<1 || BT_DRIVER_TXCOVERAGE<1 +#if BT_DRIVER_RXCOVERAGE < 1 || BT_DRIVER_TXCOVERAGE < 1 #error incomplete Bluetooth driver Commands and Events should be implemented #endif #define BT_SURVIVE_WITHOUT_HCI //#define BT_SURVIVE_WITHOUT_NET_BUFFERS -//////////////////////////////////// - #ifndef BLUETOOTH_DEVICE_TRANSPORT #error BLUETOOTH_DEVICE_TRANSPORT must be defined to build the publishing path #endif @@ -38,8 +34,11 @@ #error BLUETOOTH_DEVICE_NAME must be defined to build the publishing path #endif -#define BLUETOOTH_DEVICE_DEVFS_NAME BLUETOOTH_DEVICE_TRANSPORT BLUETOOTH_DEVICE_NAME -#define BLUETOOTH_DEVICE_PATH "bluetooth/" BLUETOOTH_DEVICE_TRANSPORT "/" BLUETOOTH_DEVICE_DEVFS_NAME +#define BLUETOOTH_DEVICE_DEVFS_NAME BLUETOOTH_DEVICE_TRANSPORT \ + BLUETOOTH_DEVICE_NAME +#define BLUETOOTH_DEVICE_PATH "bluetooth/" BLUETOOTH_DEVICE_TRANSPORT "/" \ + BLUETOOTH_DEVICE_DEVFS_NAME #endif + diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.c b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp similarity index 69% rename from src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.c rename to src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp index cd0b180506..605f1c1c1f 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.c +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp @@ -17,8 +17,6 @@ #include "snet_buffer.h" #include -#include -#include #define BT_DEBUG_THIS_MODULE #define SUBMODULE_NAME BLUETOOTH_DEVICE_DEVFS_NAME @@ -34,20 +32,20 @@ int32 api_version = B_CUR_DRIVER_API_VERSION; -/* Modules */ +// Modules static char* usb_name = B_USB_MODULE_NAME; static char* hci_name = BT_HCI_MODULE_NAME; -static char* btDevices_name = NET_BLUETOOTH_DEVICE_NAME; +static char* btDevices_name = BT_HCI_MODULE_NAME; usb_module_info* usb = NULL; -bt_hci_module_info* hci = NULL; -struct net_device_module_info* btDevices = NULL; +bt_hci_module_info* hci = NULL; // TODO remove / clean +struct bt_hci_module_info* btDevices = NULL; struct net_buffer_module_info* nb = NULL; struct bluetooth_core_data_module_info* btCoreData = NULL; // Driver Global data -static char *publish_names[MAX_BT_GENERIC_USB_DEVICES]; +static char* publish_names[MAX_BT_GENERIC_USB_DEVICES]; int32 dev_count = 0; // number of connected devices static bt_usb_dev* bt_usb_devices[MAX_BT_GENERIC_USB_DEVICES]; @@ -55,10 +53,9 @@ sem_id dev_table_sem = -1; // sem to synchronize access to device table status_t submit_nbuffer(hci_id hid, net_buffer* nbuf); -usb_support_descriptor supported_devices[] = -{ - // Generic Bluetooth USB device - // Class, SubClass, and Protocol codes that describe a Bluetooth device +usb_support_descriptor supported_devices[] = { + // Generic Bluetooth USB device + // Class, SubClass, and Protocol codes that describe a Bluetooth device { UDCLASS_WIRELESS, UDSUBCLASS_RF, UDPROTO_BLUETOOTH , 0 , 0 }, // Broadcom BCM2035 @@ -67,14 +64,14 @@ usb_support_descriptor supported_devices[] = // Devices taken from the linux Driver // AVM BlueFRITZ! USB v2.0 - { 0, 0, 0, 0x057c , 0x3800 }, + { 0, 0, 0, 0x057c, 0x3800 }, // Bluetooth Ultraport Module from IBM - { 0, 0, 0, 0x04bf , 0x030a }, + { 0, 0, 0, 0x04bf, 0x030a }, // ALPS Modules with non-standard id - { 0, 0, 0, 0x044e , 0x3001 }, - { 0, 0, 0, 0x044e , 0x3002 }, + { 0, 0, 0, 0x044e, 0x3001 }, + { 0, 0, 0, 0x044e, 0x3002 }, // Ericsson with non-standard id - { 0, 0, 0, 0x0bdb , 0x1002 } + { 0, 0, 0, 0x0bdb, 0x1002 } }; /* add a device to the list of connected devices */ @@ -93,13 +90,13 @@ spawn_device(usb_device* usb_dev) flowf("add_device()\n"); - // 16 usb dongles... + // 16 usb dongles... if (dev_count >= MAX_BT_GENERIC_USB_DEVICES) { flowf("device table full\n"); goto exit; } - /* try the allocation */ + // try the allocation new_bt_dev = (bt_usb_dev*)malloc(sizeof(bt_usb_dev)); if (new_bt_dev == NULL) { flowf("no memory\n"); @@ -107,41 +104,43 @@ spawn_device(usb_device* usb_dev) } memset(new_bt_dev, 0, sizeof(bt_usb_dev)); - /* We will need this sem for some flow control */ - new_bt_dev->cmd_complete = create_sem(1, BLUETOOTH_DEVICE_DEVFS_NAME "cmd_complete"); + // We will need this sem for some flow control + new_bt_dev->cmd_complete = create_sem(1, + BLUETOOTH_DEVICE_DEVFS_NAME "cmd_complete"); if (new_bt_dev->cmd_complete < 0) { err = new_bt_dev->cmd_complete; goto bail0; } - /* and this for something else */ + // and this for something else new_bt_dev->lock = create_sem(1, BLUETOOTH_DEVICE_DEVFS_NAME "lock"); if (new_bt_dev->lock < 0) { err = new_bt_dev->lock; goto bail1; } - /* find a free slot and fill out the name */ + // find a free slot and fill out the name acquire_sem(dev_table_sem); for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { if (bt_usb_devices[i] == NULL) { bt_usb_devices[i] = new_bt_dev; sprintf(new_bt_dev->name, "%s/%ld", BLUETOOTH_DEVICE_PATH, i); new_bt_dev->num = i; - debugf("added device %p %ld %s\n", bt_usb_devices[i] ,new_bt_dev->num,new_bt_dev->name); + debugf("added device %p %ld %s\n", bt_usb_devices[i], + new_bt_dev->num, new_bt_dev->name); break; } } release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); - /* In the case we cannot us */ + // In the case we cannot us if (bt_usb_devices[i] != new_bt_dev) { - flowf("Device could not be added\n"); + flowf("Device could not be added\n"); goto bail2; } new_bt_dev->dev = usb_dev; - /* TODO am i actually gonna use this? */ + // TODO: currently only server opens new_bt_dev->open_count = 0; dev_count++; @@ -158,7 +157,7 @@ exit: } -/* remove a device from the list of connected devices */ +// remove a device from the list of connected devices static void kill_device(bt_usb_dev* bdev) { @@ -180,40 +179,38 @@ kill_device(bt_usb_dev* bdev) bt_usb_dev* fetch_device(bt_usb_dev* dev, hci_id hid) { - int i; + int i; // debugf("(%p) or %d\n", dev, hid); acquire_sem(dev_table_sem); - if (dev != NULL) - for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { - /* somehow the device is still around */ - if (bt_usb_devices[i] == dev) { - release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); - return bt_usb_devices[i]; - } + if (dev != NULL) + for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { + if (bt_usb_devices[i] == dev) { + release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); + return bt_usb_devices[i]; + } } else - for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { - /* somehow the device is still around */ - if (bt_usb_devices[i] != NULL && bt_usb_devices[i]->hdev == hid) { - release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); - return bt_usb_devices[i]; - } + for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { + if (bt_usb_devices[i] != NULL && bt_usb_devices[i]->hdev == hid) { + release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); + return bt_usb_devices[i]; + } } release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); - return NULL; + return NULL; } + #if 0 #pragma mark - #endif - -/* called by USB Manager when device is added to the USB */ +// called by USB Manager when device is added to the USB #ifdef HAIKU_TARGET_PLATFORM_HAIKU static status_t device_added(usb_device dev, void** cookie) @@ -227,9 +224,9 @@ device_added(usb_device* dev, void** cookie) const usb_interface_info* uif; const usb_endpoint_info* ep; - status_t err = B_ERROR; + status_t err = B_ERROR; bt_usb_dev* new_bt_dev = spawn_device(dev); - int e; + int e; debugf("device_added(%ld, %p)\n", dev, new_bt_dev); @@ -239,9 +236,9 @@ device_added(usb_device* dev, void** cookie) goto bail_no_mem; } - /* we only have 1 configuration number 0 */ + // we only have 1 configuration number 0 config = usb->get_nth_configuration(dev, 0); - //dump_usb_configuration_info(config); + // dump_usb_configuration_info(config); if (config == NULL) { flowf("couldn't get default config.\n"); err = B_ERROR; @@ -250,7 +247,7 @@ device_added(usb_device* dev, void** cookie) debugf("found %ld alt interfaces.\n", config->interface->alt_count); - /* set first interface */ + // set first interface interface = &config->interface->alt[0]; err = usb->set_alt_interface(new_bt_dev->dev, interface); @@ -259,17 +256,18 @@ device_added(usb_device* dev, void** cookie) goto bail; } - /* call set_configuration() only after calling set_alt_interface()*/ + // call set_configuration() only after calling set_alt_interface() err = usb->set_configuration(dev, config); if (err != B_OK) { debugf("set_configuration() returned %ld.\n", err); goto bail; } - /* Place to find out whats our concrete device and set up some special info to our driver */ - /* TODO: if this code increases too much reconsider this implementation*/ + // Place to find out whats our concrete device and set up some special + // info to our driver. If this code increases too much reconsider + // this implementation desc = usb->get_device_descriptor(dev); - if (desc->vendor_id == 0x0a5c + if (desc->vendor_id == 0x0a5c && (desc->product_id == 0x200a || desc->product_id == 0x2009 || desc->product_id == 0x2035)) { @@ -278,18 +276,19 @@ device_added(usb_device* dev, void** cookie) } /* - else if ( desc->vendor_id == YOUR_VENDOR_HERE && desc->product_id == YOUR_PRODUCT_HERE ) { + else if ( desc->vendor_id == YOUR_VENDOR_HERE + && desc->product_id == YOUR_PRODUCT_HERE ) { YOUR_SPECIAL_FLAGS_HERE } */ - if (new_bt_dev->driver_info & BT_IGNORE_THIS_DEVICE){ + if (new_bt_dev->driver_info & BT_IGNORE_THIS_DEVICE) { err = ENODEV; goto bail; } // security check - if (config->interface->active->descr->interface_number > 0){ + if (config->interface->active->descr->interface_number > 0) { debugf("Strange condition happened %d\n", config->interface->active->descr->interface_number); err = B_ERROR; @@ -297,7 +296,7 @@ device_added(usb_device* dev, void** cookie) } debugf("Found %ld interfaces. Expected 3\n", config->interface_count); - /* Find endpoints that we need */ + // Find endpoints that we need uif = config->interface->active; for (e = 0; e < uif->descr->num_endpoints; e++) { @@ -328,21 +327,22 @@ device_added(usb_device* dev, void** cookie) } } - if (!new_bt_dev->bulk_in_ep || !new_bt_dev->bulk_out_ep || !new_bt_dev->intr_in_ep) { + if (!new_bt_dev->bulk_in_ep || !new_bt_dev->bulk_out_ep + || !new_bt_dev->intr_in_ep) { flowf("Minimal # endpoints for BT not found\n"); goto bail; } // Look into the devices suported to understand this - if (new_bt_dev->driver_info & BT_DIGIANSWER) + if (new_bt_dev->driver_info & BT_DIGIANSWER) new_bt_dev->ctrl_req = USB_TYPE_VENDOR; else new_bt_dev->ctrl_req = USB_TYPE_CLASS; - new_bt_dev->connected = true; + new_bt_dev->connected = true; - /* set the cookie that will be passed to other USB - hook functions (currently device_removed() is the only other) */ + // set the cookie that will be passed to other USB + // hook functions (currently device_removed() is the only other) *cookie = new_bt_dev; debugf("Ok %p\n", new_bt_dev); return B_OK; @@ -356,20 +356,20 @@ bail_no_mem: } -/* called by USB Manager when device is removed from the USB */ +// Called by USB Manager when device is removed from the USB static status_t device_removed(void* cookie) { - bt_usb_dev* bdev = (bt_usb_dev*) fetch_device(cookie, 0); + bt_usb_dev* bdev = fetch_device((bt_usb_dev*)cookie, 0); debugf("device_removed(%p)\n", bdev); - if (bdev == NULL) { - flowf(" not present in driver?\n"); - return B_ERROR; - } + if (bdev == NULL) { + flowf(" not present in driver?\n"); + return B_ERROR; + } - if (!TEST_AND_CLEAR(&bdev->state, RUNNING)) + if (!TEST_AND_CLEAR(&bdev->state, RUNNING)) flowf("wasnt running?\n"); flowf("Cancelling queues...\n"); @@ -394,8 +394,17 @@ device_removed(void* cookie) } -static usb_notify_hooks notify_hooks = -{ +static bt_hci_transport_hooks bluetooth_hooks = { + NULL, + &submit_nbuffer, + &submit_nbuffer, + NULL, + NULL, + H2 +}; + + +static usb_notify_hooks notify_hooks = { &device_added, &device_removed }; @@ -412,21 +421,21 @@ submit_nbuffer(hci_id hid, net_buffer* nbuf) bdev = fetch_device(NULL, hid); debugf("index=%lx nbuf=%p bdev=%p\n",hid, nbuf, bdev); - + if (bdev != NULL) { switch (nbuf->protocol) { case BT_COMMAND: // not issued this way break; - + case BT_ACL: - return submit_tx_acl(bdev, nbuf); + return submit_tx_acl(bdev, nbuf); break; default: panic("submit_nbuffer: no protocol"); break; - + } } @@ -435,9 +444,9 @@ submit_nbuffer(hci_id hid, net_buffer* nbuf) } -/* implements the POSIX open() */ +// implements the POSIX open() static status_t -device_open(const char *name, uint32 flags, void **cookie) +device_open(const char* name, uint32 flags, void **cookie) { status_t err = ENODEV; bt_usb_dev* bdev = NULL; @@ -463,8 +472,8 @@ device_open(const char *name, uint32 flags, void **cookie) // Set RUNNING if (TEST_AND_SET(&bdev->state, RUNNING)) { - flowf("dev already running! - reOpened device!\n"); - return B_ERROR; + flowf("dev already running! - reOpened device!\n"); + return B_ERROR; } acquire_sem(bdev->lock); @@ -481,30 +490,28 @@ device_open(const char *name, uint32 flags, void **cookie) } // dumping the USB frames - init_room(&bdev->eventRoom); - init_room(&bdev->aclRoom); - //init_room(new_bt_dev->scoRoom); + init_room(&bdev->eventRoom); + init_room(&bdev->aclRoom); + // init_room(new_bt_dev->scoRoom); - list_init(&bdev->snetBufferRecycleTrash); + list_init(&bdev->snetBufferRecycleTrash); // Allocate set and register the HCI device if (btDevices != NULL) { - struct net_device* ndev; - // TODO: Fill the transport descriptor - err = btDevices->init_device(bdev->name, &ndev); - - if (err == B_OK) { - bdev->hdev = hdev = ndev->index; // get the index - bdev->ndev = ndev; // get the net_device + bluetooth_device* ndev; + // TODO: Fill the transport descriptor + err = btDevices->RegisterDriver(&bluetooth_hooks, &ndev); - ndev->media = (uint32)submit_nbuffer; //XXX: interlayer-Hack + if (err == B_OK) { + bdev->hdev = hdev = ndev->index; // Get the index + bdev->ndev = ndev; // Get the net_device } else { - hdev = bdev->num; /* XXX: Lets try to go on*/ + hdev = bdev->num; // XXX: Lets try to go on } - } else { - hdev = bdev->num; /* XXX: Lets try to go on*/ - } + } else { + hdev = bdev->num; // XXX: Lets try to go on + } bdev->hdev = hdev; @@ -518,9 +525,10 @@ device_open(const char *name, uint32 flags, void **cookie) /* called when a client calls POSIX close() on the driver, but I/O - ** requests may still be pending */ + * requests may still be pending + */ static status_t -device_close(void *cookie) +device_close(void* cookie) { int32 i; void* item; @@ -539,57 +547,56 @@ device_close(void *cookie) usb->cancel_queued_transfers(bdev->intr_in_ep->handle); flowf("Cancelling possible EVENTS\n"); } - + if (bdev->bulk_in_ep!=NULL) { usb->cancel_queued_transfers(bdev->bulk_in_ep->handle); flowf("Cancelling possible ACL in\n"); } - + if (bdev->bulk_out_ep!=NULL) { usb->cancel_queued_transfers(bdev->bulk_out_ep->handle); flowf("Cancelling possible ACL out\n"); } } - + // TX for (i = 0; i < BT_DRIVER_TXCOVERAGE; i++) { if (i == BT_COMMAND) while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) { - snb_free(item); + snb_free((snet_buffer*)item); } else while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) { - nb_destroy(item); + nb_destroy((net_buffer*)item); } } // RX for (i = 0; i < BT_DRIVER_RXCOVERAGE; i++) { - nb_destroy(bdev->nbufferRx[i]); + nb_destroy(bdev->nbufferRx[i]); } snb_free(bdev->eventRx); - purge_room(&bdev->eventRoom); - purge_room(&bdev->aclRoom); + purge_room(&bdev->eventRoom); + purge_room(&bdev->aclRoom); - /* Device no longer in our Stack*/ - if (btDevices != NULL) - btDevices->uninit_device(bdev->ndev); + // Device no longer in our Stack + if (btDevices != NULL) + btDevices->UnregisterDriver(bdev->hdev); // unSet RUNNING if (TEST_AND_CLEAR(&bdev->state, RUNNING)) { - debugf(" %s not running?\n",bdev->name); - return B_ERROR; + debugf(" %s not running?\n",bdev->name); + return B_ERROR; } return B_OK; } -/* called after device_close(), when all pending I/O requests have - * returned */ +// Called after device_close(), when all pending I / O requests have returned static status_t -device_free (void *cookie) +device_free (void* cookie) { status_t err = B_OK; bt_usb_dev* bdev = (bt_usb_dev*)cookie; @@ -605,9 +612,9 @@ device_free (void *cookie) } -/* implements the POSIX ioctl() */ +// implements the POSIX ioctl() static status_t -device_control(void *cookie, uint32 msg, void *params, size_t size) +device_control(void* cookie, uint32 msg, void* params, size_t size) { status_t err = B_ERROR; bt_usb_dev* bdev = (bt_usb_dev*)cookie; @@ -634,7 +641,7 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) switch (msg) { case ISSUE_BT_COMMAND: #ifdef BT_IOCTLS_PASS_SIZE - if (size == 0) { + if (size == 0) { flowf("Invalid size control\n"); err = B_BAD_VALUE; break; @@ -644,10 +651,10 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) (*(size_t**)¶ms)++; #endif - // TODO: Reuse from some TXcompleted queue - //snbuf = snb_create(size); - snbuf = snb_fetch(&bdev->snetBufferRecycleTrash, size); - snb_put(snbuf, params, size); + // TODO: Reuse from some TXcompleted queue + // snbuf = snb_create(size); + snbuf = snb_fetch(&bdev->snetBufferRecycleTrash, size); + snb_put(snbuf, params, size); err = submit_tx_command(bdev, snbuf); debugf("command launched %ld\n", err); @@ -655,10 +662,10 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) case BT_UP: - // EVENTS + // EVENTS err = submit_rx_event(bdev); if (err != B_OK) { - CLEAR_BIT(bdev->state, ANCILLYANT); + CLEAR_BIT(bdev->state, ANCILLYANT); flowf("Queuing failed device stops running\n"); break; } @@ -667,10 +674,10 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) for (i = 0; i < MAX_ACL_IN_WINDOW; i++) { err = submit_rx_acl(bdev); if (err != B_OK && i == 0) { - CLEAR_BIT(bdev->state, ANCILLYANT); // Set the flaq in the HCI world + CLEAR_BIT(bdev->state, ANCILLYANT); // Set the flaq in the HCI world flowf("Queuing failed device stops running\n"); break; - } + } } #endif @@ -683,13 +690,13 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) break; case GET_STATS: - memcpy(params, &bdev->stat, sizeof(bt_hci_statistics)); - err = B_OK; + memcpy(params, &bdev->stat, sizeof(bt_hci_statistics)); + err = B_OK; break; case GET_HCI_ID: - *(hci_id*)params = bdev->hdev; - err = B_OK; + *(hci_id*)params = bdev->hdev; + err = B_OK; break; @@ -704,9 +711,9 @@ device_control(void *cookie, uint32 msg, void *params, size_t size) } -/* implements the POSIX read() */ +// implements the POSIX read() static status_t -device_read(void *cookie, off_t pos, void *buf, size_t *count) +device_read(void* cookie, off_t pos, void* buffer, size_t* count) { debugf("Reading... count = %ld\n", *count); @@ -715,15 +722,16 @@ device_read(void *cookie, off_t pos, void *buf, size_t *count) } -/* implements the POSIX write() */ +// implements the POSIX write() static status_t -device_write(void *cookie, off_t pos, const void *buf, size_t *count) +device_write(void* cookie, off_t pos, const void* buffer, size_t* count) { flowf("device_write()\n"); return B_ERROR; } + #if 0 #pragma mark - #endif @@ -734,25 +742,27 @@ dump_driver(int argc, char** argv) { int i; snet_buffer* item = NULL; - + for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { if (bt_usb_devices[i] != NULL) { kprintf("%s : \n", bt_usb_devices[i]->name); - kprintf("\taclroom = %d\teventroom = %d\tcommand & events =%d\n", snb_packets(&bt_usb_devices[i]->eventRoom) - , snb_packets(&bt_usb_devices[i]->aclRoom) - , snb_packets(&bt_usb_devices[i]->snetBufferRecycleTrash) ); - - while ((item = list_get_next_item(&bt_usb_devices[i]->snetBufferRecycleTrash, item)) != NULL) + kprintf("\taclroom = %d\teventroom = %d\tcommand & events =%d\n", + snb_packets(&bt_usb_devices[i]->eventRoom), + snb_packets(&bt_usb_devices[i]->aclRoom), + snb_packets(&bt_usb_devices[i]->snetBufferRecycleTrash)); + + while ((item = (snet_buffer*)list_get_next_item( + &bt_usb_devices[i]->snetBufferRecycleTrash, item)) != NULL) snb_dump(item); - } + } } return 0; } -/* called each time the driver is loaded by the kernel */ +// called each time the driver is loaded by the kernel status_t init_driver(void) { @@ -806,15 +816,15 @@ init_driver(void) } for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) { - bt_usb_devices[j] = NULL; + bt_usb_devices[j] = NULL; } - /* After here device_added and publish devices hooks are called - be carefull USB devs */ + // Note: After here device_added and publish devices hooks are called usb->register_driver(BLUETOOTH_DEVICE_DEVFS_NAME, supported_devices, 1, NULL); usb->install_notify(BLUETOOTH_DEVICE_DEVFS_NAME, ¬ify_hooks); - add_debugger_command("bth2generic", &dump_driver, "Lists H2 Transport device info"); + add_debugger_command("bth2generic", &dump_driver, + "Lists H2 Transport device info"); return B_OK; @@ -830,12 +840,12 @@ err_release2: put_module(btDevices_name); err_release3: put_module(BT_CORE_DATA_MODULE_NAME); - + return B_ERROR; } -/* called just before the kernel unloads the driver */ +// called just before the kernel unloads the driver void uninit_driver(void) { @@ -849,10 +859,10 @@ uninit_driver(void) free(publish_names[j]); if (bt_usb_devices[j] != NULL) { - // if (connected_dev != NULL) { - // debugf("Device %p still exists.\n", connected_dev); - // } - debugf("%s still present?\n",bt_usb_devices[j]->name); + // if (connected_dev != NULL) { + // debugf("Device %p still exists.\n", connected_dev); + // } + debugf("%s still present?\n",bt_usb_devices[j]->name); kill_device(bt_usb_devices[j]); } } @@ -861,7 +871,7 @@ uninit_driver(void) remove_debugger_command("bth2generic", &dump_driver); - /* Releasing modules */ + // Releasing modules put_module(usb_name); put_module(hci_name); // TODO: netbuffers @@ -900,18 +910,18 @@ publish_devices(void) release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); publish_names[i] = NULL; - debugf("published %ld devices\n", i); + debugf("published %ld devices\n", i); -// TODO: this method might make better memory use -// dev_names = (char**)malloc(sizeof (char*) * (dev_count+1)); -// if (dev_names) { -// for (i = 0; i < MAX_NUM_DEVS; i++) { -// if ((dev != NULL) && -// (dev_names[i] = (char*)malloc(strlen(DEVICE_PATH)+2/* num + \n */))) { -// sprintf(dev_names[i], "%s%ld", DEVICE_PATH, dev->num); -// debugf("publishing \"%s\"\n", dev_names[i]); -// } -// } + // TODO: this method might make better memory use + // dev_names = (char**)malloc(sizeof(char*) * (dev_count + 1)); + // if (dev_names) { + // for (i = 0; i < MAX_NUM_DEVS; i++) { + // if ((dev != NULL) // dev + \n + // && (dev_names[i] = (char*)malloc(strlen(DEVICE_PATH) + 2))) { + // sprintf(dev_names[i], "%s%ld", DEVICE_PATH, dev->num); + // debugf("publishing \"%s\"\n", dev_names[i]); + // } + // } return (const char**)publish_names; } diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.h index 01865e53bf..ba970860cb 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.h @@ -21,13 +21,13 @@ #include #include -#include +#include #include #include "snet_buffer.h" -/* USB definitions for the generic device*/ +// USB definitions for the generic device move to h2cfg #define UDCLASS_WIRELESS 0xe0 #define UDSUBCLASS_RF 0x01 #define UDPROTO_BLUETOOTH 0x01 @@ -45,7 +45,7 @@ extern usb_module_info* usb; extern bt_hci_module_info* hci; -extern struct net_device_module_info* btDevices; +extern struct bt_hci_module_info* btDevices; extern struct net_buffer_module_info* nb; extern struct bluetooth_core_data_module_info* btCoreData; @@ -64,9 +64,9 @@ struct bt_usb_dev { #else usb_device* dev; /* opaque handle */ #endif - hci_id hdev; /* HCI device id*/ - struct net_device* ndev; - + hci_id hdev; /* HCI device id*/ + bluetooth_device* ndev; + char name[B_OS_NAME_LENGTH]; bool connected; /* is the device plugged into the USB? */ int32 open_count; /* number of clients of the device */ @@ -83,35 +83,36 @@ struct bt_usb_dev { uint32 state; bt_hci_statistics stat; - - const usb_endpoint_info *bulk_in_ep; - uint16 max_packet_size_bulk_in; - const usb_endpoint_info *bulk_out_ep; - uint16 max_packet_size_bulk_out; - const usb_endpoint_info *intr_in_ep; - uint16 max_packet_size_intr_in; - + + const usb_endpoint_info* bulk_in_ep; + uint16 max_packet_size_bulk_in; + const usb_endpoint_info* bulk_out_ep; + uint16 max_packet_size_bulk_out; + const usb_endpoint_info* intr_in_ep; + uint16 max_packet_size_intr_in; + #ifdef BLUETOOTH_SUPPORTS_SCO const usb_endpoint_info *iso_in_ep; const usb_endpoint_info *iso_out_ep; #endif - + /* This so called rooms, are for dumping the USB RX frames - and try to reuse the allocations. see util submodule */ + * and try to reuse the allocations. see util submodule + */ struct list eventRoom; - struct list aclRoom; + struct list aclRoom; // Tx buffers: net_buffers for BT_ACL and snet_buffers for BT_COMMAND - // in the same array - struct list nbuffersTx[BT_DRIVER_TXCOVERAGE]; + // in the same array + struct list nbuffersTx[BT_DRIVER_TXCOVERAGE]; uint32 nbuffersPendingTx[BT_DRIVER_TXCOVERAGE]; - + // Rx buffer - net_buffer* nbufferRx[BT_DRIVER_RXCOVERAGE]; /* Wasting 1 pointer for BT_EVENT */ - snet_buffer* eventRx; /* <- which we hold here */ - + net_buffer* nbufferRx[BT_DRIVER_RXCOVERAGE]; + snet_buffer* eventRx; + // for who ever needs preallocated buffers - struct list snetBufferRecycleTrash; + struct list snetBufferRecycleTrash; }; diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.c b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.cpp similarity index 58% rename from src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.c rename to src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.cpp index 69f4c6e3a1..8f75e48b4d 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.c +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.cpp @@ -40,119 +40,10 @@ void event_complete(void* cookie, status_t status, void* data, size_t actual_len static status_t assembly_rx(bt_usb_dev* bdev, bt_packet_t type, void* data, int count) { - net_buffer* nbuf = NULL; - snet_buffer* snbuf = NULL; - - size_t currentPacketLen = 0; - size_t expectedPacketLen = 0; -#ifdef DUMP_BUFFERS - int16 index; -#endif bdev->stat.bytesRX += count; - if (type == BT_EVENT) - snbuf = bdev->eventRx; - else - nbuf = bdev->nbufferRx[type]; + return btDevices->PostTransportPacket(bdev->hdev, type, data, count); - while (count) { - - //debugf("count %d nb=%p sb=%p type=%d\n", count, nbuf, snbuf, type); - - if ((type != BT_EVENT && nbuf == NULL) - || (type == BT_EVENT && (snbuf == NULL || snb_completed(snbuf)))) { - - /* new buffer incoming */ - switch (type) { - case BT_EVENT: - if (count >= HCI_EVENT_HDR_SIZE) { - struct hci_event_header* headerPkt = data; - expectedPacketLen = HCI_EVENT_HDR_SIZE + headerPkt->elen; - snbuf = bdev->eventRx = snb_fetch(&bdev->snetBufferRecycleTrash, - expectedPacketLen); -#ifdef DUMP_BUFFERS - debugf("## Incoming EVENT frame %p len = %d ", snbuf, count); - for (index = 0 ; index < count; index++) - dprintf("%x:",((uint8*)data)[index]); - dprintf(" ## \n"); -#endif - } else { - flowf("EVENT frame corrupted\n"); - return EILSEQ; - } - break; - - case BT_ACL: - if (count >= HCI_ACL_HDR_SIZE) { - struct hci_acl_header* headerPkt = data; - - expectedPacketLen = HCI_ACL_HDR_SIZE - + B_LENDIAN_TO_HOST_INT16(headerPkt->alen); - - // Create the buffer -> TODO: this allocation can fail - bdev->nbufferRx[type] = nbuf = nb->create(expectedPacketLen); - nbuf->protocol = type; -#ifdef DUMP_BUFFERS - debugf("## Incoming ACL frame %p len = %d ", nbuf, count); - for (index = 0 ; index < count; index++) - dprintf("%x:",((uint8*)data)[index]); - dprintf(" ## \n"); -#endif - } else { - flowf("ACL frame corrupted\n"); - return EILSEQ; - } - break; - - case BT_SCO: - - break; - - default: - panic("unknown packet type in assembly"); - break; - } - - currentPacketLen = expectedPacketLen; - - } else { - // Continuation of a packet - if (type != BT_EVENT) - currentPacketLen = get_expected_size(nbuf) - nbuf->size; - else - currentPacketLen = snb_remaining_to_put(snbuf); - } - - currentPacketLen = min(currentPacketLen, count); - - if (type == BT_EVENT) - snb_put(snbuf, data, currentPacketLen); - else - nb->append(nbuf, data, currentPacketLen); - - // Complete frame? - if (type == BT_EVENT && snb_completed(snbuf)) { - post_packet_up(bdev, type, snbuf); - snbuf = bdev->eventRx = NULL; - } - - if (type != BT_EVENT && (get_expected_size(nbuf) - nbuf->size) == 0 ) { - post_packet_up(bdev, type, nbuf); - bdev->nbufferRx[type] = nbuf = NULL; - } else { -#if DEBUG_ACL - if (type == BT_ACL) - debugf("ACL Packet not filled size=%ld expected=%ld\n", - nbuf->size, get_expected_size(nbuf)); -#endif - } - - /* in case in the pipe there is info about the next buffer ... */ - count -= currentPacketLen; - data += currentPacketLen; - } - - return B_OK; } @@ -160,7 +51,6 @@ assembly_rx(bt_usb_dev* bdev, bt_packet_t type, void* data, int count) #pragma mark --- RX Complete --- #endif - void #ifndef HAIKU_TARGET_PLATFORM_HAIKU event_complete(void* cookie, uint32 status, void* data, uint32 actual_len) @@ -168,8 +58,8 @@ event_complete(void* cookie, uint32 status, void* data, uint32 actual_len) event_complete(void* cookie, status_t status, void* data, size_t actual_len) #endif { - bt_usb_dev* bdev = cookie; - //bt_usb_dev* bdev = fetch_device(cookie, 0); -> safer/slower option + bt_usb_dev* bdev = (bt_usb_dev*)cookie; + // bt_usb_dev* bdev = fetch_device(cookie, 0); -> safer / slower option status_t error; debugf("cookie@%p status=%s len=%ld\n", cookie, strerror(status), actual_len); @@ -177,13 +67,13 @@ event_complete(void* cookie, status_t status, void* data, size_t actual_len) if (bdev == NULL) return; - if (status == B_CANCELED || status == B_DEV_CRC_ERROR) // or not running anymore... - return; + if (status == B_CANCELED || status == B_DEV_CRC_ERROR) + return; // or not running anymore... if (status != B_OK || actual_len == 0) goto resubmit; - if (assembly_rx(cookie, BT_EVENT, data, actual_len) == B_OK) { + if (assembly_rx(bdev, BT_EVENT, data, actual_len) == B_OK) { bdev->stat.successfulTX++; } else { bdev->stat.errorRX++; @@ -191,8 +81,8 @@ event_complete(void* cookie, status_t status, void* data, size_t actual_len) resubmit: - error = usb->queue_interrupt(bdev->intr_in_ep->handle, data, - max(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in), event_complete, bdev); + error = usb->queue_interrupt(bdev->intr_in_ep->handle, data, + max_c(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in), event_complete, bdev); if (error != B_OK) { reuse_room(&bdev->eventRoom, data); @@ -211,20 +101,20 @@ acl_rx_complete(void* cookie, uint32 status, void* data, uint32 actual_len) acl_rx_complete(void* cookie, status_t status, void* data, size_t actual_len) #endif { - bt_usb_dev* bdev = cookie; - //bt_usb_dev* bdev = fetch_device(cookie, 0); -> safer/slower option + bt_usb_dev* bdev = (bt_usb_dev*)cookie; + // bt_usb_dev* bdev = fetch_device(cookie, 0); -> safer / slower option status_t error; if (bdev == NULL) return; - if (status == B_CANCELED || status == B_DEV_CRC_ERROR) // or not running anymore... - return; + if (status == B_CANCELED || status == B_DEV_CRC_ERROR) + return; // or not running anymore... if (status != B_OK || actual_len == 0) goto resubmit; - if (assembly_rx(cookie, BT_ACL, data, actual_len) == B_OK) { + if (assembly_rx(bdev, BT_ACL, data, actual_len) == B_OK) { bdev->stat.successfulRX++; } else { bdev->stat.errorRX++; @@ -233,10 +123,10 @@ acl_rx_complete(void* cookie, status_t status, void* data, size_t actual_len) resubmit: error = usb->queue_bulk(bdev->bulk_in_ep->handle, data, - max(HCI_MAX_FRAME_SIZE, bdev->max_packet_size_bulk_in), + max_c(HCI_MAX_FRAME_SIZE, bdev->max_packet_size_bulk_in), acl_rx_complete, (void*) bdev); - if (error != B_OK) { + if (error != B_OK) { reuse_room(&bdev->aclRoom, data); bdev->stat.rejectedRX++; debugf("RX acl resubmittion failed %s\n", strerror(error)); @@ -245,6 +135,7 @@ resubmit: } } + #if 0 #pragma mark --- RX --- #endif @@ -252,7 +143,7 @@ resubmit: status_t submit_rx_event(bt_usb_dev* bdev) { - size_t size = max(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in); + size_t size = max_c(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in); void* buf = alloc_room(&bdev->eventRoom, size); status_t status; @@ -276,8 +167,8 @@ submit_rx_event(bt_usb_dev* bdev) status_t submit_rx_acl(bt_usb_dev* bdev) -{ - size_t size = max(HCI_MAX_FRAME_SIZE, bdev->max_packet_size_bulk_in); +{ + size_t size = max_c(HCI_MAX_FRAME_SIZE, bdev->max_packet_size_bulk_in); void* buf = alloc_room(&bdev->aclRoom, size); status_t status; @@ -301,10 +192,11 @@ submit_rx_acl(bt_usb_dev* bdev) status_t submit_rx_sco(bt_usb_dev* bdev) { - /* not yet implemented */ + // not yet implemented return B_ERROR; } + #if 0 #pragma mark --- TX Complete --- #endif @@ -317,7 +209,7 @@ command_complete(void* cookie, status_t status, void* data, size_t actual_len) #endif { snet_buffer* snbuf = (snet_buffer*)cookie; - bt_usb_dev* bdev = snb_cookie(snbuf); + bt_usb_dev* bdev = (bt_usb_dev*)snb_cookie(snbuf); debugf("status = %ld len = %ld @%p\n", status, actual_len, data); @@ -326,13 +218,13 @@ command_complete(void* cookie, status_t status, void* data, size_t actual_len) bdev->stat.bytesTX += actual_len; } else { bdev->stat.errorTX++; - // the packet has been lost,too late to requeue it? + // the packet has been lost, too late to requeue it } snb_park(&bdev->snetBufferRecycleTrash, snbuf); #ifdef BT_RESCHEDULING_AFTER_COMPLETITIONS - // TODO: check just the empty queues? + // TODO: check just the empty queues schedTxProcessing(bdev); #endif } @@ -348,22 +240,24 @@ acl_tx_complete(void* cookie, status_t status, void* data, size_t actual_len) net_buffer* nbuf = (net_buffer*)cookie; bt_usb_dev* bdev = GET_DEVICE(nbuf); - debugf("fetched=%p status=%ld nbuftype %lx B%p\n", bdev, status, nbuf->type, data); + debugf("fetched=%p status=%ld type %lx %p\n", bdev, status, nbuf->type, data); if (status == B_OK) { bdev->stat.successfulTX++; bdev->stat.bytesTX += actual_len; } else { bdev->stat.errorTX++; - // the packet has been lost,too late to requeue it? + // the packet has been lost, too late to requeue it } nb_destroy(nbuf); + #ifdef BT_RESCHEDULING_AFTER_COMPLETITIONS schedTxProcessing(bdev); #endif } + #if 0 #pragma mark --- TX --- #endif @@ -376,23 +270,23 @@ submit_tx_command(bt_usb_dev* bdev, snet_buffer* snbuf) uint16 wIndex = 0; uint16 value = 0; uint16 wLength = B_HOST_TO_LENDIAN_INT16(snb_size(snbuf)); - status_t error; + status_t error; if (!GET_BIT(bdev->state, RUNNING)) { return B_DEV_NOT_READY; } - /* set cookie */ + // set cookie snb_set_cookie(snbuf, bdev); debugf("@%p\n", snb_get(snbuf)); - + error = usb->queue_request(bdev->dev, bRequestType, bRequest, - value, wIndex, wLength, snb_get(snbuf), -#ifndef HAIKU_TARGET_PLATFORM_HAIKU - wLength, //??? -#endif - command_complete, (void*) snbuf); + value, wIndex, wLength, snb_get(snbuf), +#ifndef HAIKU_TARGET_PLATFORM_HAIKU + wLength, +#endif + command_complete, (void*) snbuf); if (error != B_OK) { bdev->stat.rejectedTX++; @@ -407,21 +301,20 @@ submit_tx_command(bt_usb_dev* bdev, snet_buffer* snbuf) status_t submit_tx_acl(bt_usb_dev* bdev, net_buffer* nbuf) { - int32 index; status_t error; - /* set cookie */ + // set cookie SET_DEVICE(nbuf, bdev->hdev); if (!GET_BIT(bdev->state, RUNNING)) { return B_DEV_NOT_READY; } - + /* debugf("### Outgoing ACL: len = %ld\n", nbuf->size); - for (index = 0 ; index < nbuf->size; index++ ) { + for (uint32 index = 0 ; index < nbuf->size; index++ ) { dprintf("%x:",((uint8*)nb_get_whole_buffer(nbuf))[index]); } - flowf("### \n"); + */ error = usb->queue_bulk(bdev->bulk_out_ep->handle, nb_get_whole_buffer(nbuf), nbuf->size, acl_tx_complete, (void*)nbuf); @@ -444,6 +337,6 @@ submit_tx_sco(bt_usb_dev* bdev) return B_DEV_NOT_READY; } - /* not yet implemented */ + // not yet implemented return B_ERROR; } diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.h index f69ba718ac..15b3b17d93 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.h @@ -1,8 +1,6 @@ /* * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * * All rights reserved. Distributed under the terms of the MIT License. - * */ #ifndef _H2TRANSACTION_H_ diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.c b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.c deleted file mode 100644 index 8a9812c4fb..0000000000 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com - * All rights reserved. Distributed under the terms of the MIT License. - */ - -#include - -#include -#include - -#include "h2generic.h" -#include "h2upper.h" -#include "h2transactions.h" -#include "snet_buffer.h" - -#define BT_DEBUG_THIS_MODULE -#include - - -/* TODO: split for commands and comunication (ACL&SCO) */ -void -sched_tx_processing(bt_usb_dev* bdev) -{ - net_buffer* nbuf; - snet_buffer* snbuf; - status_t err; - - debugf("(%p)\n", bdev) - - if (!TEST_AND_SET(&bdev->state, PROCESSING)) { - // We are not processing in another thread so... START!! - - do { - /* Do while this bit is on... so someone should set it before we - * stop the iterations - */ - CLEAR_BIT(bdev->state, SENDING); - // check Commands - #ifdef EMPTY_COMMAND_QUEUE - while (!list_is_empty(&bdev->nbuffersTx[BT_COMMAND])) { - #else - if (!list_is_empty(&bdev->nbuffersTx[BT_COMMAND])) { - #endif - snbuf = list_remove_head_item(&bdev->nbuffersTx[BT_COMMAND]); - err = submit_tx_command(bdev, snbuf); - if (err != B_OK) { - // re-head it - list_insert_item_before(&bdev->nbuffersTx[BT_COMMAND], - list_get_first_item(&bdev->nbuffersTx[BT_COMMAND]), snbuf); - } - } - - // check ACl - #define EMPTY_ACL_QUEUE - #ifdef EMPTY_ACL_QUEUE - while (!list_is_empty(&bdev->nbuffersTx[BT_ACL])) { - #else - if (!list_is_empty(&bdev->nbuffersTx[BT_ACL])) { - #endif - nbuf = list_remove_head_item(&bdev->nbuffersTx[BT_ACL]); - err = submit_tx_acl(bdev, nbuf); - if (err != B_OK) { - /* re-head it*/ - list_insert_item_before(&bdev->nbuffersTx[BT_ACL], - list_get_first_item(&bdev->nbuffersTx[BT_ACL]), nbuf); - } - - } - - if (!list_is_empty(&bdev->nbuffersTx[BT_SCO])) { - /* TODO to be implemented */ - - } - - } while (GET_BIT(bdev->state, SENDING)); - - CLEAR_BIT(bdev->state, PROCESSING); - - } else { - /* We are processing so MARK that we need to still go on with that ... */ - SET_BIT(bdev->state, SENDING); - } -} - - -status_t -post_packet_up(bt_usb_dev* bdev, bt_packet_t type, void* buf) -{ - status_t err = B_ERROR; - - debugf("Frame up type=%d\n", type); - - if (type == BT_EVENT) { - snet_buffer* snbuf = (snet_buffer*)buf; - btCoreData->PostEvent(bdev->ndev, snb_get(snbuf), (size_t)snb_size(snbuf)); - snb_park(&bdev->snetBufferRecycleTrash, snbuf); - debugf("to btDataCore len=%d\n", snb_size(snbuf)); - } else { - net_buffer* nbuf = (net_buffer*) buf; - /* No need to free the buffer at allocation is gonna be reused */ - btDevices->receive_data(bdev->ndev, &nbuf); - flowf("to net_device\n"); - } - - return err; -} - - -status_t -send_packet(hci_id hid, bt_packet_t type, net_buffer* nbuf) -{ - bt_usb_dev* bdev = fetch_device(NULL, hid); - status_t err = B_OK; - - if (bdev == NULL) - return B_ERROR; - - // TODO: check if device is actually ready for this - // TODO: Lock Device - - if (nbuf != NULL) { - if (type != nbuf->protocol) // a bit strict maybe? - panic("Upper layer has not filled correctly a packet"); - - switch (type) { - case BT_COMMAND: - case BT_ACL: - case BT_SCO: - list_add_item(&bdev->nbuffersTx[type],nbuf); - bdev->nbuffersPendingTx[type]++; - break; - default: - debugf("Unknown packet type for sending %d\n",type); - // TODO: free the net_buffer -> no, allow upper layer - // handle it with the given error - err = B_BAD_VALUE; - break; - } - } else { - flowf("tx sched provoked"); - } - - // TODO: check if device is actually ready for this - // TODO: unlock device - - /* sched in All cases even if nbuf is null (hidden way to provoke - * re-scheduling) - */ - sched_tx_processing(bdev); - - return err; -} - - -status_t -send_command(hci_id hid, snet_buffer* snbuf) -{ - - bt_usb_dev* bdev = fetch_device(NULL, hid); - status_t err = B_OK; - - if (bdev == NULL) - return B_ERROR; - - // TODO: check if device is actually ready for this - // TODO: mutex? - - if (snbuf != NULL) { - - list_add_item(&bdev->nbuffersTx[BT_COMMAND],snbuf); - bdev->nbuffersPendingTx[BT_COMMAND]++; - } else { - err = B_BAD_VALUE; - flowf("tx sched provoked"); - } - - // TODO: check if device is actually ready for this - // TODO: mutex? - - /* sched in All cases even if nbuf is null (hidden way to provoke - * re-scheduling) - */ - sched_tx_processing(bdev); - - return err; -} diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.cpp b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.cpp new file mode 100644 index 0000000000..ac4ebb9479 --- /dev/null +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.cpp @@ -0,0 +1,189 @@ +/* + * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include + +#include +#include + +#include "h2generic.h" +#include "h2upper.h" +#include "h2transactions.h" +#include "snet_buffer.h" + +#define BT_DEBUG_THIS_MODULE +#include + + +// TODO: split for commands and comunication (ACL & SCO) +void +sched_tx_processing(bt_usb_dev* bdev) +{ + net_buffer* nbuf; + snet_buffer* snbuf; + status_t err; + + debugf("(%p)\n", bdev) + + if (!TEST_AND_SET(&bdev->state, PROCESSING)) { + // We are not processing in another thread so... START!! + + do { + /* Do while this bit is on... so someone should set it before we + * stop the iterations + */ + CLEAR_BIT(bdev->state, SENDING); + // check Commands + #ifdef EMPTY_COMMAND_QUEUE + while (!list_is_empty(&bdev->nbuffersTx[BT_COMMAND])) { + #else + if (!list_is_empty(&bdev->nbuffersTx[BT_COMMAND])) { + #endif + snbuf = (snet_buffer*) + list_remove_head_item(&bdev->nbuffersTx[BT_COMMAND]); + err = submit_tx_command(bdev, snbuf); + if (err != B_OK) { + // re-head it + list_insert_item_before(&bdev->nbuffersTx[BT_COMMAND], + list_get_first_item(&bdev->nbuffersTx[BT_COMMAND]), + snbuf); + } + } + + // check ACl + #define EMPTY_ACL_QUEUE + #ifdef EMPTY_ACL_QUEUE + while (!list_is_empty(&bdev->nbuffersTx[BT_ACL])) { + #else + if (!list_is_empty(&bdev->nbuffersTx[BT_ACL])) { + #endif + nbuf = (net_buffer*) + list_remove_head_item(&bdev->nbuffersTx[BT_ACL]); + err = submit_tx_acl(bdev, nbuf); + if (err != B_OK) { + // re-head it + list_insert_item_before(&bdev->nbuffersTx[BT_ACL], + list_get_first_item(&bdev->nbuffersTx[BT_ACL]), + nbuf); + } + } + + if (!list_is_empty(&bdev->nbuffersTx[BT_SCO])) { + // TODO to be implemented + } + + } while (GET_BIT(bdev->state, SENDING)); + + CLEAR_BIT(bdev->state, PROCESSING); + + } else { + // We are processing so MARK that we need to still go on with that + SET_BIT(bdev->state, SENDING); + } +} + + +#if 0 +// DEPRECATED +status_t +post_packet_up(bt_usb_dev* bdev, bt_packet_t type, void* buf) +{ + status_t err = B_ERROR; + + debugf("Frame up type=%d\n", type); + + if (type == BT_EVENT) { + snet_buffer* snbuf = (snet_buffer*)buf; + btCoreData->PostEvent(bdev->ndev, snb_get(snbuf), + (size_t)snb_size(snbuf)); + snb_park(&bdev->snetBufferRecycleTrash, snbuf); + debugf("to btDataCore len=%d\n", snb_size(snbuf)); + } else { + net_buffer* nbuf = (net_buffer*) buf; + // No need to free the buffer at allocation is gonna be reused + btDevices->receive_data(bdev->ndev, &nbuf); + flowf("to net_device\n"); + } + + return err; +} +#endif + + +status_t +send_packet(hci_id hid, bt_packet_t type, net_buffer* nbuf) +{ + bt_usb_dev* bdev = fetch_device(NULL, hid); + status_t err = B_OK; + + if (bdev == NULL) + return B_ERROR; + + // TODO: check if device is actually ready for this + // TODO: Lock Device + + if (nbuf != NULL) { + if (type != nbuf->protocol) // a bit strict maybe + panic("Upper layer has not filled correctly a packet"); + + switch (type) { + case BT_COMMAND: + case BT_ACL: + case BT_SCO: + list_add_item(&bdev->nbuffersTx[type],nbuf); + bdev->nbuffersPendingTx[type]++; + break; + default: + debugf("Unknown packet type for sending %d\n",type); + // TODO: free the net_buffer -> no, allow upper layer + // handle it with the given error + err = B_BAD_VALUE; + break; + } + } else { + flowf("tx sched provoked"); + } + + // TODO: check if device is actually ready for this + // TODO: unlock device + + // sched in any case even if nbuf is null (provoke re-scheduling) + sched_tx_processing(bdev); + + return err; +} + + +status_t +send_command(hci_id hid, snet_buffer* snbuf) +{ + bt_usb_dev* bdev = fetch_device(NULL, hid); + status_t err = B_OK; + + if (bdev == NULL) + return B_ERROR; + + // TODO: check if device is actually ready for this + // TODO: mutex + + if (snbuf != NULL) { + list_add_item(&bdev->nbuffersTx[BT_COMMAND],snbuf); + bdev->nbuffersPendingTx[BT_COMMAND]++; + } else { + err = B_BAD_VALUE; + flowf("tx sched provoked"); + } + + // TODO: check if device is actually ready for this + // TODO: mutex + + /* sched in All cases even if nbuf is null (hidden way to provoke + * re-scheduling) + */ + sched_tx_processing(bdev); + + return err; +} diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.h index de7be20949..fb400557c8 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.h @@ -1,10 +1,7 @@ /* * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * * All rights reserved. Distributed under the terms of the MIT License. - * */ - #ifndef _H2UPPER_H_ #define _H2UPPER_H_ @@ -12,10 +9,10 @@ #include "h2generic.h" -status_t post_packet_up(bt_usb_dev* bdev, bt_packet_t type, void* buf); -status_t send_packet(hci_id hid, bt_packet_t type, net_buffer* nbuf); -status_t send_command(hci_id hid, snet_buffer* snbuf); +status_t post_packet_up(bt_usb_dev* bdev, bt_packet_t type, void* buf); +status_t send_packet(hci_id hid, bt_packet_t type, net_buffer* nbuf); +status_t send_command(hci_id hid, snet_buffer* snbuf); -void sched_tx_processing(bt_usb_dev* bdev); +void sched_tx_processing(bt_usb_dev* bdev); -#endif \ No newline at end of file +#endif diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.c b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.cpp similarity index 84% rename from src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.c rename to src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.cpp index 0c462cba02..866ce77723 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.c +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.cpp @@ -22,21 +22,20 @@ void* nb_get_whole_buffer(net_buffer* nbuf) { - void* conPointer; - status_t err; + void* conPointer; + status_t err; #if 0 - /* the job could be already done */ + // the job could be already done // !!! it could be trash from other upper protocols... if (nbuf->COOKIEFIELD != NULL) return (void*)nbuf->COOKIEFIELD; #endif - err = nb->direct_access(nbuf, 0, nbuf->size, &conPointer); + err = nb->direct_access(nbuf, 0, nbuf->size, &conPointer); - if (err != B_OK) { - snooze(3*1000*1000); + if (err != B_OK) { panic("expected to be contiguous"); #if 0 - /* pity, we are gonna need a realocation */ + // We are gonna need a realocation nbuf->COOKIEFIELD = (uint32) malloc(nbuf->size); if (nbuf->COOKIEFIELD == NULL) goto fail; @@ -65,7 +64,7 @@ nb_destroy(net_buffer* nbuf) if (nbuf == NULL) return; #if 0 - /* Free possible allocated */ + // Free possible allocated if (nbuf->COOKIEFIELD != NULL) free((void*)nbuf->COOKIEFIELD); #endif @@ -77,10 +76,10 @@ nb_destroy(net_buffer* nbuf) // Extract the expected size of the packet -// TODO: This might be inefficient as at the moment of the creation of the net_buffer -// this information is known and it could be stored in any of the net_buffer fields -// but I still dont know how many of those am i gonna have free.... -size_t +// TODO: This might be inefficient as at the moment of the creation +// of the net_buffer this information is known and it could be stored +#if 0 +ssize_t get_expected_size(net_buffer* nbuf) { @@ -114,14 +113,17 @@ get_expected_size(net_buffer* nbuf) break; } - return B_ERROR; + return -1; } +#endif + #if 0 #pragma mark - room util - #endif -inline void + +void init_room(struct list* l) { list_init(l); @@ -142,7 +144,7 @@ alloc_room(struct list* l, size_t size) } -inline void +void reuse_room(struct list* l, void* room) { list_add_item(l, room); diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.h index 3ce5f4d368..3fa836880a 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.h @@ -1,10 +1,7 @@ /* * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com - * * All rights reserved. Distributed under the terms of the MIT License. - * */ - #ifndef _H2UTIL_H_ #define _H2UTIL_H_ @@ -14,7 +11,8 @@ /* net buffer utils for ACL, to be reviewed */ #define DEVICEFIELD type -#define SET_DEVICE(nbuf,hid) (nbuf->DEVICEFIELD=(nbuf->DEVICEFIELD&0xFFFFFF00)|(hid&0xFF)) +#define SET_DEVICE(nbuf, hid) \ + (nbuf->DEVICEFIELD=(nbuf->DEVICEFIELD & 0xFFFFFF00) | (hid & 0xFF)) #define GET_DEVICE(nbuf) fetch_device(NULL,(nbuf->DEVICEFIELD&0xFF)) #define COOKIEFIELD flags @@ -23,10 +21,10 @@ void nb_destroy(net_buffer* nbuf); size_t get_expected_size(net_buffer* nbuf); /* Room utils */ -inline void init_room(struct list* l); -void* alloc_room(struct list* l, size_t size); -inline void reuse_room(struct list* l, void* room); -void purge_room(struct list* l); +void init_room(struct list* l); +void* alloc_room(struct list* l, size_t size); +void reuse_room(struct list* l, void* room); +void purge_room(struct list* l); /* list utils */ #define list_purge(x) purge_room(x) diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.c b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.cpp similarity index 58% rename from src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.c rename to src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.cpp index 481c19ec1f..4ff42fd9be 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.c +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.cpp @@ -12,16 +12,16 @@ #include struct snet_buffer { - struct list_link link; + struct list_link link; - uint8* buffer; + uint8* buffer; - uint16 allocatedSize; - uint16 expectedSize; - uint16 puttingSize; - uint16 pullingSize; + uint16 allocatedSize; + uint16 expectedSize; + uint16 puttingSize; + uint16 pullingSize; - void* cookie; + void* cookie; }; @@ -29,10 +29,10 @@ struct snet_buffer { snet_buffer* snb_create(uint16 size) { - /* TODO: pointer checking */ + // TODO: pointer checking #ifdef SNB_BUFFER_ATTACHED - /* Allocating these 2 buffers together might prevent memory fragmentation? */ + // Allocating these 2 buffers together might prevent memory fragmentation snet_buffer* snb = (snet_buffer*) malloc(sizeof(snet_buffer) + size); snb->buffer = ((uint8*)snb) + sizeof(snet_buffer); #else @@ -50,7 +50,7 @@ snb_create(uint16 size) void snb_put(snet_buffer* snb, void* data, uint16 size) { - /* TODO: check overflow */ + // TODO: check overflow memcpy( &snb->buffer[snb->puttingSize], data, size); snb->puttingSize+=size; } @@ -59,14 +59,14 @@ snb_put(snet_buffer* snb, void* data, uint16 size) void* snb_pull(snet_buffer* snb, uint16 size) { - /* TODO: check overflow */ + // TODO: check overflow snb->pullingSize+=size; - return &snb->buffer[snb->pullingSize-size]; + return &snb->buffer[snb->pullingSize - size]; } -inline void +void snb_reset(snet_buffer* snb) { snb->puttingSize = snb->pullingSize = 0; @@ -89,83 +89,88 @@ snb_free(snet_buffer* snb) } -inline void* +void* snb_get(snet_buffer* snb) { - /* TODO: pointer checking */ + // TODO: pointer checking return snb->buffer; } -inline uint16 +uint16 snb_size(snet_buffer* snb) { - /* TODO: pointer checking */ + // TODO: pointer checking return snb->expectedSize; } -inline void* +void* snb_cookie(snet_buffer* snb) { - /* TODO: pointer checking */ + // TODO: pointer checking return snb->cookie; } -inline void +void snb_set_cookie(snet_buffer* snb, void* cookie) { - /* TODO: pointer checking */ + // TODO: pointer checking snb->cookie = cookie; } -/* Return true if we canot "put" more data in the buffer */ -inline bool snb_completed(snet_buffer* snb) +// Return true if we canot "put" more data in the buffer +bool +snb_completed(snet_buffer* snb) { return (snb->expectedSize == snb->puttingSize); } -/* Return true if we cannot pull more more data from the buffer */ -inline bool snb_finished(snet_buffer* snb) +// Return true if we cannot pull more more data from the buffer +bool +snb_finished(snet_buffer* snb) { return (snb->expectedSize == snb->pullingSize); } -inline uint16 snb_remaining_to_put(snet_buffer* snb) +uint16 +snb_remaining_to_put(snet_buffer* snb) { return (snb->expectedSize - snb->puttingSize); } -inline uint16 snb_remaining_to_pull(snet_buffer* snb) +uint16 +snb_remaining_to_pull(snet_buffer* snb) { return (snb->expectedSize - snb->pullingSize); } +/* + ISSUE1: Number of packets in the worst case(we always need a bigger + buffer than before) increases, never decreases: -/* ISSUE1: Number of packets in the worst case(we always need a bigger - buffer than before) increases, never decreases: + SOL1: Delete the smallest when the queue is bigger than X elements + SOL2: ? - SOL1: Delete the smallest when the queue is bigger than X elements - SOL2: ? + ISSUE2: If the queue is not gonna be used for long time. Memory c + ould be freed - ISSUE2: If the queue is not gonna be used for long time. Memory c - ould be freed + SOL1: Provide purge func. + SOL2: ? +*/ - SOL1: Provide purge func. - SOL2: ? - */ static snet_buffer* snb_attempt_reuse(snet_buffer* snb, uint16 size) { - if ( snb == NULL || (snb->allocatedSize < size) ) { + if (snb == NULL || (snb->allocatedSize < size)) { - /* Impossible or not worth, Creating a new one */ + // Impossible or not worth, Creating a new one snb_free(snb); return snb_create(size); @@ -183,15 +188,15 @@ snb_park(struct list* l, snet_buffer* snb) { snet_buffer* item = NULL; - /* insert it by order */ - while ((item = list_get_next_item(l, item)) != NULL) { - /* This one has allocated more than us place us back*/ + // insert it by order + while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL) { + // This one has allocated more than us place us back if (item->allocatedSize > snb->allocatedSize) { list_insert_item_before(l, item, snb); return; } } - /* no buffer bigger than us(or empty).. then at the end*/ + // no buffer bigger than us(or empty).. then at the end list_add_item(l, snb); } @@ -203,16 +208,18 @@ snb_fetch(struct list* l, uint16 size) snet_buffer* newitem = NULL; if (!list_is_empty(l)) - while ((item = list_get_next_item(l, item)) != NULL) { + while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL) { if (item->allocatedSize >= size) { - /* This one is for us*/ + // This one is for us break; } } newitem = snb_attempt_reuse(item, size); - /* the resulting reused one is the same as we fetched? => remove it from list*/ + /* the resulting reused one is the same + * as we fetched? => remove it from list + */ if (item == newitem) { list_remove_item(l, item); } @@ -227,7 +234,7 @@ snb_packets(struct list* l) uint16 count = 0; snet_buffer* item = NULL; - while ((item = list_get_next_item(l, item)) != NULL) + while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL) count++; return count; @@ -237,5 +244,6 @@ snb_packets(struct list* l) void snb_dump(snet_buffer* snb) { - kprintf("item=%p\tprev=%p\tnext=%p\tallocated=%d\n", snb, snb->link.prev, snb->link.next, snb->allocatedSize); + kprintf("item=%p\tprev=%p\tnext=%p\tallocated=%d\n", snb, snb->link.prev, + snb->link.next, snb->allocatedSize); } diff --git a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.h b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.h index 5d523712cf..8c86be6932 100644 --- a/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.h +++ b/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.h @@ -16,7 +16,7 @@ * * So snet_buffers are ONLY meant to be used when: * 1) You know exactily the maximun/final size of the frame - * before allocating it, and you will never exceed it. + * before allocating it, and you will never exceed it. * 2) You are not supposed to prepend data, only append. * */ @@ -31,43 +31,43 @@ struct snet_buffer; typedef struct snet_buffer snet_buffer; /* Creates a snb_buffer allocating size space for its full content */ -snet_buffer* snb_create(uint16 size); +snet_buffer* snb_create(uint16 size); /* Free the snb_buffer*/ -void snb_free(snet_buffer* snb); +void snb_free(snet_buffer* snb); /* Free the snb_buffer*/ -void* snb_get(snet_buffer* snb); +void* snb_get(snet_buffer* snb); /* Size of the snb_buffer*/ -uint16 snb_size(snet_buffer* snb); +uint16 snb_size(snet_buffer* snb); /* Cookie of the snb_buffer*/ -void* snb_cookie(snet_buffer* snb); +void* snb_cookie(snet_buffer* snb); /* Get Cookie of the snb_buffer*/ -void snb_set_cookie(snet_buffer* snb, void* cookie); +void snb_set_cookie(snet_buffer* snb, void* cookie); /* Place the memory given by data to the "tail" of the snb */ -void snb_put(snet_buffer* snb, void* data, uint16 size); +void snb_put(snet_buffer* snb, void* data, uint16 size); /* Returns a header chunk of size data */ -void* snb_pull(snet_buffer* snb, uint16 size); +void* snb_pull(snet_buffer* snb, uint16 size); /* Discards all data put or pulled from the buffer */ -void snb_reset(snet_buffer* snb); +void snb_reset(snet_buffer* snb); /* Return true if we canot "put" more data in the buffer */ -bool snb_completed(snet_buffer* snb); +bool snb_completed(snet_buffer* snb); /* Return true if we cannot pull more more data from the buffer */ -bool snb_finished(snet_buffer* snb); +bool snb_finished(snet_buffer* snb); /* Return the amount of data we can still put in the buffer */ -uint16 snb_remaining_to_put(snet_buffer* snb); +uint16 snb_remaining_to_put(snet_buffer* snb); /* Return the amount of data we can still pull in the buffer */ -uint16 snb_remaining_to_pull(snet_buffer* snb); +uint16 snb_remaining_to_pull(snet_buffer* snb); /* These to functions are provided to avoid memory fragmentation * allocating and freeing many snb_buffers and its possible overhead. * Thypical scenario would be * that you create a snb_buffer to send data, once you send you free it, * and need another one to hold the response. The idea would be once you send - * that buffer, to snb_park the buffer, and whenever you need to allocate another - * one snb_fetch it. That funcion will reuse most appropiated previous used one - * snb_buff by its memory use. + * that buffer, to snb_park the buffer, and whenever you need to allocate + * another one snb_fetch it. That funcion will reuse most appropiated + * previous used one snb_buff by its memory use. */ void snb_park(struct list* l, snet_buffer* snb); snet_buffer* snb_fetch(struct list* l, uint16 size); diff --git a/src/add-ons/kernel/network/devices/Jamfile b/src/add-ons/kernel/network/devices/Jamfile index 00a9a24769..ef265df402 100644 --- a/src/add-ons/kernel/network/devices/Jamfile +++ b/src/add-ons/kernel/network/devices/Jamfile @@ -2,4 +2,4 @@ SubDir HAIKU_TOP src add-ons kernel network devices ; SubInclude HAIKU_TOP src add-ons kernel network devices ethernet ; SubInclude HAIKU_TOP src add-ons kernel network devices loopback ; -SubInclude HAIKU_TOP src add-ons kernel network devices bluetooth ; + diff --git a/src/add-ons/kernel/network/devices/bluetooth/Jamfile b/src/add-ons/kernel/network/devices/bluetooth/Jamfile deleted file mode 100644 index 4c77e83add..0000000000 --- a/src/add-ons/kernel/network/devices/bluetooth/Jamfile +++ /dev/null @@ -1,27 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel network devices bluetooth ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -if $(TARGET_PLATFORM) != haiku { - UseHeaders [ FStandardOSHeaders ] : true ; - # Needed for and maybe other stuff. - UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; - # We need the public network headers also when not compiling for Haiku. - # Unfortunately we get more than we want, namely all POSIX headers. -} - -UsePrivateKernelHeaders ; -UsePrivateHeaders net bluetooth ; - -KernelAddon bluetooth : - bluetooth.cpp - acl.cpp -; - -# Installation -#HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/devices -# : bluetooth ; - -#Package haiku-networkingkit-cvs : -# haiku : -# boot home config add-ons kernel haiku_network protocols ; diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap_lower.cpp b/src/add-ons/kernel/network/protocols/l2cap/l2cap_lower.cpp index 42601eb536..3178820a51 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap_lower.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap_lower.cpp @@ -39,11 +39,11 @@ status_t l2cap_receive(HciConnection* conn, net_buffer* buffer) { - status_t error = B_OK; - uint16 dcid; - uint16 length; + status_t error = B_OK; + uint16 dcid; + uint16 length; - /* Check packet */ + // Check packet if (buffer->size < sizeof(l2cap_hdr_t)) { debugf("invalid L2CAP packet. Packet too small, len=%ld\n", buffer->size); gBufferModule->free(buffer); @@ -51,7 +51,7 @@ l2cap_receive(HciConnection* conn, net_buffer* buffer) } - /* Get L2CAP header */ + // Get L2CAP header NetBufferHeaderReader bufferHeader(buffer); status_t status = bufferHeader.Status(); if (status < B_OK) { @@ -61,28 +61,28 @@ l2cap_receive(HciConnection* conn, net_buffer* buffer) length = bufferHeader->length = le16toh(bufferHeader->length); dcid = bufferHeader->dcid = le16toh(bufferHeader->dcid); - bufferHeader.Remove(); /* pulling */ + bufferHeader.Remove(); // pulling - /* Check payload size */ + // Check payload size if (length != buffer->size ) { - debugf("invalid L2CAP packet. Payload length mismatch, packetlen=%d, nebufferlen=%ld\n", - length, buffer->size); + debugf("Payload length mismatch, packetlen=%d, bufferlen=%ld\n", + length, buffer->size); gBufferModule->free(buffer); return EMSGSIZE; } - /* Process packet */ + // Process packet switch (dcid) { - case L2CAP_SIGNAL_CID: /* L2CAP command */ + case L2CAP_SIGNAL_CID: // L2CAP command error = l2cap_process_signal_cmd(conn, buffer); break; - case L2CAP_CLT_CID: /* Connectionless packet - error = l2cap_cl_receive(buffer);*/ + case L2CAP_CLT_CID: // Connectionless packet + // error = l2cap_cl_receive(buffer); flowf("CL FRAME!!\n"); break; - default: /* Data packet */ + default: // Data packet error = l2cap_co_receive(conn, buffer, dcid); break; } @@ -92,7 +92,7 @@ l2cap_receive(HciConnection* conn, net_buffer* buffer) } -struct net_device_module_info* btDevices = NULL; +struct bt_hci_module_info* btDevices = NULL; #if 0 #pragma mark - thread conn sched - @@ -105,6 +105,7 @@ void purge_connection(HciConnection* conn) { L2capFrame* frame; + bool containerCanBeDestroyed; debugf("handle=%d\n", conn->handle); @@ -118,42 +119,44 @@ purge_connection(HciConnection* conn) // Here is the place to decide how many l2cap signals we want to have // per l2cap packet. 1 ATM - if (frame->type == L2CAP_C_FRAME) { + if (frame->type == L2CAP_C_FRAME && IS_SIGNAL_REQ(frame->code)) { btCoreData->TimeoutSignal(frame, bluetooth_l2cap_rtx_timeout); btCoreData->QueueSignal(frame); - } + containerCanBeDestroyed = false; + } else + containerCanBeDestroyed = true; // Add the l2cap header if (frame->buffer == NULL) panic("Malformed frame in ongoing queue"); - NetBufferPrepend bufferHeader(frame->buffer); - status_t status = bufferHeader.Status(); - if (status < B_OK) { - debugf("l2cap header could not be prepended!! frame code=%d\n", frame->code); - return; + { + NetBufferPrepend bufferHeader(frame->buffer); + status_t status = bufferHeader.Status(); + if (status < B_OK) { + debugf("header could not be prepended! code=%d\n", frame->code); + return; + } + + // fill + bufferHeader->length = htole16(frame->buffer->size - sizeof(l2cap_hdr_t)); + switch (frame->type) { + case L2CAP_C_FRAME: + bufferHeader->dcid = L2CAP_SIGNAL_CID; + break; + case L2CAP_G_FRAME: + bufferHeader->dcid = L2CAP_CLT_CID; + break; + default: + bufferHeader->dcid = frame->channel->dcid; + break; + + } } - // fill - bufferHeader->length = htole16(frame->buffer->size - sizeof(l2cap_hdr_t)); - switch (frame->type) { - case L2CAP_C_FRAME: - bufferHeader->dcid = L2CAP_SIGNAL_CID; - break; - case L2CAP_G_FRAME: - bufferHeader->dcid = L2CAP_CLT_CID; - break; - default: - bufferHeader->dcid = frame->channel->dcid; - break; - - } - - bufferHeader.Sync(); - if (btDevices == NULL) - if (get_module(NET_BLUETOOTH_DEVICE_NAME, (module_info**)&btDevices) != B_OK) { + if (get_module(BT_HCI_MODULE_NAME, (module_info**)&btDevices) != B_OK) { panic("l2cap: cannot get dev module"); } // TODO: someone put it @@ -161,7 +164,13 @@ purge_connection(HciConnection* conn) debugf("dev %p frame %p tolower\n", conn->ndevice, frame->buffer); frame->buffer->type = conn->handle; - btDevices->send_data(conn->ndevice, frame->buffer); + btDevices->PostACL(conn->ndevice->index, frame->buffer); + + // Only in the case that we need a response the frame container needs + // to be kept: Request C-Frames + if (containerCanBeDestroyed) { + delete frame; + } // frame = conn->OutGoingFrames.RemoveHead(); // } @@ -170,7 +179,7 @@ purge_connection(HciConnection* conn) static status_t -connection_thread(void *) +connection_thread(void*) { int32 code; ssize_t ssizePort; @@ -187,24 +196,24 @@ connection_thread(void *) while ((ssizePort = port_buffer_size(fPort)) != B_BAD_PORT_ID) { - if (ssizePort <= 0) { - debugf("Error %s\n", strerror(ssizePort)); - snooze(500*1000); - continue; - } + if (ssizePort <= 0) { + debugf("Error %s\n", strerror(ssizePort)); + snooze(500 * 1000); + continue; + } if (ssizePort > (ssize_t) sizeof(conn)) { - debugf("Message too big %ld\n", ssizePort); - snooze(500*1000); + debugf("Message too big %ld\n", ssizePort); + snooze(500 * 1000); continue; } ssizeRead = read_port(fPort, &code, &conn, ssizePort); if (ssizeRead != ssizePort) { - debugf("Missmatch size port=%ld read=%ld\n", ssizePort, ssizeRead); - snooze(500*1000); - continue; + debugf("Missmatch size port=%ld read=%ld\n", ssizePort, ssizeRead); + snooze(500 * 1000); + continue; } purge_connection(conn); @@ -263,8 +272,6 @@ SchedConnectionPurgeThread(HciConnection* conn) status_t error = write_port(port, (uint32) conn, &temp, sizeof(conn)); - //debugf("error post %s port=%ld size=%ld\n", strerror(error), port, sizeof(conn)); - if (error != B_OK) panic("BT Connection sched failed");