public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG)
@ 2008-07-04 21:01 David Stockwell
  2008-07-05 17:17 ` Marcel Holtmann
  0 siblings, 1 reply; 5+ messages in thread
From: David Stockwell @ 2008-07-04 21:01 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 5468 bytes --]

Over the last few days, I have developed an Agent to implement the
org.bluez.Agent interface, so that I can test the new BT2.1-compatible
Simple Secure Pairing (SSP).

I am developing in C/C++ with Glib and libgdbus, which provides the
functions and structures for method and signal definition and especially
provides for DBus introspection.  Also, I expected to develop this as a
separate process, much like the old passkey-agent.  I found that when I
did this, however, the new agent was never found by my application,
calling the Adapter.CreatePairedDevice method.  When I tested with the
hcid/simple-agent, that Python-based agent worked well.  I would like to
share the reasons for this...

1) When first testing the agent as a separate process, I figured I had
to tie that agent to the org.bluez well-known name.  The only way I
could find to do that was to connect to the Session bus (not the System
bus), and provide "org.bluez" as the name of the bus in the session.  I
used this to test the functioning of the agent with dbus-send.  However,
when I tried calling CreatePairedDevice from my application, it did not
find the agent; the error message in syslog indicated that Method
RequestPinCode with signature "o" was not found.

2) Knowing that hcid uses the System bus, I then tried to connect with
the System bus, referencing the "org.bluez" well-known connection name.
However, the connection was rejected because (as we all know) hcid owns
that name, and only one object can own a name at a time (and hcid was
not going to give it up!).

3) I connected the agent with the System bus leaving the service name
NULL, so the agent object was assigned a "unique connection name",
something like :1.56 (changes each time).  I was able to introspect the
object, and to invoke some of the methods using dbus-send, so long as I
addressed the System bus (--system) and set the destination with that
unique connection name (--dest =:1.56).  I also went down a path of
calling RegisterAgent from within the external Agent; this worked
properly in the sense that DBus was happy with it, the Agent was still
reachable from dbus-send, etc.

4) I attempted to connect with the registered Agent using
Adapter.CreatePairedDevice, the Agent was not connected to.  The reason
for this is that CreatePairedDevice explicitly uses its own "unique
connection name" to the System bus as the "bus name", and assumes that
the Object Path will be found on that bus name.  Which is only the case
if the Agent code is contained within the same process as the rest of
the application; the application calling CreatePairedDevice.

BUG-> If there is no object with that path for the unique connection
name, the code at hcid/agent.c agent_create (line 190) should throw an
error, perhaps .DoesNotExist...  What actually happens is that the code
just creates that path and attempts to call it during pairing; throwing
no error (except for the DBus error that shows up in the syslog).
Authentication then fails with no accurate indication as to why.

5) I attempted to register the Agent within the application using
Adapter.RegisterAgent.  However, again RegisterAgent assumes that the
bus name to be used is its own unique connection name; it does not
search for the object among other connections to the System bus, nor is
there any way to pass in a well-known name or a unique connection name.

BUG-> (actually, the same bug) As with CreatePairedDevice, if there is
no object with that path for the unique connection name, RegisterAgent
should throw an error.

6) Finally, I very slightly revamped my Agent code, changed the sub main
to a callable subroutine from my main application and integrated it into
the mainloop of the application.  All now works well, because the
application and the Agent are in the same process and share the same
connection to the System bus.

YOU MAY ASK, why did I not integrate the Agent code into the main
application in the first place?

The first reason is that it was not clear that this is what I needed to
do.  Although I did receive a hint about this from Johan Hedburg
(thanks!), I expected the agent should be a separate process, much like
the 3.x passkey-agent and auth-agent.

Second, depending on the application requirements, the agent may require
entry of a pincode or passkey (in my case, I am using SSP-JustWorks, so
human entry should not be needed).  Depending on the requirements, the
Agent should not hang up the main application waiting for human
interaction.  (That said, you could non-block the IO and multi-thread
the whole thing...).

Third, I just felt that putting the Agent in another process is a
somewhat more modular way to handle security, authorization and pairing.

Fourth, because it was there (the challenge of figuring this out,
learning more about DBus, GLib and the whole mess).

To that end, and in the interest of sharing, I am submitting my agent
code as a skeleton...  To react to RequestPinCode and RequestPasskey, I
have hardcoded values... I compile with C++ and use cout and string
because I am lazy (in this experimental phase); converting to standard
C, or to popping up a dialog, is trivial.  And I throw no errors (e.g.,
.Reject), nor do I really do anything with respect to actual
authorization, etc.  In other words,  it's just a start, designed to
allow me to see the interaction with the Agent during pairing,
especially with SSP.

Questions, comments?  Feel free...

David Stockwell
Frequency One

[-- Attachment #2: bluez_agent.cpp --]
[-- Type: application/octet-stream, Size: 8086 bytes --]

/***************************************************************************
 *   Copyright (C) 2008 by David Stockwell   *
 *   dstockwell@frequency-one.com   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string>
#include <iostream>
#include <cstdlib>
#include <stdlib.h>

#include "gdbus.h"

#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <glib-object.h>

using namespace std;

static	GMainLoop	*mainLoop=NULL;

static	DBusMessage *agent_authorize(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *objectPath = (char *) malloc(128);
	char *objectUUID = (char *) malloc(128);

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_OBJECT_PATH, &objectPath,
			DBUS_TYPE_STRING, &objectUUID,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(objectPath);
//		free(objectUUID);
		return NULL;
	}
	cout << "Authorize received..." << objectPath << "-" << objectUUID << endl;

//	free(objectPath);
//	free(objectUUID);

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	return reply;
}

static	DBusMessage *agent_cancel(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	cout << "Cancel received..." << endl;

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	return reply;
}

static	DBusMessage *agent_confirm_mode_change(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *mode = (char *) malloc(128);

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &mode,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(mode);
		return NULL;
	}
	cout << "ConfirmModeChange received..." << mode << endl;

//	free(mode);
	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	return reply;
}

static	DBusMessage *agent_display_passkey(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *objectPath = (char *) malloc(128);
	uint passKey;
	short entered;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_OBJECT_PATH, &objectPath,
			DBUS_TYPE_UINT32, &passKey,
			DBUS_TYPE_BYTE, &entered,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(objectPath);
		return NULL;
	}
	cout << "DisplayPasskey received..." << objectPath << "-" <<  passKey << "-" << entered << endl;

//	free(objectPath);

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	return reply;
}

static	DBusMessage *agent_release(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	cout << "Release received...exiting" << endl;

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	g_main_loop_quit(mainLoop);
	return reply;
}

static	DBusMessage *agent_request_confirmation(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *objectPath = (char *) malloc(128);
	uint passKey;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_OBJECT_PATH, &objectPath,
			DBUS_TYPE_UINT32, &passKey,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(objectPath);
		return NULL;
	}
	cout << "RequestConfirmation received..." << objectPath << "-" <<  passKey << endl;

//	free(objectPath);

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	return reply;
}

static	DBusMessage *agent_request_passkey(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *objectPath = (char *) malloc(128);
	uint passKey = 0000;			// For Testing Only

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_OBJECT_PATH, &objectPath,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(objectPath);
		return NULL;
	}
	cout << "RequestPasskey received..." << objectPath << endl;

//	free(objectPath);

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	if (!dbus_message_append_args(reply, DBUS_TYPE_UINT32, passKey, DBUS_TYPE_INVALID)) {
		dbus_message_unref(reply);
		return NULL;
	}
	return reply;
}

static	DBusMessage *agent_request_pincode(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char *objectPath = (char *) malloc(128);
	const char * pinCode = "Bluez";		// For testing only...

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_OBJECT_PATH, &objectPath,
			DBUS_TYPE_INVALID) == FALSE) {
//		free(objectPath);
		return NULL;
	}
	cout << "RequestPinCode received..." << objectPath << endl;

//	free(objectPath);

	DBusMessage *reply = dbus_message_new_method_return(msg);
	if (!reply) return NULL;

	if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &pinCode, DBUS_TYPE_INVALID)) {
		dbus_message_unref(reply);
		return NULL;
	}
	return reply;
}

/* from doc/agent-api.txt BlueZ 4.0 API */

static	GDBusMethodTable agent_methods[] = {
	{ "Authorize",		"os",	"",	agent_authorize			},
	{ "Cancel",		"",	"",	agent_cancel			},
	{ "ConfirmModeChange",	"s",	"",	agent_confirm_mode_change	},
	{ "DisplayPasskey",	"ouy",	"",	agent_display_passkey		},
	{ "Release",		"",	"",	agent_release			},
	{ "RequestConfirmation","ou",	"",	agent_request_confirmation	},
	{ "RequestPasskey",	"o",	"u",	agent_request_passkey		},
	{ "RequestPinCode",	"o",	"s",	agent_request_pincode		},
	{ }
};

/* Note that there are no signals defined.  If an answer is not positive, an error is thrown. */

int	agent_install(DBusGConnection *dBusG, string agentObjectPath)
{
	DBusError	dError;

	DBusConnection	*dBus=dbus_g_connection_get_connection(dBusG);
	dbus_error_init(&dError);
/*
	With the connection to a the System Bus, register the object for the Agent, then register the interface.
*/
	if (g_dbus_register_object(dBus, agentObjectPath.c_str())) {
		cout << "AgentPath " << agentObjectPath << " REGISTERED" << endl;
	} else {
		cout << "Failed to register AgentPath: " << agentObjectPath;
		if (dbus_error_is_set(&dError)) {
			cout << dError.message;
			dbus_error_free(&dError);
		}
		cout << endl;
		return EXIT_FAILURE;
	}

	if (g_dbus_register_interface(dBus, agentObjectPath.c_str(), "org.bluez.Agent",
			agent_methods, NULL, NULL, NULL, NULL)) {
		cout << "AgentInterface for " << agentObjectPath << " REGISTERED" << endl;
	} else {
		cout << "Failed to register interface for Agent: " << agentObjectPath;
		if (dbus_error_is_set(&dError)) {
			cout << dError.message;
			dbus_error_free(&dError);
		}
		cout << endl;
		return EXIT_FAILURE;
	}

	return	EXIT_SUCCESS;
}

int	agent_uninstall(DBusGConnection *dBusG, string agentObjectPath)
{
	DBusConnection	*dBus=dbus_g_connection_get_connection(dBusG);

	g_dbus_unregister_interface(dBus, agentObjectPath.c_str(), "org.bluez.Agent");
	g_dbus_unregister_object(dBus, agentObjectPath.c_str());
	g_dbus_cleanup_connection(dBus);
	return	EXIT_SUCCESS;
}

[-- Attachment #3: Type: text/plain, Size: 347 bytes --]

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG)
  2008-07-04 21:01 [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG) David Stockwell
@ 2008-07-05 17:17 ` Marcel Holtmann
  2008-07-05 23:39   ` David Stockwell
  0 siblings, 1 reply; 5+ messages in thread
From: Marcel Holtmann @ 2008-07-05 17:17 UTC (permalink / raw)
  To: BlueZ development

Hi David,

> Over the last few days, I have developed an Agent to implement the
> org.bluez.Agent interface, so that I can test the new BT2.1-compatible
> Simple Secure Pairing (SSP).
> 
> I am developing in C/C++ with Glib and libgdbus, which provides the
> functions and structures for method and signal definition and especially
> provides for DBus introspection.  Also, I expected to develop this as a
> separate process, much like the old passkey-agent.  I found that when I
> did this, however, the new agent was never found by my application,
> calling the Adapter.CreatePairedDevice method.  When I tested with the
> hcid/simple-agent, that Python-based agent worked well.  I would like to
> share the reasons for this...

this sounds like a bug in hcid. You can use CreateDevice on a Bluetooth
2.1 device and it will do just-works pairing.

Or try to call CreatePairedDevice with a wrong agent path and it should
gently fallback to the default one.

> 1) When first testing the agent as a separate process, I figured I had
> to tie that agent to the org.bluez well-known name.  The only way I
> could find to do that was to connect to the Session bus (not the System
> bus), and provide "org.bluez" as the name of the bus in the session.  I
> used this to test the functioning of the agent with dbus-send.  However,
> when I tried calling CreatePairedDevice from my application, it did not
> find the agent; the error message in syslog indicated that Method
> RequestPinCode with signature "o" was not found.

This is total non-sense. Session bus and system are two separate things
and nothing to do with each other.

> 2) Knowing that hcid uses the System bus, I then tried to connect with
> the System bus, referencing the "org.bluez" well-known connection name.
> However, the connection was rejected because (as we all know) hcid owns
> that name, and only one object can own a name at a time (and hcid was
> not going to give it up!).

An agent has not to provide a well known name. Our whole design is based
on the fact that an agent can connect to the system with a unique name.
Meaning that we don't need a security config file for the agent.

> 3) I connected the agent with the System bus leaving the service name
> NULL, so the agent object was assigned a "unique connection name",
> something like :1.56 (changes each time).  I was able to introspect the
> object, and to invoke some of the methods using dbus-send, so long as I
> addressed the System bus (--system) and set the destination with that
> unique connection name (--dest =:1.56).  I also went down a path of
> calling RegisterAgent from within the external Agent; this worked
> properly in the sense that DBus was happy with it, the Agent was still
> reachable from dbus-send, etc.

That is how it is suppose to be. The :1.56 is the unique and it is
unique for the life time of the system. It will never get re-assigned.

> 4) I attempted to connect with the registered Agent using
> Adapter.CreatePairedDevice, the Agent was not connected to.  The reason
> for this is that CreatePairedDevice explicitly uses its own "unique
> connection name" to the System bus as the "bus name", and assumes that
> the Object Path will be found on that bus name.  Which is only the case
> if the Agent code is contained within the same process as the rest of
> the application; the application calling CreatePairedDevice.

The object paths are per connection to the bus. So application A has its
own namespace for the objects and application B has another one.

> BUG-> If there is no object with that path for the unique connection
> name, the code at hcid/agent.c agent_create (line 190) should throw an
> error, perhaps .DoesNotExist...  What actually happens is that the code
> just creates that path and attempts to call it during pairing; throwing
> no error (except for the DBus error that shows up in the syslog).
> Authentication then fails with no accurate indication as to why.

The type DBUS_TYPE_OBJECT_PATH has to be at least "/".

> 5) I attempted to register the Agent within the application using
> Adapter.RegisterAgent.  However, again RegisterAgent assumes that the
> bus name to be used is its own unique connection name; it does not
> search for the object among other connections to the System bus, nor is
> there any way to pass in a well-known name or a unique connection name.
> 
> BUG-> (actually, the same bug) As with CreatePairedDevice, if there is
> no object with that path for the unique connection name, RegisterAgent
> should throw an error.

Not a bug. We don't care. If calling the Agent object fails, then we
fail the pairing process. That is perfectly fine.

> 6) Finally, I very slightly revamped my Agent code, changed the sub main
> to a callable subroutine from my main application and integrated it into
> the mainloop of the application.  All now works well, because the
> application and the Agent are in the same process and share the same
> connection to the System bus.

That is how it is meant to be :)

> YOU MAY ASK, why did I not integrate the Agent code into the main
> application in the first place?
> 
> The first reason is that it was not clear that this is what I needed to
> do.  Although I did receive a hint about this from Johan Hedburg
> (thanks!), I expected the agent should be a separate process, much like
> the 3.x passkey-agent and auth-agent.
> 
> Second, depending on the application requirements, the agent may require
> entry of a pincode or passkey (in my case, I am using SSP-JustWorks, so
> human entry should not be needed).  Depending on the requirements, the
> Agent should not hang up the main application waiting for human
> interaction.  (That said, you could non-block the IO and multi-thread
> the whole thing...).

Nothing is blocking anything. The agent is fully async. Fix your agent
implementation :)

> Third, I just felt that putting the Agent in another process is a
> somewhat more modular way to handle security, authorization and pairing.

For the default agent, yes, and that is still possible. For the pairing
specific agent, they are tightly coupled anyway. The use case is a
wizard like setup dialog.

> Fourth, because it was there (the challenge of figuring this out,
> learning more about DBus, GLib and the whole mess).
> 
> To that end, and in the interest of sharing, I am submitting my agent
> code as a skeleton...  To react to RequestPinCode and RequestPasskey, I
> have hardcoded values... I compile with C++ and use cout and string
> because I am lazy (in this experimental phase); converting to standard
> C, or to popping up a dialog, is trivial.  And I throw no errors (e.g.,
> .Reject), nor do I really do anything with respect to actual
> authorization, etc.  In other words,  it's just a start, designed to
> allow me to see the interaction with the Agent during pairing,
> especially with SSP.

You know that there is a simple-agent Python script inside the
bluez-utils source code :)

Regards

Marcel



-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG)
  2008-07-05 17:17 ` Marcel Holtmann
@ 2008-07-05 23:39   ` David Stockwell
  2008-07-06 10:59     ` Marcel Holtmann
  0 siblings, 1 reply; 5+ messages in thread
From: David Stockwell @ 2008-07-05 23:39 UTC (permalink / raw)
  To: BlueZ development

> Hi David,

Hello, Marcel...
>
>> Over the last few days, I have developed an Agent to implement the
>> org.bluez.Agent interface, so that I can test the new 
>> BT2.1-compatible
>> Simple Secure Pairing (SSP).
>>
>> did this, however, the new agent was never found by my application,
>> calling the Adapter.CreatePairedDevice method.  When I tested with 
>> the
>> hcid/simple-agent, that Python-based agent worked well.  I would like 
>> to
>> share the reasons for this...
>
> this sounds like a bug in hcid. You can use CreateDevice on a 
> Bluetooth
> 2.1 device and it will do just-works pairing.

When I CreatePairedDevice, the devices pair, but end up using legacy 
pairing with a pin code.  This makes me suspicious.

At the same time, CreateDevice does not appear to attempt to pair at 
all.

I am investigating to see if somehow my remote device is not in SSP mode 
(s/b default at this level of CSR's BlueLab SDK).  Alternatively, I am 
checking to see if the BT USB dongle is not quite capable of supporting 
SSP, because of an older HCI stack.
>
> Or try to call CreatePairedDevice with a wrong agent path and it 
> should
> gently fallback to the default one.

Thanks, now that my in-process Agent is working, I have verified that 
this fallback works.
>
>> 1) When first testing the agent as a separate process, I figured I 
>> had
>> to tie that agent to the org.bluez well-known name.  The only way I
>> could find to do that was to connect to the Session bus (not the 
>> System
>> bus), and provide "org.bluez" as the name of the bus in the session. 
>> I
>> used this to test the functioning of the agent with dbus-send. 
>> However,
>> when I tried calling CreatePairedDevice from my application, it did 
>> not
>> find the agent; the error message in syslog indicated that Method
>> RequestPinCode with signature "o" was not found.
>
> This is total non-sense. Session bus and system are two separate 
> things
> and nothing to do with each other.

Agreed, I was documenting my learning process...it would have been 
better to post this to bluez-users, not to bluez-devel (after all, you 
all know this in excruciating detail, right?)
>
>> 2) Knowing that hcid uses the System bus, I then tried to connect 
>> with
>> the System bus, referencing the "org.bluez" well-known connection 
>> name.
>
> An agent has not to provide a well known name. Our whole design is 
> based
> on the fact that an agent can connect to the system with a unique 
> name.
> Meaning that we don't need a security config file for the agent.

Agree with the concern for a security config file, which should not be a 
bluez issue in any event, but for the provider of the Agent.  However, 
if using a unique connection name, there is no way to pass that unique 
name to RegisterAgent.  Plus the issue of telling the 
RegisterAgent-calling what that unique name is.
>
>> 3) I connected the agent with the System bus leaving the service name
>> NULL, so the agent object was assigned a "unique connection name",
>> something like :1.56 (changes each time).  I was able to introspect 
>> the
>> object, and to invoke some of the methods using dbus-send, so long as 
>> I
>> addressed the System bus (--system) and set the destination with that
>> unique connection name (--dest =:1.56).  I also went down a path of
>> calling RegisterAgent from within the external Agent; this worked
>> properly in the sense that DBus was happy with it, the Agent was 
>> still
>> reachable from dbus-send, etc.
>
> That is how it is suppose to be. The :1.56 is the unique and it is
> unique for the life time of the system. It will never get re-assigned.

Yes, I know: again, better to send to bluez-users.  Sorry.
>
>> 4) I attempted to connect with the registered Agent using
>> Adapter.CreatePairedDevice, the Agent was not connected to.  The 
>> reason
>> for this is that CreatePairedDevice explicitly uses its own "unique
>> connection name" to the System bus as the "bus name", and assumes 
>> that
>> the Object Path will be found on that bus name.  Which is only the 
>> case
>> if the Agent code is contained within the same process as the rest of
>> the application; the application calling CreatePairedDevice.
>
> The object paths are per connection to the bus. So application A has 
> its
> own namespace for the objects and application B has another one.

For CreatePairedDevice, a bad path (e.g., /x/y/zzy) is fine and causes 
fall-back to the Register(ed)Agent if any.  Maybe a little inelegant 
(imho), but fine.
>
>
>> BUG-> (actually, the same bug) As with CreatePairedDevice, if there 
>> is
>> no object with that path for the unique connection name, 
>> RegisterAgent
>> should throw an error.
>
> Not a bug. We don't care. If calling the Agent object fails, then we
> fail the pairing process. That is perfectly fine.

I agree that failing pairing is OK; I am more concerned about 
RegisterAgent not finding the Object Path and not telling anybody (even 
the syslog).
>
>
> You know that there is a simple-agent Python script inside the
> bluez-utils source code :)

Yes, it was the basis for my work.  Thanks.  For perhaps irrational 
reasons, I prefer to use C/C++ at this point, despite the extra work.

That said, except for the "bug" questions, this should have been posted 
to bluez-users; I am sure there are others who may be struggling with 
these interfaces (and what is coming down the pike), and my intent is to 
save them a bit of struggle.

Best regards, David
>
> Regards
>
> Marcel
>
>
>
>
> 


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG)
  2008-07-05 23:39   ` David Stockwell
@ 2008-07-06 10:59     ` Marcel Holtmann
  2008-07-07 15:21       ` [Bluez-devel] Creating a 4.x org.bluez.Agent (more on SSP) David Stockwell
  0 siblings, 1 reply; 5+ messages in thread
From: Marcel Holtmann @ 2008-07-06 10:59 UTC (permalink / raw)
  To: BlueZ development

Hi David,

> >> Over the last few days, I have developed an Agent to implement the
> >> org.bluez.Agent interface, so that I can test the new 
> >> BT2.1-compatible
> >> Simple Secure Pairing (SSP).
> >>
> >> did this, however, the new agent was never found by my application,
> >> calling the Adapter.CreatePairedDevice method.  When I tested with 
> >> the
> >> hcid/simple-agent, that Python-based agent worked well.  I would like 
> >> to
> >> share the reasons for this...
> >
> > this sounds like a bug in hcid. You can use CreateDevice on a 
> > Bluetooth
> > 2.1 device and it will do just-works pairing.
> 
> When I CreatePairedDevice, the devices pair, but end up using legacy 
> pairing with a pin code.  This makes me suspicious.

you will need the kernel patches from my bluetooth-2.6 repository to
enable Simple Pairing.

> At the same time, CreateDevice does not appear to attempt to pair at 
> all.

With Simple Pairing it is just-works model. Otherwise no pairing.

> >> 2) Knowing that hcid uses the System bus, I then tried to connect 
> >> with
> >> the System bus, referencing the "org.bluez" well-known connection 
> >> name.
> >
> > An agent has not to provide a well known name. Our whole design is 
> > based
> > on the fact that an agent can connect to the system with a unique 
> > name.
> > Meaning that we don't need a security config file for the agent.
> 
> Agree with the concern for a security config file, which should not be a 
> bluez issue in any event, but for the provider of the Agent.  However, 
> if using a unique connection name, there is no way to pass that unique 
> name to RegisterAgent.  Plus the issue of telling the 
> RegisterAgent-calling what that unique name is.

The whole point is not to pass bus names around at all. We get the
unique name of the agent from the D-Bus message. This is all meant to be
this way so we can track the existence of an agent and if it dies
unexpectedly. Also you can only register yourself as an agent. You
should never mess around with other applications. It is on purpose
contained like this.

> >> 4) I attempted to connect with the registered Agent using
> >> Adapter.CreatePairedDevice, the Agent was not connected to.  The 
> >> reason
> >> for this is that CreatePairedDevice explicitly uses its own "unique
> >> connection name" to the System bus as the "bus name", and assumes 
> >> that
> >> the Object Path will be found on that bus name.  Which is only the 
> >> case
> >> if the Agent code is contained within the same process as the rest of
> >> the application; the application calling CreatePairedDevice.
> >
> > The object paths are per connection to the bus. So application A has 
> > its
> > own namespace for the objects and application B has another one.
> 
> For CreatePairedDevice, a bad path (e.g., /x/y/zzy) is fine and causes 
> fall-back to the Register(ed)Agent if any.  Maybe a little inelegant 
> (imho), but fine.

The right way is to actually implement an agent if you wanna use
CreatePairedDevice. This fallback happens to work. Use it if you must,
but we are not encouraging people to do so. Also when writing real UI
application you do want a specific agent in this case anyway.

> >> BUG-> (actually, the same bug) As with CreatePairedDevice, if there 
> >> is
> >> no object with that path for the unique connection name, 
> >> RegisterAgent
> >> should throw an error.
> >
> > Not a bug. We don't care. If calling the Agent object fails, then we
> > fail the pairing process. That is perfectly fine.
> 
> I agree that failing pairing is OK; I am more concerned about 
> RegisterAgent not finding the Object Path and not telling anybody (even 
> the syslog).

Again. That is up to the agent to implement this right. Doing any extra
checking for hcid side is wasted time. And we do syslog issues when
calling the agent fails.

> > You know that there is a simple-agent Python script inside the
> > bluez-utils source code :)
> 
> Yes, it was the basis for my work.  Thanks.  For perhaps irrational 
> reasons, I prefer to use C/C++ at this point, despite the extra work.

I have to fixup the passkey-agent.c example, but there was simply no
time.

> That said, except for the "bug" questions, this should have been posted 
> to bluez-users; I am sure there are others who may be struggling with 
> these interfaces (and what is coming down the pike), and my intent is to 
> save them a bit of struggle.

I don't care. In a few month I will merge the mailing lists anyway.

Regards

Marcel



-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bluez-devel] Creating a 4.x org.bluez.Agent (more on SSP)
  2008-07-06 10:59     ` Marcel Holtmann
@ 2008-07-07 15:21       ` David Stockwell
  0 siblings, 0 replies; 5+ messages in thread
From: David Stockwell @ 2008-07-07 15:21 UTC (permalink / raw)
  To: BlueZ development

Hello again, Marcel...

> Hi David,
>
> you will need the kernel patches from my bluetooth-2.6 repository to
> enable Simple Pairing.

I have them and have installed them.  The problem is that I am using a 
BT2.0 compliant USB dongle.  Alas, no BT2.1 compliant dongle is 
available in the US market at this time.

>> At the same time, CreateDevice does not appear to attempt to pair at
>> all.
>
> With Simple Pairing it is just-works model. Otherwise no pairing.

As above, Simple Pairing is not possible, but it does not appear to even 
attempt to fall back to legacy mode.  No messages, no errors thrown, no 
debug messages.

>> For CreatePairedDevice, a bad path (e.g., /x/y/zzy) is fine and 
>> causes
>> fall-back to the Register(ed)Agent if any.  Maybe a little inelegant
>> (imho), but fine.
>
> The right way is to actually implement an agent if you wanna use
> CreatePairedDevice. This fallback happens to work. Use it if you must,
> but we are not encouraging people to do so. Also when writing real UI
> application you do want a specific agent in this case anyway.

Agreed...my comment has to do with the fact that one MUST use 
CreatePairedDevice (at least at this point) to pair.  CreateDevice does 
not even attempt to pair (or at least that is the case if SSP is not 
available).

If you use CreatePairedDevice, you must supply an object path (valid or 
invalid) for the agent.  Therefore, as far as I am concerned, there is 
no real point to registering an agent at all, given that I must supply 
the path to CreatePairedDevice in any event.

On the other hand, if CreateDevice should trigger pairing and actually 
does, and if it can fall back to some default legacy pairing mode, well 
and good.  No agent needed at all.

> I have to fixup the passkey-agent.c example, but there was simply no
> time.

I will be happy to send you mine to save you the effort, unless it 
totally sucks.

Cheers... 


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-07-07 15:21 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-04 21:01 [Bluez-devel] Creating a 4.x org.bluez.Agent (with BUG) David Stockwell
2008-07-05 17:17 ` Marcel Holtmann
2008-07-05 23:39   ` David Stockwell
2008-07-06 10:59     ` Marcel Holtmann
2008-07-07 15:21       ` [Bluez-devel] Creating a 4.x org.bluez.Agent (more on SSP) David Stockwell

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