From: Santiago Carot-Nemesio <sancane@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Santiago Carot-Nemesio <sancane@gmail.com>
Subject: [PATCH 05/25] Save and restore state of MCLs
Date: Fri, 14 May 2010 12:19:32 +0200 [thread overview]
Message-ID: <1273832392-18654-5-git-send-email-sancane@gmail.com> (raw)
In-Reply-To: <1273832392-18654-4-git-send-email-sancane@gmail.com>
---
mcap/mcap.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 154 insertions(+), 4 deletions(-)
diff --git a/mcap/mcap.c b/mcap/mcap.c
index 90c5fa3..f8caa01 100644
--- a/mcap/mcap.c
+++ b/mcap/mcap.c
@@ -34,8 +34,16 @@
#include "mcap_lib.h"
#include "mcap_internal.h"
+#define MAX_CACHED 10 /* 10 devices */
+
#define MCAP_ERROR g_quark_from_static_string("mcap-error-quark")
+#define RELEASE_TIMER(__mcl) do { \
+ g_source_remove(__mcl->tid); \
+ __mcl->tid = 0; \
+} while(0)
+
+
/* MCAP finite state machine functions */
static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
@@ -147,24 +155,166 @@ static struct mcap_mcl *find_mcl(GSList *list, const bdaddr_t *addr)
return NULL;
}
+static void shutdown_mdl(struct mcap_mdl *mdl)
+{
+ mdl->state = MDL_CLOSED;
+
+ g_source_remove(mdl->wid);
+
+ if (mdl->dc) {
+ g_io_channel_shutdown(mdl->dc, TRUE, NULL);
+ g_io_channel_unref(mdl->dc);
+ mdl->dc = NULL;
+ }
+}
+
+static void mcap_free_mdls(struct mcap_mcl *mcl, gboolean save)
+{
+ GSList *l;
+ struct mcap_mdl *mdl;
+
+ if (!mcl->mdls)
+ return;
+
+ for (l = mcl->mdls; l; l = l->next) {
+ mdl = l->data;
+ shutdown_mdl(mdl);
+ if (!save)
+ g_free(mdl);
+ }
+
+ if (!save) {
+ g_slist_free(mcl->mdls);
+ mcl->mdls = NULL;
+ }
+}
+
+static void close_mcl(struct mcap_mcl *mcl, gboolean save)
+{
+ gboolean store = ((!(mcl->ctrl & MCAP_CTRL_FREE)) && save);
+
+ if (mcl->tid) {
+ RELEASE_TIMER(mcl);
+ }
+
+ if (mcl->cc) {
+ g_io_channel_shutdown(mcl->cc, TRUE, NULL);
+ g_io_channel_unref(mcl->cc);
+ mcl->cc = NULL;
+ }
+
+ g_source_remove(mcl->wid);
+ if (mcl->lcmd) {
+ g_free(mcl->lcmd);
+ mcl->lcmd = NULL;
+ }
+
+ if (mcl->priv_data) {
+ g_free(mcl->priv_data);
+ mcl->priv_data = NULL;
+ }
+
+ mcap_free_mdls(mcl, store);
+
+ if (mcl->cb && !store) {
+ g_free(mcl->cb);
+ mcl->cb = NULL;
+ }
+
+ mcl->state = MCL_IDLE;
+
+ if (store)
+ return;
+
+ g_free(mcl);
+}
+
+static void mcap_mcl_shutdown(struct mcap_mcl *mcl)
+{
+ close_mcl(mcl, TRUE);
+}
+
static void mcap_mcl_release(struct mcap_mcl *mcl)
{
- /* TODO */
+ close_mcl(mcl, FALSE);
}
static void mcap_mcl_check_del(struct mcap_mcl *mcl)
{
- /* TODO */
+ if (mcl->ctrl & MCAP_CTRL_CACHED)
+ mcap_mcl_shutdown(mcl);
+ else
+ mcap_mcl_unref(mcl);
}
static void mcap_cache_mcl(struct mcap_mcl *mcl)
{
- /* TODO */
+ GSList *l;
+ struct mcap_mcl *last;
+ int len;
+
+ if (mcl->ctrl & MCAP_CTRL_CACHED)
+ return;
+
+ mcl->ms->mcls = g_slist_remove(mcl->ms->mcls, mcl);
+
+ if ((mcl->ctrl & MCAP_CTRL_NOCACHE) || (mcl->ref < 2)) {
+ mcap_mcl_unref(mcl);
+ return;
+ }
+
+ debug("Caching MCL");
+
+ len = g_slist_length(mcl->ms->cached);
+ if (len == MAX_CACHED) {
+ /* Remove the latest cached mcl */
+ l = g_slist_last(mcl->ms->cached);
+ last = l->data;
+ mcl->ms->cached = g_slist_remove(mcl->ms->cached, last);
+ last->ctrl &= ~MCAP_CTRL_CACHED;
+ if (last->ctrl & MCAP_CTRL_CONN) {
+ /* If connection process is not success this MCL will be
+ * freed next time that close_mcl is invoked */
+ last->ctrl |= MCAP_CTRL_FREE;
+ } else {
+ last->ms->mcl_uncached_cb(last, last->ms->user_data);
+ mcap_mcl_unref(last);
+ }
+ }
+
+ mcl->ms->cached = g_slist_prepend(mcl->ms->cached, mcl);
+ mcl->ctrl |= MCAP_CTRL_CACHED;
+ mcap_mcl_shutdown(mcl);
}
static void mcap_uncache_mcl(struct mcap_mcl *mcl)
{
- /* TODO */
+ if (!(mcl->ctrl & MCAP_CTRL_CACHED))
+ return;
+
+ debug("Got MCL from cache");
+
+ mcl->ms->cached = g_slist_remove(mcl->ms->cached, mcl);
+ mcl->ms->mcls = g_slist_prepend(mcl->ms->mcls, mcl);
+ mcl->ctrl &= ~MCAP_CTRL_CACHED;
+ mcl->ctrl &= ~MCAP_CTRL_FREE;
+}
+
+void mcap_close_mcl(struct mcap_mcl *mcl, gboolean cache)
+{
+ if (!mcl)
+ return;
+
+ if (mcl->cc) {
+ g_io_channel_shutdown(mcl->cc, TRUE, NULL);
+ g_io_channel_unref(mcl->cc);
+ mcl->cc = NULL;
+ }
+
+ mcl->state = MCL_IDLE;
+
+ if (!cache)
+ mcl->ctrl |= MCAP_CTRL_NOCACHE;
}
struct mcap_mcl *mcap_mcl_ref(struct mcap_mcl *mcl)
--
1.6.3.3
next prev parent reply other threads:[~2010-05-14 10:19 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-14 10:19 [PATCH 01/25] Initial support for MCAP Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 02/25] Initial work to create MCAP instances Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 03/25] Initial work to process incomming connection of MCLs Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 04/25] Process events over Control Channels Santiago Carot-Nemesio
2010-05-14 10:19 ` Santiago Carot-Nemesio [this message]
2010-05-14 10:19 ` [PATCH 06/25] Release MCAP instances Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 07/25] Process md_create_mdl_req in CONNECTED state Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 08/25] Process md_reconnect_mdl_req " Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 09/25] Process md_delete_mdl_req " Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 10/25] Process md_abort_mdl_req in PENDING state Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 11/25] Process commands in ACTIVE state Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 12/25] Managing connection of Data Channels Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 13/25] Enable connect operation to a remote MCAP instances Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 14/25] Implement set callbacks operation over MCLs Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 15/25] Implement function to send md_create_mdl_req Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 16/25] Implement function to send md_reconnect_mdl_req Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 17/25] Implement function to send md_delete_mdl_req Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 18/25] Implement function to send md_abort_mdl_req Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 19/25] Process response to std. op. codes Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 20/25] Process md_create_mdl_rsp Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 21/25] Process md_reconnect_mdl_rsp Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 22/25] Process md_abort_mdl_rsp Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 23/25] Process md_delete_mdl_rsp Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 24/25] Enable connection of Data Channel with remote MCAP instances Santiago Carot-Nemesio
2010-05-14 10:19 ` [PATCH 25/25] Initial support for clock synchronization protocol Santiago Carot-Nemesio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1273832392-18654-5-git-send-email-sancane@gmail.com \
--to=sancane@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).