Author: oruizdorantes Date: 2010-01-17 16:46:36 +0100 (Sun, 17 Jan 2010) New Revision: 35117 Changeset: http://dev.haiku-os.org/changeset/35117/haiku Added: haiku/trunk/src/add-ons/kernel/bluetooth/hci/ haiku/trunk/src/add-ons/kernel/bluetooth/hci/Jamfile haiku/trunk/src/add-ons/kernel/bluetooth/hci/acl.cpp haiku/trunk/src/add-ons/kernel/bluetooth/hci/acl.h haiku/trunk/src/add-ons/kernel/bluetooth/hci/bluetooth.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.cpp Removed: haiku/trunk/headers/os/bluetooth/HCI/btHCI_module.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.c haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.c haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.c haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.c haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.c haiku/trunk/src/add-ons/kernel/network/devices/bluetooth/ Modified: haiku/trunk/headers/os/bluetooth/HCI/btHCI_transport.h haiku/trunk/headers/private/bluetooth/btCoreData.h haiku/trunk/headers/private/bluetooth/btModules.h haiku/trunk/src/add-ons/kernel/bluetooth/Jamfile haiku/trunk/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/Jamfile haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2cfg.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2transactions.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2upper.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2util.h haiku/trunk/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/snet_buffer.h haiku/trunk/src/add-ons/kernel/network/devices/Jamfile haiku/trunk/src/add-ons/kernel/network/protocols/l2cap/l2cap_lower.cpp Log: - 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. Modified: haiku/trunk/headers/os/bluetooth/HCI/btHCI_transport.h =================================================================== --- haiku/trunk/headers/os/bluetooth/HCI/btHCI_transport.h 2010-01-17 15:29:04 UTC (rev 35116) +++ haiku/trunk/headers/os/bluetooth/HCI/btHCI_transport.h 2010-01-17 15:46:36 UTC (rev 35117) @@ -7,89 +7,156 @@ #include <bluetooth/HCI/btHCI.h> +#include <util/DoublyLinkedList.h> + #include <net_buffer.h> #include <Drivers.h> -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; char realName[B_OS_NAME_LENGTH]; } 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<bluetooth_device> { + + 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" Modified: haiku/trunk/headers/private/bluetooth/btCoreData.h =================================================================== --- haiku/trunk/headers/private/bluetooth/btCoreData.h 2010-01-17 15:29:04 UTC (rev 35116) +++ haiku/trunk/headers/private/bluetooth/btCoreData.h 2010-01-17 15:46:36 UTC (rev 35117) @@ -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 <module.h> -#include <lock.h> -#include <util/DoublyLinkedList.h> -#include <util/DoublyLinkedQueue.h> - -#include <net_buffer.h> -#include <net_device.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/HCI/btHCI.h> -#include <l2cap.h> - -#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> { - 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<L2capChannel> ChannelList; - DoublyLinkedList<L2capFrame> ExpectedResponses; - DoublyLinkedList<L2capFrame> 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<L2capChannel> { - 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<L2capFrame> { - - 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 <module.h> +#include <lock.h> +#include <util/DoublyLinkedList.h> +#include <util/DoublyLinkedQueue.h> + +#include <net_buffer.h> +#include <net_device.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/HCI/btHCI.h> +#include <bluetooth/HCI/btHCI_transport.h> +#include <l2cap.h> + +#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> { + 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<L2capChannel> ChannelList; + DoublyLinkedList<L2capFrame> ExpectedResponses; + DoublyLinkedList<L2capFrame> 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<L2capChannel> { + 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<L2capFrame> { + + 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 Modified: haiku/trunk/headers/private/bluetooth/btModules.h =================================================================== --- haiku/trunk/headers/private/bluetooth/btModules.h 2010-01-17 15:29:04 UTC (rev 35116) +++ haiku/trunk/headers/private/bluetooth/btModules.h 2010-01-17 15:46:36 UTC (rev 35117) @@ -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 Modified: haiku/trunk/src/add-ons/kernel/bluetooth/Jamfile =================================================================== --- haiku/trunk/src/add-ons/kernel/bluetooth/Jamfile 2010-01-17 15:29:04 UTC (rev 35116) +++ haiku/trunk/src/add-ons/kernel/bluetooth/Jamfile 2010-01-17 15:46:36 UTC (rev 35117) @@ -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 ; Modified: haiku/trunk/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp 2010-01-17 15:29:04 UTC (rev 35116) +++ haiku/trunk/src/add-ons/kernel/bluetooth/btCoreData/BTCoreData.cpp 2010-01-17 15:46:36 UTC (rev 35117) @@ -15,10 +15,11 @@ #include <btDebug.h> DoublyLinkedList<HciConnection> 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 @@ inline bool ExistConnectionByHandle(uint16 handle, hci_id hid) { - return (ConnectionByHandle(handle,hid)); + return (ConnectionByHandle(handle, hid)); } @@ -37,39 +38,48 @@ HciConnection* conn; L2capChannel* chan; L2capFrame* frame; - DoublyLinkedList<HciConnection>::Iterator iterator = sConnectionList.GetIterator(); + DoublyLinkedList<HciConnection>::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<L2capChannel>::Iterator channelIterator = conn->ChannelList.GetIterator(); + DoublyLinkedList<L2capChannel>::Iterator channelIterator + = conn->ChannelList.GetIterator(); + while (channelIterator.HasNext()) { chan = channelIterator.Next(); kprintf("\t\tscid=%x dcid=%x state=%x cfg=%x\n", chan->scid, - chan->dcid, chan->state, chan->cfgState); + chan->dcid, chan->state, chan->cfgState); } // Each outgoing kprintf("\n\tOutGoingFrames\n"); - DoublyLinkedList<L2capFrame>::Iterator frameIterator = conn->OutGoingFrames.GetIterator(); + DoublyLinkedList<L2capFrame>::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<L2capFrame>::Iterator frameExpectedIterator = conn->ExpectedResponses.GetIterator(); + DoublyLinkedList<L2capFrame>::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 @@ } - 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 @@ 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 @@ case B_MODULE_INIT: new (&sConnectionList) DoublyLinkedList<HciConnection>; 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 @@ return B_ERROR; } + bluetooth_core_data_module_info sBCDModule = { { BT_CORE_DATA_MODULE_NAME, @@ -167,7 +185,7 @@ }, PostEvent, AddConnection, -/* RemoveConnection,*/ + // RemoveConnection, RemoveConnection, RouteConnection, @@ -198,7 +216,7 @@ }; -module_info *modules[] = { - (module_info *)&sBCDModule, +module_info* modules[] = { + (module_info*)&sBCDModule, NULL }; Added: haiku/trunk/src/add-ons/kernel/bluetooth/hci/Jamfile =================================================================== --- haiku/trunk/src/add-ons/kernel/bluetooth/hci/Jamfile (rev 0) +++ haiku/trunk/src/add-ons/kernel/bluetooth/hci/Jamfile 2010-01-17 15:46:36 UTC (rev 35117) @@ -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 +; Added: haiku/trunk/src/add-ons/kernel/bluetooth/hci/acl.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/bluetooth/hci/acl.cpp (rev 0) +++ haiku/trunk/src/add-ons/kernel/bluetooth/hci/acl.cpp 2010-01-17 15:46:36 UTC (rev 35117) @@ -0,0 +1,179 @@ +/* + * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include <KernelExport.h> +#include <string.h> + +#include <NetBufferUtilities.h> +#include <net_protocol.h> + +#include <bluetooth/HCI/btHCI_acl.h> +#include <bluetooth/HCI/btHCI_transport.h> +#include <bluetooth/HCI/btHCI_event.h> +#include <bluetooth/bdaddrUtils.h> + +//#define BT_DEBUG_THIS_MODULE +#define SUBMODULE_NAME "ACL" +#define SUBMODULE_COLOR 34 +#include <btDebug.h> +#include <btCoreData.h> +#include <btModules.h> +#include <l2cap.h> + +#include "acl.h" + +extern struct bluetooth_core_data_module_info* btCoreData; + +struct net_protocol_module_info* L2cap = NULL; + +extern void RegisterConnection(hci_id hid, uint16 handle); +extern void unRegisterConnection(hci_id hid, uint16 handle); + +status_t PostToUpper(HciConnection* conn, net_buffer* buf); + +status_t +AclAssembly(net_buffer* nbuf, hci_id hid) +{ + status_t error = B_OK; + + // Check ACL data packet. Driver should ensure report complete ACL packets + if (nbuf->size < sizeof(struct hci_acl_header)) { + debugf("Invalid ACL data packet, small length=%ld\n", nbuf->size); + gBufferModule->free(nbuf); + return (EMSGSIZE); + } + + // Strip ACL data packet header + NetBufferHeaderReader<struct hci_acl_header> aclHeader(nbuf); + status_t status = aclHeader.Status(); + if (status < B_OK) { + gBufferModule->free(nbuf); + return ENOBUFS; + } + + + // Get ACL connection handle, PB flag and payload length + aclHeader->handle = le16toh(aclHeader->handle); + + uint16 con_handle = get_acl_handle(aclHeader->handle); + uint16 pb = get_acl_pb_flag(aclHeader->handle); + uint16 length = le16toh(aclHeader->alen); + + aclHeader.Remove(); + + debugf("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 + + HciConnection* conn = btCoreData->ConnectionByHandle(con_handle, hid); + if (conn == NULL) { + debugf("Uexpected handle=%#x does not exist!\n", con_handle); + conn = btCoreData->AddConnection(con_handle, BT_ACL, BDADDR_NULL, hid); + } + + // Verify connection state + if (conn->status!= HCI_CONN_OPEN) { + flowf("unexpected ACL data packet. Connection not open\n"); + gBufferModule->free(nbuf); + return EHOSTDOWN; + } + + + // Process packet + if (pb == HCI_ACL_PACKET_START) { + if (conn->currentRxPacket != NULL) { + debugf("Dropping incomplete L2CAP packet, got %ld want %d \n", + conn->currentRxPacket->size, length ); + gBufferModule->free(conn->currentRxPacket); + conn->currentRxPacket = NULL; + conn->currentRxExpectedLength = 0; + } + + // Get L2CAP header, ACL header was dimissed + if (nbuf->size < sizeof(l2cap_hdr_t)) { + debugf("Invalid L2CAP start fragment, small, length=%ld\n", + nbuf->size); + gBufferModule->free(nbuf); + return (EMSGSIZE); + } + + + NetBufferHeaderReader<l2cap_hdr_t> l2capHeader(nbuf); + status_t status = l2capHeader.Status(); + if (status < B_OK) { + gBufferModule->free(nbuf); + return ENOBUFS; + } + + l2capHeader->length = le16toh(l2capHeader->length); + l2capHeader->dcid = le16toh(l2capHeader->dcid); + + debugf("New L2CAP, handle=%#x length=%d\n", con_handle, + le16toh(l2capHeader->length)); + + // Start new L2CAP packet + conn->currentRxPacket = nbuf; + conn->currentRxExpectedLength = l2capHeader->length + sizeof(l2cap_hdr_t); + + + } else if (pb == HCI_ACL_PACKET_FRAGMENT) { + if (conn->currentRxPacket == NULL) { + gBufferModule->free(nbuf); + return (EINVAL); + } + + // Add fragment to the L2CAP packet + gBufferModule->merge(conn->currentRxPacket, nbuf, true); + + } else { + debugf("invalid ACL data packet. Invalid PB flag=%#x\n", pb); + gBufferModule->free(nbuf); + return (EINVAL); + } + + // substract the length of content of the ACL packet + conn->currentRxExpectedLength -= length; + + if (conn->currentRxExpectedLength < 0) { + + debugf("Mismatch. Got %ld, expected %ld\n", + conn->currentRxPacket->size, conn->currentRxExpectedLength); + + gBufferModule->free(conn->currentRxPacket); [... truncated: 3037 lines follow ...]