1 /* 2 * Copyright 2008, Oliver Ruiz Dorantes. All rights reserved. 3 * Copyright 2024, Haiku, Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 #include "L2capEndpoint.h" 7 8 #include <stdio.h> 9 #include <string.h> 10 11 #include <NetBufferUtilities.h> 12 13 #include <btDebug.h> 14 #include "L2capEndpointManager.h" 15 #include "l2cap_address.h" 16 #include "l2cap_signal.h" 17 18 19 static l2cap_qos sDefaultQOS = { 20 .flags = 0x0, 21 .service_type = 1, 22 .token_rate = 0xffffffff, /* maximum */ 23 .token_bucket_size = 0xffffffff, /* maximum */ 24 .peak_bandwidth = 0x00000000, /* maximum */ 25 .access_latency = 0xffffffff, /* don't care */ 26 .delay_variation = 0xffffffff /* don't care */ 27 }; 28 29 30 static inline bigtime_t 31 absolute_timeout(bigtime_t timeout) 32 { 33 if (timeout == 0 || timeout == B_INFINITE_TIMEOUT) 34 return timeout; 35 36 return timeout + system_time(); 37 } 38 39 40 static inline status_t 41 posix_error(status_t error) 42 { 43 if (error == B_TIMED_OUT) 44 return B_WOULD_BLOCK; 45 46 return error; 47 } 48 49 50 // #pragma mark - endpoint 51 52 53 L2capEndpoint::L2capEndpoint(net_socket* socket) 54 : 55 ProtocolSocket(socket), 56 fAcceptSemaphore(-1), 57 fState(CLOSED), 58 fConnection(NULL), 59 fChannelID(L2CAP_NULL_CID), 60 fDestinationChannelID(L2CAP_NULL_CID) 61 { 62 CALLED(); 63 64 mutex_init(&fLock, "l2cap endpoint"); 65 fCommandWait.Init(this, "l2cap endpoint command"); 66 67 // Set MTU and flow control settings to defaults 68 fChannelConfig.incoming_mtu = L2CAP_MTU_DEFAULT; 69 memcpy(&fChannelConfig.incoming_flow, &sDefaultQOS, sizeof(l2cap_qos)); 70 71 fChannelConfig.outgoing_mtu = L2CAP_MTU_DEFAULT; 72 memcpy(&fChannelConfig.outgoing_flow, &sDefaultQOS, sizeof(l2cap_qos)); 73 74 fChannelConfig.flush_timeout = L2CAP_FLUSH_TIMEOUT_DEFAULT; 75 fChannelConfig.link_timeout = L2CAP_LINK_TIMEOUT_DEFAULT; 76 77 fConfigState = {}; 78 79 gStackModule->init_fifo(&fReceiveQueue, "l2cap recv", L2CAP_MTU_MAXIMUM); 80 gStackModule->init_fifo(&fSendQueue, "l2cap send", L2CAP_MTU_MAXIMUM); 81 gStackModule->init_timer(&fSendTimer, L2capEndpoint::_SendTimer, this); 82 } 83 84 85 L2capEndpoint::~L2capEndpoint() 86 { 87 CALLED(); 88 89 mutex_lock(&fLock); 90 mutex_destroy(&fLock); 91 92 ASSERT(fState == CLOSED); 93 94 fCommandWait.NotifyAll(B_ERROR); 95 96 gStackModule->uninit_fifo(&fReceiveQueue); 97 gStackModule->uninit_fifo(&fSendQueue); 98 gStackModule->wait_for_timer(&fSendTimer); 99 } 100 101 102 status_t 103 L2capEndpoint::_WaitForStateChange(bigtime_t absoluteTimeout) 104 { 105 channel_status state = fState; 106 while (fState == state) { 107 status_t status = fCommandWait.Wait(&fLock, 108 B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, absoluteTimeout); 109 if (status != B_OK) 110 return posix_error(status); 111 } 112 113 return B_OK; 114 } 115 116 117 status_t 118 L2capEndpoint::Open() 119 { 120 CALLED(); 121 return ProtocolSocket::Open(); 122 } 123 124 125 status_t 126 L2capEndpoint::Shutdown() 127 { 128 CALLED(); 129 MutexLocker locker(fLock); 130 131 if (fState == CLOSED) { 132 // Nothing to do. 133 return B_OK; 134 } 135 if (fState == LISTEN) { 136 delete_sem(fAcceptSemaphore); 137 fAcceptSemaphore = -1; 138 gSocketModule->set_max_backlog(socket, 0); 139 fState = BOUND; 140 return B_OK; 141 } 142 143 status_t status; 144 bigtime_t timeout = absolute_timeout(socket->receive.timeout); 145 if (gStackModule->is_restarted_syscall()) 146 timeout = gStackModule->restore_syscall_restart_timeout(); 147 else 148 gStackModule->store_syscall_restart_timeout(timeout); 149 150 // FIXME: If we are currently waiting for a connection or configuration, 151 // we need to wait for that command to return (and free its ident on timeout.) 152 153 while (fState > OPEN) { 154 status = _WaitForStateChange(timeout); 155 if (status != B_OK) 156 return status; 157 } 158 if (fState == CLOSED) 159 return B_OK; 160 161 uint8 ident = btCoreData->allocate_command_ident(fConnection, this); 162 if (ident == L2CAP_NULL_IDENT) 163 return ENOBUFS; 164 165 status = send_l2cap_disconnection_req(fConnection, ident, 166 fDestinationChannelID, fChannelID); 167 if (status != B_OK) 168 return status; 169 170 fState = WAIT_FOR_DISCONNECTION_RSP; 171 172 while (fState != CLOSED) { 173 status = _WaitForStateChange(timeout); 174 if (status != B_OK) 175 return status; 176 } 177 178 return B_OK; 179 } 180 181 182 status_t 183 L2capEndpoint::Close() 184 { 185 return Shutdown(); 186 } 187 188 189 status_t 190 L2capEndpoint::Free() 191 { 192 CALLED(); 193 194 return B_OK; 195 } 196 197 198 status_t 199 L2capEndpoint::Bind(const struct sockaddr* _address) 200 { 201 const sockaddr_l2cap* address 202 = reinterpret_cast<const sockaddr_l2cap*>(_address); 203 if (AddressModule()->is_empty_address(_address, true)) 204 return B_OK; // We don't need to bind to empty. 205 if (!AddressModule()->is_same_family(_address)) 206 return EAFNOSUPPORT; 207 if (address->l2cap_len != sizeof(struct sockaddr_l2cap)) 208 return EAFNOSUPPORT; 209 210 CALLED(); 211 MutexLocker _(fLock); 212 213 if (fState != CLOSED) 214 return EISCONN; 215 216 status_t status = gL2capEndpointManager.Bind(this, *address); 217 if (status != B_OK) 218 return status; 219 220 fState = BOUND; 221 return B_OK; 222 } 223 224 225 status_t 226 L2capEndpoint::Unbind() 227 { 228 CALLED(); 229 MutexLocker _(fLock); 230 231 if (LocalAddress().IsEmpty(true)) 232 return EINVAL; 233 234 status_t status = gL2capEndpointManager.Unbind(this); 235 if (status != B_OK) 236 return status; 237 238 if (fState == BOUND) 239 fState = CLOSED; 240 return B_OK; 241 } 242 243 244 status_t 245 L2capEndpoint::Listen(int backlog) 246 { 247 CALLED(); 248 MutexLocker _(fLock); 249 250 if (fState != BOUND) 251 return B_BAD_VALUE; 252 253 fAcceptSemaphore = create_sem(0, "l2cap accept"); 254 if (fAcceptSemaphore < B_OK) { 255 ERROR("%s: Semaphore could not be created\n", __func__); 256 return ENOBUFS; 257 } 258 259 gSocketModule->set_max_backlog(socket, backlog); 260 261 fState = LISTEN; 262 return B_OK; 263 } 264 265 266 status_t 267 L2capEndpoint::Connect(const struct sockaddr* _address) 268 { 269 const sockaddr_l2cap* address 270 = reinterpret_cast<const sockaddr_l2cap*>(_address); 271 if (!AddressModule()->is_same_family(_address)) 272 return EAFNOSUPPORT; 273 if (address->l2cap_len != sizeof(struct sockaddr_l2cap)) 274 return EAFNOSUPPORT; 275 276 TRACE("l2cap: connect(\"%s\")\n", 277 ConstSocketAddress(&gL2capAddressModule, _address).AsString().Data()); 278 MutexLocker _(fLock); 279 280 status_t status; 281 bigtime_t timeout = absolute_timeout(socket->send.timeout); 282 if (gStackModule->is_restarted_syscall()) { 283 timeout = gStackModule->restore_syscall_restart_timeout(); 284 285 while (fState != CLOSED && fState != OPEN) { 286 status = _WaitForStateChange(timeout); 287 if (status != B_OK) 288 return status; 289 } 290 return (fState == OPEN) ? B_OK : ECONNREFUSED; 291 } else { 292 gStackModule->store_syscall_restart_timeout(timeout); 293 } 294 295 if (fState == LISTEN) 296 return EINVAL; 297 if (fState == OPEN) 298 return EISCONN; 299 if (fState != CLOSED) 300 return EALREADY; 301 302 // Set up route. 303 hci_id hid = btCoreData->RouteConnection(address->l2cap_bdaddr); 304 if (hid <= 0) 305 return ENETUNREACH; 306 307 TRACE("l2cap: %" B_PRId32 " for route %s\n", hid, 308 bdaddrUtils::ToString(address->l2cap_bdaddr).String()); 309 310 fConnection = btCoreData->ConnectionByDestination( 311 address->l2cap_bdaddr, hid); 312 if (fConnection == NULL) 313 return EHOSTUNREACH; 314 315 memcpy(&socket->peer, _address, sizeof(struct sockaddr_l2cap)); 316 317 status = gL2capEndpointManager.BindToChannel(this); 318 if (status != B_OK) 319 return status; 320 321 fConfigState = {}; 322 323 uint8 ident = btCoreData->allocate_command_ident(fConnection, this); 324 if (ident == L2CAP_NULL_IDENT) 325 return ENOBUFS; 326 327 status = send_l2cap_connection_req(fConnection, ident, 328 address->l2cap_psm, fChannelID); 329 if (status != B_OK) 330 return status; 331 332 fState = WAIT_FOR_CONNECTION_RSP; 333 334 while (fState != CLOSED && fState != OPEN) { 335 status = _WaitForStateChange(timeout); 336 if (status != B_OK) 337 return status; 338 } 339 return (fState == OPEN) ? B_OK : ECONNREFUSED; 340 } 341 342 343 status_t 344 L2capEndpoint::Accept(net_socket** _acceptedSocket) 345 { 346 CALLED(); 347 MutexLocker locker(fLock); 348 349 status_t status; 350 bigtime_t timeout = absolute_timeout(socket->receive.timeout); 351 if (gStackModule->is_restarted_syscall()) 352 timeout = gStackModule->restore_syscall_restart_timeout(); 353 else 354 gStackModule->store_syscall_restart_timeout(timeout); 355 356 do { 357 locker.Unlock(); 358 359 status = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT 360 | B_CAN_INTERRUPT, timeout); 361 if (status != B_OK) { 362 if (status == B_TIMED_OUT && socket->receive.timeout == 0) 363 return B_WOULD_BLOCK; 364 365 return status; 366 } 367 368 locker.Lock(); 369 status = gSocketModule->dequeue_connected(socket, _acceptedSocket); 370 } while (status != B_OK); 371 372 return status; 373 } 374 375 376 ssize_t 377 L2capEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer) 378 { 379 CALLED(); 380 MutexLocker locker(fLock); 381 382 *_buffer = NULL; 383 384 bigtime_t timeout = 0; 385 if ((flags & MSG_DONTWAIT) == 0) { 386 timeout = absolute_timeout(socket->receive.timeout); 387 if (gStackModule->is_restarted_syscall()) 388 timeout = gStackModule->restore_syscall_restart_timeout(); 389 else 390 gStackModule->store_syscall_restart_timeout(timeout); 391 } 392 393 if (fState == CLOSED) 394 flags |= MSG_DONTWAIT; 395 396 return gStackModule->fifo_dequeue_buffer(&fReceiveQueue, flags, timeout, _buffer); 397 } 398 399 400 ssize_t 401 L2capEndpoint::SendData(net_buffer* buffer) 402 { 403 CALLED(); 404 MutexLocker locker(fLock); 405 406 if (buffer == NULL) 407 return ENOBUFS; 408 409 if (fState != OPEN) 410 return ENOTCONN; 411 412 ssize_t sent = 0; 413 while (buffer != NULL) { 414 net_buffer* current = buffer; 415 buffer = NULL; 416 if (current->size > fChannelConfig.outgoing_mtu) { 417 // Break up into MTU-sized chunks. 418 buffer = gBufferModule->split(current, fChannelConfig.outgoing_mtu); 419 if (buffer == NULL) { 420 if (sent > 0) { 421 gBufferModule->free(current); 422 return sent; 423 } 424 return ENOMEM; 425 } 426 } 427 428 const size_t bufferSize = current->size; 429 status_t status = gStackModule->fifo_enqueue_buffer(&fSendQueue, current); 430 if (status != B_OK) { 431 gBufferModule->free(current); 432 return sent; 433 } 434 435 sent += bufferSize; 436 } 437 438 if (!gStackModule->is_timer_active(&fSendTimer)) 439 gStackModule->set_timer(&fSendTimer, 0); 440 441 return sent; 442 } 443 444 445 status_t 446 L2capEndpoint::ReceiveData(net_buffer* buffer) 447 { 448 // FIXME: Check address specified in net_buffer! 449 return gStackModule->fifo_enqueue_buffer(&fReceiveQueue, buffer); 450 } 451 452 453 /*static*/ void 454 L2capEndpoint::_SendTimer(net_timer* timer, void* _endpoint) 455 { 456 L2capEndpoint* endpoint = (L2capEndpoint*)_endpoint; 457 458 MutexLocker locker(endpoint->fLock); 459 if (!locker.IsLocked() || gStackModule->is_timer_active(timer)) 460 return; 461 462 endpoint->_SendQueued(); 463 } 464 465 466 void 467 L2capEndpoint::_SendQueued() 468 { 469 CALLED(); 470 ASSERT_LOCKED_MUTEX(&fLock); 471 472 if (fState != OPEN) 473 return; 474 475 net_buffer* buffer; 476 while (gStackModule->fifo_dequeue_buffer(&fSendQueue, MSG_DONTWAIT, 0, &buffer) >= 0) { 477 NetBufferPrepend<l2cap_basic_header> header(buffer); 478 if (header.Status() != B_OK) { 479 ERROR("%s: header could not be prepended!\n", __func__); 480 gBufferModule->free(buffer); 481 continue; 482 } 483 484 header->length = B_HOST_TO_LENDIAN_INT16(buffer->size - sizeof(l2cap_basic_header)); 485 header->dcid = B_HOST_TO_LENDIAN_INT16(fDestinationChannelID); 486 487 buffer->type = fConnection->handle; 488 btDevices->PostACL(fConnection->ndevice->index, buffer); 489 } 490 } 491 492 493 ssize_t 494 L2capEndpoint::Sendable() 495 { 496 CALLED(); 497 MutexLocker locker(fLock); 498 499 if (fState != OPEN) { 500 if (_IsEstablishing()) 501 return 0; 502 return EPIPE; 503 } 504 505 MutexLocker fifoLocker(fSendQueue.lock); 506 return (fSendQueue.max_bytes - fSendQueue.current_bytes); 507 } 508 509 510 ssize_t 511 L2capEndpoint::Receivable() 512 { 513 CALLED(); 514 MutexLocker locker(fLock); 515 516 MutexLocker fifoLocker(fReceiveQueue.lock); 517 return fReceiveQueue.current_bytes; 518 } 519 520 521 void 522 L2capEndpoint::_HandleCommandRejected(uint8 ident, uint16 reason, 523 const l2cap_command_reject_data& data) 524 { 525 CALLED(); 526 MutexLocker locker(fLock); 527 528 switch (fState) { 529 case WAIT_FOR_CONNECTION_RSP: 530 // Connection request was rejected. Reset state. 531 fState = CLOSED; 532 socket->error = ECONNREFUSED; 533 break; 534 535 case CONFIGURATION: 536 // TODO: Adjust and resend configuration request. 537 break; 538 539 default: 540 ERROR("l2cap: unknown command unexpectedly rejected (ident %d)\n", ident); 541 break; 542 } 543 544 fCommandWait.NotifyAll(); 545 } 546 547 548 void 549 L2capEndpoint::_HandleConnectionReq(HciConnection* connection, 550 uint8 ident, uint16 psm, uint16 scid) 551 { 552 MutexLocker locker(fLock); 553 if (fState != LISTEN) { 554 send_l2cap_connection_rsp(connection, ident, 0, scid, 555 l2cap_connection_rsp::RESULT_PSM_NOT_SUPPORTED, 0); 556 return; 557 } 558 locker.Unlock(); 559 560 net_socket* newSocket; 561 status_t status = gSocketModule->spawn_pending_socket(socket, &newSocket); 562 if (status != B_OK) { 563 ERROR("l2cap: could not spawn child for endpoint: %s\n", strerror(status)); 564 send_l2cap_connection_rsp(connection, ident, 0, scid, 565 l2cap_connection_rsp::RESULT_NO_RESOURCES, 0); 566 return; 567 } 568 569 L2capEndpoint* endpoint = (L2capEndpoint*)newSocket->first_protocol; 570 MutexLocker newEndpointLocker(endpoint->fLock); 571 572 status = gL2capEndpointManager.BindToChannel(endpoint); 573 if (status != B_OK) { 574 ERROR("l2cap: could not allocate channel for endpoint: %s\n", strerror(status)); 575 send_l2cap_connection_rsp(connection, ident, 0, scid, 576 l2cap_connection_rsp::RESULT_NO_RESOURCES, 0); 577 return; 578 } 579 580 endpoint->fAcceptSemaphore = fAcceptSemaphore; 581 582 endpoint->fConnection = connection; 583 endpoint->fState = CONFIGURATION; 584 585 endpoint->fDestinationChannelID = scid; 586 587 send_l2cap_connection_rsp(connection, ident, endpoint->fChannelID, scid, 588 l2cap_connection_rsp::RESULT_SUCCESS, 0); 589 } 590 591 592 void 593 L2capEndpoint::_HandleConnectionRsp(uint8 ident, const l2cap_connection_rsp& response) 594 { 595 CALLED(); 596 MutexLocker locker(fLock); 597 fCommandWait.NotifyAll(); 598 599 if (fState != WAIT_FOR_CONNECTION_RSP) { 600 ERROR("l2cap: unexpected connection response, scid=%d, state=%d\n", 601 response.scid, fState); 602 send_l2cap_command_reject(fConnection, ident, 603 l2cap_command_reject::REJECTED_INVALID_CID, 0, response.scid, response.dcid); 604 return; 605 } 606 607 if (fChannelID != response.scid) { 608 ERROR("l2cap: invalid connection response, mismatched SCIDs (%d, %d)\n", 609 fChannelID, response.scid); 610 send_l2cap_command_reject(fConnection, ident, 611 l2cap_command_reject::REJECTED_INVALID_CID, 0, response.scid, response.dcid); 612 return; 613 } 614 615 if (response.result == l2cap_connection_rsp::RESULT_PENDING) { 616 // The connection is still pending on the remote end. 617 // We will receive another CONNECTION_RSP later. 618 619 // TODO: Increase/reset timeout? (We don't have any timeouts presently.) 620 return; 621 } else if (response.result != l2cap_connection_rsp::RESULT_SUCCESS) { 622 // Some error response. 623 // TODO: Translate `result` if possible? 624 socket->error = ECONNREFUSED; 625 626 fState = CLOSED; 627 fCommandWait.NotifyAll(); 628 } 629 630 // Success: channel is now open for configuration. 631 fState = CONFIGURATION; 632 fDestinationChannelID = response.dcid; 633 634 _SendChannelConfig(); 635 } 636 637 638 void 639 L2capEndpoint::_SendChannelConfig() 640 { 641 uint16* mtu = NULL; 642 if (fChannelConfig.incoming_mtu != L2CAP_MTU_DEFAULT) 643 mtu = &fChannelConfig.incoming_mtu; 644 645 uint16* flush_timeout = NULL; 646 if (fChannelConfig.flush_timeout != L2CAP_FLUSH_TIMEOUT_DEFAULT) 647 flush_timeout = &fChannelConfig.flush_timeout; 648 649 l2cap_qos* flow = NULL; 650 if (memcmp(&sDefaultQOS, &fChannelConfig.outgoing_flow, 651 sizeof(fChannelConfig.outgoing_flow)) != 0) { 652 flow = &fChannelConfig.outgoing_flow; 653 } 654 655 uint8 ident = btCoreData->allocate_command_ident(fConnection, this); 656 if (ident == L2CAP_NULL_IDENT) { 657 // TODO: Retry later? 658 return; 659 } 660 661 status_t status = send_l2cap_configuration_req(fConnection, ident, 662 fDestinationChannelID, 0, flush_timeout, mtu, flow); 663 if (status != B_OK) { 664 socket->error = status; 665 return; 666 } 667 668 fConfigState.out = ConfigState::SENT; 669 } 670 671 672 void 673 L2capEndpoint::_HandleConfigurationReq(uint8 ident, uint16 flags, 674 uint16* mtu, uint16* flush_timeout, l2cap_qos* flow) 675 { 676 CALLED(); 677 MutexLocker locker(fLock); 678 fCommandWait.NotifyAll(); 679 680 if (fState != CONFIGURATION && fState != OPEN) { 681 ERROR("l2cap: unexpected configuration req: invalid channel state (cid=%d, state=%d)\n", 682 fChannelID, fState); 683 send_l2cap_configuration_rsp(fConnection, ident, fChannelID, 0, 684 l2cap_configuration_rsp::RESULT_REJECTED, NULL); 685 return; 686 } 687 688 if (fState == OPEN) { 689 // Re-configuration. 690 fConfigState = {}; 691 fState = CONFIGURATION; 692 } 693 694 // Process options. 695 // TODO: Validate parameters! 696 if (mtu != NULL && *mtu != fChannelConfig.outgoing_mtu) 697 fChannelConfig.outgoing_mtu = *mtu; 698 if (flush_timeout != NULL && *flush_timeout != fChannelConfig.flush_timeout) 699 fChannelConfig.flush_timeout = *flush_timeout; 700 if (flow != NULL) 701 fChannelConfig.incoming_flow = *flow; 702 703 send_l2cap_configuration_rsp(fConnection, ident, fChannelID, 0, 704 l2cap_configuration_rsp::RESULT_SUCCESS, NULL); 705 706 if ((flags & L2CAP_CFG_FLAG_CONTINUATION) != 0) { 707 // More options are coming, just keep waiting. 708 return; 709 } 710 711 // We now have all options. 712 fConfigState.in = ConfigState::DONE; 713 714 if (fConfigState.out < ConfigState::SENT) 715 _SendChannelConfig(); 716 else if (fConfigState.out == ConfigState::DONE) 717 _MarkEstablished(); 718 } 719 720 721 void 722 L2capEndpoint::_HandleConfigurationRsp(uint8 ident, uint16 scid, uint16 flags, 723 uint16 result, uint16* mtu, uint16* flush_timeout, l2cap_qos* flow) 724 { 725 CALLED(); 726 MutexLocker locker(fLock); 727 fCommandWait.NotifyAll(); 728 729 if (fState != CONFIGURATION) { 730 ERROR("l2cap: unexpected configuration rsp: invalid channel state (cid=%d, state=%d)\n", 731 fChannelID, fState); 732 send_l2cap_command_reject(fConnection, ident, 733 l2cap_command_reject::REJECTED_INVALID_CID, 0, scid, fChannelID); 734 return; 735 } 736 if (scid != fChannelID) { 737 ERROR("l2cap: unexpected configuration rsp: invalid source channel (cid=%d, scid=%d)\n", 738 fChannelID, scid); 739 send_l2cap_command_reject(fConnection, ident, 740 l2cap_command_reject::REJECTED_INVALID_CID, 0, scid, fChannelID); 741 return; 742 } 743 744 // TODO: Validate parameters! 745 if (result == l2cap_configuration_rsp::RESULT_PENDING) { 746 // We will receive another CONFIGURATION_RSP later. 747 return; 748 } else if (result == l2cap_configuration_rsp::RESULT_UNACCEPTABLE_PARAMS) { 749 // The acceptable parameters are specified in options. 750 if (mtu != NULL && *mtu != fChannelConfig.incoming_mtu) 751 fChannelConfig.incoming_mtu = *mtu; 752 if (flush_timeout != NULL && *flush_timeout != fChannelConfig.flush_timeout) 753 fChannelConfig.flush_timeout = *flush_timeout; 754 } else if (result == l2cap_configuration_rsp::RESULT_FLOW_SPEC_REJECTED) { 755 if (flow != NULL) 756 fChannelConfig.outgoing_flow = *flow; 757 } else if (result != l2cap_configuration_rsp::RESULT_SUCCESS) { 758 ERROR("l2cap: unhandled configuration response! (result=%d)\n", 759 result); 760 return; 761 } 762 763 if ((flags & L2CAP_CFG_FLAG_CONTINUATION) != 0) { 764 // More options are coming, just keep waiting. 765 return; 766 } 767 768 if (result != l2cap_configuration_rsp::RESULT_SUCCESS) { 769 // Resend configuration request to try again. 770 _SendChannelConfig(); 771 return; 772 } 773 774 // We now have all options. 775 fConfigState.out = ConfigState::DONE; 776 777 if (fConfigState.in == ConfigState::DONE) 778 _MarkEstablished(); 779 } 780 781 782 status_t 783 L2capEndpoint::_MarkEstablished() 784 { 785 CALLED(); 786 ASSERT_LOCKED_MUTEX(&fLock); 787 788 fState = OPEN; 789 fCommandWait.NotifyAll(); 790 791 status_t error = B_OK; 792 if (gSocketModule->has_parent(socket)) { 793 error = gSocketModule->set_connected(socket); 794 if (error == B_OK) { 795 release_sem(fAcceptSemaphore); 796 fAcceptSemaphore = -1; 797 } else { 798 ERROR("%s: could not set endpoint %p connected: %s\n", __func__, this, 799 strerror(error)); 800 } 801 } 802 803 return error; 804 } 805 806 807 void 808 L2capEndpoint::_HandleDisconnectionReq(uint8 ident, uint16 scid) 809 { 810 CALLED(); 811 MutexLocker locker(fLock); 812 fCommandWait.NotifyAll(); 813 814 if (scid != fDestinationChannelID) { 815 ERROR("l2cap: unexpected disconnection req: invalid source channel (cid=%d, scid=%d)\n", 816 fChannelID, scid); 817 send_l2cap_command_reject(fConnection, ident, 818 l2cap_command_reject::REJECTED_INVALID_CID, 0, scid, fChannelID); 819 return; 820 } 821 822 if (fState != WAIT_FOR_DISCONNECTION_RSP) 823 fState = RECEIVED_DISCONNECTION_REQ; 824 825 // The dcid/scid are the same as in the REQ command. 826 status_t status = send_l2cap_disconnection_rsp(fConnection, ident, fChannelID, scid); 827 if (status != B_OK) { 828 // TODO? 829 return; 830 } 831 832 _MarkClosed(); 833 } 834 835 836 void 837 L2capEndpoint::_HandleDisconnectionRsp(uint8 ident, uint16 dcid, uint16 scid) 838 { 839 CALLED(); 840 MutexLocker locker(fLock); 841 fCommandWait.NotifyAll(); 842 843 if (fState != WAIT_FOR_DISCONNECTION_RSP) { 844 ERROR("l2cap: unexpected disconnection rsp (cid=%d, scid=%d)\n", 845 fChannelID, scid); 846 send_l2cap_command_reject(fConnection, ident, 847 l2cap_command_reject::REJECTED_INVALID_CID, 0, scid, fChannelID); 848 return; 849 } 850 851 if (dcid != fDestinationChannelID && scid != fChannelID) { 852 ERROR("l2cap: unexpected disconnection rsp: mismatched CIDs (dcid=%d, scid=%d)\n", 853 dcid, scid); 854 return; 855 } 856 857 _MarkClosed(); 858 } 859 860 861 void 862 L2capEndpoint::_MarkClosed() 863 { 864 CALLED(); 865 ASSERT_LOCKED_MUTEX(&fLock); 866 867 fState = CLOSED; 868 869 gL2capEndpointManager.UnbindFromChannel(this); 870 } 871