1/*
2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5#ifndef _BTCOREDATA_H
6#define _BTCOREDATA_H
7
8
9#include <module.h>
10#include <lock.h>
11#include <util/DoublyLinkedList.h>
12
13#include <net_buffer.h>
14#include <net_device.h>
15
16#include <bluetooth/bluetooth.h>
17#include <bluetooth/HCI/btHCI.h>
18#include <bluetooth/HCI/btHCI_transport.h>
19#include <l2cap.h>
20
21
22#define BT_CORE_DATA_MODULE_NAME "bluetooth/btCoreData/v1"
23
24
25struct L2capChannel;
26struct L2capFrame;
27struct L2capEndpoint;
28
29typedef enum _connection_status {
30	HCI_CONN_CLOSED,
31	HCI_CONN_OPEN,
32} connection_status;
33
34
35#ifdef __cplusplus
36
37struct HciConnection : DoublyLinkedListLinkImpl<HciConnection> {
38	HciConnection();
39	virtual ~HciConnection();
40
41	hci_id				Hid;
42	bluetooth_device*	ndevice;
43	net_buffer*			currentRxPacket;
44	ssize_t				currentRxExpectedLength;
45	bdaddr_t			destination;
46	uint16				handle;
47	int					type;
48	uint16				mtu;
49	connection_status	status;
50	uint16				lastCid;
51	uint8				lastIdent;
52	DoublyLinkedList<L2capChannel> ChannelList;
53	DoublyLinkedList<L2capFrame> ExpectedResponses;
54	DoublyLinkedList<L2capFrame> OutGoingFrames;
55	mutex				fLock;
56	mutex				fLockExpected;
57};
58
59#else
60
61struct HciConnection;
62
63#endif
64
65typedef enum _channel_status {
66	L2CAP_CHAN_CLOSED,				/* channel closed */
67	L2CAP_CHAN_W4_L2CAP_CON_RSP,	/* wait for L2CAP resp. */
68	L2CAP_CHAN_W4_L2CA_CON_RSP,		/* wait for upper resp. */
69	L2CAP_CHAN_CONFIG,				/* L2CAP configuration */
70	L2CAP_CHAN_OPEN,				/* channel open */
71	L2CAP_CHAN_W4_L2CAP_DISCON_RSP,	/* wait for L2CAP discon. */
72	L2CAP_CHAN_W4_L2CA_DISCON_RSP	/* wait for upper discon. */
73} channel_status;
74
75
76#ifdef __cplusplus
77
78typedef struct _ChannelConfiguration {
79
80	uint16			imtu;	/* incoming channel MTU */
81	l2cap_flow_t	iflow;	/* incoming flow control */
82	uint16			omtu;	/* outgoing channel MTU */
83	l2cap_flow_t	oflow;	/* outgoing flow control */
84
85	uint16			flush_timo;	/* flush timeout */
86	uint16			link_timo;	/* link timeout */
87
88} ChannelConfiguration;
89
90struct L2capChannel : DoublyLinkedListLinkImpl<L2capChannel> {
91	HciConnection*	conn;
92	uint16			scid;
93	uint16			dcid;
94	uint16			psm;
95	uint8			ident;
96	uint8			cfgState;
97
98	channel_status		state;
99	ChannelConfiguration*	configuration;
100	L2capEndpoint*		endpoint;
101};
102
103#endif
104
105
106typedef enum _frametype {
107	L2CAP_C_FRAME, // signals
108	L2CAP_G_FRAME, // CL packets
109	L2CAP_B_FRAME, // CO packets
110
111	L2CAP_I_FRAME,
112	L2CAP_S_FRAME
113} frame_type;
114
115#ifdef __cplusplus
116
117struct L2capFrame : DoublyLinkedListLinkImpl<L2capFrame> {
118
119	HciConnection*	conn;
120	L2capChannel*	channel;
121
122	uint16			flags;	/* command flags */
123	#define L2CAP_CMD_PENDING	(1 << 0)	/* command is pending */
124
125	uint8			code;	/* L2CAP command opcode */
126	uint8			ident;	/* L2CAP command ident */
127
128	frame_type		type;
129
130	net_buffer*		buffer; // contains 1 l2cap / mutliple acls
131
132    // TODO :struct callout	timo;		/* RTX/ERTX timeout */
133};
134
135#endif
136
137
138struct bluetooth_core_data_module_info {
139	module_info info;
140
141	status_t				(*PostEvent)(bluetooth_device* ndev, void* event,
142								size_t size);
143	struct HciConnection*	(*AddConnection)(uint16 handle, int type,
144								const bdaddr_t& dst, hci_id hid);
145
146	// status_t				(*RemoveConnection)(bdaddr_t destination, hci_id hid);
147	status_t				(*RemoveConnection)(uint16 handle, hci_id hid);
148
149	hci_id					(*RouteConnection)(const bdaddr_t& destination);
150
151	void					(*SetAclBuffer)(struct HciConnection* conn,
152								net_buffer* nbuf);
153	void					(*SetAclExpectedSize)(struct HciConnection* conn,
154								size_t size);
155	void					(*AclPutting)(struct HciConnection* conn,
156								size_t size);
157	bool					(*AclComplete)(struct HciConnection* conn);
158	bool					(*AclOverFlowed)(struct HciConnection* conn);
159
160	struct HciConnection*	(*ConnectionByHandle)(uint16 handle, hci_id hid);
161	struct HciConnection*	(*ConnectionByDestination)(
162								const bdaddr_t& destination, hci_id hid);
163
164	struct L2capChannel*	(*AddChannel)(struct HciConnection* conn,
165								uint16 psm);
166	void					(*RemoveChannel)(struct HciConnection* conn,
167								uint16 scid);
168	struct L2capChannel*	(*ChannelBySourceID)(struct HciConnection* conn,
169								uint16 sid);
170	uint16					(*ChannelAllocateCid)(struct HciConnection* conn);
171	uint16					(*ChannelAllocateIdent)(struct HciConnection* conn);
172
173	struct L2capFrame*		(*SignalByIdent)(struct HciConnection* conn,
174								uint8 ident);
175	status_t				(*TimeoutSignal)(struct L2capFrame* frame,
176								uint32 timeo);
177	status_t				(*UnTimeoutSignal)(struct L2capFrame* frame);
178	struct L2capFrame*		(*SpawnFrame)(struct HciConnection* conn,
179								struct L2capChannel* channel,
180								net_buffer* buffer, frame_type frame);
181	struct L2capFrame*		(*SpawnSignal)(struct HciConnection* conn,
182								struct L2capChannel* channel,
183								net_buffer* buffer, uint8 ident, uint8 code);
184	status_t				(*AcknowledgeSignal)(struct L2capFrame* frame);
185	status_t				(*QueueSignal)(struct L2capFrame* frame);
186
187};
188
189
190inline bool ExistConnectionByDestination(const bdaddr_t& destination,
191				hci_id hid);
192inline bool ExistConnectionByHandle(uint16 handle, hci_id hid);
193
194
195#endif // _BTCOREDATA_H
196