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 #include <net_datalink.h> 22 #include <net_protocol.h> 23 #include <net_stack.h> 24 #include <NetBufferUtilities.h> 25 26 #include <KernelExport.h> 27 #include <util/list.h> 28 29 #include <new> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #include <bluetooth/HCI/btHCI_acl.h> 34 35 #include "l2cap_address.h" 36 37 38 #define BT_DEBUG_THIS_MODULE 39 #include <btDebug.h> 40 41 42 typedef NetBufferField<uint16, offsetof(hci_acl_header, alen)> AclLenField; 43 44 45 struct l2cap_protocol : net_protocol { 46 }; 47 48 49 extern net_protocol_module_info gL2CAPModule; 50 51 net_buffer_module_info *gBufferModule; 52 static net_stack_module_info *sStackModule; 53 54 static struct net_domain *sDomain; 55 56 net_protocol * 57 l2cap_init_protocol(net_socket *socket) 58 { 59 flowf("\n"); 60 61 l2cap_protocol *protocol = new (std::nothrow) l2cap_protocol; 62 if (protocol == NULL) 63 return NULL; 64 65 return protocol; 66 } 67 68 69 status_t 70 l2cap_uninit_protocol(net_protocol *protocol) 71 { 72 flowf("\n"); 73 74 delete protocol; 75 return B_OK; 76 } 77 78 79 status_t 80 l2cap_open(net_protocol *protocol) 81 { 82 flowf("\n"); 83 84 return B_OK; 85 } 86 87 88 status_t 89 l2cap_close(net_protocol *protocol) 90 { 91 flowf("\n"); 92 93 return B_OK; 94 } 95 96 97 status_t 98 l2cap_free(net_protocol *protocol) 99 { 100 flowf("\n"); 101 102 return B_OK; 103 } 104 105 106 status_t 107 l2cap_connect(net_protocol *protocol, const struct sockaddr *address) 108 { 109 flowf("\n"); 110 111 return B_ERROR; 112 } 113 114 115 status_t 116 l2cap_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) 117 { 118 flowf("\n"); 119 120 return EOPNOTSUPP; 121 } 122 123 124 status_t 125 l2cap_control(net_protocol *protocol, int level, int option, void *value, 126 size_t *_length) 127 { 128 flowf("\n"); 129 130 /* return protocol->next->module->control(protocol->next, level, option, value, _length); */ 131 return EOPNOTSUPP; 132 } 133 134 135 status_t 136 l2cap_getsockopt(net_protocol *protocol, int level, int option, 137 void *value, int *length) 138 { 139 flowf("\n"); 140 141 /* return protocol->next->module->getsockopt(protocol->next, level, option, value, length); */ 142 return EOPNOTSUPP; 143 } 144 145 146 status_t 147 l2cap_setsockopt(net_protocol *protocol, int level, int option, 148 const void *value, int length) 149 { 150 flowf("\n"); 151 152 /* return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */ 153 return EOPNOTSUPP; 154 } 155 156 157 status_t 158 l2cap_bind(net_protocol *protocol, const struct sockaddr *address) 159 { 160 flowf("\n"); 161 162 return B_ERROR; 163 } 164 165 166 status_t 167 l2cap_unbind(net_protocol *protocol, struct sockaddr *address) 168 { 169 flowf("\n"); 170 171 return B_ERROR; 172 } 173 174 175 status_t 176 l2cap_listen(net_protocol *protocol, int count) 177 { 178 flowf("\n"); 179 180 return EOPNOTSUPP; 181 } 182 183 184 status_t 185 l2cap_shutdown(net_protocol *protocol, int direction) 186 { 187 flowf("\n"); 188 189 return EOPNOTSUPP; 190 } 191 192 193 status_t 194 l2cap_send_data(net_protocol *protocol, net_buffer *buffer) 195 { 196 flowf("\n"); 197 198 return protocol->next->module->send_data(protocol->next, buffer); 199 } 200 201 202 status_t 203 l2cap_send_routed_data(net_protocol *protocol, struct net_route *route, 204 net_buffer *buffer) 205 { 206 flowf("\n"); 207 208 return protocol->next->module->send_routed_data(protocol->next, route, buffer); 209 } 210 211 212 ssize_t 213 l2cap_send_avail(net_protocol *protocol) 214 { 215 flowf("\n"); 216 217 return B_ERROR; 218 } 219 220 221 status_t 222 l2cap_read_data(net_protocol *protocol, size_t numBytes, uint32 flags, 223 net_buffer **_buffer) 224 { 225 flowf("\n"); 226 227 return B_ERROR; 228 } 229 230 231 ssize_t 232 l2cap_read_avail(net_protocol *protocol) 233 { 234 flowf("\n"); 235 236 return B_ERROR; 237 } 238 239 240 struct net_domain * 241 l2cap_get_domain(net_protocol *protocol) 242 { 243 flowf("\n"); 244 245 return sDomain; 246 } 247 248 249 size_t 250 l2cap_get_mtu(net_protocol *protocol, const struct sockaddr *address) 251 { 252 flowf("\n"); 253 254 return protocol->next->module->get_mtu(protocol->next, address); 255 } 256 257 258 status_t 259 l2cap_receive_data(net_buffer *buffer) 260 { 261 debugf("received some data, buffer length %lu\n", buffer->size); 262 263 NetBufferHeaderReader<hci_acl_header> bufferHeader(buffer); 264 if (bufferHeader.Status() < B_OK) 265 return bufferHeader.Status(); 266 267 hci_acl_header &header = bufferHeader.Data(); 268 269 debugf(" got handle %u, len %u\n", header.handle, header.alen); 270 debugf(" computed checksum: %ld\n", gBufferModule->checksum(buffer, 0, buffer->size, true)); 271 272 if (gBufferModule->checksum(buffer, 0, buffer->size, true) != 0) 273 return B_BAD_DATA; 274 275 gBufferModule->free(buffer); 276 return B_OK; 277 } 278 279 280 status_t 281 l2cap_error(uint32 code, net_buffer *data) 282 { 283 flowf("\n"); 284 285 return B_ERROR; 286 } 287 288 289 status_t 290 l2cap_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, 291 void *errorData) 292 { 293 flowf("\n"); 294 295 return B_ERROR; 296 } 297 298 299 #if 0 300 #pragma mark - 301 #endif 302 303 static status_t 304 l2cap_std_ops(int32 op, ...) 305 { 306 flowf("\n"); 307 308 switch (op) { 309 case B_MODULE_INIT: 310 { 311 status_t error; 312 313 error = sStackModule->register_domain_protocols(AF_BLUETOOTH, SOCK_STREAM, BLUETOOTH_PROTO_L2CAP, 314 "network/protocols/l2cap/v1", 315 NULL); 316 if (error != B_OK) { 317 return error; 318 } 319 320 error = sStackModule->register_domain_receiving_protocol(AF_BLUETOOTH, BLUETOOTH_PROTO_L2CAP, 321 "network/protocols/l2cap/v1"); 322 if (error != B_OK) { 323 return error; 324 } 325 326 error = sStackModule->register_domain(AF_BLUETOOTH, "l2cap", &gL2CAPModule, 327 &gL2cap4AddressModule, &sDomain); 328 if (error != B_OK) { 329 return error; 330 } 331 332 333 return B_OK; 334 } 335 336 case B_MODULE_UNINIT: 337 338 sStackModule->unregister_domain(sDomain); 339 return B_OK; 340 341 default: 342 return B_ERROR; 343 } 344 } 345 346 347 net_protocol_module_info gL2CAPModule = { 348 { 349 "network/protocols/l2cap/v1", 350 0, 351 l2cap_std_ops 352 }, 353 NET_PROTOCOL_ATOMIC_MESSAGES, 354 355 l2cap_init_protocol, 356 l2cap_uninit_protocol, 357 l2cap_open, 358 l2cap_close, 359 l2cap_free, 360 l2cap_connect, 361 l2cap_accept, 362 l2cap_control, 363 l2cap_getsockopt, 364 l2cap_setsockopt, 365 l2cap_bind, 366 l2cap_unbind, 367 l2cap_listen, 368 l2cap_shutdown, 369 l2cap_send_data, 370 l2cap_send_routed_data, 371 l2cap_send_avail, 372 l2cap_read_data, 373 l2cap_read_avail, 374 l2cap_get_domain, 375 l2cap_get_mtu, 376 l2cap_receive_data, 377 NULL, 378 l2cap_error, 379 l2cap_error_reply, 380 }; 381 382 module_dependency module_dependencies[] = { 383 {NET_STACK_MODULE_NAME, (module_info **)&sStackModule}, 384 {NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule}, 385 {} 386 }; 387 388 module_info *modules[] = { 389 (module_info *)&gL2CAPModule, 390 NULL 391 }; 392