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 #include "L2capEndpoint.h" 6 #include "l2cap_address.h" 7 #include "l2cap_upper.h" 8 #include "l2cap_lower.h" 9 10 #include <stdio.h> 11 #include <string.h> 12 #include <sys/stat.h> 13 14 #include <bluetooth/bdaddrUtils.h> 15 #include <bluetooth/L2CAP/btL2CAP.h> 16 17 #define BT_DEBUG_THIS_MODULE 18 #define MODULE_NAME "l2cap" 19 #define SUBMODULE_NAME "Endpoint" 20 #define SUBMODULE_COLOR 32 21 #include <btDebug.h> 22 23 24 static inline bigtime_t 25 absolute_timeout(bigtime_t timeout) 26 { 27 if (timeout == 0 || timeout == B_INFINITE_TIMEOUT) 28 return timeout; 29 30 // TODO: Make overflow safe! 31 return timeout + system_time(); 32 } 33 34 35 L2capEndpoint::L2capEndpoint(net_socket* socket) 36 : 37 ProtocolSocket(socket), 38 fConfigurationSet(false), 39 fEstablishSemaphore(-1), 40 fPeerEndpoint(NULL), 41 fChannel(NULL) 42 { 43 debugf("[%ld] %p\n", find_thread(NULL), this); 44 45 /* Set MTU and flow control settings to defaults */ 46 fConfiguration.imtu = L2CAP_MTU_DEFAULT; 47 memcpy(&fConfiguration.iflow, &default_qos , sizeof(l2cap_flow_t) ); 48 49 fConfiguration.omtu = L2CAP_MTU_DEFAULT; 50 memcpy(&fConfiguration.oflow, &default_qos , sizeof(l2cap_flow_t) ); 51 52 fConfiguration.flush_timo = L2CAP_FLUSH_TIMO_DEFAULT; 53 fConfiguration.link_timo = L2CAP_LINK_TIMO_DEFAULT; 54 55 // TODO: XXX not for listening endpoints, imtu should be known first 56 gStackModule->init_fifo(&fReceivingFifo, "l2cap recvfifo", L2CAP_MTU_DEFAULT); 57 } 58 59 60 L2capEndpoint::~L2capEndpoint() 61 { 62 debugf("[%ld] %p\n", find_thread(NULL), this); 63 64 gStackModule->uninit_fifo(&fReceivingFifo); 65 } 66 67 68 status_t 69 L2capEndpoint::Init() 70 { 71 debugf("[%ld] %p\n", find_thread(NULL), this); 72 73 return B_OK; 74 } 75 76 77 void 78 L2capEndpoint::Uninit() 79 { 80 debugf("[%ld] %p\n", find_thread(NULL), this); 81 82 } 83 84 85 status_t 86 L2capEndpoint::Open() 87 { 88 debugf("[%ld] %p\n", find_thread(NULL), this); 89 90 status_t error = ProtocolSocket::Open(); 91 if (error != B_OK) 92 return error; 93 94 return B_OK; 95 } 96 97 98 status_t 99 L2capEndpoint::Close() 100 { 101 debugf("[%ld] %p\n", find_thread(NULL), this); 102 103 if (fChannel == NULL) { 104 // TODO: Parent socket 105 106 } else { 107 // Child Socket 108 if (fState == CLOSED) { 109 debugf("Already closed by peer %p\n", this); 110 // TODO: Clean needed stuff 111 return B_OK; 112 } else { 113 // Issue Disconnection request over the channel 114 MarkClosed(); 115 116 bigtime_t timeout = absolute_timeout(300 * 1000 * 1000); 117 118 status_t error = l2cap_upper_dis_req(fChannel); 119 120 if (error != B_OK) 121 return error; 122 123 return acquire_sem_etc(fEstablishSemaphore, 1, 124 B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, timeout); 125 } 126 } 127 128 if (fEstablishSemaphore != -1) { 129 delete_sem(fEstablishSemaphore); 130 } 131 132 return B_OK; 133 } 134 135 136 status_t 137 L2capEndpoint::Free() 138 { 139 debugf("[%ld] %p\n", find_thread(NULL), this); 140 141 return B_OK; 142 } 143 144 145 status_t 146 L2capEndpoint::Bind(const struct sockaddr* _address) 147 { 148 const sockaddr_l2cap* address 149 = reinterpret_cast<const sockaddr_l2cap*>(_address); 150 151 if (_address == NULL) 152 return B_ERROR; 153 154 if (address->l2cap_family != AF_BLUETOOTH ) 155 return EAFNOSUPPORT; 156 157 if (address->l2cap_len != sizeof(struct sockaddr_l2cap)) 158 return EAFNOSUPPORT; 159 160 // TODO: Check if that PSM is already bound 161 // return EADDRINUSE; 162 163 // TODO: Check if the PSM is valid, check assigned numbers document for valid 164 // psm available to applications. 165 // All PSM values shall be ODD, that is, the least significant bit of the least 166 // significant octet must be ’1’. Also, all PSM values shall have the least 167 // significant bit of the most significant octet equal to ’0’. This allows 168 // the PSM field to be extended beyond 16 bits. 169 if ((address->l2cap_psm & 1) == 0) 170 return B_ERROR; 171 172 memcpy(&socket->address, _address, sizeof(struct sockaddr_l2cap)); 173 socket->address.ss_len = sizeof(struct sockaddr_l2cap); 174 175 debugf("for %s psm=%d\n", bdaddrUtils::ToString(address->l2cap_bdaddr), 176 address->l2cap_psm); 177 178 fState = BOUND; 179 180 return B_OK; 181 } 182 183 184 status_t 185 L2capEndpoint::Unbind() 186 { 187 debugf("[%ld] %p\n", find_thread(NULL), this); 188 189 return B_OK; 190 } 191 192 193 status_t 194 L2capEndpoint::Listen(int backlog) 195 { 196 debugf("[%ld] %p\n", find_thread(NULL), this); 197 198 if (fState != BOUND) { 199 debugf("Invalid State %p\n", this); 200 return B_BAD_VALUE; 201 } 202 203 fEstablishSemaphore = create_sem(0, "l2cap serv accept"); 204 if (fEstablishSemaphore < B_OK) { 205 flowf("Semaphore could not be created\n"); 206 return ENOBUFS; 207 } 208 209 gSocketModule->set_max_backlog(socket, backlog); 210 211 fState = LISTEN; 212 213 return B_OK; 214 } 215 216 217 status_t 218 L2capEndpoint::Connect(const struct sockaddr* _address) 219 { 220 const sockaddr_l2cap* address 221 = reinterpret_cast<const sockaddr_l2cap*>(_address); 222 223 if (address->l2cap_len != sizeof(*address)) 224 return EINVAL; 225 226 // Check for any specific status? 227 if (fState == CONNECTING) { 228 return EINPROGRESS; 229 } 230 231 // TODO: should not be in the BOUND status first? 232 233 debugf("[%ld] %p->L2capEndpoint::Connect(\"%s\")\n", find_thread(NULL), 234 this, ConstSocketAddress(&gL2cap4AddressModule, _address) 235 .AsString().Data()); 236 237 // TODO: If we were bound to a specific source address 238 239 // Route, we must find a Connection descriptor with address->l2cap_address 240 hci_id hid = btCoreData->RouteConnection(address->l2cap_bdaddr); 241 242 debugf("%lx for route %s\n", hid, 243 bdaddrUtils::ToString(address->l2cap_bdaddr)); 244 245 if (hid > 0) { 246 HciConnection* connection = btCoreData->ConnectionByDestination( 247 address->l2cap_bdaddr, hid); 248 249 L2capChannel* channel = btCoreData->AddChannel(connection, 250 address->l2cap_psm); 251 252 if (channel == NULL) 253 return ENOMEM; 254 255 // Send connection request 256 if (l2cap_upper_con_req(channel) == B_OK) { 257 fState = CONNECTING; 258 259 BindToChannel(channel); 260 261 fEstablishSemaphore = create_sem(0, "l2cap client"); 262 if (fEstablishSemaphore < B_OK) { 263 flowf("Semaphore could not be created\n"); 264 return ENOBUFS; 265 } 266 267 bigtime_t timeout = absolute_timeout(300 * 1000 * 1000); 268 269 return acquire_sem_etc(fEstablishSemaphore, 1, 270 B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, timeout); 271 272 } else { 273 return ECONNREFUSED; 274 } 275 } 276 277 return ENETUNREACH; 278 } 279 280 281 status_t 282 L2capEndpoint::Accept(net_socket** _acceptedSocket) 283 { 284 debugf("[%ld]\n", find_thread(NULL)); 285 286 // MutexLocker locker(fLock); 287 288 status_t status; 289 bigtime_t timeout = absolute_timeout(300 * 1000 * 1000); 290 291 do { 292 // locker.Unlock(); 293 294 status = acquire_sem_etc(fEstablishSemaphore, 1, B_ABSOLUTE_TIMEOUT 295 | B_CAN_INTERRUPT, timeout); 296 297 if (status != B_OK) 298 return status; 299 300 // locker.Lock(); 301 status = gSocketModule->dequeue_connected(socket, _acceptedSocket); 302 303 if (status != B_OK) { 304 debugf("Could not dequeue socket %s\n", strerror(status)); 305 } else { 306 307 ((L2capEndpoint*)((*_acceptedSocket)->first_protocol))->fState = ESTABLISHED; 308 // unassign any channel for the parent endpoint 309 fChannel = NULL; 310 // we are listening again 311 fState = LISTEN; 312 } 313 314 } while (status != B_OK); 315 316 return status; 317 } 318 319 320 ssize_t 321 L2capEndpoint::Send(const iovec* vecs, size_t vecCount, 322 ancillary_data_container* ancillaryData) 323 { 324 debugf("[%ld] %p Send(%p, %ld, %p)\n", find_thread(NULL), 325 this, vecs, vecCount, ancillaryData); 326 327 return B_OK; 328 } 329 330 331 ssize_t 332 L2capEndpoint::Receive(const iovec* vecs, size_t vecCount, 333 ancillary_data_container** _ancillaryData, struct sockaddr* _address, 334 socklen_t* _addressLength) 335 { 336 debugf("[%ld] %p Receive(%p, %ld)\n", find_thread(NULL), 337 this, vecs, vecCount); 338 339 if (fState != ESTABLISHED) { 340 debugf("Invalid State %p\n", this); 341 return B_BAD_VALUE; 342 } 343 344 return B_OK; 345 } 346 347 348 ssize_t 349 L2capEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer) 350 { 351 debugf("e->%p num=%ld, f=%ld)\n", this, numBytes, flags); 352 353 if (fState != ESTABLISHED) { 354 debugf("Invalid State %p\n", this); 355 return B_BAD_VALUE; 356 } 357 358 return gStackModule->fifo_dequeue_buffer(&fReceivingFifo, flags, 359 B_INFINITE_TIMEOUT, _buffer); 360 } 361 362 363 ssize_t 364 L2capEndpoint::SendData(net_buffer* buffer) 365 { 366 debugf("size=%ld\n", buffer->size); 367 368 if (fState != ESTABLISHED) { 369 debugf("Invalid State %p\n", this); 370 return B_BAD_VALUE; 371 } 372 373 btCoreData->SpawnFrame(fChannel->conn, fChannel, buffer, L2CAP_B_FRAME); 374 375 SchedConnectionPurgeThread(fChannel->conn); 376 377 // TODO: Report bytes sent? 378 return B_OK; 379 } 380 381 382 ssize_t 383 L2capEndpoint::Sendable() 384 { 385 debugf("[%ld] %p\n", find_thread(NULL), this); 386 387 return B_OK; 388 } 389 390 391 ssize_t 392 L2capEndpoint::Receivable() 393 { 394 debugf("[%ld] %p\n", find_thread(NULL), this); 395 396 return 0; 397 } 398 399 400 L2capEndpoint* 401 L2capEndpoint::ForPsm(uint16 psm) 402 { 403 L2capEndpoint* endpoint; 404 405 DoublyLinkedList<L2capEndpoint>::Iterator iterator 406 = EndpointList.GetIterator(); 407 408 while (iterator.HasNext()) { 409 410 endpoint = iterator.Next(); 411 if (((struct sockaddr_l2cap*)&endpoint->socket->address)->l2cap_psm == psm 412 && endpoint->fState == LISTEN) { 413 // TODO endpoint ocupied, lock it! define a channel for it 414 return endpoint; 415 } 416 } 417 418 return NULL; 419 } 420 421 422 void 423 L2capEndpoint::BindNewEnpointToChannel(L2capChannel* channel) 424 { 425 net_socket* newSocket; 426 status_t error = gSocketModule->spawn_pending_socket(socket, &newSocket); 427 if (error != B_OK) { 428 debugf("Could not spawn child for Endpoint %p\n", this); 429 // TODO: Handle situation 430 return; 431 } 432 433 L2capEndpoint* endpoint = (L2capEndpoint*)newSocket->first_protocol; 434 435 endpoint->fChannel = channel; 436 endpoint->fPeerEndpoint = this; 437 438 channel->endpoint = endpoint; 439 440 debugf("new socket %p/e->%p from parent %p/e->%p\n", 441 newSocket, endpoint, socket, this); 442 443 // Provide the channel the configuration set by the user socket 444 channel->configuration = &fConfiguration; 445 446 // It might be used keep the last negotiated channel 447 // fChannel = channel; 448 449 debugf("New endpoint %p for psm %d, schannel %x dchannel %x\n", endpoint, 450 channel->psm, channel->scid, channel->dcid); 451 } 452 453 454 void 455 L2capEndpoint::BindToChannel(L2capChannel* channel) 456 { 457 this->fChannel = channel; 458 channel->endpoint = this; 459 460 // Provide the channel the configuration set by the user socket 461 channel->configuration = &fConfiguration; 462 463 // no parent to give feedback 464 fPeerEndpoint = NULL; 465 } 466 467 468 status_t 469 L2capEndpoint::MarkEstablished() 470 { 471 status_t error = B_OK; 472 debugf("Endpoint %p for psm %d, schannel %x dchannel %x\n", this, 473 fChannel->psm, fChannel->scid, fChannel->dcid); 474 475 fChannel->state = L2CAP_CHAN_OPEN; 476 fState = ESTABLISHED; 477 478 if (fPeerEndpoint != NULL) { 479 480 error = gSocketModule->set_connected(socket); 481 if (error == B_OK) { 482 release_sem(fPeerEndpoint->fEstablishSemaphore); 483 } else { 484 debugf("Could not set child Endpoint %p %s\n", this, strerror(error)); 485 } 486 } else 487 release_sem(fEstablishSemaphore); 488 489 return error; 490 } 491 492 493 status_t 494 L2capEndpoint::MarkClosed() 495 { 496 flowf("\n"); 497 if (fState == CLOSED) { 498 release_sem(fEstablishSemaphore); 499 } 500 501 fState = CLOSED; 502 503 return B_OK; 504 } 505