1/* 2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 * 5 */ 6 7/*- 8 * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com> 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19*/ 20 21 22#include <net_datalink.h> 23#include <net_protocol.h> 24#include <net_stack.h> 25#include <NetBufferUtilities.h> 26 27#include <KernelExport.h> 28#include <util/list.h> 29#include <util/DoublyLinkedList.h> 30 31#include <new> 32#include <stdlib.h> 33#include <string.h> 34 35#include "l2cap_address.h" 36#include "l2cap_internal.h" 37#include "l2cap_lower.h" 38#include "L2capEndpoint.h" 39 40#include <bluetooth/HCI/btHCI_acl.h> 41#include <btModules.h> 42 43 44#include <btDebug.h> 45 46 47typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField; 48DoublyLinkedList<L2capEndpoint> EndpointList; 49 50extern net_protocol_module_info gL2CAPModule; 51 52// module references 53bluetooth_core_data_module_info* btCoreData; 54 55net_buffer_module_info* gBufferModule; 56net_stack_module_info* gStackModule; 57net_socket_module_info* gSocketModule; 58 59static struct net_domain* sDomain; 60 61net_protocol* 62l2cap_init_protocol(net_socket* socket) 63{ 64 CALLED(); 65 66 L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket); 67 if (protocol == NULL) 68 return NULL; 69 70 EndpointList.Add(protocol); 71 72 return protocol; 73} 74 75 76status_t 77l2cap_uninit_protocol(net_protocol* protocol) 78{ 79 CALLED(); 80 81 L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol); 82 83 // TODO: Some more checkins / uninit 84 EndpointList.Remove(endpoint); 85 86 delete endpoint; 87 88 return B_OK; 89} 90 91 92status_t 93l2cap_open(net_protocol* protocol) 94{ 95 CALLED(); 96 97 return B_OK; 98} 99 100 101status_t 102l2cap_close(net_protocol* protocol) 103{ 104 L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol); 105 106 CALLED(); 107 108 endpoint->Close(); 109 110 return B_OK; 111} 112 113 114status_t 115l2cap_free(net_protocol* protocol) 116{ 117 CALLED(); 118 119 return B_OK; 120} 121 122 123status_t 124l2cap_connect(net_protocol* protocol, const struct sockaddr* address) 125{ 126 CALLED(); 127 128 if (address == NULL) 129 return EINVAL; 130 131 if (address->sa_family != AF_BLUETOOTH) 132 return EAFNOSUPPORT; 133 134 return ((L2capEndpoint*)protocol)->Connect(address);; 135} 136 137 138status_t 139l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 140{ 141 CALLED(); 142 return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket); 143} 144 145 146status_t 147l2cap_control(net_protocol* protocol, int level, int option, void* value, 148 size_t* _length) 149{ 150 CALLED(); 151 return EOPNOTSUPP; 152} 153 154 155status_t 156l2cap_getsockopt(net_protocol* protocol, int level, int option, 157 void* value, int* length) 158{ 159 CALLED(); 160 return B_OK; 161} 162 163 164status_t 165l2cap_setsockopt(net_protocol* protocol, int level, int option, 166 const void* value, int length) 167{ 168 CALLED(); 169 ((L2capEndpoint*)protocol)->fConfigurationSet = true; 170 return B_OK; 171} 172 173 174status_t 175l2cap_bind(net_protocol* protocol, const struct sockaddr* address) 176{ 177 CALLED(); 178 return ((L2capEndpoint*)protocol)->Bind(address); 179} 180 181 182status_t 183l2cap_unbind(net_protocol* protocol, struct sockaddr* address) 184{ 185 CALLED(); 186 return B_ERROR; 187} 188 189 190status_t 191l2cap_listen(net_protocol* protocol, int count) 192{ 193 CALLED(); 194 return ((L2capEndpoint*)protocol)->Listen(count); 195} 196 197 198status_t 199l2cap_shutdown(net_protocol* protocol, int direction) 200{ 201 CALLED(); 202 return EOPNOTSUPP; 203} 204 205 206status_t 207l2cap_send_data(net_protocol* protocol, net_buffer* buffer) 208{ 209 CALLED(); 210 211 if (buffer == NULL) 212 return ENOBUFS; 213 214 return ((L2capEndpoint*)protocol)->SendData(buffer); 215} 216 217 218status_t 219l2cap_send_routed_data(net_protocol* protocol, struct net_route* route, 220 net_buffer* buffer) 221{ 222 CALLED(); 223 return EOPNOTSUPP; 224} 225 226 227ssize_t 228l2cap_send_avail(net_protocol* protocol) 229{ 230 CALLED(); 231 return B_ERROR; 232} 233 234 235status_t 236l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags, 237 net_buffer** _buffer) 238{ 239 CALLED(); 240 return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer); 241} 242 243 244ssize_t 245l2cap_read_avail(net_protocol* protocol) 246{ 247 CALLED(); 248 return B_ERROR; 249} 250 251 252struct net_domain* 253l2cap_get_domain(net_protocol* protocol) 254{ 255 CALLED(); 256 return sDomain; 257} 258 259 260size_t 261l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address) 262{ 263 CALLED(); 264 return protocol->next->module->get_mtu(protocol->next, address); 265} 266 267 268status_t 269l2cap_receive_data(net_buffer* buffer) 270{ 271 HciConnection* conn = (HciConnection*)buffer; 272 TRACE("%s: received some data, buffer length %" B_PRIu32 "\n", __func__, 273 conn->currentRxPacket->size); 274 275 l2cap_receive(conn, conn->currentRxPacket); 276 277 return B_OK; 278} 279 280 281status_t 282l2cap_error_received(net_error error, net_buffer* data) 283{ 284 CALLED(); 285 286 return B_ERROR; 287} 288 289 290status_t 291l2cap_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 292 net_error_data* errorData) 293{ 294 CALLED(); 295 296 return B_ERROR; 297} 298 299 300// #pragma mark - 301 302 303static status_t 304l2cap_std_ops(int32 op, ...) 305{ 306 status_t error; 307 308 CALLED(); 309 310 switch (op) { 311 case B_MODULE_INIT: 312 { 313 error = gStackModule->register_domain_protocols(AF_BLUETOOTH, 314 SOCK_STREAM, BLUETOOTH_PROTO_L2CAP, 315 "network/protocols/l2cap/v1", 316 NULL); 317 if (error != B_OK) 318 return error; 319 320 error = gStackModule->register_domain_receiving_protocol( 321 AF_BLUETOOTH, 322 BLUETOOTH_PROTO_L2CAP, 323 "network/protocols/l2cap/v1"); 324 if (error != B_OK) 325 return error; 326 327 error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", 328 &gL2CAPModule, &gL2cap4AddressModule, &sDomain); 329 if (error != B_OK) 330 return error; 331 332 new (&EndpointList) DoublyLinkedList<L2capEndpoint>; 333 334 error = InitializeConnectionPurgeThread(); 335 336 return B_OK; 337 } 338 339 case B_MODULE_UNINIT: 340 341 error = QuitConnectionPurgeThread(); 342 gStackModule->unregister_domain(sDomain); 343 344 return B_OK; 345 346 default: 347 return B_ERROR; 348 } 349} 350 351 352net_protocol_module_info gL2CAPModule = { 353 { 354 NET_BLUETOOTH_L2CAP_NAME, 355 B_KEEP_LOADED, 356 l2cap_std_ops 357 }, 358 NET_PROTOCOL_ATOMIC_MESSAGES, 359 360 l2cap_init_protocol, 361 l2cap_uninit_protocol, 362 l2cap_open, 363 l2cap_close, 364 l2cap_free, 365 l2cap_connect, 366 l2cap_accept, 367 l2cap_control, 368 l2cap_getsockopt, 369 l2cap_setsockopt, 370 l2cap_bind, 371 l2cap_unbind, 372 l2cap_listen, 373 l2cap_shutdown, 374 l2cap_send_data, 375 l2cap_send_routed_data, 376 l2cap_send_avail, 377 l2cap_read_data, 378 l2cap_read_avail, 379 l2cap_get_domain, 380 l2cap_get_mtu, 381 l2cap_receive_data, 382 NULL, // deliver_data() 383 l2cap_error_received, 384 l2cap_error_reply, 385 NULL, // add_ancillary_data() 386 NULL, // process_ancillary_data() 387 NULL, // process_ancillary_data_no_container() 388 NULL, // send_data_no_buffer() 389 NULL // read_data_no_buffer() 390}; 391 392module_dependency module_dependencies[] = { 393 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 394 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 395 {BT_CORE_DATA_MODULE_NAME, (module_info**)&btCoreData}, 396 {NET_SOCKET_MODULE_NAME, (module_info**)&gSocketModule}, 397 {} 398}; 399 400module_info* modules[] = { 401 (module_info*)&gL2CAPModule, 402 NULL 403}; 404