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