summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-07-30 02:42:23 +0200
committerPatrick McHardy <kaber@trash.net>2010-07-30 02:44:03 +0200
commit897ce45c142f16ec430241bc91b4bee5c3af995a (patch)
treeb7968fc667cc893346c866ee9d7bde7e9a58959c
parent901ff947e8331acce34c4f9d332b05d0f5d2d7b6 (diff)
lce: reorder functions
Group functions into data links, paging and transactions. Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--src/lce.c732
1 files changed, 368 insertions, 364 deletions
diff --git a/src/lce.c b/src/lce.c
index e89b73a..aa093d2 100644
--- a/src/lce.c
+++ b/src/lce.c
@@ -138,155 +138,6 @@ static struct dect_lte *dect_lte_alloc(const struct dect_handle *dh,
#endif
/*
- * Paging
- */
-
-static int dect_lce_broadcast(const struct dect_handle *dh,
- const uint8_t *msg, size_t len)
-{
- ssize_t size;
-
- dect_hexdump(DECT_DEBUG_LCE, "LCE: BCAST TX", msg, len);
- size = send(dh->b_sap->fd, msg, len, 0);
- assert(size == (ssize_t)len);
- return 0;
-}
-
-/**
- * Request collective or group ringing
- *
- * @param dh libdect DECT handle
- * @param pattern ring pattern
- */
-int dect_lce_group_ring_req(struct dect_handle *dh,
- enum dect_ring_patterns pattern)
-{
- struct dect_short_page_msg msg;
- uint16_t page;
-
- msg.hdr = DECT_LCE_PAGE_W_FLAG;
- msg.hdr |= DECT_LCE_PAGE_GENERAL_VOICE;
-
- page = pattern << DECT_LCE_SHORT_PAGE_RING_PATTERN_SHIFT;
- page = 0;
- page |= DECT_TPUI_CBI & DECT_LCE_SHORT_PAGE_TPUI_MASK;
- msg.information = __cpu_to_be16(page);
-
- return dect_lce_broadcast(dh, &msg.hdr, sizeof(msg));
-}
-EXPORT_SYMBOL(dect_lce_group_ring_req);
-
-static int dect_lce_page(const struct dect_handle *dh,
- const struct dect_ipui *ipui)
-{
- struct dect_short_page_msg msg;
- struct dect_tpui tpui;
- uint16_t page;
-
- dect_ipui_to_tpui(&tpui, ipui);
-
- msg.hdr = DECT_LCE_PAGE_GENERAL_VOICE;
- page = dect_build_tpui(&tpui) & DECT_LCE_SHORT_PAGE_TPUI_MASK;
- msg.information = __cpu_to_be16(page);
-
- return dect_lce_broadcast(dh, &msg.hdr, sizeof(msg));
-}
-
-static void dect_lce_send_page_response(struct dect_handle *dh)
-{
- struct dect_ie_portable_identity portable_identity;
- struct dect_ie_fixed_identity fixed_identity;
- struct dect_lce_page_response_msg msg = {
- .portable_identity = &portable_identity,
- .fixed_identity = &fixed_identity,
- };
-
- portable_identity.type = DECT_PORTABLE_ID_TYPE_IPUI;
- portable_identity.ipui = dh->ipui;
-
- fixed_identity.type = DECT_FIXED_ID_TYPE_PARK;
- fixed_identity.ari = dh->pari;
-
- if (dect_open_transaction(dh, &dh->page_transaction, &dh->ipui,
- DECT_PD_LCE) < 0)
- return;
-
- dect_lce_send(dh, &dh->page_transaction, &lce_page_response_msg_desc,
- &msg.common, DECT_LCE_PAGE_RESPONSE);
-}
-
-static void dect_lce_rcv_short_page(struct dect_handle *dh,
- struct dect_msg_buf *mb)
-{
- struct dect_short_page_msg *msg = (void *)mb->data;
- struct dect_tpui tpui;
- uint16_t info, t;
- uint8_t hdr, pattern;
- bool w;
-
- w = msg->hdr & DECT_LCE_PAGE_W_FLAG;
- hdr = msg->hdr & DECT_LCE_PAGE_HDR_MASK;
- info = __be16_to_cpu(msg->information);
- lce_debug("short page: w=%u hdr=%u information=%04x\n", w, hdr, info);
-
- if (hdr == DECT_LCE_PAGE_UNKNOWN_RINGING) {
- pattern = (info & DECT_LCE_SHORT_PAGE_RING_PATTERN_MASK) >>
- DECT_LCE_SHORT_PAGE_RING_PATTERN_SHIFT;
-
- if (w == 0) {
- /* assigned connectionless group TPUI or CBI */
- if ((info ^ DECT_TPUI_CBI) &
- DECT_LCE_SHORT_PAGE_GROUP_MASK)
- return;
- } else {
- /* group mask */
- return;
- }
-
- lce_debug("LCE_GROUP_RING-ind: pattern: %x\n", pattern);
- dh->ops->lce_ops->lce_group_ring_ind(dh, pattern);
- } else {
- if (w == 0) {
- /* default individual TPUI */
- dect_ipui_to_tpui(&tpui, &dh->ipui);
- t = dect_build_tpui(&tpui);
- if (info != t)
- return;
- } else {
- /* assigned TPUI or CBI */
- t = dect_build_tpui(&dh->tpui);
- if (info != t && info != DECT_TPUI_CBI)
- return;
- }
-
- dect_lce_send_page_response(dh);
- }
-}
-
-static void dect_lce_bsap_event(struct dect_handle *dh, struct dect_fd *dfd,
- uint32_t events)
-{
- struct dect_msg_buf _mb, *mb = &_mb;
- struct msghdr msg;
-
- dect_debug(DECT_DEBUG_LCE, "\n");
-
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- if (dect_mbuf_rcv(dfd, &msg, mb) < 0)
- return;
- dect_mbuf_dump(DECT_DEBUG_LCE, mb, "LCE: BCAST RX");
-
- switch (mb->len) {
- case 3:
- return dect_lce_rcv_short_page(dh, mb);
- default:
- break;
- }
-}
-
-/*
* Data links
*/
@@ -587,26 +438,158 @@ int dect_lce_send(const struct dect_handle *dh,
}
}
-static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer)
+static void dect_ddl_rcv_msg(struct dect_handle *dh, struct dect_data_link *ddl)
{
- struct dect_data_link *ddl = timer->data;
+ struct dect_msg_buf _mb, *mb = &_mb;
+ struct dect_transaction *ta;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cmsg_buf[4 * CMSG_SPACE(16)];
+ uint8_t pd, tv;
+ bool f;
- ddl_debug(ddl, "Page timer");
- if (ddl->page_count++ == DECT_DDL_PAGE_RETRANS_MAX)
- dect_ddl_shutdown(dh, ddl);
- else {
- dect_lce_page(dh, &ddl->ipui);
- dect_start_timer(dh, ddl->page_timer, DECT_DDL_PAGE_TIMEOUT);
+ msg.msg_control = cmsg_buf;
+ msg.msg_controllen = sizeof(cmsg_buf);
+
+ if (dect_mbuf_rcv(ddl->dfd, &msg, mb) < 0) {
+ switch (errno) {
+ case ENOTCONN:
+ if (ddl->state == DECT_DATA_LINK_RELEASE_PENDING)
+ return dect_ddl_release_complete(dh, ddl);
+ else {
+ if (list_empty(&ddl->transactions))
+ return dect_ddl_destroy(dh, ddl);
+ else
+ return dect_ddl_shutdown(dh, ddl);
+ }
+ case ETIMEDOUT:
+ case ECONNRESET:
+ case EHOSTUNREACH:
+ return dect_ddl_shutdown(dh, ddl);
+ default:
+ ddl_debug(ddl, "unhandled receive error: %s",
+ strerror(errno));
+ BUG();
+ }
+ }
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ const struct dect_dl_encrypt *dle;
+
+ if (cmsg->cmsg_level != SOL_DECT)
+ continue;
+
+ switch (cmsg->cmsg_type) {
+ case DECT_DL_ENCRYPT:
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(*dle)))
+ continue;
+ dle = (struct dect_dl_encrypt *)CMSG_DATA(cmsg);
+ dect_ddl_encrypt_ind(dh, ddl, dle->status);
+ continue;
+ default:
+ ddl_debug(ddl, "unhandled cmsg: %u\n", cmsg->cmsg_type);
+ continue;
+ }
}
+
+ dect_mbuf_dump(DECT_DEBUG_LCE, mb, "LCE: RX");
+
+ if (mb->len < DECT_S_HDR_SIZE)
+ return;
+ f = (mb->data[0] & DECT_S_TI_F_FLAG);
+ tv = (mb->data[0] & DECT_S_TI_TV_MASK) >> DECT_S_TI_TV_SHIFT;
+ pd = (mb->data[0] & DECT_S_PD_MASK);
+ mb->type = (mb->data[1] & DECT_S_PD_MSG_TYPE_MASK);
+ dect_mbuf_pull(mb, DECT_S_HDR_SIZE);
+
+ if (pd >= array_size(protocols) || protocols[pd] == NULL) {
+ ddl_debug(ddl, "unknown protocol %u", pd);
+ return;
+ }
+
+ if (tv >= protocols[pd]->max_transactions) {
+ ddl_debug(ddl, "invalid %s transaction value %u\n",
+ protocols[pd]->name, tv);
+ return;
+ }
+
+ if (dect_timer_running(ddl->sdu_timer))
+ dect_ddl_stop_sdu_timer(dh, ddl);
+
+ if (tv == DECT_TV_CONNECTIONLESS)
+ return dect_clss_rcv(dh, mb);
+
+ ta = dect_ddl_transaction_lookup(ddl, pd, tv, !f);
+ if (ta == NULL) {
+ struct dect_transaction req = {
+ .link = ddl,
+ .pd = pd,
+ .role = DECT_TRANSACTION_RESPONDER,
+ .tv = tv,
+ };
+ ddl_debug(ddl, "new transaction: protocol: %s F: %u TV: %u",
+ protocols[pd]->name, f, tv);
+ protocols[pd]->open(dh, &req, mb);
+ } else
+ protocols[pd]->rcv(dh, ta, mb);
}
-/**
- * dect_ddl_establish - Establish an outgoing data link
- *
- */
+static void dect_ddl_complete_direct_establish(struct dect_handle *dh,
+ struct dect_data_link *ddl)
+{
+ struct dect_msg_buf *mb, *mb_next;
+
+ ddl->state = DECT_DATA_LINK_ESTABLISHED;
+ ddl_debug(ddl, "complete direct link establishment");
+
+ /* Send queued messages */
+ list_for_each_entry_safe(mb, mb_next, &ddl->msg_queue, list) {
+ list_del(&mb->list);
+ dect_send(dh, ddl, mb);
+ }
+
+ dect_unregister_fd(dh, ddl->dfd);
+ dect_register_fd(dh, ddl->dfd, DECT_FD_READ);
+}
+
+static void dect_ddl_complete_indirect_establish(struct dect_handle *dh,
+ struct dect_data_link *ddl,
+ struct dect_data_link *req)
+{
+ struct dect_transaction *ta, *ta_next;
+ struct dect_msg_buf *mb, *mb_next;
+
+ /* Stop page timer */
+ dect_stop_timer(dh, req->page_timer);
+ dect_free(dh, req->page_timer);
+
+ ddl_debug(ddl, "complete indirect link establishment req %p", req);
+ ddl->ipui = req->ipui;
+
+ /* Transfer transactions to the new link */
+ list_for_each_entry_safe(ta, ta_next, &req->transactions, list) {
+ ddl_debug(ta->link, "transfer transaction to link %p", ddl);
+ list_move_tail(&ta->list, &ddl->transactions);
+ ta->link = ddl;
+ }
+
+ /* Send queued messages */
+ list_for_each_entry_safe(mb, mb_next, &req->msg_queue, list) {
+ list_del(&mb->list);
+ dect_send(dh, ddl, mb);
+ }
+
+ /* Release pending link */
+ dect_ddl_destroy(dh, req);
+}
+
+static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer);
static void dect_lce_data_link_event(struct dect_handle *dh,
struct dect_fd *dfd, uint32_t events);
+/**
+ * dect_ddl_establish - Establish an outgoing data link
+ */
static struct dect_data_link *dect_ddl_establish(struct dect_handle *dh,
const struct dect_ipui *ipui)
{
@@ -658,53 +641,146 @@ err1:
return NULL;
}
-static void dect_ddl_complete_direct_establish(struct dect_handle *dh,
- struct dect_data_link *ddl)
+struct dect_data_link *dect_ddl_connect(struct dect_handle *dh,
+ const struct dect_ipui *ipui)
{
- struct dect_msg_buf *mb, *mb_next;
+ struct dect_data_link *ddl;
- ddl->state = DECT_DATA_LINK_ESTABLISHED;
- ddl_debug(ddl, "complete direct link establishment");
+ ddl = dect_ddl_get_by_ipui(dh, ipui);
+ if (ddl == NULL)
+ ddl = dect_ddl_establish(dh, ipui);
+ return ddl;
+}
- /* Send queued messages */
- list_for_each_entry_safe(mb, mb_next, &ddl->msg_queue, list) {
- list_del(&mb->list);
- dect_send(dh, ddl, mb);
+static void dect_lce_data_link_event(struct dect_handle *dh,
+ struct dect_fd *dfd, uint32_t events)
+{
+ struct dect_data_link *ddl = dfd->data;
+
+ dect_debug(DECT_DEBUG_LCE, "\n");
+ if (events & DECT_FD_WRITE) {
+ switch (ddl->state) {
+ case DECT_DATA_LINK_ESTABLISH_PENDING:
+ dect_ddl_complete_direct_establish(dh, ddl);
+ break;
+ default:
+ break;
+ }
}
- dect_unregister_fd(dh, ddl->dfd);
- dect_register_fd(dh, ddl->dfd, DECT_FD_READ);
+ if (events & DECT_FD_READ) {
+ dect_ddl_rcv_msg(dh, ddl);
+ }
}
-static void dect_ddl_complete_indirect_establish(struct dect_handle *dh,
- struct dect_data_link *ddl,
- struct dect_data_link *req)
+static void dect_lce_ssap_listener_event(struct dect_handle *dh,
+ struct dect_fd *dfd, uint32_t events)
{
- struct dect_transaction *ta, *ta_next;
- struct dect_msg_buf *mb, *mb_next;
+ struct dect_data_link *ddl;
+ struct dect_fd *nfd;
- /* Stop page timer */
- dect_stop_timer(dh, req->page_timer);
- dect_free(dh, req->page_timer);
+ dect_debug(DECT_DEBUG_LCE, "\n");
+ ddl = dect_ddl_alloc(dh);
+ if (ddl == NULL)
+ goto err1;
- ddl_debug(ddl, "complete indirect link establishment req %p", req);
- ddl->ipui = req->ipui;
+ nfd = dect_accept(dh, dfd, (struct sockaddr *)&ddl->dlei,
+ sizeof(ddl->dlei));
+ if (nfd == NULL)
+ goto err2;
+ ddl->dfd = nfd;
- /* Transfer transactions to the new link */
- list_for_each_entry_safe(ta, ta_next, &req->transactions, list) {
- ddl_debug(ta->link, "transfer transaction to link %p", ddl);
- list_move_tail(&ta->list, &ddl->transactions);
- ta->link = ddl;
- }
+ dect_setup_fd(nfd, dect_lce_data_link_event, ddl);
+ if (dect_register_fd(dh, nfd, DECT_FD_READ) < 0)
+ goto err3;
- /* Send queued messages */
- list_for_each_entry_safe(mb, mb_next, &req->msg_queue, list) {
- list_del(&mb->list);
- dect_send(dh, ddl, mb);
- }
+ ddl->state = DECT_DATA_LINK_ESTABLISHED;
+ if (dect_ddl_schedule_sdu_timer(dh, ddl) < 0)
+ goto err4;
- /* Release pending link */
- dect_ddl_destroy(dh, req);
+ list_add_tail(&ddl->list, &dh->links);
+ ddl_debug(ddl, "new link: PMID: %x LCN: %u LLN: %u SAPI: %u",
+ ddl->dlei.dect_pmid, ddl->dlei.dect_lcn,
+ ddl->dlei.dect_lln, ddl->dlei.dect_sapi);
+ return;
+
+err4:
+ dect_unregister_fd(dh, nfd);
+err3:
+ dect_close(dh, nfd);
+err2:
+ dect_free(dh, ddl);
+err1:
+ lce_debug("dect_lce_ssap_listener_event: %s\n", strerror(errno));
+ return;
+}
+
+/*
+ * Paging
+ */
+
+static int dect_lce_broadcast(const struct dect_handle *dh,
+ const uint8_t *msg, size_t len)
+{
+ ssize_t size;
+
+ dect_hexdump(DECT_DEBUG_LCE, "LCE: BCAST TX", msg, len);
+ size = send(dh->b_sap->fd, msg, len, 0);
+ assert(size == (ssize_t)len);
+ return 0;
+}
+
+/**
+ * Request collective or group ringing
+ *
+ * @param dh libdect DECT handle
+ * @param pattern ring pattern
+ */
+int dect_lce_group_ring_req(struct dect_handle *dh,
+ enum dect_ring_patterns pattern)
+{
+ struct dect_short_page_msg msg;
+ uint16_t page;
+
+ msg.hdr = DECT_LCE_PAGE_W_FLAG;
+ msg.hdr |= DECT_LCE_PAGE_GENERAL_VOICE;
+
+ page = pattern << DECT_LCE_SHORT_PAGE_RING_PATTERN_SHIFT;
+ page = 0;
+ page |= DECT_TPUI_CBI & DECT_LCE_SHORT_PAGE_TPUI_MASK;
+ msg.information = __cpu_to_be16(page);
+
+ return dect_lce_broadcast(dh, &msg.hdr, sizeof(msg));
+}
+EXPORT_SYMBOL(dect_lce_group_ring_req);
+
+static int dect_lce_page(const struct dect_handle *dh,
+ const struct dect_ipui *ipui)
+{
+ struct dect_short_page_msg msg;
+ struct dect_tpui tpui;
+ uint16_t page;
+
+ dect_ipui_to_tpui(&tpui, ipui);
+
+ msg.hdr = DECT_LCE_PAGE_GENERAL_VOICE;
+ page = dect_build_tpui(&tpui) & DECT_LCE_SHORT_PAGE_TPUI_MASK;
+ msg.information = __cpu_to_be16(page);
+
+ return dect_lce_broadcast(dh, &msg.hdr, sizeof(msg));
+}
+
+static void dect_ddl_page_timer(struct dect_handle *dh, struct dect_timer *timer)
+{
+ struct dect_data_link *ddl = timer->data;
+
+ ddl_debug(ddl, "Page timer");
+ if (ddl->page_count++ == DECT_DDL_PAGE_RETRANS_MAX)
+ dect_ddl_shutdown(dh, ddl);
+ else {
+ dect_lce_page(dh, &ddl->ipui);
+ dect_start_timer(dh, ddl->page_timer, DECT_DDL_PAGE_TIMEOUT);
+ }
}
static int dect_lce_send_page_reject(const struct dect_handle *dh,
@@ -793,6 +869,100 @@ static void dect_lce_rcv_page_reject(struct dect_handle *dh,
dect_msg_free(dh, &lce_page_reject_msg_desc, &msg.common);
}
+static void dect_lce_send_page_response(struct dect_handle *dh)
+{
+ struct dect_ie_portable_identity portable_identity;
+ struct dect_ie_fixed_identity fixed_identity;
+ struct dect_lce_page_response_msg msg = {
+ .portable_identity = &portable_identity,
+ .fixed_identity = &fixed_identity,
+ };
+
+ portable_identity.type = DECT_PORTABLE_ID_TYPE_IPUI;
+ portable_identity.ipui = dh->ipui;
+
+ fixed_identity.type = DECT_FIXED_ID_TYPE_PARK;
+ fixed_identity.ari = dh->pari;
+
+ if (dect_open_transaction(dh, &dh->page_transaction, &dh->ipui,
+ DECT_PD_LCE) < 0)
+ return;
+
+ dect_lce_send(dh, &dh->page_transaction, &lce_page_response_msg_desc,
+ &msg.common, DECT_LCE_PAGE_RESPONSE);
+}
+
+static void dect_lce_rcv_short_page(struct dect_handle *dh,
+ struct dect_msg_buf *mb)
+{
+ struct dect_short_page_msg *msg = (void *)mb->data;
+ struct dect_tpui tpui;
+ uint16_t info, t;
+ uint8_t hdr, pattern;
+ bool w;
+
+ w = msg->hdr & DECT_LCE_PAGE_W_FLAG;
+ hdr = msg->hdr & DECT_LCE_PAGE_HDR_MASK;
+ info = __be16_to_cpu(msg->information);
+ lce_debug("short page: w=%u hdr=%u information=%04x\n", w, hdr, info);
+
+ if (hdr == DECT_LCE_PAGE_UNKNOWN_RINGING) {
+ pattern = (info & DECT_LCE_SHORT_PAGE_RING_PATTERN_MASK) >>
+ DECT_LCE_SHORT_PAGE_RING_PATTERN_SHIFT;
+
+ if (w == 0) {
+ /* assigned connectionless group TPUI or CBI */
+ if ((info ^ DECT_TPUI_CBI) &
+ DECT_LCE_SHORT_PAGE_GROUP_MASK)
+ return;
+ } else {
+ /* group mask */
+ return;
+ }
+
+ lce_debug("LCE_GROUP_RING-ind: pattern: %x\n", pattern);
+ dh->ops->lce_ops->lce_group_ring_ind(dh, pattern);
+ } else {
+ if (w == 0) {
+ /* default individual TPUI */
+ dect_ipui_to_tpui(&tpui, &dh->ipui);
+ t = dect_build_tpui(&tpui);
+ if (info != t)
+ return;
+ } else {
+ /* assigned TPUI or CBI */
+ t = dect_build_tpui(&dh->tpui);
+ if (info != t && info != DECT_TPUI_CBI)
+ return;
+ }
+
+ dect_lce_send_page_response(dh);
+ }
+}
+
+static void dect_lce_bsap_event(struct dect_handle *dh, struct dect_fd *dfd,
+ uint32_t events)
+{
+ struct dect_msg_buf _mb, *mb = &_mb;
+ struct msghdr msg;
+
+ dect_debug(DECT_DEBUG_LCE, "\n");
+
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
+ if (dect_mbuf_rcv(dfd, &msg, mb) < 0)
+ return;
+ dect_mbuf_dump(DECT_DEBUG_LCE, mb, "LCE: BCAST RX");
+
+ switch (mb->len) {
+ case 3:
+ return dect_lce_rcv_short_page(dh, mb);
+ default:
+ break;
+ }
+}
+
static void dect_lce_rcv(struct dect_handle *dh, struct dect_transaction *ta,
struct dect_msg_buf *mb)
{
@@ -826,122 +996,9 @@ static const struct dect_nwk_protocol lce_protocol = {
.rcv = dect_lce_rcv,
};
-static void dect_ddl_rcv_msg(struct dect_handle *dh, struct dect_data_link *ddl)
-{
- struct dect_msg_buf _mb, *mb = &_mb;
- struct dect_transaction *ta;
- struct msghdr msg;
- struct cmsghdr *cmsg;
- char cmsg_buf[4 * CMSG_SPACE(16)];
- uint8_t pd, tv;
- bool f;
-
- msg.msg_control = cmsg_buf;
- msg.msg_controllen = sizeof(cmsg_buf);
-
- if (dect_mbuf_rcv(ddl->dfd, &msg, mb) < 0) {
- switch (errno) {
- case ENOTCONN:
- if (ddl->state == DECT_DATA_LINK_RELEASE_PENDING)
- return dect_ddl_release_complete(dh, ddl);
- else {
- if (list_empty(&ddl->transactions))
- return dect_ddl_destroy(dh, ddl);
- else
- return dect_ddl_shutdown(dh, ddl);
- }
- case ETIMEDOUT:
- case ECONNRESET:
- case EHOSTUNREACH:
- return dect_ddl_shutdown(dh, ddl);
- default:
- ddl_debug(ddl, "unhandled receive error: %s",
- strerror(errno));
- BUG();
- }
- }
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- const struct dect_dl_encrypt *dle;
-
- if (cmsg->cmsg_level != SOL_DECT)
- continue;
-
- switch (cmsg->cmsg_type) {
- case DECT_DL_ENCRYPT:
- if (cmsg->cmsg_len < CMSG_LEN(sizeof(*dle)))
- continue;
- dle = (struct dect_dl_encrypt *)CMSG_DATA(cmsg);
- dect_ddl_encrypt_ind(dh, ddl, dle->status);
- continue;
- default:
- ddl_debug(ddl, "unhandled cmsg: %u\n", cmsg->cmsg_type);
- continue;
- }
- }
-
- dect_mbuf_dump(DECT_DEBUG_LCE, mb, "LCE: RX");
-
- if (mb->len < DECT_S_HDR_SIZE)
- return;
- f = (mb->data[0] & DECT_S_TI_F_FLAG);
- tv = (mb->data[0] & DECT_S_TI_TV_MASK) >> DECT_S_TI_TV_SHIFT;
- pd = (mb->data[0] & DECT_S_PD_MASK);
- mb->type = (mb->data[1] & DECT_S_PD_MSG_TYPE_MASK);
- dect_mbuf_pull(mb, DECT_S_HDR_SIZE);
-
- if (pd >= array_size(protocols) || protocols[pd] == NULL) {
- ddl_debug(ddl, "unknown protocol %u", pd);
- return;
- }
-
- if (tv >= protocols[pd]->max_transactions) {
- ddl_debug(ddl, "invalid %s transaction value %u\n",
- protocols[pd]->name, tv);
- return;
- }
-
- if (dect_timer_running(ddl->sdu_timer))
- dect_ddl_stop_sdu_timer(dh, ddl);
-
- if (tv == DECT_TV_CONNECTIONLESS)
- return dect_clss_rcv(dh, mb);
-
- ta = dect_ddl_transaction_lookup(ddl, pd, tv, !f);
- if (ta == NULL) {
- struct dect_transaction req = {
- .link = ddl,
- .pd = pd,
- .role = DECT_TRANSACTION_RESPONDER,
- .tv = tv,
- };
- ddl_debug(ddl, "new transaction: protocol: %s F: %u TV: %u",
- protocols[pd]->name, f, tv);
- protocols[pd]->open(dh, &req, mb);
- } else
- protocols[pd]->rcv(dh, ta, mb);
-}
-
-static void dect_lce_data_link_event(struct dect_handle *dh,
- struct dect_fd *dfd, uint32_t events)
-{
- struct dect_data_link *ddl = dfd->data;
-
- dect_debug(DECT_DEBUG_LCE, "\n");
- if (events & DECT_FD_WRITE) {
- switch (ddl->state) {
- case DECT_DATA_LINK_ESTABLISH_PENDING:
- dect_ddl_complete_direct_establish(dh, ddl);
- break;
- default:
- break;
- }
- }
-
- if (events & DECT_FD_READ) {
- dect_ddl_rcv_msg(dh, ddl);
- }
-}
+/*
+ * Transactions
+ */
static int dect_transaction_alloc_tv(const struct dect_data_link *ddl,
const struct dect_nwk_protocol *protocol)
@@ -977,17 +1034,6 @@ int dect_ddl_open_transaction(struct dect_handle *dh, struct dect_transaction *t
return 0;
}
-struct dect_data_link *dect_ddl_connect(struct dect_handle *dh,
- const struct dect_ipui *ipui)
-{
- struct dect_data_link *ddl;
-
- ddl = dect_ddl_get_by_ipui(dh, ipui);
- if (ddl == NULL)
- ddl = dect_ddl_establish(dh, ipui);
- return ddl;
-}
-
int dect_open_transaction(struct dect_handle *dh, struct dect_transaction *ta,
const struct dect_ipui *ipui, enum dect_pds pd)
{
@@ -1057,48 +1103,6 @@ void dect_transaction_get_ulei(struct sockaddr_dect_lu *addr,
addr->dect_lcn = ddl->dlei.dect_lcn;
}
-static void dect_lce_ssap_listener_event(struct dect_handle *dh,
- struct dect_fd *dfd, uint32_t events)
-{
- struct dect_data_link *ddl;
- struct dect_fd *nfd;
-
- dect_debug(DECT_DEBUG_LCE, "\n");
- ddl = dect_ddl_alloc(dh);
- if (ddl == NULL)
- goto err1;
-
- nfd = dect_accept(dh, dfd, (struct sockaddr *)&ddl->dlei,
- sizeof(ddl->dlei));
- if (nfd == NULL)
- goto err2;
- ddl->dfd = nfd;
-
- dect_setup_fd(nfd, dect_lce_data_link_event, ddl);
- if (dect_register_fd(dh, nfd, DECT_FD_READ) < 0)
- goto err3;
-
- ddl->state = DECT_DATA_LINK_ESTABLISHED;
- if (dect_ddl_schedule_sdu_timer(dh, ddl) < 0)
- goto err4;
-
- list_add_tail(&ddl->list, &dh->links);
- ddl_debug(ddl, "new link: PMID: %x LCN: %u LLN: %u SAPI: %u",
- ddl->dlei.dect_pmid, ddl->dlei.dect_lcn,
- ddl->dlei.dect_lln, ddl->dlei.dect_sapi);
- return;
-
-err4:
- dect_unregister_fd(dh, nfd);
-err3:
- dect_close(dh, nfd);
-err2:
- dect_free(dh, ddl);
-err1:
- lce_debug("dect_lce_ssap_listener_event: %s\n", strerror(errno));
- return;
-}
-
int dect_lce_init(struct dect_handle *dh)
{
struct sockaddr_dect_ssap s_addr;