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#define BT_DEBUG_THIS_MODULE 45#define SUBMODULE_NAME "L2cap" 46#define SUBMODULE_COLOR 32 47#include <btDebug.h> 48 49 50typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField; 51DoublyLinkedList<L2capEndpoint> EndpointList; 52 53extern net_protocol_module_info gL2CAPModule; 54 55// module references 56bluetooth_core_data_module_info* btCoreData; 57 58net_buffer_module_info* gBufferModule; 59net_stack_module_info* gStackModule; 60net_socket_module_info* gSocketModule; 61 62static struct net_domain* sDomain; 63 64net_protocol* 65l2cap_init_protocol(net_socket* socket) 66{ 67 L2capEndpoint* protocol = new(std::nothrow) L2capEndpoint(socket); 68 if (protocol == NULL) 69 return NULL; 70 71 EndpointList.Add(protocol); 72 debugf("Prococol created %p\n", protocol); 73 74 return protocol; 75} 76 77 78status_t 79l2cap_uninit_protocol(net_protocol* protocol) 80{ 81 flowf("\n"); 82 83 L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol); 84 85 // TODO: Some more checkins / uninit 86 EndpointList.Remove(endpoint); 87 88 delete endpoint; 89 90 return B_OK; 91} 92 93 94status_t 95l2cap_open(net_protocol* protocol) 96{ 97 flowf("\n"); 98 99 return B_OK; 100} 101 102 103status_t 104l2cap_close(net_protocol* protocol) 105{ 106 L2capEndpoint* endpoint = static_cast<L2capEndpoint*>(protocol); 107 108 flowf("\n"); 109 110 endpoint->Close(); 111 112 return B_OK; 113} 114 115 116status_t 117l2cap_free(net_protocol* protocol) 118{ 119 flowf("\n"); 120 121 return B_OK; 122} 123 124 125status_t 126l2cap_connect(net_protocol* protocol, const struct sockaddr* address) 127{ 128 debugf("from %p, with %p\n", protocol, address); 129 130 if (address == NULL) 131 return EINVAL; 132 133 if (address->sa_family != AF_BLUETOOTH) 134 return EAFNOSUPPORT; 135 136 137 return ((L2capEndpoint*)protocol)->Connect(address);; 138} 139 140 141status_t 142l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 143{ 144 return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket); 145} 146 147 148status_t 149l2cap_control(net_protocol* protocol, int level, int option, void* value, 150 size_t* _length) 151{ 152 flowf("\n"); 153 154 return EOPNOTSUPP; 155} 156 157 158status_t 159l2cap_getsockopt(net_protocol* protocol, int level, int option, 160 void* value, int* length) 161{ 162 flowf("\n"); 163 164 return B_OK; 165} 166 167 168status_t 169l2cap_setsockopt(net_protocol* protocol, int level, int option, 170 const void* value, int length) 171{ 172 flowf("\n"); 173 174 ((L2capEndpoint*)protocol)->fConfigurationSet = true; 175 176 return B_OK; 177} 178 179 180status_t 181l2cap_bind(net_protocol* protocol, const struct sockaddr* address) 182{ 183 debugf("from %p, with %p\n", protocol, address); 184 185 return ((L2capEndpoint*)protocol)->Bind(address); 186} 187 188 189status_t 190l2cap_unbind(net_protocol* protocol, struct sockaddr* address) 191{ 192 flowf("\n"); 193 194 return B_ERROR; 195} 196 197 198status_t 199l2cap_listen(net_protocol* protocol, int count) 200{ 201 return ((L2capEndpoint*)protocol)->Listen(count); 202} 203 204 205status_t 206l2cap_shutdown(net_protocol* protocol, int direction) 207{ 208 flowf("\n"); 209 210 return EOPNOTSUPP; 211} 212 213 214status_t 215l2cap_send_data(net_protocol* protocol, net_buffer* buffer) 216{ 217 flowf("\n"); 218 219 if (buffer == NULL) 220 return ENOBUFS; 221 222 return ((L2capEndpoint*)protocol)->SendData(buffer); 223} 224 225 226status_t 227l2cap_send_routed_data(net_protocol* protocol, struct net_route* route, 228 net_buffer* buffer) 229{ 230 flowf("\n"); 231 232 return EOPNOTSUPP; 233} 234 235 236ssize_t 237l2cap_send_avail(net_protocol* protocol) 238{ 239 flowf("\n"); 240 241 return B_ERROR; 242} 243 244 245status_t 246l2cap_read_data(net_protocol* protocol, size_t numBytes, uint32 flags, 247 net_buffer** _buffer) 248{ 249 flowf("\n"); 250 251 return ((L2capEndpoint*)protocol)->ReadData(numBytes, flags, _buffer); 252} 253 254 255ssize_t 256l2cap_read_avail(net_protocol* protocol) 257{ 258 flowf("\n"); 259 260 return B_ERROR; 261} 262 263 264struct net_domain* 265l2cap_get_domain(net_protocol* protocol) 266{ 267 flowf("\n"); 268 269 return sDomain; 270} 271 272 273size_t 274l2cap_get_mtu(net_protocol* protocol, const struct sockaddr* address) 275{ 276 flowf("\n"); 277 278 return protocol->next->module->get_mtu(protocol->next, address); 279} 280 281 282status_t 283l2cap_receive_data(net_buffer* buffer) 284{ 285 HciConnection* conn = (HciConnection*)buffer; 286 debugf("received some data, buffer length %lu\n", 287 conn->currentRxPacket->size); 288 289 l2cap_receive(conn, conn->currentRxPacket); 290 291 return B_OK; 292} 293 294 295status_t 296l2cap_error_received(net_error error, net_buffer* data) 297{ 298 flowf("\n"); 299 300 return B_ERROR; 301} 302 303 304status_t 305l2cap_error_reply(net_protocol* protocol, net_buffer* cause, net_error error, 306 net_error_data* errorData) 307{ 308 flowf("\n"); 309 310 return B_ERROR; 311} 312 313 314// #pragma mark - 315 316 317static status_t 318l2cap_std_ops(int32 op, ...) 319{ 320 status_t error; 321 322 flowf("\n"); 323 324 switch (op) { 325 case B_MODULE_INIT: 326 { 327 error = gStackModule->register_domain_protocols(AF_BLUETOOTH, 328 SOCK_STREAM, BLUETOOTH_PROTO_L2CAP, 329 "network/protocols/l2cap/v1", 330 NULL); 331 if (error != B_OK) 332 return error; 333 334 error = gStackModule->register_domain_receiving_protocol( 335 AF_BLUETOOTH, 336 BLUETOOTH_PROTO_L2CAP, 337 "network/protocols/l2cap/v1"); 338 if (error != B_OK) 339 return error; 340 341 error = gStackModule->register_domain(AF_BLUETOOTH, "l2cap", 342 &gL2CAPModule, &gL2cap4AddressModule, &sDomain); 343 if (error != B_OK) 344 return error; 345 346 new (&EndpointList) DoublyLinkedList<L2capEndpoint>; 347 348 error = InitializeConnectionPurgeThread(); 349 350 return B_OK; 351 } 352 353 case B_MODULE_UNINIT: 354 355 error = QuitConnectionPurgeThread(); 356 gStackModule->unregister_domain(sDomain); 357 358 return B_OK; 359 360 default: 361 return B_ERROR; 362 } 363} 364 365 366net_protocol_module_info gL2CAPModule = { 367 { 368 NET_BLUETOOTH_L2CAP_NAME, 369 B_KEEP_LOADED, 370 l2cap_std_ops 371 }, 372 NET_PROTOCOL_ATOMIC_MESSAGES, 373 374 l2cap_init_protocol, 375 l2cap_uninit_protocol, 376 l2cap_open, 377 l2cap_close, 378 l2cap_free, 379 l2cap_connect, 380 l2cap_accept, 381 l2cap_control, 382 l2cap_getsockopt, 383 l2cap_setsockopt, 384 l2cap_bind, 385 l2cap_unbind, 386 l2cap_listen, 387 l2cap_shutdown, 388 l2cap_send_data, 389 l2cap_send_routed_data, 390 l2cap_send_avail, 391 l2cap_read_data, 392 l2cap_read_avail, 393 l2cap_get_domain, 394 l2cap_get_mtu, 395 l2cap_receive_data, 396 NULL, // deliver_data() 397 l2cap_error_received, 398 l2cap_error_reply, 399 NULL, // add_ancillary_data() 400 NULL, // process_ancillary_data() 401 NULL, // process_ancillary_data_no_container() 402 NULL, // send_data_no_buffer() 403 NULL // read_data_no_buffer() 404}; 405 406module_dependency module_dependencies[] = { 407 {NET_STACK_MODULE_NAME, (module_info**)&gStackModule}, 408 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule}, 409 {BT_CORE_DATA_MODULE_NAME, (module_info**)&btCoreData}, 410 {NET_SOCKET_MODULE_NAME, (module_info**)&gSocketModule}, 411 {} 412}; 413 414module_info* modules[] = { 415 (module_info*)&gL2CAPModule, 416 NULL 417}; 418