From a58b3b32350051afd1b2d40541550ba9272cd96e Mon Sep 17 00:00:00 2001 From: Oliver Ruiz Dorantes Date: Sun, 27 Sep 2009 19:07:24 +0000 Subject: [PATCH] Implement a bit further the sockets interface git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33320 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/l2cap/L2capEndpoint.cpp | 131 +++++++++++++----- .../network/protocols/l2cap/L2capEndpoint.h | 54 ++++---- .../kernel/network/protocols/l2cap/l2cap.cpp | 6 +- .../network/protocols/l2cap/l2cap_signal.cpp | 59 ++++---- .../network/protocols/l2cap/l2cap_upper.cpp | 66 +++++++-- .../network/protocols/l2cap/l2cap_upper.h | 5 +- 6 files changed, 207 insertions(+), 114 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.cpp b/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.cpp index e6ba1fe932..613a685dd9 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.cpp @@ -1,9 +1,6 @@ -/* - * Copyright 2008, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Oliver Ruiz Dorantes, oliver-ruiz.dorantes_at_gmail.com +/* + * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. */ #include "L2capEndpoint.h" #include "l2cap_address.h" @@ -15,6 +12,9 @@ #include #define BT_DEBUG_THIS_MODULE +#define MODULE_NAME "l2cap" +#define SUBMODULE_NAME "Endpoint" +#define SUBMODULE_COLOR 32 #include @@ -32,10 +32,12 @@ absolute_timeout(bigtime_t timeout) L2capEndpoint::L2capEndpoint(net_socket* socket) : ProtocolSocket(socket), + fConfigurationSet(false), fPeerEndpoint(NULL), - fAcceptSemaphore(-1) + fAcceptSemaphore(-1), + fChannel(NULL) { - debugf("[%ld] %p->L2capEndpoint::L2capEndpoint()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); /* Set MTU and flow control settings to defaults */ configuration.imtu = L2CAP_MTU_DEFAULT; @@ -47,16 +49,13 @@ L2capEndpoint::L2capEndpoint(net_socket* socket) configuration.flush_timo = L2CAP_FLUSH_TIMO_DEFAULT; configuration.link_timo = L2CAP_LINK_TIMO_DEFAULT; - configurationSet = false; - gStackModule->init_fifo(&fReceivingFifo, "l2cap recvfifo", L2CAP_MTU_DEFAULT); } L2capEndpoint::~L2capEndpoint() { - debugf("[%ld] %p->L2capEndpoint::~L2capEndpoint()\n", find_thread(NULL), this); - + debugf("[%ld] %p\n", find_thread(NULL), this); } @@ -64,7 +63,7 @@ L2capEndpoint::~L2capEndpoint() status_t L2capEndpoint::Init() { - debugf("[%ld] %p->L2capEndpoint::Init()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return B_OK; } @@ -73,7 +72,7 @@ L2capEndpoint::Init() void L2capEndpoint::Uninit() { - debugf("[%ld] %p->L2capEndpoint::Uninit()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); } @@ -81,7 +80,7 @@ L2capEndpoint::Uninit() status_t L2capEndpoint::Open() { - debugf("[%ld] %p->L2capEndpoint::Open()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); status_t error = ProtocolSocket::Open(); if (error != B_OK) @@ -94,7 +93,7 @@ L2capEndpoint::Open() status_t L2capEndpoint::Close() { - debugf("[%ld] %p->L2capEndpoint::Close()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return B_OK; } @@ -103,7 +102,7 @@ L2capEndpoint::Close() status_t L2capEndpoint::Free() { - debugf("[%ld] %p->L2capEndpoint::Free()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return B_OK; } @@ -137,7 +136,7 @@ L2capEndpoint::Bind(const struct sockaddr *_address) memcpy(&socket->address, _address, sizeof(struct sockaddr_l2cap)); socket->address.ss_len = sizeof(struct sockaddr_l2cap); - fState = LISTEN; + fState = CLOSED; return B_OK; @@ -147,7 +146,7 @@ L2capEndpoint::Bind(const struct sockaddr *_address) status_t L2capEndpoint::Unbind() { - debugf("[%ld] %p->L2capEndpoint::Unbind()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return B_OK; } @@ -156,12 +155,20 @@ L2capEndpoint::Unbind() status_t L2capEndpoint::Listen(int backlog) { - if (fState != CLOSED) + debugf("[%ld] %p\n", find_thread(NULL), this); + + if (fState != CLOSED) { + flowf("Invalid State\n"); return B_BAD_VALUE; + } - fAcceptSemaphore = create_sem(0, "tcp accept"); - if (fAcceptSemaphore < B_OK) + fAcceptSemaphore = create_sem(0, "l2cap serv accept"); + if (fAcceptSemaphore < B_OK) { + flowf("Semaphore could not be created\n"); return ENOBUFS; + } + + gSocketModule->set_max_backlog(socket, backlog); fState = LISTEN; @@ -190,12 +197,42 @@ L2capEndpoint::Connect(const struct sockaddr *_address) status_t L2capEndpoint::Accept(net_socket **_acceptedSocket) { - debugf("[%ld] %p->L2capEndpoint::Accept()\n", find_thread(NULL), this); + debugf("[%ld]\n", find_thread(NULL)); - bigtime_t timeout = absolute_timeout(socket->receive.timeout); + // MutexLocker locker(fLock); - TOUCH(timeout); - return B_OK; + status_t status; + bigtime_t timeout = absolute_timeout(300*1000*1000); + + do { + // locker.Unlock(); + + status = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT + | B_CAN_INTERRUPT, timeout); + + if (status != B_OK) + return status; + + // locker.Lock(); + status = gSocketModule->dequeue_connected(socket, _acceptedSocket); + + if (status != B_OK) + debugf("Could not dequeue socket %s\n", strerror(status)); + + //TODO: Establish relationship with the negotiated channel by the parent endpoint + ((L2capEndpoint*)socket)->fChannel = fChannel; + + // point parent + ((L2capEndpoint*)socket)->fPeerEndpoint = this; + + // unassign any channel for the parent endpoint + fChannel = NULL; + + fState = LISTEN; + + } while (status != B_OK); + + return status; } @@ -203,7 +240,7 @@ ssize_t L2capEndpoint::Send(const iovec *vecs, size_t vecCount, ancillary_data_container *ancillaryData) { - debugf("[%ld] %p->L2capEndpoint::Send(%p, %ld, %p)\n", find_thread(NULL), + debugf("[%ld] %p Send(%p, %ld, %p)\n", find_thread(NULL), this, vecs, vecCount, ancillaryData); return B_OK; @@ -215,7 +252,7 @@ L2capEndpoint::Receive(const iovec *vecs, size_t vecCount, ancillary_data_container **_ancillaryData, struct sockaddr *_address, socklen_t *_addressLength) { - debugf("[%ld] %p->L2capEndpoint::Receive(%p, %ld)\n", find_thread(NULL), + debugf("[%ld] %p Receive(%p, %ld)\n", find_thread(NULL), this, vecs, vecCount); @@ -227,15 +264,15 @@ ssize_t L2capEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer) { - return gStackModule->fifo_dequeue_buffer(&fReceivingFifo, flags, B_INFINITE_TIMEOUT, _buffer); - + return gStackModule->fifo_dequeue_buffer(&fReceivingFifo, flags, + B_INFINITE_TIMEOUT, _buffer); } ssize_t L2capEndpoint::Sendable() { - debugf("[%ld] %p->L2capEndpoint::Sendable()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return 0; } @@ -244,7 +281,7 @@ L2capEndpoint::Sendable() ssize_t L2capEndpoint::Receivable() { - debugf("[%ld] %p->L2capEndpoint::Receivable()\n", find_thread(NULL), this); + debugf("[%ld] %p\n", find_thread(NULL), this); return 0; } @@ -253,8 +290,7 @@ L2capEndpoint::Receivable() L2capEndpoint* L2capEndpoint::ForPsm(uint16 psm) { - - L2capEndpoint* endpoint; + L2capEndpoint* endpoint; DoublyLinkedList::Iterator iterator = EndpointList.GetIterator(); @@ -275,8 +311,29 @@ L2capEndpoint::ForPsm(uint16 psm) void L2capEndpoint::BindToChannel(L2capChannel* channel) { - - this->channel = channel; - channel->configuration = &configuration; + fChannel = channel; + fChannel->endpoint = this; + + fChannel->configuration = &configuration; + + debugf("Endpoint %p for psm %d, schannel %x dchannel %x\n", this, + channel->psm, channel->scid, channel->dcid); } + + +status_t +L2capEndpoint::MarkEstablished() +{ + debugf("Endpoint %p for psm %d, schannel %x dchannel %x\n", this, + fChannel->psm, fChannel->scid, fChannel->dcid); + + net_socket* newSocket; + status_t error = gSocketModule->spawn_pending_socket(socket, &newSocket); + + gSocketModule->set_connected(newSocket); + + release_sem(fAcceptSemaphore); + + return error; +} diff --git a/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.h b/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.h index e354643a45..cc71d3938f 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.h +++ b/src/add-ons/kernel/network/protocols/l2cap/L2capEndpoint.h @@ -1,9 +1,6 @@ -/* - * Copyright 2008, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Oliver Ruiz Dorantes, oliver-ruiz.dorantes_at_gmail.com +/* + * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com + * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef L2CAP_ENDPOINT_H #define L2CAP_ENDPOINT_H @@ -47,17 +44,18 @@ public: mutex_unlock(&fLock); } - status_t Bind(const struct sockaddr *_address); - status_t Unbind(); - status_t Listen(int backlog); - status_t Connect(const struct sockaddr *address); - status_t Accept(net_socket **_acceptedSocket); + status_t Bind(const struct sockaddr *_address); + status_t Unbind(); + status_t Listen(int backlog); + status_t Connect(const struct sockaddr *address); + status_t Accept(net_socket **_acceptedSocket); + + ssize_t Send(const iovec *vecs, size_t vecCount, + ancillary_data_container *ancillaryData); + ssize_t Receive(const iovec *vecs, size_t vecCount, + ancillary_data_container **_ancillaryData, + struct sockaddr *_address, socklen_t *_addressLength); - ssize_t Send(const iovec *vecs, size_t vecCount, - ancillary_data_container *ancillaryData); - ssize_t Receive(const iovec *vecs, size_t vecCount, - ancillary_data_container **_ancillaryData, struct sockaddr *_address, - socklen_t *_addressLength); ssize_t ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer); ssize_t Sendable(); ssize_t Receivable(); @@ -67,15 +65,19 @@ public: status_t Shutdown(int direction); - void BindToChannel(L2capChannel* channel); - - static L2capEndpoint* ForPsm(uint16 psm); - - ChannelConfiguration configuration; - L2capChannel* channel; - - bool configurationSet; - net_fifo fReceivingFifo; + void BindToChannel(L2capChannel* channel); + status_t MarkEstablished(); + + static L2capEndpoint* ForPsm(uint16 psm); + + bool RequiresConfiguration() + { + return fConfigurationSet; + } + + ChannelConfiguration configuration; + net_fifo fReceivingFifo; + bool fConfigurationSet; private: typedef enum { @@ -101,7 +103,7 @@ private: State fState; L2capEndpoint* fPeerEndpoint; sem_id fAcceptSemaphore; - + L2capChannel* fChannel; }; diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp b/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp index 5d3ef6bf0e..d5668a9273 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap.cpp @@ -126,9 +126,7 @@ l2cap_connect(net_protocol* protocol, const struct sockaddr* address) status_t l2cap_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) { - flowf("\n"); - - return EOPNOTSUPP; + return ((L2capEndpoint*)protocol)->Accept(_acceptedSocket); } @@ -160,7 +158,7 @@ l2cap_setsockopt(net_protocol* protocol, int level, int option, { flowf("\n"); - ((L2capEndpoint*)protocol)->configurationSet = true; + ((L2capEndpoint*)protocol)->fConfigurationSet = true; /* return protocol->next->module->setsockopt(protocol->next, level, option, value, length); */ return EOPNOTSUPP; diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap_signal.cpp b/src/add-ons/kernel/network/protocols/l2cap/l2cap_signal.cpp index c97cb7ddae..2fc0440e27 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap_signal.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap_signal.cpp @@ -100,7 +100,8 @@ l2cap_process_cmd_rej(HciConnection* conn, uint8 ident, net_buffer* buffer); status_t l2cap_process_signal_cmd(HciConnection* conn, net_buffer* buffer) { - net_buffer* m = buffer; + net_buffer* m = buffer; + debugf("Signal size=%ld\n", buffer->size); while (m != NULL) { @@ -212,8 +213,8 @@ l2cap_process_signal_cmd(HciConnection* conn, net_buffer* buffer) static status_t l2cap_process_con_req(HciConnection* conn, uint8 ident, net_buffer* buffer) { - L2capChannel* ch; - uint16 dcid, psm; + L2capChannel* ch; + uint16 dcid, psm; /* Get con req data */ NetBufferHeaderReader command(buffer); @@ -262,9 +263,9 @@ l2cap_process_con_req(HciConnection* conn, uint8 ident, net_buffer* buffer) static status_t l2cap_process_con_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer) { - L2capFrame* cmd = NULL; - uint16 scid, dcid, result, status; - status_t error = 0; + L2capFrame* cmd = NULL; + uint16 scid, dcid, result, status; + status_t error = 0; /* Get command parameters */ NetBufferHeaderReader command(buffer); @@ -359,7 +360,7 @@ reject: static option_status getNextSignalOption(net_buffer* nbuf, size_t* off, l2cap_cfg_opt_t* hdr, l2cap_cfg_opt_val_t* val) { - int hint; + int hint; size_t len = nbuf->size - (*off); if (len == 0) @@ -425,16 +426,16 @@ getNextSignalOption(net_buffer* nbuf, size_t* off, l2cap_cfg_opt_t* hdr, l2cap_c static status_t l2cap_process_cfg_req(HciConnection* conn, uint8 ident, net_buffer* buffer) { - L2capChannel* channel = NULL; - uint16 dcid; - uint16 respond; - uint16 result; + L2capChannel* channel = NULL; + uint16 dcid; + uint16 respond; + uint16 result; - l2cap_cfg_opt_t hdr; + l2cap_cfg_opt_t hdr; l2cap_cfg_opt_val_t val; - size_t off; - status_t error = 0; + size_t off; + status_t error = 0; debugf("configuration=%ld\n", buffer->size); @@ -554,14 +555,14 @@ reject: static status_t l2cap_process_cfg_rsp(HciConnection *conn, uint8 ident, net_buffer *buffer) { - L2capFrame *cmd = NULL; - uint16 scid, cflag, result; + L2capFrame *cmd = NULL; + uint16 scid, cflag, result; - l2cap_cfg_opt_t hdr; - l2cap_cfg_opt_val_t val; + l2cap_cfg_opt_t hdr; + l2cap_cfg_opt_val_t val; - size_t off; - status_t error = 0; + size_t off; + status_t error = 0; NetBufferHeaderReader command(buffer); status_t status = command.Status(); @@ -655,7 +656,7 @@ l2cap_process_cfg_rsp(HciConnection *conn, uint8 ident, net_buffer *buffer) btCoreData->TimeoutSignal(cmd, bluetooth_l2cap_rtx_timeout); else { /* Send L2CA_Config response to the upper layer protocol */ - //INDICATION error = ng_l2cap_l2ca_cfg_rsp(cmd->channel, cmd->token, result); + error = l2cap_upper_cfg_rsp(cmd->channel /*, cmd->token, result*/); if (error != 0) { /* * XXX FIXME what to do here? we were not able to send @@ -668,10 +669,7 @@ l2cap_process_cfg_rsp(HciConnection *conn, uint8 ident, net_buffer *buffer) btCoreData->RemoveChannel(conn, cmd->channel->scid); } - cmd->channel->cfgState |= L2CAP_CFG_OUT; - if ((cmd->channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) { - cmd->channel->state = L2CAP_CHAN_OPEN; - } + btCoreData->AcknowledgeSignal(cmd); } @@ -770,7 +768,7 @@ reject: static status_t l2cap_process_discon_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer) { - L2capFrame *cmd = NULL; + L2capFrame* cmd = NULL; int16 scid, dcid; status_t error = 0; @@ -827,7 +825,7 @@ out: static status_t l2cap_process_echo_req(HciConnection *conn, uint8 ident, net_buffer *buffer) { - L2capFrame *cmd = NULL; + L2capFrame* cmd = NULL; cmd = btCoreData->SpawnSignal(conn, NULL, l2cap_echo_req(ident, NULL, 0), ident, L2CAP_ECHO_RSP); if (cmd == NULL) { @@ -917,8 +915,8 @@ static status_t l2cap_process_info_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer) { l2cap_info_rsp_cp* cp = NULL; - L2capFrame* cmd = NULL; - status_t error = B_OK; + L2capFrame* cmd = NULL; + status_t error = B_OK; /* Get command parameters */ NetBufferHeaderReader command(buffer); @@ -950,8 +948,7 @@ l2cap_process_info_rsp(HciConnection* conn, uint8 ident, net_buffer* buffer) switch (command->type) { case L2CAP_CONNLESS_MTU: - /* - // TODO: Check specs ?? + /* TODO: Check specs ?? if (conn->rx_pkt->m_pkthdr.len == sizeof(uint16)) { *mtod(conn->rx_pkt, uint16 *) = le16toh(*mtod(conn->rx_pkt,uint16 *)); } else { diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.cpp b/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.cpp index 9459440856..2d5d772ddf 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.cpp +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.cpp @@ -1,7 +1,6 @@ /* * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com * All rights reserved. Distributed under the terms of the MIT License. - * */ #include #include @@ -31,17 +30,17 @@ l2cap_l2ca_con_ind(L2capChannel* channel) } // Pair Channel with endpoint - channel->endpoint = endpoint; endpoint->BindToChannel(channel); - debugf("Endpoint %p bound for psm %d, schannel %x dchannel %x\n",endpoint, channel->psm, channel->scid, channel->dcid); - - net_buffer* buf = l2cap_con_rsp(channel->ident, channel->scid, channel->dcid, L2CAP_SUCCESS, L2CAP_NO_INFO); - L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, channel->ident, L2CAP_CON_RSP); + net_buffer* buf = l2cap_con_rsp(channel->ident, channel->scid, channel->dcid, + L2CAP_SUCCESS, L2CAP_NO_INFO); + L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, + channel->ident, L2CAP_CON_RSP); if (cmd == NULL) { gBufferModule->free(buf); return ENOMEM; } + // we can move to configuration... channel->state = L2CAP_CHAN_CONFIG; @@ -54,12 +53,16 @@ l2cap_l2ca_con_ind(L2capChannel* channel) status_t l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel) { - // if our configuration has not been yet send .. + // if our configuration has not been yet sent ... if(!(channel->cfgState & L2CAP_CFG_OUT_SENT)) { - // send config_rsp - net_buffer* buf = l2cap_cfg_rsp(channel->ident, channel->dcid, 0, L2CAP_SUCCESS, NULL); - L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, channel->ident, L2CAP_CFG_RSP); + // TODO: check if we can handle this conf + + // send config_rsp + net_buffer* buf = l2cap_cfg_rsp(channel->ident, channel->dcid, 0, + L2CAP_SUCCESS, NULL); + L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, + channel->ident, L2CAP_CFG_RSP); if (cmd == NULL) { gBufferModule->free(buf); channel->state = L2CAP_CHAN_CLOSED; @@ -67,7 +70,7 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel) } flowf("Sending cfg resp\n"); - /* Link command to the queue */ + // Link command to the queue SchedConnectionPurgeThread(channel->conn); // set status @@ -82,22 +85,26 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel) if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) { // Channel can be declared open channel->state = L2CAP_CHAN_OPEN; + channel->endpoint->MarkEstablished(); + } else { // send configuration Request by our side - if (channel->endpoint->configurationSet) { + if (channel->endpoint->RequiresConfiguration()) { // TODO: define complete configuration packet } else { // nothing special requested net_buffer* buf = l2cap_cfg_req(channel->ident, channel->dcid, 0, NULL); - L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, channel->ident, L2CAP_CFG_REQ); + L2capFrame* cmd = btCoreData->SpawnSignal(channel->conn, channel, buf, + channel->ident, L2CAP_CFG_REQ); if (cmd == NULL) { gBufferModule->free(buf); channel->state = L2CAP_CHAN_CLOSED; return ENOMEM; } - + flowf("Sending cfg req\n"); + // Link command to the queue SchedConnectionPurgeThread(channel->conn); @@ -109,6 +116,19 @@ l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel) } +status_t +l2cap_upper_cfg_rsp(L2capChannel* channel) +{ + channel->cfgState |= L2CAP_CFG_OUT; + if ((channel->cfgState & L2CAP_CFG_BOTH) == L2CAP_CFG_BOTH) { + channel->state = L2CAP_CHAN_OPEN; + return channel->endpoint->MarkEstablished(); + } + + return B_OK; +} + + status_t l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel) { @@ -121,6 +141,7 @@ l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel) status_t l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid) { + debugf("Handle %d To dcid %d\n", conn->handle, dcid); L2capChannel* channel = btCoreData->ChannelBySourceID(conn, dcid); @@ -134,7 +155,22 @@ l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid) return B_ERROR; } - flowf("Enqueue to fifo\n"); return gStackModule->fifo_enqueue_buffer(&channel->endpoint->fReceivingFifo, buffer); +} + + +status_t +l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm) +{ + + L2capEndpoint* endpoint = L2capEndpoint::ForPsm(psm); + + if (endpoint == NULL) { + debugf("no enpoint bound with psm %d\n", psm); + return B_ERROR; + } + + flowf("Enqueue to fifo\n"); + return gStackModule->fifo_enqueue_buffer(&endpoint->fReceivingFifo, buffer); } diff --git a/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.h b/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.h index 75723a809e..c921241cc0 100644 --- a/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.h +++ b/src/add-ons/kernel/network/protocols/l2cap/l2cap_upper.h @@ -8,10 +8,13 @@ #include "l2cap_internal.h" status_t l2cap_l2ca_con_ind(L2capChannel* channel); -status_t l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel); status_t l2cap_l2ca_cfg_rsp_ind(L2capChannel* channel); +status_t l2cap_upper_con_rsp(HciConnection* conn, L2capChannel* channel); +status_t l2cap_upper_cfg_rsp(L2capChannel* channel); + status_t l2cap_co_receive(HciConnection* conn, net_buffer* buffer, uint16 dcid); +status_t l2cap_cl_receive(HciConnection* conn, net_buffer* buffer, uint16 psm); #endif