summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGu Chaojie <chao.jie.gu@intel.com>2014-06-19 10:02:53 +0800
committerGu Chaojie <chao.jie.gu@intel.com>2014-06-19 10:04:08 +0800
commit102bdac3a2c00237fad447e84bf0216abcc09098 (patch)
tree45ac56f8ff3546ab66b1075e35940e24294a47e1
parent4a4f2b45261695f24a2084089cf3ef3841bb7376 (diff)
downloadbluez-102bdac3a2c00237fad447e84bf0216abcc09098.tar.gz
bluez-102bdac3a2c00237fad447e84bf0216abcc09098.tar.bz2
bluez-102bdac3a2c00237fad447e84bf0216abcc09098.zip
add NAP network disconnect signal
Change-Id: Ib869d38a192d9848581940538c91e8ede881d135 Signed-off-by: Gu Chaojie <chao.jie.gu@intel.com>
-rw-r--r--profiles/network/bnep.c5
-rw-r--r--profiles/network/bnep.h2
-rw-r--r--profiles/network/server.c85
3 files changed, 81 insertions, 11 deletions
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 87304c54..a396a6e6 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -668,3 +668,8 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
return BNEP_SUCCESS;
}
+
+int bnep_if_down_wrapper(const char *devname)
+{
+ bnep_if_down(devname);
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index bc43d4fa..245875ff 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -49,3 +49,5 @@ ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
uint16_t *src);
+
+int bnep_if_down_wrapper(const char *devname);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 8a231e45..902783f5 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -84,6 +84,9 @@ struct network_server {
static GSList *adapters = NULL;
static gboolean security = TRUE;
+static gboolean server_disconnected_cb(GIOChannel *chan,
+ GIOCondition cond, gpointer user_data);
+
static struct network_adapter *find_adapter(GSList *list,
struct btd_adapter *adapter)
{
@@ -125,6 +128,20 @@ static struct network_server *find_server_by_uuid(GSList *list,
return NULL;
}
+static struct network_session *find_session(GSList *list, GIOChannel *io)
+{
+ GSList *l;
+
+ for (l = list; l; l = l->next) {
+ struct network_session *session = l->data;
+
+ if (session->io == io)
+ return session;
+ }
+
+ return NULL;
+}
+
static sdp_record_t *server_record_new(const char *name, uint16_t id)
{
sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
@@ -269,19 +286,66 @@ static void setup_destroy(void *user_data)
struct network_adapter *na = user_data;
struct network_session *setup = na->setup;
+ na->setup = NULL;
+
if (!setup)
return;
- na->setup = NULL;
-
session_free(setup);
}
+static gboolean server_disconnected_cb(GIOChannel *chan,
+ GIOCondition cond, gpointer user_data)
+{
+ struct network_server *ns = NULL;
+ struct network_session *session = NULL;
+ char address[20] = {0};
+ GError *gerr = NULL;
+ const char *paddr = address;
+ const char *name_str = NULL;
+
+ if (!user_data)
+ return FALSE;
+
+ ns = (struct network_server *) user_data;
+
+ session = find_session(ns->sessions, chan);
+
+ if (session)
+ name_str = session->dev;
+ else
+ info("Session is not exist!");
+
+ bt_io_get(chan, &gerr, BT_IO_OPT_DEST, &address,
+ BT_IO_OPT_INVALID);
+
+ DBG("send peerdisconnected signal");
+
+ g_dbus_emit_signal(btd_get_dbus_connection(),
+ adapter_get_path(ns->na->adapter),
+ NETWORK_SERVER_INTERFACE, "PeerDisconnected",
+ DBUS_TYPE_STRING, &name_str,
+ DBUS_TYPE_STRING, &paddr,
+ DBUS_TYPE_INVALID);
+
+ if (session) {
+ ns->sessions = g_slist_remove(ns->sessions, session);
+ session_free(session);
+ }
+
+ if (g_slist_length(ns->sessions) == 0 &&
+ name_str != NULL)
+ bnep_if_down_wrapper(name_str);
+
+ return FALSE;
+}
+
static gboolean bnep_setup(GIOChannel *chan,
GIOCondition cond, gpointer user_data)
{
struct network_adapter *na = user_data;
struct network_server *ns;
+ struct network_session *session;
uint8_t packet[BNEP_MTU];
struct bnep_setup_conn_req *req = (void *) packet;
uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
@@ -365,6 +429,10 @@ static gboolean bnep_setup(GIOChannel *chan,
ba2str(&na->setup->dst, paddr);
+ session = g_memdup(na->setup, sizeof(struct network_session));
+
+ ns->sessions = g_slist_append(ns->sessions, session);
+
na->setup = NULL;
DBG("send peerconnected signal");
@@ -377,6 +445,10 @@ static gboolean bnep_setup(GIOChannel *chan,
}
reply:
+ g_io_add_watch_full(chan, G_PRIORITY_DEFAULT,
+ G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ server_disconnected_cb, ns, NULL);
+
bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
return FALSE;
@@ -517,15 +589,6 @@ static void server_remove_sessions(struct network_server *ns)
continue;
bnep_server_delete(ns->bridge, session->dev, &session->dst);
-
- DBG("send peerdisconnected signal");
-
- g_dbus_emit_signal(btd_get_dbus_connection(),
- adapter_get_path(ns->na->adapter),
- NETWORK_SERVER_INTERFACE, "PeerDisconnected",
- DBUS_TYPE_STRING, &session->dev,
- DBUS_TYPE_STRING, &session->dst,
- DBUS_TYPE_INVALID);
}
g_slist_free_full(ns->sessions, session_free);