On Mon, 2009-07-27 at 08:44 +0100, Zhao, Forrest wrote:
> The second point is best solved via an obexd plugin. This is
were help
> would be very welcome. Forrest, do you think you could point us in the
> right direction? My hope that this is trivial for someone who knows
> the obexd source code. We could use help:
> 1. addding a new SyncML plugin to obexd
> 2. adding the SyncML service description (OBEX binding document,
> 5.2.1)
> 3. writing stubs for Connect/Disconnect/Put/Get/Abort operations:
> * CONNECT: use a dummy connection ID
> * PUT: discard incoming data
> * GET: send dummy data
> 4. how the data could be exchanged with a D-Bus service as part
> of the obexd event loop
>
> These stubs then need to be extended so that they actually talk to the
> sync D-Bus service via its (still to be defined) API.
Your described code logic is almost right to support SyncML
client/OBEX server. But I think we could start this work after sync
D-Bus API is stable.
The requirements of the obexd plugin drive the design D-Bus API, so we
need to work on this in parallel. Here's my take on obexd + synx D-Bus
server interaction for a server initiated sync via OBEX, with
SyncEvolution acting as SyncML client:
1. obexd: publish SyncML as Bluetooth service
2. third-party SyncML server (could use libsyncml command line tool
for testing): pair with Bluetooth stack, create connection to
obexd
3. obexd: instantiate org.syncevolution.sync service,
*asynchronously* call connect(config="", session=0,
transporthandle=org.syncevolution.transport instance)
4. syncevo-dbus-server: look up default configuration (config="")
and accept the connection, returning a org.syncevolution.session
instance and the corresponding session number
5. obexd: accept the OBEX connection, setting the session number as
connection ID
6. SyncML server: PUT SyncML Notification message
7. obexd: gather complete data of all PUTs, call
transporthandle.process(data=byte array, mime type=string)
8. syncevo-dbus-server:
* check type to distinguish between server initiated sync
("application/vnd.syncml.ds.notification", supported)
and SyncML client ("application/vnd.syncml+(wb)xml", not
supported yet)
* instantiate EvolutionSyncClient based on parameters in
the notification message, with transporthandle as
transport agent
* run the sync, let it produce the first SyncML message
* return that message as result of
transporthandle.process(), then go idle
9. obexd: reply (?) to GET with that data
10. obexd+syncevo-dbus-server: process more PUT/GET exchanges in the
same way until transporthandle.process() returns an empty
message, indicating the end of the session, but with
transporthandle still valid
11. obexd: close connection, call
transporthandle.close(success=true/false) indicating whether the
connection was shut down properly
12. syncevo-dbus-server: treat the last message as sent, close down
sync session, free transporthandle
The session number was chosen as integer value because not all transport
stubs might support a string, whereas an integer can always be turned
into a string. What is the type of an OBEX Connection ID?
All calls must be made asynchronously. There is no guaranteed response
time for any of them.
I'm not sure how the OBEX server initiates or replies to the GET that
the binding document describes. I hope the experts know better how to
implement that ;-)
Error handling: if syncevo-dbus-server dies unexpectedly, all
communication with transporthandle fails. There's no way to recover from
this. The OBEX client must be told that there was a unrecoverable error.
I'm less sure about the situation when the connection or obexd go down.
In HTTP, clients can resend their PUT with the old URL (which often
includes a session ID). If the server is smart, it will keep that
session alive long enough to continue despite intermittent loss of IP
connectivity and the resulting transport error. Is the same possible
with OBEX, in other words, can an OBEX client reconnect with the same
connection ID?
It doesn't seem like this is possible. Just in case (and for HTTP), the
connect() call above takes a session identifier. If non-null, it can
check whether that session is still alive and reconnect to it.
If OBEX really doesn't support resuming an interrupted connection, then
syncevo-dbus-server would have to check whether the first message in a
new connection is something which matches an active session. That
changes steps 3-7, because the connect cannot be processed without the
message data. A unique ID for the peer would be useful, but only if it
remains constant after a loss of connection. In HTTP that's not the
case, because the same client might have a different IP after
reconnecting.
I hope the description above makes sense. If not, then let's clarify the
questions that I raised and I'll follow up with a detailed D-Bus API
description.
--
Best Regards, Patrick Ohly
The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.