Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH_v2 3/7] profiles/network: Rename common.c|h to bnep.c|h
From: Ravi kumar Veeramally @ 2013-11-28 19:52 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZJVZUjsTpgbAWx7J+gg4OYd4SkzvH+2nLAqaMnH-rm49Q@mail.gmail.com>

Hi Luiz,

On 28.11.2013 18:19, Luiz Augusto von Dentz wrote:
> Hi Ravi,
>
> On Thu, Nov 28, 2013 at 4:45 PM, Ravi kumar Veeramally
> <ravikumar.veeramally@linux.intel.com> wrote:
>> Files common.c|h contains only bnep related code, it makes
>> more sence with bnep.c|h.
>> ---
>>   Makefile.plugins              |   2 +-
>>   profiles/network/bnep.c       | 453 ++++++++++++++++++++++++++++++++++++++++++
>>   profiles/network/bnep.h       |  42 ++++
>>   profiles/network/common.c     | 453 ------------------------------------------
>>   profiles/network/common.h     |  42 ----
>>   profiles/network/connection.c |   2 +-
>>   profiles/network/manager.c    |   2 +-
>>   profiles/network/server.c     |   2 +-
>>   8 files changed, 499 insertions(+), 499 deletions(-)
>>   create mode 100644 profiles/network/bnep.c
>>   create mode 100644 profiles/network/bnep.h
>>   delete mode 100644 profiles/network/common.c
>>   delete mode 100644 profiles/network/common.h
> Did you use git mv? I would expect something like the following if did:
  Yes, I did git mv.
   reason might be bnep.c has it's own include file bnep.h.
   So bnpe.c is 99% bnep.h 100%.

> ---
>   profiles/network/{common.c => bnep.c} | 0
>   profiles/network/{common.h => bnep.h} | 0
>   2 files changed, 0 insertions(+), 0 deletions(-)
>   rename profiles/network/{common.c => bnep.c} (100%)
>   rename profiles/network/{common.h => bnep.h} (100%)
>
> diff --git a/profiles/network/common.c b/profiles/network/bnep.c
> similarity index 100%
> rename from profiles/network/common.c
> rename to profiles/network/bnep.c
> diff --git a/profiles/network/common.h b/profiles/network/bnep.h
> similarity index 100%
> rename from profiles/network/common.h
> rename to profiles/network/bnep.h
> --
  Have you tried to compile after it?

Thanks,
Ravi.

^ permalink raw reply

* Re: SM: is BlueZ the Master/Initiator or Slave/Responder?
From: Vinicius Costa Gomes @ 2013-11-28 16:59 UTC (permalink / raw)
  To: Scott James Remnant
  Cc: linux-bluetooth@vger.kernel.org, Holtmann, Marcel, Johan Hedberg,
	Brian Gix
In-Reply-To: <CAHZ1yC=Tx=4zRL_rV0-b-sqhQCO=AmXzCy93Q5jnb2=z2Kr6KQ@mail.gmail.com>

Hi Scott,

On 13:17 Mon 25 Nov, Scott James Remnant wrote:
> We are able to pass all qualification tests with BlueZ as the Master except one:
> 
>   TP/KDU/BV-06-C - Master Key Distribution - Encryption Key bit
> 
> This test requires that BlueZ initiates pairing with the
> SMP_DIST_ENC_KEY bit set in the init_key_dist member of struct
> smp_cmd_pairing - however this member is always initialized to zero
> and never changed.

This test is in theory correct, but it doesn't test anything that does make
sense at this point. Let me try to explain, setting the Encryption Key bit in
the initiator key distribution field in the Pairing Request means that the
Initiator wants to send its Encryption Key to the Responder.

This is only useful in cases that both devices expect the roles to be reversed
in future connections (The Master of this connection would become the Slave in
future connections). And IIRC we weren't able to test this role reversal and
it even offends the current GAP spec for Dual mode devices.

> 
> This seems to have changed at some point in the past, 2b64d153 added
> MITM mechanism and changed the init_key_dist member initialization
> from dist_keys to 0
> 
> 
> So two questions:
> 
>  1) should BlueZ be able to behave as Master? It passes the majority
> of the tests except this one.

BlueZ should be able to bahave as Master, if not, it is a bug.

> 
>  2) given the above, is this a bug that init_key_dist is 0 or is it a
> test plan error that it requires this?

I think it is a bit of both, for the current situation the Master distributing
its keys doesn't make much sense and we should be able to change this value to
be able to test the key distribution parts.

What I suggest is adding a debugfs entry to change the value of init_key_dist
for Pairing Requests, and keep the default being 0.

(disclaimer: I am follwing development from the sidelines for some time, so
feel free to correct me.)

> 
> Scott
> -- 
> Scott James Remnant | Chrome OS Systems | keybuk@google.com | Google
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Cheers,
-- 
Vinicius

^ permalink raw reply

* Re: [PATCH_v2 3/7] profiles/network: Rename common.c|h to bnep.c|h
From: Luiz Augusto von Dentz @ 2013-11-28 16:19 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1385649955-29276-4-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Thu, Nov 28, 2013 at 4:45 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> Files common.c|h contains only bnep related code, it makes
> more sence with bnep.c|h.
> ---
>  Makefile.plugins              |   2 +-
>  profiles/network/bnep.c       | 453 ++++++++++++++++++++++++++++++++++++++++++
>  profiles/network/bnep.h       |  42 ++++
>  profiles/network/common.c     | 453 ------------------------------------------
>  profiles/network/common.h     |  42 ----
>  profiles/network/connection.c |   2 +-
>  profiles/network/manager.c    |   2 +-
>  profiles/network/server.c     |   2 +-
>  8 files changed, 499 insertions(+), 499 deletions(-)
>  create mode 100644 profiles/network/bnep.c
>  create mode 100644 profiles/network/bnep.h
>  delete mode 100644 profiles/network/common.c
>  delete mode 100644 profiles/network/common.h

Did you use git mv? I would expect something like the following if did:

---
 profiles/network/{common.c => bnep.c} | 0
 profiles/network/{common.h => bnep.h} | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename profiles/network/{common.c => bnep.c} (100%)
 rename profiles/network/{common.h => bnep.h} (100%)

diff --git a/profiles/network/common.c b/profiles/network/bnep.c
similarity index 100%
rename from profiles/network/common.c
rename to profiles/network/bnep.c
diff --git a/profiles/network/common.h b/profiles/network/bnep.h
similarity index 100%
rename from profiles/network/common.h
rename to profiles/network/bnep.h

^ permalink raw reply

* Re: [PATCH_v2 1/7] profiles/network: Remove redundant code for bnep interface name
From: Luiz Augusto von Dentz @ 2013-11-28 16:12 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Ravi kumar Veeramally, BlueZ development
In-Reply-To: <CAJdJm_Marb2+Q4e=zLeHq9Qf4a=o4z3-Q55mpL0bDWq3h1-s_Q@mail.gmail.com>

Hi,

On Thu, Nov 28, 2013 at 5:52 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi Ravi,
>
> On Thu, Nov 28, 2013 at 10:45 AM, Ravi kumar Veeramally
> <ravikumar.veeramally@linux.intel.com> wrote:
>> Remove redundant code for copying bnepX interface name from connection
>> and server files. It is better to place on actual function call.
>> ---
>>  profiles/network/common.c     | 3 +--
>>  profiles/network/connection.c | 2 --
>>  profiles/network/server.c     | 3 ---
>>  3 files changed, 1 insertion(+), 7 deletions(-)
>>
>> diff --git a/profiles/network/common.c b/profiles/network/common.c
>> index 0b291bd..b94b3a5 100644
>> --- a/profiles/network/common.c
>> +++ b/profiles/network/common.c
>> @@ -150,8 +150,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
>>         struct bnep_connadd_req req;
>>
>>         memset(&req, 0, sizeof(req));
>> -       strncpy(req.device, dev, 16);
>> -       req.device[15] = '\0';
>> +       strcpy(req.device, "bnep%d");
>>         req.sock = sk;
>>         req.role = role;
>>         if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
>> diff --git a/profiles/network/connection.c b/profiles/network/connection.c
>> index 5966268..301f66d 100644
>> --- a/profiles/network/connection.c
>> +++ b/profiles/network/connection.c
>> @@ -692,8 +692,6 @@ int connection_register(struct btd_service *service)
>>
>>         nc = g_new0(struct network_conn, 1);
>>         nc->id = id;
>> -       memset(nc->dev, 0, sizeof(nc->dev));
>> -       strcpy(nc->dev, "bnep%d");
>>         nc->service = btd_service_ref(service);
>>         nc->state = DISCONNECTED;
>>         nc->peer = peer;
>> diff --git a/profiles/network/server.c b/profiles/network/server.c
>> index 0050b30..3a7e52a 100644
>> --- a/profiles/network/server.c
>> +++ b/profiles/network/server.c
>> @@ -269,9 +269,6 @@ static int server_connadd(struct network_server *ns,
>>         char devname[16];
>>         int err, nsk;
>>
>> -       memset(devname, 0, sizeof(devname));
>> -       strcpy(devname, "bnep%d");
>> -
>>         nsk = g_io_channel_unix_get_fd(session->io);
>>         err = bnep_connadd(nsk, dst_role, devname);
>
> You are still passing a (now uninitialized) devname pointer to
> bnep_connadd(). Is this still necessary?

Well either bnep_connadd has to return the interface name or we should
pass as reference so it get initialized inside bnep_connadd in case of
success.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 01/10] android: Initialize IPC with command and notification sockets
From: Luiz Augusto von Dentz @ 2013-11-28 16:06 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1385648130-12808-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Thu, Nov 28, 2013 at 4:15 PM, Szymon Janc <szymon.janc@tieto.com> wrote:
> Pass sockets after succesfully connected to HAL. This will allow
> to improve IPC helpers API.
> ---
>  android/ipc.c  | 15 +++++++++++++++
>  android/ipc.h  |  3 +++
>  android/main.c |  5 +++++
>  3 files changed, 23 insertions(+)
>
> diff --git a/android/ipc.c b/android/ipc.c
> index 25c36fd..028d4ad 100644
> --- a/android/ipc.c
> +++ b/android/ipc.c
> @@ -36,6 +36,21 @@
>  #include "ipc.h"
>  #include "log.h"
>
> +static int cmd_sk = -1;
> +static int notif_sk = -1;
> +
> +void ipc_init(int command_sk, int notification_sk)
> +{
> +       cmd_sk = command_sk;
> +       notif_sk = notification_sk;
> +}
> +
> +void ipc_cleanup(void)
> +{
> +       cmd_sk = -1;
> +       notif_sk = -1;
> +}
> +
>  void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
>                                                         void *param, int fd)
>  {
> diff --git a/android/ipc.h b/android/ipc.h
> index ad4a2d2..5786d2d 100644
> --- a/android/ipc.h
> +++ b/android/ipc.h
> @@ -21,6 +21,9 @@
>   *
>   */
>
> +void ipc_init(int command_sk, int notification_sk);
> +void ipc_cleanup(void);
> +
>  void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
>                                                         void *param, int fd);
>  void ipc_send_rsp(int sk, uint8_t service_id, uint8_t opcode, uint8_t status);
> diff --git a/android/main.c b/android/main.c
> index bfd2a87..4e6ad38 100644
> --- a/android/main.c
> +++ b/android/main.c
> @@ -354,6 +354,9 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
>
>         g_io_add_watch(hal_cmd_io, cond, cmd_watch_cb, NULL);
>
> +       ipc_init(g_io_channel_unix_get_fd(hal_cmd_io),
> +                               g_io_channel_unix_get_fd(hal_notif_io));
> +
>         info("Successfully connected to HAL");
>
>         return FALSE;
> @@ -494,6 +497,8 @@ static void cleanup_hal_connection(void)
>                 g_io_channel_unref(hal_notif_io);
>                 hal_notif_io = NULL;
>         }
> +
> +       ipc_cleanup();
>  }
>
>  static bool set_capabilities(void)
> --
> 1.8.3.2

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH_v2 1/7] profiles/network: Remove redundant code for bnep interface name
From: Anderson Lizardo @ 2013-11-28 15:52 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: BlueZ development
In-Reply-To: <1385649955-29276-2-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Thu, Nov 28, 2013 at 10:45 AM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> Remove redundant code for copying bnepX interface name from connection
> and server files. It is better to place on actual function call.
> ---
>  profiles/network/common.c     | 3 +--
>  profiles/network/connection.c | 2 --
>  profiles/network/server.c     | 3 ---
>  3 files changed, 1 insertion(+), 7 deletions(-)
>
> diff --git a/profiles/network/common.c b/profiles/network/common.c
> index 0b291bd..b94b3a5 100644
> --- a/profiles/network/common.c
> +++ b/profiles/network/common.c
> @@ -150,8 +150,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
>         struct bnep_connadd_req req;
>
>         memset(&req, 0, sizeof(req));
> -       strncpy(req.device, dev, 16);
> -       req.device[15] = '\0';
> +       strcpy(req.device, "bnep%d");
>         req.sock = sk;
>         req.role = role;
>         if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
> diff --git a/profiles/network/connection.c b/profiles/network/connection.c
> index 5966268..301f66d 100644
> --- a/profiles/network/connection.c
> +++ b/profiles/network/connection.c
> @@ -692,8 +692,6 @@ int connection_register(struct btd_service *service)
>
>         nc = g_new0(struct network_conn, 1);
>         nc->id = id;
> -       memset(nc->dev, 0, sizeof(nc->dev));
> -       strcpy(nc->dev, "bnep%d");
>         nc->service = btd_service_ref(service);
>         nc->state = DISCONNECTED;
>         nc->peer = peer;
> diff --git a/profiles/network/server.c b/profiles/network/server.c
> index 0050b30..3a7e52a 100644
> --- a/profiles/network/server.c
> +++ b/profiles/network/server.c
> @@ -269,9 +269,6 @@ static int server_connadd(struct network_server *ns,
>         char devname[16];
>         int err, nsk;
>
> -       memset(devname, 0, sizeof(devname));
> -       strcpy(devname, "bnep%d");
> -
>         nsk = g_io_channel_unix_get_fd(session->io);
>         err = bnep_connadd(nsk, dst_role, devname);

You are still passing a (now uninitialized) devname pointer to
bnep_connadd(). Is this still necessary?

Best Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH 1/2] android/pics: Add PTS PICS for PBAP
From: Johan Hedberg @ 2013-11-28 14:48 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1385647052-26572-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Thu, Nov 28, 2013, Jakub Tyszkowski wrote:
> PTS PICS for PBAP, targeting Android 4.4.
> 
> ---
>  android/Makefile.am   |   2 +-
>  android/pics-pbap.txt | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 442 insertions(+), 1 deletion(-)
>  create mode 100644 android/pics-pbap.txt

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH_v2 7/7] android: Add reasons for adding capabilites to process
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

CAP_NET_ADMIN: Allow use of MGMT interface
CAP_NET_BIND_SERVICE: Allow use of privileged PSM
CAP_NET_RAW: Allow use of bnep ioctl calls
---
 android/main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/main.c b/android/main.c
index bfd2a87..803d7a8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -505,6 +505,9 @@ static bool set_capabilities(void)
 	header.version = _LINUX_CAPABILITY_VERSION;
 	header.pid = 0;
 
+	/* CAP_NET_ADMIN: Allow use of MGMT interface
+	 * CAP_NET_BIND_SERVICE: Allow use of privileged PSM
+	 * CAP_NET_RAW: Allow use of bnep ioctl calls */
 	cap.effective = cap.permitted =
 		CAP_TO_MASK(CAP_NET_RAW) |
 		CAP_TO_MASK(CAP_NET_ADMIN) |
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 6/7] android/pan: Implement the get local role method in daemon
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Returns local role of the device (NONE, PANU or NAP).
---
 android/pan.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 7524dae..ede9d4a 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -276,11 +276,17 @@ static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
+static uint8_t bt_pan_get_role(int sk, void *cmd, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hal_rsp_pan_get_role rsp;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	rsp.local_role = local_role;
+	ipc_send(sk, HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, sizeof(rsp),
+								&rsp, -1);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
@@ -292,7 +298,7 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 		status = bt_pan_enable(buf, len);
 		break;
 	case HAL_OP_PAN_GET_ROLE:
-		status = bt_pan_get_role(buf, len);
+		status = bt_pan_get_role(sk, buf, len);
 		break;
 	case HAL_OP_PAN_CONNECT:
 		status = bt_pan_connect(buf, len);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 5/7] android/pan: Implement pan disconnect method in daemon
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Disconnect ongoing PANU role connection betweek devices, free
the device and notify the connection state.
---
 android/pan.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 058ce70..7524dae 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -238,9 +238,35 @@ static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
 static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct network_peer *np;
+	GSList *l;
+	bdaddr_t dst;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(peers, &dst, peer_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	np = l->data;
+
+	if (np->watch) {
+		g_source_remove(np->watch);
+		np->watch = 0;
+	}
+
+	bnep_if_down(np->dev);
+	bnep_kill_connection(&dst);
+
+	bt_pan_notify_conn_state(np, HAL_PAN_STATE_DISCONNECTED);
+	network_peer_free(np);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 4/7] android/pan: Implement pan connect method in daemon
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Implements the PAN connect method in android daemon with PANU role
only. Setting up the bnep environment, adds connection and makes
bnep interface up are part of bnep_connect call. Notifies bnep
interface on control state call back and connection status on
connection state call back.
---
 android/Android.mk  |   2 +
 android/Makefile.am |   3 +-
 android/pan.c       | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 213 insertions(+), 8 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index c4d722d..549613c 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \
 	../lib/hci.c \
 	../btio/btio.c \
 	../src/sdp-client.c \
+	../profiles/network/bnep.c \
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib) \
@@ -66,6 +67,7 @@ lib_headers := \
 	sdp.h \
 	rfcomm.h \
 	sco.h \
+	bnep.h \
 
 $(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
 
diff --git a/android/Makefile.am b/android/Makefile.am
index 38aa00a..ea8cb5b 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -24,7 +24,8 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/socket.h android/socket.c \
 				android/pan.h android/pan.c \
 				btio/btio.h btio/btio.c \
-				src/sdp-client.h src/sdp-client.c
+				src/sdp-client.h src/sdp-client.c \
+				profiles/network/bnep.h profiles/network/bnep.c
 
 android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
diff --git a/android/pan.c b/android/pan.c
index ada458a..058ce70 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -29,37 +29,228 @@
 #include <fcntl.h>
 #include <glib.h>
 
+#include "btio/btio.h"
 #include "lib/bluetooth.h"
+#include "lib/bnep.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "src/glib-helper.h"
+#include "profiles/network/bnep.h"
+
 #include "log.h"
 #include "pan.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "utils.h"
+#include "bluetooth.h"
 
+static bdaddr_t adapter_addr;
 static int notification_sk = -1;
+GSList *peers = NULL;
+uint8_t local_role = HAL_PAN_ROLE_NONE;
 
-static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
+struct network_peer {
+	char		dev[16];
+	bdaddr_t	dst;
+	uint8_t		conn_state;
+	uint8_t		role;
+	GIOChannel	*io;
+	guint		watch;
+};
+
+static int peer_cmp(gconstpointer s, gconstpointer user_data)
 {
-	DBG("Not Implemented");
+	const struct network_peer *np = s;
+	const bdaddr_t *dst = user_data;
 
-	return HAL_STATUS_FAILED;
+	return bacmp(&np->dst, dst);
 }
 
-static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
+static void network_peer_free(struct network_peer *np)
+{
+	local_role = HAL_PAN_ROLE_NONE;
+
+	if (np->watch > 0) {
+		g_source_remove(np->watch);
+		np->watch = 0;
+	}
+
+	if (np->io) {
+		g_io_channel_unref(np->io);
+		np->io = NULL;
+	}
+
+	peers = g_slist_remove(peers, np);
+	g_free(np);
+	np = NULL;
+}
+
+static void bt_pan_notify_conn_state(struct network_peer *np, uint8_t state)
+{
+	struct hal_ev_pan_conn_state ev;
+	char addr[18];
+
+	if (np->conn_state == state)
+		return;
+
+	np->conn_state = state;
+	ba2str(&np->dst, addr);
+	DBG("device %s state %u", addr, state);
+
+	bdaddr2android(&np->dst, ev.bdaddr);
+	ev.state = state;
+	ev.local_role = local_role;
+	ev.remote_role = np->role;
+	ev.status = HAL_STATUS_SUCCESS;
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE,
+							sizeof(ev), &ev, -1);
+}
+
+static void bt_pan_notify_ctrl_state(struct network_peer *np, uint8_t state)
+{
+	struct hal_ev_pan_ctrl_state ev;
+
+	DBG("");
+
+	ev.state = state;
+	ev.local_role = local_role;
+	ev.status = HAL_STATUS_SUCCESS;
+	memcpy(ev.name, np->dev, sizeof(np->dev));
+
+	ipc_send(notification_sk, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE,
+							sizeof(ev), &ev, -1);
+}
+
+static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct network_peer *np = data;
+
+	DBG("%s disconnected", np->dev);
+
+	bt_pan_notify_conn_state(np, HAL_PAN_STATE_DISCONNECTED);
+	network_peer_free(np);
+
+	return FALSE;
+}
+
+static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+{
+	struct network_peer *np = data;
+
+	DBG("");
+
+	if (err < 0) {
+		error("bnep connect req failed: %s", strerror(-err));
+		bt_pan_notify_conn_state(np, HAL_PAN_STATE_DISCONNECTED);
+		network_peer_free(np);
+		return;
+	}
+
+	memcpy(np->dev, iface, sizeof(np->dev));
+
+	DBG("%s connected", np->dev);
+
+	bt_pan_notify_ctrl_state(np, HAL_PAN_CTRL_ENABLED);
+	bt_pan_notify_conn_state(np, HAL_PAN_STATE_CONNECTED);
+
+	np->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_watchdog_cb, np);
+	g_io_channel_unref(np->io);
+	np->io = NULL;
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
+{
+	struct network_peer *np = data;
+	uint16_t src, dst;
+	int perr;
+
+	DBG("");
+
+	if (err) {
+		error("%s", err->message);
+		bt_pan_notify_conn_state(np, HAL_PAN_STATE_DISCONNECTED);
+		network_peer_free(np);
+	}
+
+	src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+	dst = (np->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+
+	perr = bnep_connect(np->io, src, dst, bnep_conn_cb, np);
+	if (perr < 0) {
+		error("bnep connect req failed: %s", strerror(-perr));
+		bt_pan_notify_conn_state(np, HAL_PAN_STATE_DISCONNECTED);
+		network_peer_free(np);
+		return;
+	}
+}
+
+static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
+{
+	struct network_peer *np;
+	bdaddr_t dst;
+	char addr[18];
+	GSList *l;
+	GError *gerr = NULL;
+
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(peers, &dst, peer_cmp);
+	if (l)
+		return HAL_STATUS_FAILED;
+
+	np = g_new0(struct network_peer, 1);
+	bacpy(&np->dst, &dst);
+	local_role = cmd->local_role;
+	np->role = cmd->remote_role;
+
+	ba2str(&np->dst, addr);
+	DBG("connecting to %s %s", addr, np->dev);
+
+	np->io = bt_io_connect(connect_cb, np, NULL, &gerr,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_DEST_BDADDR, &np->dst,
+					BT_IO_OPT_PSM, BNEP_PSM,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_OMTU, BNEP_MTU,
+					BT_IO_OPT_IMTU, BNEP_MTU,
+					BT_IO_OPT_INVALID);
+	if (!np->io) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		g_free(np);
+		return HAL_STATUS_FAILED;
+	}
+
+	peers = g_slist_append(peers, np);
+	bt_pan_notify_conn_state(np, HAL_PAN_STATE_CONNECTING);
+
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
+static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
-								uint16_t len)
+static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
@@ -93,11 +284,21 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 
 bool bt_pan_register(int sk, const bdaddr_t *addr)
 {
+	int err;
+
 	DBG("");
 
 	if (notification_sk >= 0)
 		return false;
 
+	bacpy(&adapter_addr, addr);
+
+	err = bnep_init();
+	if (err) {
+		error("bnep init failed");
+		return false;
+	}
+
 	notification_sk = sk;
 
 	return true;
@@ -111,4 +312,5 @@ void bt_pan_unregister(void)
 		return;
 
 	notification_sk = -1;
+	bnep_cleanup();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 3/7] profiles/network: Rename common.c|h to bnep.c|h
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Files common.c|h contains only bnep related code, it makes
more sence with bnep.c|h.
---
 Makefile.plugins              |   2 +-
 profiles/network/bnep.c       | 453 ++++++++++++++++++++++++++++++++++++++++++
 profiles/network/bnep.h       |  42 ++++
 profiles/network/common.c     | 453 ------------------------------------------
 profiles/network/common.h     |  42 ----
 profiles/network/connection.c |   2 +-
 profiles/network/manager.c    |   2 +-
 profiles/network/server.c     |   2 +-
 8 files changed, 499 insertions(+), 499 deletions(-)
 create mode 100644 profiles/network/bnep.c
 create mode 100644 profiles/network/bnep.h
 delete mode 100644 profiles/network/common.c
 delete mode 100644 profiles/network/common.h

diff --git a/Makefile.plugins b/Makefile.plugins
index f5025e9..6a1ddbf 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -47,7 +47,7 @@ builtin_sources += profiles/audio/control.h profiles/audio/control.c \
 
 builtin_modules += network
 builtin_sources += profiles/network/manager.c \
-			profiles/network/common.h profiles/network/common.c \
+			profiles/network/bnep.h profiles/network/bnep.c \
 			profiles/network/server.h profiles/network/server.c \
 			profiles/network/connection.h \
 			profiles/network/connection.c
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
new file mode 100644
index 0000000..946ae52
--- /dev/null
+++ b/profiles/network/bnep.c
@@ -0,0 +1,453 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/bnep.h>
+
+#include <glib.h>
+
+#include "log.h"
+#include "bnep.h"
+#include "lib/uuid.h"
+
+#define CON_SETUP_RETRIES      3
+#define CON_SETUP_TO           9
+
+static int ctl;
+
+static struct {
+	const char	*name;		/* Friendly name */
+	const char	*uuid128;	/* UUID 128 */
+	uint16_t	id;		/* Service class identifier */
+} __svc[] = {
+	{ "panu",	PANU_UUID,	BNEP_SVC_PANU	},
+	{ "gn",		GN_UUID,	BNEP_SVC_GN	},
+	{ "nap",	NAP_UUID,	BNEP_SVC_NAP	},
+	{ NULL }
+};
+
+struct __service_16 {
+	uint16_t dst;
+	uint16_t src;
+} __attribute__ ((packed));
+
+struct bnep_conn {
+	GIOChannel	*io;
+	uint16_t	src;
+	uint16_t	dst;
+	guint	attempts;
+	guint	setup_to;
+	void	*data;
+	bnep_connect_cb	conn_cb;
+};
+
+uint16_t bnep_service_id(const char *svc)
+{
+	int i;
+	uint16_t id;
+
+	/* Friendly service name */
+	for (i = 0; __svc[i].name; i++) {
+		if (!strcasecmp(svc, __svc[i].name))
+			return __svc[i].id;
+	}
+
+	/* UUID 128 string */
+	for (i = 0; __svc[i].uuid128; i++) {
+		if (!strcasecmp(svc, __svc[i].uuid128))
+			return __svc[i].id;
+	}
+
+	/* Try convert to HEX */
+	id = strtol(svc, NULL, 16);
+	if ((id < BNEP_SVC_PANU) || (id > BNEP_SVC_GN))
+		return 0;
+
+	return id;
+}
+
+const char *bnep_uuid(uint16_t id)
+{
+	int i;
+
+	for (i = 0; __svc[i].uuid128; i++)
+		if (__svc[i].id == id)
+			return __svc[i].uuid128;
+	return NULL;
+}
+
+const char *bnep_name(uint16_t id)
+{
+	int i;
+
+	for (i = 0; __svc[i].name; i++)
+		if (__svc[i].id == id)
+			return __svc[i].name;
+	return NULL;
+}
+
+int bnep_init(void)
+{
+	ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP);
+
+	if (ctl < 0) {
+		int err = -errno;
+
+		if (err == -EPROTONOSUPPORT)
+			warn("kernel lacks bnep-protocol support");
+		else
+			error("Failed to open control socket: %s (%d)",
+						strerror(-err), -err);
+
+		return err;
+	}
+
+	return 0;
+}
+
+int bnep_cleanup(void)
+{
+	close(ctl);
+	return 0;
+}
+
+int bnep_kill_connection(const bdaddr_t *dst)
+{
+	struct bnep_conndel_req req;
+
+	memset(&req, 0, sizeof(req));
+	baswap((bdaddr_t *)&req.dst, dst);
+	req.flags = 0;
+	if (ioctl(ctl, BNEPCONNDEL, &req)) {
+		int err = -errno;
+		error("Failed to kill connection: %s (%d)",
+						strerror(-err), -err);
+		return err;
+	}
+	return 0;
+}
+
+int bnep_connadd(int sk, uint16_t role, char *dev)
+{
+	struct bnep_connadd_req req;
+
+	memset(&req, 0, sizeof(req));
+	strcpy(req.device, "bnep%d");
+	req.sock = sk;
+	req.role = role;
+	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
+		int err = -errno;
+		error("Failed to add device %s: %s(%d)",
+				dev, strerror(-err), -err);
+		return err;
+	}
+
+	strncpy(dev, req.device, 16);
+	return 0;
+}
+
+int bnep_if_up(const char *devname)
+{
+	struct ifreq ifr;
+	int sk, err;
+
+	sk = socket(AF_INET, SOCK_DGRAM, 0);
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
+
+	ifr.ifr_flags |= IFF_UP;
+	ifr.ifr_flags |= IFF_MULTICAST;
+
+	err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+
+	close(sk);
+
+	if (err < 0) {
+		error("Could not bring up %s", devname);
+		return err;
+	}
+
+	return 0;
+}
+
+int bnep_if_down(const char *devname)
+{
+	struct ifreq ifr;
+	int sk, err;
+
+	sk = socket(AF_INET, SOCK_DGRAM, 0);
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
+
+	ifr.ifr_flags &= ~IFF_UP;
+
+	/* Bring down the interface */
+	err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+
+	close(sk);
+
+	if (err < 0) {
+		error("Could not bring down %s", devname);
+		return err;
+	}
+
+	return 0;
+}
+
+static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct bnep_conn *bc = data;
+	struct bnep_control_rsp *rsp;
+	struct timeval timeo;
+	char pkt[BNEP_MTU];
+	char iface[16];
+	ssize_t r;
+	int sk;
+
+	if (cond & G_IO_NVAL)
+		goto failed;
+
+	if (bc->setup_to > 0) {
+		g_source_remove(bc->setup_to);
+		bc->setup_to = 0;
+	}
+
+	if (cond & (G_IO_HUP | G_IO_ERR)) {
+		error("Hangup or error on l2cap server socket");
+		goto failed;
+	}
+
+	sk = g_io_channel_unix_get_fd(chan);
+	memset(pkt, 0, BNEP_MTU);
+	r = read(sk, pkt, sizeof(pkt) - 1);
+	if (r < 0) {
+		error("IO Channel read error");
+		goto failed;
+	}
+
+	if (r == 0) {
+		error("No packet received on l2cap socket");
+		goto failed;
+	}
+
+	errno = EPROTO;
+
+	if ((size_t) r < sizeof(*rsp)) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	rsp = (void *) pkt;
+	if (rsp->type != BNEP_CONTROL) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
+		return TRUE;
+
+	r = ntohs(rsp->resp);
+	if (r != BNEP_SUCCESS) {
+		error("bnep failed");
+		goto failed;
+	}
+
+	memset(&timeo, 0, sizeof(timeo));
+	timeo.tv_sec = 0;
+	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+
+	sk = g_io_channel_unix_get_fd(bc->io);
+	if (bnep_connadd(sk, bc->src, iface)) {
+		error("bnep conn could not be added");
+		goto failed;
+	}
+
+	if (bnep_if_up(iface)) {
+		error("could not up %s", iface);
+		goto failed;
+	}
+
+	bc->conn_cb(chan, iface, 0, bc->data);
+	g_free(bc);
+
+	return FALSE;
+
+failed:
+	bc->conn_cb(NULL, NULL, -EIO, bc->data);
+	g_free(bc);
+
+	return FALSE;
+}
+
+
+static int bnep_setup_conn_req(struct bnep_conn *bc)
+{
+	struct bnep_setup_conn_req *req;
+	struct __service_16 *s;
+	unsigned char pkt[BNEP_MTU];
+	int fd;
+
+	/* Send request */
+	req = (void *) pkt;
+	req->type = BNEP_CONTROL;
+	req->ctrl = BNEP_SETUP_CONN_REQ;
+	req->uuid_size = 2;     /* 16bit UUID */
+	s = (void *) req->service;
+	s->src = htons(bc->src);
+	s->dst = htons(bc->dst);
+
+	fd = g_io_channel_unix_get_fd(bc->io);
+	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
+		error("bnep connection req send failed: %s", strerror(errno));
+		return -errno;
+	}
+
+	bc->attempts++;
+
+	return 0;
+}
+
+static gboolean bnep_conn_req_to(gpointer user_data)
+{
+	struct bnep_conn *bc = user_data;
+
+	if (bc->attempts == CON_SETUP_RETRIES) {
+		error("Too many bnep connection attempts");
+	} else {
+		error("bnep connection setup TO, retrying...");
+		if (bnep_setup_conn_req(bc) == 0)
+			return TRUE;
+	}
+
+	bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
+	g_free(bc);
+
+	return FALSE;
+}
+
+int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
+					bnep_connect_cb conn_cb, void *data)
+{
+	struct bnep_conn *bc;
+	int err;
+
+	if (!io || !conn_cb)
+		return -EINVAL;
+
+	bc = g_new0(struct bnep_conn, 1);
+	bc->io = io;
+	bc->attempts = 0;
+	bc->src = src;
+	bc->dst = dst;
+	bc->conn_cb = conn_cb;
+	bc->data = data;
+
+	err = bnep_setup_conn_req(bc);
+	if (err < 0)
+		return err;
+
+	bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+							bnep_conn_req_to, bc);
+	g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_setup_cb, bc);
+	return 0;
+}
+
+int bnep_add_to_bridge(const char *devname, const char *bridge)
+{
+	int ifindex;
+	struct ifreq ifr;
+	int sk, err;
+
+	if (!devname || !bridge)
+		return -EINVAL;
+
+	ifindex = if_nametoindex(devname);
+
+	sk = socket(AF_INET, SOCK_STREAM, 0);
+	if (sk < 0)
+		return -1;
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
+	ifr.ifr_ifindex = ifindex;
+
+	err = ioctl(sk, SIOCBRADDIF, &ifr);
+
+	close(sk);
+
+	if (err < 0)
+		return err;
+
+	info("bridge %s: interface %s added", bridge, devname);
+
+	return 0;
+}
+
+int bnep_del_from_bridge(const char *devname, const char *bridge)
+{
+	int ifindex = if_nametoindex(devname);
+	struct ifreq ifr;
+	int sk, err;
+
+	if (!devname || !bridge)
+		return -EINVAL;
+
+	sk = socket(AF_INET, SOCK_STREAM, 0);
+	if (sk < 0)
+		return -1;
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
+	ifr.ifr_ifindex = ifindex;
+
+	err = ioctl(sk, SIOCBRDELIF, &ifr);
+
+	close(sk);
+
+	if (err < 0)
+		return err;
+
+	info("bridge %s: interface %s removed", bridge, devname);
+
+	return 0;
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
new file mode 100644
index 0000000..11db828
--- /dev/null
+++ b/profiles/network/bnep.h
@@ -0,0 +1,42 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int bnep_init(void);
+int bnep_cleanup(void);
+
+uint16_t bnep_service_id(const char *svc);
+const char *bnep_uuid(uint16_t id);
+const char *bnep_name(uint16_t id);
+
+int bnep_kill_connection(const bdaddr_t *dst);
+
+int bnep_connadd(int sk, uint16_t role, char *dev);
+int bnep_if_up(const char *devname);
+int bnep_if_down(const char *devname);
+int bnep_add_to_bridge(const char *devname, const char *bridge);
+int bnep_del_from_bridge(const char *devname, const char *bridge);
+
+typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
+								void *data);
+int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
+					bnep_connect_cb conn_cb, void *data);
diff --git a/profiles/network/common.c b/profiles/network/common.c
deleted file mode 100644
index 1230584..0000000
--- a/profiles/network/common.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <net/if.h>
-#include <linux/sockios.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/l2cap.h>
-#include <bluetooth/bnep.h>
-
-#include <glib.h>
-
-#include "log.h"
-#include "common.h"
-#include "lib/uuid.h"
-
-#define CON_SETUP_RETRIES      3
-#define CON_SETUP_TO           9
-
-static int ctl;
-
-static struct {
-	const char	*name;		/* Friendly name */
-	const char	*uuid128;	/* UUID 128 */
-	uint16_t	id;		/* Service class identifier */
-} __svc[] = {
-	{ "panu",	PANU_UUID,	BNEP_SVC_PANU	},
-	{ "gn",		GN_UUID,	BNEP_SVC_GN	},
-	{ "nap",	NAP_UUID,	BNEP_SVC_NAP	},
-	{ NULL }
-};
-
-struct __service_16 {
-	uint16_t dst;
-	uint16_t src;
-} __attribute__ ((packed));
-
-struct bnep_conn {
-	GIOChannel	*io;
-	uint16_t	src;
-	uint16_t	dst;
-	guint	attempts;
-	guint	setup_to;
-	void	*data;
-	bnep_connect_cb	conn_cb;
-};
-
-uint16_t bnep_service_id(const char *svc)
-{
-	int i;
-	uint16_t id;
-
-	/* Friendly service name */
-	for (i = 0; __svc[i].name; i++) {
-		if (!strcasecmp(svc, __svc[i].name))
-			return __svc[i].id;
-	}
-
-	/* UUID 128 string */
-	for (i = 0; __svc[i].uuid128; i++) {
-		if (!strcasecmp(svc, __svc[i].uuid128))
-			return __svc[i].id;
-	}
-
-	/* Try convert to HEX */
-	id = strtol(svc, NULL, 16);
-	if ((id < BNEP_SVC_PANU) || (id > BNEP_SVC_GN))
-		return 0;
-
-	return id;
-}
-
-const char *bnep_uuid(uint16_t id)
-{
-	int i;
-
-	for (i = 0; __svc[i].uuid128; i++)
-		if (__svc[i].id == id)
-			return __svc[i].uuid128;
-	return NULL;
-}
-
-const char *bnep_name(uint16_t id)
-{
-	int i;
-
-	for (i = 0; __svc[i].name; i++)
-		if (__svc[i].id == id)
-			return __svc[i].name;
-	return NULL;
-}
-
-int bnep_init(void)
-{
-	ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP);
-
-	if (ctl < 0) {
-		int err = -errno;
-
-		if (err == -EPROTONOSUPPORT)
-			warn("kernel lacks bnep-protocol support");
-		else
-			error("Failed to open control socket: %s (%d)",
-						strerror(-err), -err);
-
-		return err;
-	}
-
-	return 0;
-}
-
-int bnep_cleanup(void)
-{
-	close(ctl);
-	return 0;
-}
-
-int bnep_kill_connection(const bdaddr_t *dst)
-{
-	struct bnep_conndel_req req;
-
-	memset(&req, 0, sizeof(req));
-	baswap((bdaddr_t *)&req.dst, dst);
-	req.flags = 0;
-	if (ioctl(ctl, BNEPCONNDEL, &req)) {
-		int err = -errno;
-		error("Failed to kill connection: %s (%d)",
-						strerror(-err), -err);
-		return err;
-	}
-	return 0;
-}
-
-int bnep_connadd(int sk, uint16_t role, char *dev)
-{
-	struct bnep_connadd_req req;
-
-	memset(&req, 0, sizeof(req));
-	strcpy(req.device, "bnep%d");
-	req.sock = sk;
-	req.role = role;
-	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
-		int err = -errno;
-		error("Failed to add device %s: %s(%d)",
-				dev, strerror(-err), -err);
-		return err;
-	}
-
-	strncpy(dev, req.device, 16);
-	return 0;
-}
-
-int bnep_if_up(const char *devname)
-{
-	struct ifreq ifr;
-	int sk, err;
-
-	sk = socket(AF_INET, SOCK_DGRAM, 0);
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
-
-	ifr.ifr_flags |= IFF_UP;
-	ifr.ifr_flags |= IFF_MULTICAST;
-
-	err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
-
-	close(sk);
-
-	if (err < 0) {
-		error("Could not bring up %s", devname);
-		return err;
-	}
-
-	return 0;
-}
-
-int bnep_if_down(const char *devname)
-{
-	struct ifreq ifr;
-	int sk, err;
-
-	sk = socket(AF_INET, SOCK_DGRAM, 0);
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);
-
-	ifr.ifr_flags &= ~IFF_UP;
-
-	/* Bring down the interface */
-	err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
-
-	close(sk);
-
-	if (err < 0) {
-		error("Could not bring down %s", devname);
-		return err;
-	}
-
-	return 0;
-}
-
-static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
-								gpointer data)
-{
-	struct bnep_conn *bc = data;
-	struct bnep_control_rsp *rsp;
-	struct timeval timeo;
-	char pkt[BNEP_MTU];
-	char iface[16];
-	ssize_t r;
-	int sk;
-
-	if (cond & G_IO_NVAL)
-		goto failed;
-
-	if (bc->setup_to > 0) {
-		g_source_remove(bc->setup_to);
-		bc->setup_to = 0;
-	}
-
-	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		error("Hangup or error on l2cap server socket");
-		goto failed;
-	}
-
-	sk = g_io_channel_unix_get_fd(chan);
-	memset(pkt, 0, BNEP_MTU);
-	r = read(sk, pkt, sizeof(pkt) - 1);
-	if (r < 0) {
-		error("IO Channel read error");
-		goto failed;
-	}
-
-	if (r == 0) {
-		error("No packet received on l2cap socket");
-		goto failed;
-	}
-
-	errno = EPROTO;
-
-	if ((size_t) r < sizeof(*rsp)) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	rsp = (void *) pkt;
-	if (rsp->type != BNEP_CONTROL) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
-		return TRUE;
-
-	r = ntohs(rsp->resp);
-	if (r != BNEP_SUCCESS) {
-		error("bnep failed");
-		goto failed;
-	}
-
-	memset(&timeo, 0, sizeof(timeo));
-	timeo.tv_sec = 0;
-	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
-
-	sk = g_io_channel_unix_get_fd(bc->io);
-	if (bnep_connadd(sk, bc->src, iface)) {
-		error("bnep conn could not be added");
-		goto failed;
-	}
-
-	if (bnep_if_up(iface)) {
-		error("could not up %s", iface);
-		goto failed;
-	}
-
-	bc->conn_cb(chan, iface, 0, bc->data);
-	g_free(bc);
-
-	return FALSE;
-
-failed:
-	bc->conn_cb(NULL, NULL, -EIO, bc->data);
-	g_free(bc);
-
-	return FALSE;
-}
-
-
-static int bnep_setup_conn_req(struct bnep_conn *bc)
-{
-	struct bnep_setup_conn_req *req;
-	struct __service_16 *s;
-	unsigned char pkt[BNEP_MTU];
-	int fd;
-
-	/* Send request */
-	req = (void *) pkt;
-	req->type = BNEP_CONTROL;
-	req->ctrl = BNEP_SETUP_CONN_REQ;
-	req->uuid_size = 2;     /* 16bit UUID */
-	s = (void *) req->service;
-	s->src = htons(bc->src);
-	s->dst = htons(bc->dst);
-
-	fd = g_io_channel_unix_get_fd(bc->io);
-	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
-		error("bnep connection req send failed: %s", strerror(errno));
-		return -errno;
-	}
-
-	bc->attempts++;
-
-	return 0;
-}
-
-static gboolean bnep_conn_req_to(gpointer user_data)
-{
-	struct bnep_conn *bc = user_data;
-
-	if (bc->attempts == CON_SETUP_RETRIES) {
-		error("Too many bnep connection attempts");
-	} else {
-		error("bnep connection setup TO, retrying...");
-		if (bnep_setup_conn_req(bc) == 0)
-			return TRUE;
-	}
-
-	bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
-	g_free(bc);
-
-	return FALSE;
-}
-
-int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
-					bnep_connect_cb conn_cb, void *data)
-{
-	struct bnep_conn *bc;
-	int err;
-
-	if (!io || !conn_cb)
-		return -EINVAL;
-
-	bc = g_new0(struct bnep_conn, 1);
-	bc->io = io;
-	bc->attempts = 0;
-	bc->src = src;
-	bc->dst = dst;
-	bc->conn_cb = conn_cb;
-	bc->data = data;
-
-	err = bnep_setup_conn_req(bc);
-	if (err < 0)
-		return err;
-
-	bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
-							bnep_conn_req_to, bc);
-	g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							bnep_setup_cb, bc);
-	return 0;
-}
-
-int bnep_add_to_bridge(const char *devname, const char *bridge)
-{
-	int ifindex;
-	struct ifreq ifr;
-	int sk, err;
-
-	if (!devname || !bridge)
-		return -EINVAL;
-
-	ifindex = if_nametoindex(devname);
-
-	sk = socket(AF_INET, SOCK_STREAM, 0);
-	if (sk < 0)
-		return -1;
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
-	ifr.ifr_ifindex = ifindex;
-
-	err = ioctl(sk, SIOCBRADDIF, &ifr);
-
-	close(sk);
-
-	if (err < 0)
-		return err;
-
-	info("bridge %s: interface %s added", bridge, devname);
-
-	return 0;
-}
-
-int bnep_del_from_bridge(const char *devname, const char *bridge)
-{
-	int ifindex = if_nametoindex(devname);
-	struct ifreq ifr;
-	int sk, err;
-
-	if (!devname || !bridge)
-		return -EINVAL;
-
-	sk = socket(AF_INET, SOCK_STREAM, 0);
-	if (sk < 0)
-		return -1;
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
-	ifr.ifr_ifindex = ifindex;
-
-	err = ioctl(sk, SIOCBRDELIF, &ifr);
-
-	close(sk);
-
-	if (err < 0)
-		return err;
-
-	info("bridge %s: interface %s removed", bridge, devname);
-
-	return 0;
-}
diff --git a/profiles/network/common.h b/profiles/network/common.h
deleted file mode 100644
index 11db828..0000000
--- a/profiles/network/common.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-int bnep_init(void);
-int bnep_cleanup(void);
-
-uint16_t bnep_service_id(const char *svc);
-const char *bnep_uuid(uint16_t id);
-const char *bnep_name(uint16_t id);
-
-int bnep_kill_connection(const bdaddr_t *dst);
-
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_if_up(const char *devname);
-int bnep_if_down(const char *devname);
-int bnep_add_to_bridge(const char *devname, const char *bridge);
-int bnep_del_from_bridge(const char *devname, const char *bridge);
-
-typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
-								void *data);
-int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
-					bnep_connect_cb conn_cb, void *data);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 5723afd..6ad0277 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -47,7 +47,7 @@
 #include "service.h"
 
 #include "error.h"
-#include "common.h"
+#include "bnep.h"
 #include "connection.h"
 
 #define NETWORK_PEER_INTERFACE "org.bluez.Network1"
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index ab4224d..8ac2dec 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -43,7 +43,7 @@
 #include "device.h"
 #include "profile.h"
 #include "service.h"
-#include "common.h"
+#include "bnep.h"
 #include "connection.h"
 #include "server.h"
 
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 3a7e52a..b3aab11 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -48,7 +48,7 @@
 #include "error.h"
 #include "sdpd.h"
 
-#include "common.h"
+#include "bnep.h"
 #include "server.h"
 
 #define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 2/7] profiles/network: Refactor bnep connection setup functionality
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Moving bnep connection setup related functionality to common.c.
Provided bnep_connect call with bnep_connect_cb for status and
bnep interface name. It will be simple if someone want to utilize
this call otherwise they have to reimplement similar functionality
with minimal changes (e.g. android/pan).
---
 profiles/network/common.c     | 178 ++++++++++++++++++++++++++++++++++++++++++
 profiles/network/common.h     |   5 ++
 profiles/network/connection.c | 167 +++------------------------------------
 3 files changed, 194 insertions(+), 156 deletions(-)

diff --git a/profiles/network/common.c b/profiles/network/common.c
index b94b3a5..1230584 100644
--- a/profiles/network/common.c
+++ b/profiles/network/common.c
@@ -46,6 +46,9 @@
 #include "common.h"
 #include "lib/uuid.h"
 
+#define CON_SETUP_RETRIES      3
+#define CON_SETUP_TO           9
+
 static int ctl;
 
 static struct {
@@ -59,6 +62,21 @@ static struct {
 	{ NULL }
 };
 
+struct __service_16 {
+	uint16_t dst;
+	uint16_t src;
+} __attribute__ ((packed));
+
+struct bnep_conn {
+	GIOChannel	*io;
+	uint16_t	src;
+	uint16_t	dst;
+	guint	attempts;
+	guint	setup_to;
+	void	*data;
+	bnep_connect_cb	conn_cb;
+};
+
 uint16_t bnep_service_id(const char *svc)
 {
 	int i;
@@ -214,6 +232,166 @@ int bnep_if_down(const char *devname)
 	return 0;
 }
 
+static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct bnep_conn *bc = data;
+	struct bnep_control_rsp *rsp;
+	struct timeval timeo;
+	char pkt[BNEP_MTU];
+	char iface[16];
+	ssize_t r;
+	int sk;
+
+	if (cond & G_IO_NVAL)
+		goto failed;
+
+	if (bc->setup_to > 0) {
+		g_source_remove(bc->setup_to);
+		bc->setup_to = 0;
+	}
+
+	if (cond & (G_IO_HUP | G_IO_ERR)) {
+		error("Hangup or error on l2cap server socket");
+		goto failed;
+	}
+
+	sk = g_io_channel_unix_get_fd(chan);
+	memset(pkt, 0, BNEP_MTU);
+	r = read(sk, pkt, sizeof(pkt) - 1);
+	if (r < 0) {
+		error("IO Channel read error");
+		goto failed;
+	}
+
+	if (r == 0) {
+		error("No packet received on l2cap socket");
+		goto failed;
+	}
+
+	errno = EPROTO;
+
+	if ((size_t) r < sizeof(*rsp)) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	rsp = (void *) pkt;
+	if (rsp->type != BNEP_CONTROL) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
+		return TRUE;
+
+	r = ntohs(rsp->resp);
+	if (r != BNEP_SUCCESS) {
+		error("bnep failed");
+		goto failed;
+	}
+
+	memset(&timeo, 0, sizeof(timeo));
+	timeo.tv_sec = 0;
+	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+
+	sk = g_io_channel_unix_get_fd(bc->io);
+	if (bnep_connadd(sk, bc->src, iface)) {
+		error("bnep conn could not be added");
+		goto failed;
+	}
+
+	if (bnep_if_up(iface)) {
+		error("could not up %s", iface);
+		goto failed;
+	}
+
+	bc->conn_cb(chan, iface, 0, bc->data);
+	g_free(bc);
+
+	return FALSE;
+
+failed:
+	bc->conn_cb(NULL, NULL, -EIO, bc->data);
+	g_free(bc);
+
+	return FALSE;
+}
+
+
+static int bnep_setup_conn_req(struct bnep_conn *bc)
+{
+	struct bnep_setup_conn_req *req;
+	struct __service_16 *s;
+	unsigned char pkt[BNEP_MTU];
+	int fd;
+
+	/* Send request */
+	req = (void *) pkt;
+	req->type = BNEP_CONTROL;
+	req->ctrl = BNEP_SETUP_CONN_REQ;
+	req->uuid_size = 2;     /* 16bit UUID */
+	s = (void *) req->service;
+	s->src = htons(bc->src);
+	s->dst = htons(bc->dst);
+
+	fd = g_io_channel_unix_get_fd(bc->io);
+	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
+		error("bnep connection req send failed: %s", strerror(errno));
+		return -errno;
+	}
+
+	bc->attempts++;
+
+	return 0;
+}
+
+static gboolean bnep_conn_req_to(gpointer user_data)
+{
+	struct bnep_conn *bc = user_data;
+
+	if (bc->attempts == CON_SETUP_RETRIES) {
+		error("Too many bnep connection attempts");
+	} else {
+		error("bnep connection setup TO, retrying...");
+		if (bnep_setup_conn_req(bc) == 0)
+			return TRUE;
+	}
+
+	bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
+	g_free(bc);
+
+	return FALSE;
+}
+
+int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
+					bnep_connect_cb conn_cb, void *data)
+{
+	struct bnep_conn *bc;
+	int err;
+
+	if (!io || !conn_cb)
+		return -EINVAL;
+
+	bc = g_new0(struct bnep_conn, 1);
+	bc->io = io;
+	bc->attempts = 0;
+	bc->src = src;
+	bc->dst = dst;
+	bc->conn_cb = conn_cb;
+	bc->data = data;
+
+	err = bnep_setup_conn_req(bc);
+	if (err < 0)
+		return err;
+
+	bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+							bnep_conn_req_to, bc);
+	g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_setup_cb, bc);
+	return 0;
+}
+
 int bnep_add_to_bridge(const char *devname, const char *bridge)
 {
 	int ifindex;
diff --git a/profiles/network/common.h b/profiles/network/common.h
index 9a8caac..11db828 100644
--- a/profiles/network/common.h
+++ b/profiles/network/common.h
@@ -35,3 +35,8 @@ int bnep_if_up(const char *devname);
 int bnep_if_down(const char *devname);
 int bnep_add_to_bridge(const char *devname, const char *bridge);
 int bnep_del_from_bridge(const char *devname, const char *bridge);
+
+typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
+								void *data);
+int bnep_connect(GIOChannel *io, uint16_t src, uint16_t dst,
+					bnep_connect_cb conn_cb, void *data);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 301f66d..5723afd 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -51,8 +51,6 @@
 #include "connection.h"
 
 #define NETWORK_PEER_INTERFACE "org.bluez.Network1"
-#define CON_SETUP_RETRIES      3
-#define CON_SETUP_TO           9
 
 typedef enum {
 	CONNECTED,
@@ -73,16 +71,9 @@ struct network_conn {
 	GIOChannel	*io;
 	guint		dc_id;
 	struct network_peer *peer;
-	guint		attempt_cnt;
-	guint		timeout_source;
 	DBusMessage	*connect;
 };
 
-struct __service_16 {
-	uint16_t dst;
-	uint16_t src;
-} __attribute__ ((packed));
-
 static GSList *peers = NULL;
 
 static uint16_t get_service_id(struct btd_service *service)
@@ -163,11 +154,6 @@ static void local_connect_cb(struct network_conn *nc, int err)
 
 static void cancel_connection(struct network_conn *nc, int err)
 {
-	if (nc->timeout_source > 0) {
-		g_source_remove(nc->timeout_source);
-		nc->timeout_source = 0;
-	}
-
 	btd_service_connecting_complete(nc->service, err);
 	if (nc->connect)
 		local_connect_cb(nc, err);
@@ -200,83 +186,24 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
 	connection_destroy(NULL, user_data);
 }
 
-static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
-							gpointer data)
+static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
 {
 	struct network_conn *nc = data;
-	struct bnep_control_rsp *rsp;
-	struct timeval timeo;
-	char pkt[BNEP_MTU];
-	ssize_t r;
-	int sk;
 	const char *path;
 	DBusConnection *conn;
 
-	DBG("cond %u", cond);
-
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
-	if (nc->timeout_source > 0) {
-		g_source_remove(nc->timeout_source);
-		nc->timeout_source = 0;
-	}
-
-	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		error("Hangup or error on l2cap server socket");
-		goto failed;
-	}
-
-	sk = g_io_channel_unix_get_fd(chan);
-
-	memset(pkt, 0, BNEP_MTU);
-	r = read(sk, pkt, sizeof(pkt) -1);
-	if (r < 0) {
-		error("IO Channel read error");
-		goto failed;
-	}
-
-	if (r == 0) {
-		error("No packet received on l2cap socket");
-		goto failed;
-	}
-
-	errno = EPROTO;
-
-	if ((size_t) r < sizeof(*rsp)) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	rsp = (void *) pkt;
-	if (rsp->type != BNEP_CONTROL) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
-		return TRUE;
-
-	r = ntohs(rsp->resp);
-
-	if (r != BNEP_SUCCESS) {
-		error("bnep failed");
-		goto failed;
-	}
-
-	memset(&timeo, 0, sizeof(timeo));
-	timeo.tv_sec = 0;
-
-	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+	DBG("");
 
-	if (bnep_connadd(sk, BNEP_SVC_PANU, nc->dev)) {
-		error("%s could not be added", nc->dev);
+	if (err < 0) {
+		error("connect failed %s", strerror(-err));
 		goto failed;
 	}
 
-	bnep_if_up(nc->dev);
+	info("%s connected", nc->dev);
 
+	memcpy(nc->dev, iface, sizeof(nc->dev));
 	btd_service_connecting_complete(nc->service, 0);
+
 	if (nc->connect)
 		local_connect_cb(nc, 0);
 
@@ -292,88 +219,16 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 
 	nc->state = CONNECTED;
 	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
-						nc, NULL);
-
-	info("%s connected", nc->dev);
-	/* Start watchdog */
+								nc, NULL);
 	g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-			(GIOFunc) bnep_watchdog_cb, nc);
+							bnep_watchdog_cb, nc);
 	g_io_channel_unref(nc->io);
 	nc->io = NULL;
 
-	return FALSE;
+	return;
 
 failed:
 	cancel_connection(nc, -EIO);
-
-	return FALSE;
-}
-
-static int bnep_send_conn_req(struct network_conn *nc)
-{
-	struct bnep_setup_conn_req *req;
-	struct __service_16 *s;
-	unsigned char pkt[BNEP_MTU];
-	int fd;
-
-	DBG("");
-
-	/* Send request */
-	req = (void *) pkt;
-	req->type = BNEP_CONTROL;
-	req->ctrl = BNEP_SETUP_CONN_REQ;
-	req->uuid_size = 2;	/* 16bit UUID */
-	s = (void *) req->service;
-	s->dst = htons(nc->id);
-	s->src = htons(BNEP_SVC_PANU);
-
-	fd = g_io_channel_unix_get_fd(nc->io);
-	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
-		int err = -errno;
-		error("bnep connection req send failed: %s", strerror(errno));
-		return err;
-	}
-
-	nc->attempt_cnt++;
-
-	return 0;
-}
-
-static gboolean bnep_conn_req_to(gpointer user_data)
-{
-	struct network_conn *nc;
-
-	nc = user_data;
-	if (nc->attempt_cnt == CON_SETUP_RETRIES) {
-		error("Too many bnep connection attempts");
-	} else {
-		error("bnep connection setup TO, retrying...");
-		if (bnep_send_conn_req(nc) == 0)
-			return TRUE;
-	}
-
-	cancel_connection(nc, -ETIMEDOUT);
-
-	return FALSE;
-}
-
-static int bnep_connect(struct network_conn *nc)
-{
-	int err;
-
-	nc->attempt_cnt = 0;
-
-	err = bnep_send_conn_req(nc);
-	if (err < 0)
-		return err;
-
-	nc->timeout_source = g_timeout_add_seconds(CON_SETUP_TO,
-							bnep_conn_req_to, nc);
-
-	g_io_add_watch(nc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							bnep_setup_cb, nc);
-
-	return 0;
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
@@ -386,7 +241,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 		goto failed;
 	}
 
-	perr = bnep_connect(nc);
+	perr = bnep_connect(nc->io, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
 	if (perr < 0) {
 		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
 		goto failed;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 1/7] profiles/network: Remove redundant code for bnep interface name
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1385649955-29276-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Remove redundant code for copying bnepX interface name from connection
and server files. It is better to place on actual function call.
---
 profiles/network/common.c     | 3 +--
 profiles/network/connection.c | 2 --
 profiles/network/server.c     | 3 ---
 3 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/profiles/network/common.c b/profiles/network/common.c
index 0b291bd..b94b3a5 100644
--- a/profiles/network/common.c
+++ b/profiles/network/common.c
@@ -150,8 +150,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
 	struct bnep_connadd_req req;
 
 	memset(&req, 0, sizeof(req));
-	strncpy(req.device, dev, 16);
-	req.device[15] = '\0';
+	strcpy(req.device, "bnep%d");
 	req.sock = sk;
 	req.role = role;
 	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 5966268..301f66d 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -692,8 +692,6 @@ int connection_register(struct btd_service *service)
 
 	nc = g_new0(struct network_conn, 1);
 	nc->id = id;
-	memset(nc->dev, 0, sizeof(nc->dev));
-	strcpy(nc->dev, "bnep%d");
 	nc->service = btd_service_ref(service);
 	nc->state = DISCONNECTED;
 	nc->peer = peer;
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 0050b30..3a7e52a 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -269,9 +269,6 @@ static int server_connadd(struct network_server *ns,
 	char devname[16];
 	int err, nsk;
 
-	memset(devname, 0, sizeof(devname));
-	strcpy(devname, "bnep%d");
-
 	nsk = g_io_channel_unix_get_fd(session->io);
 	err = bnep_connadd(nsk, dst_role, devname);
 	if (err < 0)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v2 0/7] Refactor bnep code and implement pan methods
From: Ravi kumar Veeramally @ 2013-11-28 14:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

v2: Refactored profiles/network/common.* as per Johan's comments
    (renaming common.c|h to bnep.c|h and moving bnep related code to
     bnep.c ro reduce redundancy in profiles/netowrk/connection.c and
     android/pan.c)

v1: This patch set supports PANU role with a minor fix in android. Added
    CAP_NET_RAW capability for bnep services. Creates bnep connection and
    up the inreface on connect call and free the device on disconnect call.
    Interface name(bnepX) will be notified on control state cb. Android
    environment will create IP address with dhcp calls.

Ravi kumar Veeramally (7):
  profiles/network: Remove redundant code for bnep interface name
  profiles/network: Refactor bnep connection setup functionality
  profiles/network: Rename common.c|h to bnep.c|h
  android/pan: Implement pan connect method in daemon
  android/pan: Implement pan disconnect method in daemon
  android/pan: Implement the get local role method in daemon
  android: Add reasons for adding capabilites to process

 Makefile.plugins              |   2 +-
 android/Android.mk            |   2 +
 android/Makefile.am           |   3 +-
 android/main.c                |   3 +
 android/pan.c                 | 252 ++++++++++++++++++++++-
 profiles/network/bnep.c       | 453 ++++++++++++++++++++++++++++++++++++++++++
 profiles/network/bnep.h       |  42 ++++
 profiles/network/common.c     | 276 -------------------------
 profiles/network/common.h     |  37 ----
 profiles/network/connection.c | 171 ++--------------
 profiles/network/manager.c    |   2 +-
 profiles/network/server.c     |   5 +-
 12 files changed, 760 insertions(+), 488 deletions(-)
 create mode 100644 profiles/network/bnep.c
 create mode 100644 profiles/network/bnep.h
 delete mode 100644 profiles/network/common.c
 delete mode 100644 profiles/network/common.h

-- 
1.8.3.2


^ permalink raw reply

* [PATCH 10/10] android/socket: Remove unneeded code
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

The flag is already set in bt_io_listen.
---
 android/socket.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 8df6e01..ea88712 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -696,8 +696,6 @@ static int handle_listen(void *buf)
 
 	rfsock->real_sock = g_io_channel_unix_get_fd(io);
 
-	/* TODO: Add server watch */
-	g_io_channel_set_close_on_unref(io, TRUE);
 	g_io_channel_unref(io);
 
 	DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 09/10] android/socket: Avoid double close of file descriptor
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Since we close all file descriptors in cleanup_rfsock do not close it also
during iochannel cleaning up. The flag was setup in bt_io_listen and
bt_io_connect calls.
---
 android/socket.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 45ff90e..8df6e01 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -641,6 +641,7 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 	/* Handle rfcomm events */
 	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
 	id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock_acc);
+	g_io_channel_set_close_on_unref(io, FALSE);
 
 	rfsock_acc->rfcomm_watch = id;
 
@@ -777,6 +778,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 	/* Handle rfcomm events */
 	cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 	id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock);
+	g_io_channel_set_close_on_unref(io, FALSE);
 
 	rfsock->rfcomm_watch = id;
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 08/10] android/socket: Strip extra log messages
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Remove debug messages when sending data, debug still exist for connection
establishment. Do not print error when connection hang up, print debug
instead.
---
 android/socket.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 3f07dc6..45ff90e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -488,11 +488,12 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 	unsigned char buf[1024];
 	int len, sent;
 
-	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
-		rfsock->fd, rfsock->real_sock, rfsock->channel,
-		g_io_channel_unix_get_fd(io));
+	if (cond & G_IO_HUP) {
+		DBG("Socket %d hang up", g_io_channel_unix_get_fd(io));
+		goto fail;
+	}
 
-	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+	if (cond & (G_IO_ERR | G_IO_NVAL)) {
 		error("Socket error: sock %d cond %d",
 					g_io_channel_unix_get_fd(io), cond);
 		goto fail;
@@ -505,16 +506,12 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 		return TRUE;
 	}
 
-	DBG("read %d bytes write to %d", len, rfsock->real_sock);
-
 	sent = try_write_all(rfsock->real_sock, buf, len);
 	if (sent < 0) {
 		error("write(): %s", strerror(errno));
 		goto fail;
 	}
 
-	DBG("Written %d bytes", sent);
-
 	return TRUE;
 fail:
 	connections = g_list_remove(connections, rfsock);
@@ -530,11 +527,12 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 	unsigned char buf[1024];
 	int len, sent;
 
-	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
-		rfsock->fd, rfsock->real_sock, rfsock->channel,
-		g_io_channel_unix_get_fd(io));
+	if (cond & G_IO_HUP) {
+		DBG("Socket %d hang up", g_io_channel_unix_get_fd(io));
+		goto fail;
+	}
 
-	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+	if (cond & (G_IO_ERR | G_IO_NVAL)) {
 		error("Socket error: sock %d cond %d",
 					g_io_channel_unix_get_fd(io), cond);
 		goto fail;
@@ -547,16 +545,12 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 		return TRUE;
 	}
 
-	DBG("read %d bytes, write to fd %d", len, rfsock->fd);
-
 	sent = try_write_all(rfsock->fd, buf, len);
 	if (sent < 0) {
 		error("write(): %s", strerror(errno));
 		goto fail;
 	}
 
-	DBG("Written %d bytes", sent);
-
 	return TRUE;
 fail:
 	connections = g_list_remove(connections, rfsock);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 07/10] android/hidhost: Shutdown ctrl_io channel if intr_io fails
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This fix possible memory leak.
---
 android/hidhost.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/android/hidhost.c b/android/hidhost.c
index d50c5b8..1f5aa5d 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1219,8 +1219,12 @@ bool bt_hid_register(int sk, const bdaddr_t *addr)
 				BT_IO_OPT_INVALID);
 	if (!intr_io) {
 		error("Failed to listen on intr channel: %s", err->message);
-		g_io_channel_unref(ctrl_io);
 		g_error_free(err);
+
+		g_io_channel_shutdown(ctrl_io, TRUE, NULL);
+		g_io_channel_unref(ctrl_io);
+		ctrl_io = NULL;
+
 		return false;
 	}
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 06/10] android/socket: Fix rfsock lists
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This fixes several places where rfsock structure were not removed
from the list due to connection errors.
---
 android/socket.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index d55db54..3f07dc6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -625,8 +625,6 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 		return;
 	}
 
-	connections = g_list_append(connections, rfsock_acc);
-
 	DBG("rfsock: fd %d real_sock %d chan %u sock %d",
 		rfsock->fd, rfsock->real_sock, rfsock->channel,
 		sock_acc);
@@ -636,6 +634,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
 		return;
 	}
 
+	connections = g_list_append(connections, rfsock_acc);
+
 	/* Handle events from Android */
 	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
 	io_stack = g_io_channel_unix_new(rfsock_acc->fd);
@@ -700,7 +700,6 @@ static int handle_listen(void *buf)
 	}
 
 	rfsock->real_sock = g_io_channel_unix_get_fd(io);
-	servers = g_list_append(servers, rfsock);
 
 	/* TODO: Add server watch */
 	g_io_channel_set_close_on_unref(io, TRUE);
@@ -717,6 +716,8 @@ static int handle_listen(void *buf)
 
 	rfsock->service_handle = sdp_service_register(profile, cmd->name);
 
+	servers = g_list_append(servers, rfsock);
+
 	return hal_fd;
 }
 
@@ -787,6 +788,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
 
 	return;
 fail:
+	connections = g_list_remove(connections, rfsock);
 	cleanup_rfsock(rfsock);
 }
 
@@ -865,6 +867,7 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 
 	return;
 fail:
+	connections = g_list_remove(connections, rfsock);
 	cleanup_rfsock(rfsock);
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 05/10] android/socket: Cleanup sockets on unregister
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This cleans up rfsock structures closing all sockets and making general cleanup
for servers and for connections. This will be called form socket unregister.
---
 android/socket.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/android/socket.c b/android/socket.c
index 1fb154d..d55db54 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -943,7 +943,27 @@ bool bt_socket_register(int sk, const bdaddr_t *addr)
 	return true;
 }
 
+static void free_connection(gpointer data, gpointer user_data)
+{
+	struct rfcomm_sock *rfsock = data;
+
+	connections = g_list_remove(connections, rfsock);
+	cleanup_rfsock(rfsock);
+}
+
+static void free_server(gpointer data, gpointer user_data)
+{
+	struct rfcomm_sock *rfsock = data;
+
+	servers = g_list_remove(servers, rfsock);
+	cleanup_rfsock(rfsock);
+}
+
 void bt_socket_unregister(void)
 {
 	DBG("");
+
+	g_list_foreach(connections, free_connection, NULL);
+
+	g_list_foreach(servers, free_server, NULL);
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 04/10] android/main: Free enabled string on exit
From: Andrei Emeltchenko @ 2013-11-28 14:38 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 android/main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/main.c b/android/main.c
index 4dc3061..30792c5 100644
--- a/android/main.c
+++ b/android/main.c
@@ -566,6 +566,7 @@ int main(int argc, char *argv[])
 	__btd_log_init("*", 0);
 
 	if (!set_capabilities()) {
+		__btd_log_cleanup();
 		g_source_remove(signal);
 		return EXIT_FAILURE;
 	}
@@ -574,11 +575,13 @@ int main(int argc, char *argv[])
 							quit_eventloop, NULL);
 	if (bluetooth_start_timeout == 0) {
 		error("Failed to init startup timeout");
+		__btd_log_cleanup();
 		g_source_remove(signal);
 		return EXIT_FAILURE;
 	}
 
 	if (!bt_bluetooth_start(option_index, adapter_ready)) {
+		__btd_log_cleanup();
 		g_source_remove(bluetooth_start_timeout);
 		g_source_remove(signal);
 		return EXIT_FAILURE;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 03/10] android/main: Remove signal source on exit
From: Andrei Emeltchenko @ 2013-11-28 14:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Remove signal source on exit and move check capability function in order
to avoid extra check.
---
 android/main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/android/main.c b/android/main.c
index dd5c622..4dc3061 100644
--- a/android/main.c
+++ b/android/main.c
@@ -565,18 +565,22 @@ int main(int argc, char *argv[])
 
 	__btd_log_init("*", 0);
 
-	if (!set_capabilities())
+	if (!set_capabilities()) {
+		g_source_remove(signal);
 		return EXIT_FAILURE;
+	}
 
 	bluetooth_start_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
 							quit_eventloop, NULL);
 	if (bluetooth_start_timeout == 0) {
 		error("Failed to init startup timeout");
+		g_source_remove(signal);
 		return EXIT_FAILURE;
 	}
 
 	if (!bt_bluetooth_start(option_index, adapter_ready)) {
 		g_source_remove(bluetooth_start_timeout);
+		g_source_remove(signal);
 		return EXIT_FAILURE;
 	}
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 02/10] android/main: Remove timeout source on exit
From: Andrei Emeltchenko @ 2013-11-28 14:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385649486-19978-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This fixes memory leak types of warnings from some tools.
---
 android/main.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/android/main.c b/android/main.c
index 830eef2..dd5c622 100644
--- a/android/main.c
+++ b/android/main.c
@@ -575,8 +575,10 @@ int main(int argc, char *argv[])
 		return EXIT_FAILURE;
 	}
 
-	if (!bt_bluetooth_start(option_index, adapter_ready))
+	if (!bt_bluetooth_start(option_index, adapter_ready)) {
+		g_source_remove(bluetooth_start_timeout);
 		return EXIT_FAILURE;
+	}
 
 	/* Use params: mtu = 0, flags = 0 */
 	start_sdp_server(0, 0);
@@ -589,6 +591,9 @@ int main(int argc, char *argv[])
 
 	g_source_remove(signal);
 
+	if (bluetooth_start_timeout > 0)
+		g_source_remove(bluetooth_start_timeout);
+
 	cleanup_hal_connection();
 	stop_sdp_server();
 	bt_bluetooth_cleanup();
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 01/10] android: Avoid memory leak warnings for event_loop
From: Andrei Emeltchenko @ 2013-11-28 14:37 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Move creation of event_loop closer to g_main_loop_run. This avoids
calling g_main_loop_unref too many times in initialization error paths.
This is safe since g_main_loop_quit eval to NOOP if parameter == NULL.
---
 android/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/main.c b/android/main.c
index bfd2a87..830eef2 100644
--- a/android/main.c
+++ b/android/main.c
@@ -559,7 +559,6 @@ int main(int argc, char *argv[])
 		exit(EXIT_SUCCESS);
 	}
 
-	event_loop = g_main_loop_new(NULL, FALSE);
 	signal = setup_signalfd();
 	if (!signal)
 		return EXIT_FAILURE;
@@ -584,6 +583,8 @@ int main(int argc, char *argv[])
 
 	DBG("Entering main loop");
 
+	event_loop = g_main_loop_new(NULL, FALSE);
+
 	g_main_loop_run(event_loop);
 
 	g_source_remove(signal);
-- 
1.8.3.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox