summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orlenko <zxteam@gmail.com>2010-08-03 19:47:11 +1100
committerAlexander Orlenko <zxteam@gmail.com>2010-08-03 19:47:11 +1100
commita3829c5c961ac8ba2e90761ce9a07db702501a3a (patch)
treec71c10e0ed3882e391fb7f860a6b417e67b28d96
parent1b0516575b99c06046004771bd2d1d7dbebc06b2 (diff)
downloadbluez-tools-a3829c5c961ac8ba2e90761ce9a07db702501a3a.tar.gz
Added support of obex-data-server API
-rw-r--r--contrib/bluez-api-4.66-fixed/agent.xml (renamed from contrib/bluezAgent.xml)0
-rwxr-xr-xcontrib/gen-dbus-gobject.pl18
-rwxr-xr-xcontrib/generate-all.sh14
-rw-r--r--contrib/obex-data-server-api-0.4.5-fixed.txt858
-rw-r--r--src/Makefile.am8
-rw-r--r--src/lib/marshallers.c286
-rw-r--r--src/lib/marshallers.h82
-rw-r--r--src/lib/marshallers.list11
-rw-r--r--src/lib/obexmanager.c263
-rw-r--r--src/lib/obexmanager.h73
-rw-r--r--src/lib/obexserver.c372
-rw-r--r--src/lib/obexserver.h73
-rw-r--r--src/lib/obexserver_session.c350
-rw-r--r--src/lib/obexserver_session.h71
-rw-r--r--src/lib/obexsession.c495
-rw-r--r--src/lib/obexsession.h85
16 files changed, 2961 insertions, 98 deletions
diff --git a/contrib/bluezAgent.xml b/contrib/bluez-api-4.66-fixed/agent.xml
index 86e442b..86e442b 100644
--- a/contrib/bluezAgent.xml
+++ b/contrib/bluez-api-4.66-fixed/agent.xml
diff --git a/contrib/gen-dbus-gobject.pl b/contrib/gen-dbus-gobject.pl
index 0f893be..8095a91 100755
--- a/contrib/gen-dbus-gobject.pl
+++ b/contrib/gen-dbus-gobject.pl
@@ -199,7 +199,7 @@ sub get_default_value {
my $default_value;
$default_value = 'NULL' if $c_type =~ /\*$/;
- $default_value = 'FALSE' if $c_type eq 'gboolean';
+ $default_value = 'FALSE' if $c_type =~ /boolean/;
$default_value = '0' if $c_type =~ /int/;
die "unknown C type (3): $c_type\n" unless defined $default_value;
@@ -654,6 +654,10 @@ EOT
$signals_registration .=
"\t\t\tg_cclosure_marshal_VOID__STRING,\n".
"\t\t\tG_TYPE_NONE, 1, G_TYPE_STRING);\n\n";
+ } elsif ($arg_t eq 'object_string_string') {
+ $signals_registration .=
+ "\t\t\tg_cclosure_bluez_marshal_VOID__STRING_STRING_STRING,\n".
+ "\t\t\tG_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);\n\n";
} elsif ($arg_t eq 'string_variant') {
$signals_registration .=
"\t\t\tg_cclosure_bluez_marshal_VOID__STRING_BOXED,\n".
@@ -666,10 +670,22 @@ EOT
$signals_registration .=
"\t\t\tg_cclosure_bluez_marshal_VOID__STRING_BOOLEAN,\n".
"\t\t\tG_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);\n\n";
+ } elsif ($arg_t eq 'uint64') {
+ $signals_registration .=
+ "\t\t\tg_cclosure_bluez_marshal_VOID__UINT64,\n".
+ "\t\t\tG_TYPE_NONE, 1, G_TYPE_UINT64);\n\n";
} elsif ($arg_t eq 'int32_int32') {
$signals_registration .=
"\t\t\tg_cclosure_bluez_marshal_VOID__INT_INT,\n".
"\t\t\tG_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);\n\n";
+ } elsif ($arg_t eq 'string_string') {
+ $signals_registration .=
+ "\t\t\tg_cclosure_bluez_marshal_VOID__STRING_STRING,\n".
+ "\t\t\tG_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);\n\n";
+ } elsif ($arg_t eq 'string_string_uint64') {
+ $signals_registration .=
+ "\t\t\tg_cclosure_bluez_marshal_VOID__STRING_STRING_UINT64,\n".
+ "\t\t\tG_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64);\n\n";
} else {
die "unknown signal arguments: $arg_t\n";
}
diff --git a/contrib/generate-all.sh b/contrib/generate-all.sh
index 42ce4b6..30b6c73 100755
--- a/contrib/generate-all.sh
+++ b/contrib/generate-all.sh
@@ -39,3 +39,17 @@
./gen-dbus-gobject.pl -header bluez-api-4.66-fixed/serial-api.txt > ../src/lib/serial.h
./gen-dbus-gobject.pl -source bluez-api-4.66-fixed/serial-api.txt > ../src/lib/serial.c
+# obex-data-server API
+
+./gen-dbus-gobject.pl -header obex-data-server-api-0.4.5-fixed.txt > ../src/lib/obexmanager.h
+./gen-dbus-gobject.pl -source obex-data-server-api-0.4.5-fixed.txt > ../src/lib/obexmanager.c
+
+./gen-dbus-gobject.pl -header obex-data-server-api-0.4.5-fixed.txt 2 > ../src/lib/obexserver.h
+./gen-dbus-gobject.pl -source obex-data-server-api-0.4.5-fixed.txt 2 > ../src/lib/obexserver.c
+
+./gen-dbus-gobject.pl -header obex-data-server-api-0.4.5-fixed.txt 3 > ../src/lib/obexsession.h
+./gen-dbus-gobject.pl -source obex-data-server-api-0.4.5-fixed.txt 3 > ../src/lib/obexsession.c
+
+./gen-dbus-gobject.pl -header obex-data-server-api-0.4.5-fixed.txt 4 > ../src/lib/obexserver_session.h
+./gen-dbus-gobject.pl -source obex-data-server-api-0.4.5-fixed.txt 4 > ../src/lib/obexserver_session.c
+
diff --git a/contrib/obex-data-server-api-0.4.5-fixed.txt b/contrib/obex-data-server-api-0.4.5-fixed.txt
new file mode 100644
index 0000000..b9a7325
--- /dev/null
+++ b/contrib/obex-data-server-api-0.4.5-fixed.txt
@@ -0,0 +1,858 @@
+OBEX API description
+********************
+
+Manager hierarchy
+===============================
+
+Service org.openobex
+Interface org.openobex.Manager
+Object path /org/openobex
+Object name OBEXManager
+
+Methods object CreateBluetoothSession(string target_address, string source_address, string pattern)
+
+ Creates a Bluetooth OBEX session and returns the new session object
+ of type org.openobex.Session. Session is automatically connected.
+ The target_address represents the remote Bluetooth device,
+ source_address specifies which Bluetooth adapter to use
+ (to use default adapter, use "00:00:00:00:00:00") and
+ the pattern specifies the OBEX service it connects to,
+ or the OBEX service using a fixed Bluetooth channel.
+ Pattern can be a UUID-128 identifying the service or
+ place holder as "opp" (for Object Push) or "ftp" (for FTP).
+ In case you want to use a fixed channel, UUID has to be
+ like: UUID:CHANNEL where UUID is a valid UUID or service
+ place holder like before, and CHANNEL is an integer
+ representing a valid RFCOMM channel. Session object can
+ only be used when SessionConnected signal is emitted.
+ If connection fails (remote device refuses connection, link dies, etc.),
+ SessionConnectError signal is emitted instead. To cancel
+ connecting use CancelSessionConnect method.
+
+ Returns object path for the created session.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+ org.openobex.Error.TransportNotAvailable
+
+ object CreateBluetoothImagingSession(string target_address, string source_addres, string bip_feature) {skiped}
+
+ Create Bluetooth OBEX session using BIP profile and returns new
+ session object of type org.openobex.Session. target_address
+ represents the remote Bluetooth device, source_address specifies
+ which Bluetooth adapter to use ("00:00:00:00:00:00" for default
+ adapter). bip_feature specifies imaging feature to use
+ ("imagepush" or "remotedisplay"). In case you want to use a fixed
+ RFCOMM channel, bip_feature has to be like FEATURE:CHANNEL where
+ CHANNEL is an integer representing a valid RFCOMM channel. Session
+ object can only be used when SessionConnected signal is emitted.
+ If connection fails, SessionConnectError signal is emitted instead.
+ To cancel connecting use CancelSessionConnect method.
+
+ Returns object path for the created session.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+ org.openobex.Error.TransportNotAvailable
+
+ object CreateUsbSession(integer interface_number, string profile) {skipped}
+
+ Creates a USB OBEX session and returns the new session object
+ of type org.openobex.Session. Session is automatically connected.
+ To find out about available USB OBEX interfaces, use GetUsbInterfacesNum
+ and GetUsbInterfaceInfo. profile specifies profile to be used for
+ session (FTP profile is commonly used for USB OBEX sessions).
+ Session object can only be used when SessionConnected signal is emitted.
+ If connection fails (remote device refuses connection, link dies, etc.),
+ SessionConnectError signal is emitted instead.
+ Do not use CancelSessionConnect with USB sessions (connection is
+ established instantly).
+
+ Returns object path for the created session.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+ org.openobex.Error.TransportNotAvailable
+
+ object CreateTtySession(string tty_dev, string profile) {skipped}
+
+ Creates OBEX session using TTY device and returns the new session
+ object of type org.openobex.Session. Session is automatically
+ connected.
+ tty_dev specifies TTY device node.
+ pattern specifies the profile to be used for session which may be
+ either "ftp" for OBEX FTP server, "opp" for OBEX Object Push server
+ or "bip" for OBEX Basic Imaging server.
+ Session object can only be used when SessionConnected signal is emitted.
+ If connection fails (remote device refuses connection, link dies, etc.),
+ SessionConnectError signal is emitted instead.
+ Do not use CancelSessionConnect with TTY sessions (connection is
+ established instantly).
+
+ Returns object path for the created session.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+
+ integer GetUsbInterfacesNum() {skipped}
+
+ Returns the number of available USB OBEX interfaces
+
+ Possible errors: none
+
+ dict GetUsbInterfaceInfo(integer interface_number) {skipped}
+
+ Returns info about specified USB OBEX interface:
+ "Manufacturer" : Manufacturer of the device
+ "Product" : Product name of the device
+ "Serial" : Serial number of the device
+ "Configuration" : USB configuration that this interface belongs to
+ "ControlInterface" : description of the OBEX control interface, typically
+ reveals the functionality of the interface
+ "DataInterfaceIdle" : description of the OBEX data idle interface, typically empty
+ "DataInterfaceActive" : description of the OBEX data active interface, typically empty
+
+ If specified interface number is too large, returns empty structure.
+
+ Possible errors: none
+
+ boolean CancelSessionConnect(object session_object)
+
+ Cancells session connection. If Session is being connected,
+ connection will be cancelled and SessionConnectError signal
+ with org.openobex.Cancelled error will be emitted. If session
+ is already connected or invalid session is supplied, this function
+ will do nothing and FALSE will be returned.
+
+ Returns TRUE if cancelled successfully, FALSE otherwise.
+
+ Possible errors: none
+
+ object CreateBluetoothServer(string source_address, string pattern, boolean require_pairing)
+
+ Gets Server object for specified bluetooth source address.
+ source_address can be Bluetooth address of any adapter or just
+ "00:00:00:00:00:00" for default adapter.
+ pattern specifies the type of server to create which may be
+ either "ftp" for OBEX FTP server, "opp" for OBEX Object Push server
+ or "bip" for OBEX Basic Imaging server.
+ require_pairing specifies whether client device should be paired
+ before allowing any operations (recommended values: True for FTP,
+ False for OPP).
+
+ Returns object path for the created server.
+
+ Possible errors: org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.TransportNotAvailable
+
+ object CreateTtyServer(string tty_dev, string pattern) {skipped}
+
+ Gets Server object for specified TTY device (e.g. /dev/ttyUSB0).
+ This kind of server can be used on embedded devices to serve files via USB OBEX.
+ tty_dev specifies TTY device node.
+ pattern specifies the type of server which may be
+ either "ftp" for OBEX FTP server, "opp" for OBEX Object Push server
+ or "bip" for OBEX Basic Imaging server.
+
+ Return object path for the created server.
+
+ Possible errors: org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+
+ dict GetSessionInfo(object session_object)
+
+ Returns info about specified session:
+ "BluetoothTargetAddress" : Target device Bluetooth address (only for Bluetooth sessions);
+ "BluetoothSourceAddress" : Source Bluetooth address (hci device used) (only for Bluetooth sessions);
+ "BluetoothChannel" : RFCOMM channel used for session (only for Bluetooth sessions);
+ "UsbInterfaceNumber" : USB interface number (only for USB sessions);
+ "TTYDevice" : TTY device which is used (only for TTY sessions);
+ If specified session does not exist, returns empty structure.
+ session_object specifies DBus path of Session object.
+
+ Possible errors: none
+
+ dict GetServerInfo(object server_object)
+
+ Returns info about specified server:
+ "BluetoothSourceAddress" : Bluetooth source address (only for Bluetooth servers);
+ "RequirePairing" : if connecting to server triggers pairing (only for Bluetooth servers);
+ "TTYDevice" : TTY device which is used (only for TTY servers);
+ If specified session does not exist, returns empty structure.
+ server_object specifies DBus path of Server object.
+
+ Possible errors: none
+
+ array{string} GetSessionList()
+
+ Returns list of open sessions. Array contains DBus paths of sessions.
+
+ Possible errors: none
+
+ array{string} GetServerList()
+
+ Returns list of open servers. Array contains DBus paths of servers.
+
+ Possible errors: none
+
+ string GetVersion()
+
+ Returns obex-data-server version and obex-data-server API version.
+ Returned string is formated like that: "<ods_ver>:<ods_api_ver>".
+ API version is an integer. When API incompatible with older one is
+ released, this number is increased by one. As of ods version 0.4
+ API version is 1. Example of returned string: "0.4:1".
+
+ Possible errors: none
+
+Signals SessionConnected(object path)
+
+ Emitted when Session is connected to target device.
+
+ SessionConnectError(object path, string error_name, string error_message)
+
+ Emitted when Session connection fails. Session object must not be
+ used after that.
+
+ SessionClosed(object path)
+
+ Emitted when Session is closed and no longer valid.
+
+Server hierarchy
+===============================
+
+Service org.openobex
+Interface org.openobex.Server
+Object path /org/openobex/server{0,1,2...}
+Object name OBEXServer
+
+Methods void Start(string path, boolean allow_write, boolean auto_accept)
+
+ Starts OBEX Object Push / FTP server (begins
+ listening for connections). Started signal is emitted after
+ the server is started. If error occurs, ErrorOccurred signal is emitted
+ instead. Once the server is started, it emits SessionCreated signal
+ for every newly connected client.
+
+ If this is Object Push server, path defines where all received files
+ will be saved. In case of FTP server path is the top-level folder which
+ will be served. allow_write specifies whether write operations
+ will be allowed (put and delete). In most cases, allow_write should be
+ set to True.
+ auto_accept specifies whether incoming files should be always accepted
+ (recommended values: True for FTP, False for OPP). If auto_accept is
+ set to False, either Accept() or Reject() has to be called
+ every time after you receive TransferStarted signal in ServerSession
+ object. If Accept() or Reject() is not called in 15 seconds after
+ TransferStarted signal, timeout will happen and the incoming file will
+ be automatically rejected. It is important to listen for Cancelled
+ signal on ServerSession object when auto_accept is False because
+ you can receive Cancelled signal while waiting for user to accept or
+ reject incoming file. This would effectively mean that timeout happened
+ and the incoming file was rejected.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.Started
+
+ void Stop()
+
+ Stops the server. All client connections will be closed and
+ operations will be cancelled. Stopped signal is emitted
+ after the server is stopped.
+
+ Possible errors: org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotStarted
+
+ void Close()
+
+ Closes the server. If server is not stopped, all client connections
+ will be closed, operations will be cancelled. Server object will
+ be destroyed after that. Closed signal is emitted immediately
+ when this method is invoked.
+
+ Possible errors: org.openobex.Error.NotAuthorized
+
+ boolean IsStarted()
+
+ Returns true if server is started, false otherwise.
+
+ Possible errors: none
+
+ void SetOption(string name, variant value)
+
+ Sets server options. Supported options:
+ "Limit" : maximum server sessions that server will accept
+ (0 for no limit). Default is 0. Value type is uint16.
+ "RequireImagingThumbnails" : whether to require clients to send
+ thumbnails for uploaded images (specific to BIP servers).
+ Default is False. Value type is boolean.
+
+ Possible errors: org.openobex.Error.InvalidArguments
+
+ dict GetServerSessionInfo(object session_object)
+
+ Returns info about specified server session:
+ "BluetoothAddress" : Client device Bluetooth address;
+ If specified server session does not exist, returns empty structure.
+ session_object specifies DBus path of ServerSession object.
+
+ Possible errors: none
+
+ array{string} GetServerSessionList()
+
+ Returns list of open server sessions. Array contains DBus paths
+ of server sessions.
+
+ Possible errors: none
+
+Signals Started()
+
+ This signal informs that the server was started.
+
+ Stopped()
+
+ This signal informs that the server was stopped and all operations
+ were ceased.
+
+ Closed()
+
+ This signal informs that the server was closed and it's object is
+ no longer valid.
+
+ ErrorOccurred(string error_name, string error_message)
+
+ This signal informs that error occurred while starting or stopping
+ the server.
+
+ SessionCreated(object session_object)
+
+ Signal informs that client connected to server and new ServerSession
+ object was created. Returns path of ServerSession object.
+
+ SessionRemoved(object session_object)
+
+ Signal informs that client disconnected from server. Returns
+ path of ServerSession object that was closed.
+
+Session hierarchy
+===============================
+
+Service org.openobex
+Interface org.openobex.Session
+Object path /org/openobex/session{0,1,2...}
+Object name OBEXSession
+
+Methods void Disconnect()
+
+ Disconnects from remote device by sending OBEX disconnect command.
+ Disconnected signal is emitted once disconnected. Normally,
+ "Close" should be called immediately after Session is disconnected.
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.OutOfMemory
+
+ void Close()
+
+ Closes the session (the actual connection to remote device is closed).
+ Session object is finalized and can not be used anymore.
+ Closed signal is emitted once closed.
+
+ Possible errors: org.openobex.Error.Failed
+ org.openobex.Error.NotAuthorized
+
+ void ChangeCurrentFolder(string path)
+
+ Changes current path on a remote device to the specified one.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.OutOfMemory
+
+ void ChangeCurrentFolderBackward()
+
+ Changes current path on a remote device one level up. If current
+ folder is root, path is not changed.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.OutOfMemory
+
+ void ChangeCurrentFolderToRoot()
+
+ Changes current path on a remote device to root.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.OutOfMemory
+
+ string GetCurrentPath()
+
+ Returns current path on a remote device.
+
+ Possible errors: none
+
+ void CopyRemoteFile(string remote_filename, string local_path)
+
+ Starts receiving a specified file from a remote device.
+ remote_filename specifies the file to receive on a remote device.
+ local_path is the path where received file will be saved.
+ TransferStarted signal is emitted when transfer starts. If error
+ occurs during operation, ErrorOccurred signal is emitted instead.
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.NotFound
+ org.openobex.Error.OutOfMemory
+
+ void CopyRemoteFileByType(string type, string local_path)
+
+ Starts receiving default object of specified type from a remote
+ device. type specifies OBEX type to receive. local_path is the path
+ where received file will be saved. TransferStarted signal is emitted
+ when transfer starts. If error occurs during operation,
+ ErrorOccurred signal is emitted instead.
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.NotFound
+ org.openobex.Error.OutOfMemory
+
+ void CreateFolder(string folder_name)
+
+ Creates a folder on a remote device with a specified
+ name. This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Busy
+ org.openobex.Error.Failed
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.OutOfMemory
+
+ string RetrieveFolderListing()
+
+ Retrieves the list of files in the current folder.
+ The list is XML formatted string. See OBEX specification for
+ info about the format.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: none?
+
+ string GetCapability()
+
+ Retrieves the FTP capability object.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: none?
+
+ void SendFile(string local_path)
+
+ Starts sending a specified file to a remote device.
+ local_path specifies the path to file that will be sent.
+ TransferStarted signal is emitted when transfer starts. If error
+ occurs during operation, ErrorOccurred signal is emitted.
+
+ Possible errors: org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.Busy
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.OutOfMemory
+ org.openobex.Error.NotFound
+ !! org.openobex.Error.Failed
+
+ void SendFileExt(string local_path, string remote_filename, string type)
+
+ Starts sending a specified file to a remote device. It's possible
+ to specify different filename (remote_filename) than that of local
+ file. When remote_filename is empty, original filename is used.
+ type specifies particular OBEX type to send file as. type can be
+ empty. When type is used, remote_filename must be empty.
+ TransferStarted signal is emitted when transfer starts. If error
+ occurs during operation, ErrorOccurred signal is emitted.
+
+ Possible errors: org.openobex.Error.NotAuthorized
+ org.openobex.Error.NotConnected
+ org.openobex.Error.Busy
+ org.openobex.Error.InvalidArguments
+ org.openobex.Error.OutOfMemory
+ org.openobex.Error.NotFound
+ !! org.openobex.Error.Failed
+
+ void DeleteRemoteFile(string remote_filename)
+
+ Deletes specified file on remote device.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Failed
+
+ void RemoteCopy(string remote_source, string remote_destination)
+
+ FTP profile
+
+ Initiates remote copy operation (data is copied from one location
+ to the other in remote device). remote_source specifies a file
+ or folder to be copied (this file or folder has to exist in current
+ directory). remote_destination specifies path where to copy data.
+ This path can be relative to current folder or relative to root
+ folder. Both slash ('/') and backslash ('\') symbols can be used in
+ path. Example source/destination pairs :
+ 'File.txt' : 'Folder/OtherFolder/NewFile.txt'
+ 'Folder' : '/Folder/OtherFolder/NewFolder' (relative to root folder)
+ 'Folder' : 'Folder\NewFolder'
+ Note that ods does not check remote_destination argument validity.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+ ! This method is not included in official FTP profile specification,
+ therefore not many devices support it.
+
+ Possible errors: none?
+
+ void RemoteMove(string remote_source, string remote_destination)
+
+ FTP profile
+
+ Initiates remote move operation (data is moved from one location
+ to the other in remote device). See RemoteCopy method for how the
+ arguments should be used.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+ ! This method is not included in official FTP profile specification,
+ therefore not many devices support it.
+
+ Possible errors: none?
+
+ string GetImagingCapabilities() {skipped}
+
+ BIP profile, all features
+
+ Retrieves imaging capabilities object ("x-bt/img-capabilities").
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: none?
+
+ void GetImageInfo(string local_path, out uint16 width, out uint16 height, out string encoding) {skipped}
+
+ BIP profile utility function
+
+ Returns image info for specified locally stored image. Returns
+ width, height and encoding. Can be used to determine how image
+ should be resized to match remote device preferred image format
+ specified in imaging capabilities object.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.InvalidArguments
+ org.openobex.Error.NotSupported
+ org.openobex.Error.Failed
+
+ void PutImage(string local_path) {skipped}
+
+ BIP profile, ImagePush and RemoteDisplay features
+
+ Pushes image to remote device. local_path specifies image filename.
+ TransferStarted signal is emitted when transfer starts. If error
+ occurs during operation, ErrorOccurred signal is emitted. When
+ transfer finishes successfully, ImageHandleReceived signal is
+ emitted (ImageHandleReceived signal returns image handle for pushed
+ image to be used in further operations).
+
+ Possible errors: none?
+
+ void PutImageResized(string local_path, uint16 width, uint16 height, string encoding, string transformation) {skipped}
+
+ BIP profile, ImagePush and RemoteDisplay features
+
+ Pushes resized/encoded image to remote device. Client application
+ should parse ImagingCapabilities object prior to this to acquire
+ image formats supported by remote device. local_path specifies
+ original image filename. width and height specify new dimensions.
+ encoding specifies image format ("JPEG", "PNG", etc.). If encoding
+ is empty, original encoding will be preserved. See ImageMagick
+ supported formats list for available values. transformation
+ defines how image should be resized. Possible transformations are
+ "stretch" (stretches image to new dimensions), "crop" (crops image)
+ or "fill" (in case dimensions are bigger than original, image is filled
+ with white backround). If specified dimensions match the original
+ dimensions, no resizing will be done. If invalid transformation value
+ is used, "stretch" will be used by default.
+ TransferStarted signal is emitted when transfer starts. If error
+ occurs during operation, ErrorOccurred signal is emitted. When
+ transfer finishes successfully, ImageHandleReceived signal is
+ emitted (ImageHandleReceived signal returns image handle for pushed
+ image to be used in further operations).
+
+ Possible errors: none?
+
+ void PutLinkedAttachment(string image_handle, string local_path, string content_type, string charset) {skipped}
+
+ BIP profile, ImagePush feature
+
+ Pushes attachment linked to previously pushed image. image_handle
+ specifies handle of previously pushed image, local_path is path
+ to file to be sent. content_type specifies attachment's MIME
+ content type, e.g. "text/plain". content_type is optional and can
+ be empty. charset specifies charset in which attachment is encoded.
+ charset is also optional and can be empty. Progress of transfer
+ is reported using TransferStarted, TransferProgress, ErrorOccurred
+ and TransferCompleted signals.
+
+ Possible errors: none?
+
+ void RemoteDisplaySelectImage(string image_handle) {skipped}
+
+ BIP profile, RemoteDisplay feature
+
+ Selects previously pushed image (using PutImage or PutImageResized
+ methods). image_handle specifies image handle corresponding to
+ previously pushed image (returned by ImageHandleReceived signal).
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Failed
+
+ void RemoteDisplayShowCurrentImage() {skipped}
+
+ BIP profile, RemoteDisplay feature
+
+ Triggers remote device to show currently selected image.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Failed
+
+ void RemoteDisplayShowNextImage() {skipped}
+
+ BIP profile, RemoteDisplay feature
+
+ Triggers remote device to show next image.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Failed
+
+ void RemoteDisplayShowPreviousImage() {skipped}
+
+ BIP profile, RemoteDisplay feature
+
+ Triggers remote device to show previous image.
+ This method only returns after operation is finished.
+ This means that if method returned without any error,
+ operation is complete (this is in contrast with how file
+ transfers work).
+
+ Possible errors: org.openobex.Error.Failed
+
+ dict GetTransferInfo()
+
+ Returns info about the ongoing transfer:
+ "LocalPath" : full local path;
+ "RemoteFilename" : filename;
+ "Size" : total bytes being transferred;
+ "Time" : last modification time of file being sent;
+ "OBEXCommand" : either "GET" or "PUT";
+
+ Possible errors: none
+
+ boolean IsBusy()
+
+ Returns true if there is an operation in progress, false otherwise.
+
+ Possible errors: none
+
+ void Cancel()
+
+ Cancels any operation that is in progress.
+
+ Possible errors: org.openobex.Error.Failed
+
+Signals Cancelled()
+
+ This signal informs that the current transfer was cancelled either by
+ client or by server.
+
+ Disconnected()
+
+ This signal informs that the session was disconnected.
+
+ Closed()
+
+ This signal informs that the session was terminated and that it's object
+ is no longer valid.
+
+ TransferStarted(string filename, string local_path, uint64 total_bytes)
+
+ This signal informs that transfer was started.
+
+ total_bytes is the number of total bytes that are being sent (0
+ if total bytes are unknown). filename specifies the filename (without
+ path) of file being sent or null if it is unknown. local_path specifies
+ where the file is stored locally.
+
+ TransferProgress(uint64 bytes_transferred)
+
+ This signal is emitted constantly during the transfer.
+ bytes_transferred specifies how many bytes were already transferred.
+
+ TransferCompleted()
+
+ This signal informs that transfer was completed.
+
+ ErrorOccurred(string error_name, string error_message)
+
+ This signal informs that error occurred while performing some operation.
+
+ ImageHandleReceived(string image_handle, boolean thumbnail_requested) {skipped}
+
+ This signal returns image handle for pushed image (using PutImage or
+ PutImageResized). thumbnail_requested specifies whether Imaging
+ Responder requested client to send thumbnail. If thumbnail was
+ requested, TransferStarted/TransferProgress/TransferCompleted
+ signals will be emitted when transferring thumbnail.
+
+ServerSession hierarchy
+===============================
+
+Service org.openobex
+Interface org.openobex.ServerSession
+Object path /org/openobex/serversession{0,1,2...}
+Object name OBEXServerSession
+
+Methods void Accept()
+
+ Accepts incoming file (use this when auto_accept is set to False for
+ corresponding Server object). If auto_accept is True, this function will
+ do nothing. Call this method just after receiving TransferStarted signal.
+ If there is no transfer in progress or if current transfer is not
+ an incoming transfer, error will be returned. If you do not call
+ Accept() or Reject() in 15 seconds after TransferStarted signal,
+ incoming file will be automatically rejected and you will receive
+ Cancelled signal.
+
+ Possible errors: org.openobex.Error.Failed
+
+ void Reject()
+
+ Rejects incoming file (use this when auto_accept is set to False for
+ corresponding Server object). If auto_accept is True, this function will
+ do nothing. Call this method just after receiving TransferStarted signal.
+ If there is no transfer in progress or if current transfer is not
+ an incoming transfer, error will be returned. If you do not call
+ Accept() or Reject() in 15 seconds after TransferStarted signal,
+ incoming file will be automatically rejected and you will receive
+ Cancelled signal.
+
+ Possible errors: org.openobex.Error.Failed
+
+ void Disconnect()
+
+ Disconnects from remote device.
+ ServerSession object is finalized and can not be used anymore.
+ Disconnected signal is emitted once disconnected.
+
+ Possible errors: none?
+
+ dict GetTransferInfo()
+
+ Returns all info about the ongoing transfer (filename, local path,
+ total bytes).
+
+ Possible errors: none
+
+ void Cancel()
+
+ Cancels any operation that is in progress.
+
+ Possible errors: org.openobex.Error.Failed
+
+Signals Cancelled()
+
+ This signal informs that the current transfer was cancelled either by
+ client or by server.
+
+ Disconnected()
+
+ This signal informs that the ServerSession was disconnected.
+ ServerSession object is finalized and can not be used anymore.
+
+ TransferStarted(string filename, string local_path, uint64 total_bytes)
+
+ This signal informs that transfer was started.
+
+ total_bytes is the number of total bytes that are being sent (0
+ if total bytes are unknown). filename specifies the filename (without
+ path) of file being sent or null if it is unknown. local_path specifies
+ where the file is stored locally.
+
+ TransferProgress(uint64 bytes_transferred)
+
+ This signal is emitted constantly during the transfer.
+ bytes_transferred specifies how many bytes were already transferred.
+
+ TransferCompleted()
+
+ This signal informs that transfer was completed.
+
+ ErrorOccurred(string error_name, string error_message)
+
+ This signal informs that error occurred while performing some operation.
+
+ RemoteDisplayRequested(string filename) {skipped}
+
+ This signal is used for Imaging sessions that use Remote Display
+ feature. Signal informs that remote device requested display of
+ previously uploaded image. filename specifies the filename of image
+ to be displayed.
diff --git a/src/Makefile.am b/src/Makefile.am
index aab0406..4e499fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,7 +28,12 @@ lib_sources = lib/marshallers.c lib/marshallers.h \
lib/serial.c lib/serial.h \
lib/sdp.c lib/sdp.h
-bin_PROGRAMS = bt-monitor bt-adapter bt-agent bt-device bt-input bt-audio bt-network bt-serial
+obex_sources = lib/obexmanager.c lib/obexmanager.h \
+ lib/obexsession.c lib/obexsession.h \
+ lib/obexserver.c lib/obexserver.h \
+ lib/obexserver_session.c lib/obexserver_session.h
+
+bin_PROGRAMS = bt-monitor bt-adapter bt-agent bt-device bt-input bt-audio bt-network bt-serial bt-obex
bt_monitor_SOURCES = $(lib_sources) bt-monitor.c
bt_adapter_SOURCES = ${lib_sources} bt-adapter.c
bt_agent_SOURCES = $(lib_sources) bt-agent.c
@@ -37,6 +42,7 @@ bt_input_SOURCES = $(lib_sources) bt-input.c
bt_audio_SOURCES = $(lib_sources) bt-audio.c
bt_network_SOURCES = $(lib_sources) bt-network.c
bt_serial_SOURCES = $(lib_sources) bt-serial.c
+bt_obex_SOURCES = $(lib_sources) $(obex_sources) bt-obex.c
#CLEANFILES = Makefile.in lib/marshallers.c lib/marshallers.h
diff --git a/src/lib/marshallers.c b/src/lib/marshallers.c
index 80801c6..8391165 100644
--- a/src/lib/marshallers.c
+++ b/src/lib/marshallers.c
@@ -47,7 +47,42 @@
#endif /* !G_ENABLE_DEBUG */
-/* VOID:STRING,BOXED (lib/marshallers.list:1) */
+/* VOID:UINT64 (lib/marshallers.list:1) */
+void
+g_cclosure_bluez_marshal_VOID__UINT64 (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__UINT64) (gpointer data1,
+ guint64 arg_1,
+ gpointer data2);
+ register GMarshalFunc_VOID__UINT64 callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__UINT64) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_uint64 (param_values + 1),
+ data2);
+}
+
+/* VOID:STRING,BOXED (lib/marshallers.list:2) */
void
g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
@@ -84,28 +119,24 @@ g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure,
data2);
}
-/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:2) */
+/* VOID:STRING,STRING (lib/marshallers.list:3) */
void
-g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
+g_cclosure_bluez_marshal_VOID__STRING_STRING (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (gpointer data1,
- gpointer arg_1,
- guint arg_2,
- guchar arg_3,
- gpointer arg_4,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER callback;
+ typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_STRING callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
- gboolean v_return;
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 5);
+ g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
@@ -117,38 +148,32 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closur
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
- callback = (GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (marshal_data ? marshal_data : cc->callback);
+ callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_uint (param_values + 2),
- g_marshal_value_peek_uchar (param_values + 3),
- g_marshal_value_peek_pointer (param_values + 4),
- data2);
-
- g_value_set_boolean (return_value, v_return);
+ callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ data2);
}
-/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:3) */
+/* VOID:STRING,STRING,STRING (lib/marshallers.list:4) */
void
-g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
+g_cclosure_bluez_marshal_VOID__STRING_STRING_STRING (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
{
- typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer arg_3,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER callback;
+ typedef void (*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_STRING_STRING callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
- gboolean v_return;
- g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 4);
if (G_CCLOSURE_SWAP_DATA (closure))
@@ -161,18 +186,55 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure,
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
- callback = (GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
+ callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data ? marshal_data : cc->callback);
- v_return = callback (data1,
- g_marshal_value_peek_boxed (param_values + 1),
- g_marshal_value_peek_string (param_values + 2),
- g_marshal_value_peek_pointer (param_values + 3),
- data2);
+ callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ g_marshal_value_peek_string (param_values + 3),
+ data2);
+}
- g_value_set_boolean (return_value, v_return);
+/* VOID:STRING,STRING,UINT64 (lib/marshallers.list:5) */
+void
+g_cclosure_bluez_marshal_VOID__STRING_STRING_UINT64 (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__STRING_STRING_UINT64) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ guint64 arg_3,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_STRING_UINT64 callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__STRING_STRING_UINT64) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ g_marshal_value_peek_uint64 (param_values + 3),
+ data2);
}
-/* BOOLEAN:POINTER (lib/marshallers.list:4) */
+/* BOOLEAN:POINTER (lib/marshallers.list:7) */
void
g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
@@ -211,7 +273,91 @@ g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:5) */
+/* BOOLEAN:STRING,POINTER (lib/marshallers.list:8) */
+void
+g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__STRING_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:9) */
+void
+g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__BOXED_STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_boxed (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ g_marshal_value_peek_pointer (param_values + 3),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:10) */
void
g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
@@ -254,7 +400,7 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:6) */
+/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:11) */
void
g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
@@ -297,26 +443,28 @@ g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* BOOLEAN:STRING,POINTER (lib/marshallers.list:7) */
+/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:12) */
void
-g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure,
- GValue *return_value G_GNUC_UNUSED,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint G_GNUC_UNUSED,
- gpointer marshal_data)
+g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
{
- typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__STRING_POINTER callback;
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (gpointer data1,
+ gpointer arg_1,
+ guint arg_2,
+ guchar arg_3,
+ gpointer arg_4,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 3);
+ g_return_if_fail (n_param_values == 5);
if (G_CCLOSURE_SWAP_DATA (closure))
{
@@ -328,11 +476,13 @@ g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure,
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
- callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
+ callback = (GMarshalFunc_BOOLEAN__BOXED_UINT_UCHAR_POINTER) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
- g_marshal_value_peek_string (param_values + 1),
- g_marshal_value_peek_pointer (param_values + 2),
+ g_marshal_value_peek_boxed (param_values + 1),
+ g_marshal_value_peek_uint (param_values + 2),
+ g_marshal_value_peek_uchar (param_values + 3),
+ g_marshal_value_peek_pointer (param_values + 4),
data2);
g_value_set_boolean (return_value, v_return);
diff --git a/src/lib/marshallers.h b/src/lib/marshallers.h
index 121b114..d5b7555 100644
--- a/src/lib/marshallers.h
+++ b/src/lib/marshallers.h
@@ -6,7 +6,15 @@
G_BEGIN_DECLS
-/* VOID:STRING,BOXED (lib/marshallers.list:1) */
+/* VOID:UINT64 (lib/marshallers.list:1) */
+extern void g_cclosure_bluez_marshal_VOID__UINT64 (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:STRING,BOXED (lib/marshallers.list:2) */
extern void g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -14,23 +22,31 @@ extern void g_cclosure_bluez_marshal_VOID__STRING_BOXED (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data);
-/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:2) */
-extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
+/* VOID:STRING,STRING (lib/marshallers.list:3) */
+extern void g_cclosure_bluez_marshal_VOID__STRING_STRING (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
-/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:3) */
-extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
+/* VOID:STRING,STRING,STRING (lib/marshallers.list:4) */
+extern void g_cclosure_bluez_marshal_VOID__STRING_STRING_STRING (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
-/* BOOLEAN:POINTER (lib/marshallers.list:4) */
+/* VOID:STRING,STRING,UINT64 (lib/marshallers.list:5) */
+extern void g_cclosure_bluez_marshal_VOID__STRING_STRING_UINT64 (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* BOOLEAN:POINTER (lib/marshallers.list:7) */
extern void g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -38,7 +54,23 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__POINTER (GClosure *closure,
gpointer invocation_hint,
gpointer marshal_data);
-/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:5) */
+/* BOOLEAN:STRING,POINTER (lib/marshallers.list:8) */
+extern void g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* BOOLEAN:BOXED,STRING,POINTER (lib/marshallers.list:9) */
+extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_STRING_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* BOOLEAN:BOXED,POINTER,POINTER (lib/marshallers.list:10) */
extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -46,7 +78,7 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_POINTER_POINTER (GClosure
gpointer invocation_hint,
gpointer marshal_data);
-/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:6) */
+/* BOOLEAN:BOXED,UINT,POINTER (lib/marshallers.list:11) */
extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -54,13 +86,13 @@ extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_POINTER (GClosure *
gpointer invocation_hint,
gpointer marshal_data);
-/* BOOLEAN:STRING,POINTER (lib/marshallers.list:7) */
-extern void g_cclosure_bluez_marshal_BOOLEAN__STRING_POINTER (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
+/* BOOLEAN:BOXED,UINT,UCHAR,POINTER (lib/marshallers.list:12) */
+extern void g_cclosure_bluez_marshal_BOOLEAN__BOXED_UINT_UCHAR_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
G_END_DECLS
diff --git a/src/lib/marshallers.list b/src/lib/marshallers.list
index 4096a34..93ec5f6 100644
--- a/src/lib/marshallers.list
+++ b/src/lib/marshallers.list
@@ -1,7 +1,12 @@
+VOID:UINT64
VOID:STRING,BOXED
-BOOLEAN:BOXED,UINT,UCHAR,POINTER
-BOOLEAN:BOXED,STRING,POINTER
+VOID:STRING,STRING
+VOID:STRING,STRING,STRING
+VOID:STRING,STRING,UINT64
+
BOOLEAN:POINTER
+BOOLEAN:STRING,POINTER
+BOOLEAN:BOXED,STRING,POINTER
BOOLEAN:BOXED,POINTER,POINTER
BOOLEAN:BOXED,UINT,POINTER
-BOOLEAN:STRING,POINTER
+BOOLEAN:BOXED,UINT,UCHAR,POINTER
diff --git a/src/lib/obexmanager.c b/src/lib/obexmanager.c
new file mode 100644
index 0000000..f207084
--- /dev/null
+++ b/src/lib/obexmanager.c
@@ -0,0 +1,263 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+
+#include "dbus-common.h"
+#include "marshallers.h"
+#include "obexmanager.h"
+
+#define OBEXMANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXMANAGER_TYPE, OBEXManagerPrivate))
+
+struct _OBEXManagerPrivate {
+ DBusGProxy *dbus_g_proxy;
+
+ /* Introspection data */
+ DBusGProxy *introspection_g_proxy;
+ gchar *introspection_xml;
+};
+
+G_DEFINE_TYPE(OBEXManager, obexmanager, G_TYPE_OBJECT);
+
+enum {
+ SESSION_CLOSED,
+ SESSION_CONNECT_ERROR,
+ SESSION_CONNECTED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void session_closed_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data);
+static void session_connect_error_handler(DBusGProxy *dbus_g_proxy, const gchar *path, const gchar *error_name, const gchar *error_message, gpointer data);
+static void session_connected_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data);
+
+static void obexmanager_dispose(GObject *gobject)
+{
+ OBEXManager *self = OBEXMANAGER(gobject);
+
+ /* DBus signals disconnection */
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionClosed", G_CALLBACK(session_closed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionConnectError", G_CALLBACK(session_connect_error_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionConnected", G_CALLBACK(session_connected_handler), self);
+
+ /* Proxy free */
+ g_object_unref(self->priv->dbus_g_proxy);
+
+ /* Introspection data free */
+ g_free(self->priv->introspection_xml);
+ g_object_unref(self->priv->introspection_g_proxy);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(obexmanager_parent_class)->dispose(gobject);
+}
+
+static void obexmanager_class_init(OBEXManagerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = obexmanager_dispose;
+
+ g_type_class_add_private(klass, sizeof(OBEXManagerPrivate));
+
+ /* Signals registation */
+ signals[SESSION_CLOSED] = g_signal_new("SessionClosed",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[SESSION_CONNECT_ERROR] = g_signal_new("SessionConnectError",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ signals[SESSION_CONNECTED] = g_signal_new("SessionConnected",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void obexmanager_init(OBEXManager *self)
+{
+ self->priv = OBEXMANAGER_GET_PRIVATE(self);
+
+ g_assert(conn != NULL);
+
+ GError *error = NULL;
+
+ /* Getting introspection XML */
+ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXMANAGER_PATH, "org.freedesktop.DBus.Introspectable");
+ self->priv->introspection_xml = NULL;
+ if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+
+ gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXMANAGER_INTERFACE, "\">", NULL);
+ if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) {
+ g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXMANAGER_INTERFACE, BLUEZ_DBUS_OBEXMANAGER_PATH);
+ g_assert(FALSE);
+ }
+ g_free(check_intf_regex_str);
+
+ self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, BLUEZ_DBUS_OBEXMANAGER_PATH, BLUEZ_DBUS_OBEXMANAGER_INTERFACE);
+
+ /* DBus signals connection */
+
+ /* SessionClosed(object path) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionClosed", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionClosed", G_CALLBACK(session_closed_handler), self, NULL);
+
+ /* SessionConnectError(object path, string error_name, string error_message) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionConnectError", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionConnectError", G_CALLBACK(session_connect_error_handler), self, NULL);
+
+ /* SessionConnected(object path) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionConnected", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionConnected", G_CALLBACK(session_connected_handler), self, NULL);
+}
+
+/* Methods */
+
+/* boolean CancelSessionConnect(object session_object) */
+gboolean obexmanager_cancel_session_connect(OBEXManager *self, const gchar *session_object, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gboolean ret = FALSE;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CancelSessionConnect", error, DBUS_TYPE_G_OBJECT_PATH, session_object, G_TYPE_INVALID, G_TYPE_BOOLEAN, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* object CreateBluetoothServer(string source_address, string pattern, boolean require_pairing) */
+gchar *obexmanager_create_bluetooth_server(OBEXManager *self, const gchar *source_address, const gchar *pattern, const gboolean require_pairing, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateBluetoothServer", error, G_TYPE_STRING, source_address, G_TYPE_STRING, pattern, G_TYPE_BOOLEAN, require_pairing, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* object CreateBluetoothSession(string target_address, string source_address, string pattern) */
+gchar *obexmanager_create_bluetooth_session(OBEXManager *self, const gchar *target_address, const gchar *source_address, const gchar *pattern, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateBluetoothSession", error, G_TYPE_STRING, target_address, G_TYPE_STRING, source_address, G_TYPE_STRING, pattern, G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* dict GetServerInfo(object server_object) */
+GHashTable *obexmanager_get_server_info(OBEXManager *self, const gchar *server_object, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ GHashTable *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetServerInfo", error, DBUS_TYPE_G_OBJECT_PATH, server_object, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* array{string} GetServerList() */
+gchar **obexmanager_get_server_list(OBEXManager *self, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gchar **ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetServerList", error, G_TYPE_INVALID, G_TYPE_STRV, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* dict GetSessionInfo(object session_object) */
+GHashTable *obexmanager_get_session_info(OBEXManager *self, const gchar *session_object, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ GHashTable *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetSessionInfo", error, DBUS_TYPE_G_OBJECT_PATH, session_object, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* array{string} GetSessionList() */
+gchar **obexmanager_get_session_list(OBEXManager *self, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gchar **ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetSessionList", error, G_TYPE_INVALID, G_TYPE_STRV, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* string GetVersion() */
+gchar *obexmanager_get_version(OBEXManager *self, GError **error)
+{
+ g_assert(OBEXMANAGER_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetVersion", error, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* Signals handlers */
+static void session_closed_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data)
+{
+ OBEXManager *self = OBEXMANAGER(data);
+
+ g_signal_emit(self, signals[SESSION_CLOSED], 0, path);
+}
+
+static void session_connect_error_handler(DBusGProxy *dbus_g_proxy, const gchar *path, const gchar *error_name, const gchar *error_message, gpointer data)
+{
+ OBEXManager *self = OBEXMANAGER(data);
+
+ g_signal_emit(self, signals[SESSION_CONNECT_ERROR], 0, path, error_name, error_message);
+}
+
+static void session_connected_handler(DBusGProxy *dbus_g_proxy, const gchar *path, gpointer data)
+{
+ OBEXManager *self = OBEXMANAGER(data);
+
+ g_signal_emit(self, signals[SESSION_CONNECTED], 0, path);
+}
+
diff --git a/src/lib/obexmanager.h b/src/lib/obexmanager.h
new file mode 100644
index 0000000..f5964f2
--- /dev/null
+++ b/src/lib/obexmanager.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEXMANAGER_H
+#define __OBEXMANAGER_H
+
+#include <glib-object.h>
+
+#define BLUEZ_DBUS_OBEXMANAGER_PATH "/org/openobex"
+#define BLUEZ_DBUS_OBEXMANAGER_INTERFACE "org.openobex.Manager"
+
+/*
+ * Type macros
+ */
+#define OBEXMANAGER_TYPE (obexmanager_get_type())
+#define OBEXMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXMANAGER_TYPE, OBEXManager))
+#define OBEXMANAGER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXMANAGER_TYPE))
+#define OBEXMANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXMANAGER_TYPE, OBEXManagerClass))
+#define OBEXMANAGER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXMANAGER_TYPE))
+#define OBEXMANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXMANAGER_TYPE, OBEXManagerClass))
+
+typedef struct _OBEXManager OBEXManager;
+typedef struct _OBEXManagerClass OBEXManagerClass;
+typedef struct _OBEXManagerPrivate OBEXManagerPrivate;
+
+struct _OBEXManager {
+ GObject parent_instance;
+
+ /*< private >*/
+ OBEXManagerPrivate *priv;
+};
+
+struct _OBEXManagerClass {
+ GObjectClass parent_class;
+};
+
+/* used by OBEXMANAGER_TYPE */
+GType obexmanager_get_type(void) G_GNUC_CONST;
+
+/*
+ * Method definitions
+ */
+gboolean obexmanager_cancel_session_connect(OBEXManager *self, const gchar *session_object, GError **error);
+gchar *obexmanager_create_bluetooth_server(OBEXManager *self, const gchar *source_address, const gchar *pattern, const gboolean require_pairing, GError **error);
+gchar *obexmanager_create_bluetooth_session(OBEXManager *self, const gchar *target_address, const gchar *source_address, const gchar *pattern, GError **error);
+GHashTable *obexmanager_get_server_info(OBEXManager *self, const gchar *server_object, GError **error);
+gchar **obexmanager_get_server_list(OBEXManager *self, GError **error);
+GHashTable *obexmanager_get_session_info(OBEXManager *self, const gchar *session_object, GError **error);
+gchar **obexmanager_get_session_list(OBEXManager *self, GError **error);
+gchar *obexmanager_get_version(OBEXManager *self, GError **error);
+
+#endif /* __OBEXMANAGER_H */
+
diff --git a/src/lib/obexserver.c b/src/lib/obexserver.c
new file mode 100644
index 0000000..b067e74
--- /dev/null
+++ b/src/lib/obexserver.c
@@ -0,0 +1,372 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+
+#include "dbus-common.h"
+#include "marshallers.h"
+#include "obexserver.h"
+
+#define OBEXSERVER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXSERVER_TYPE, OBEXServerPrivate))
+
+struct _OBEXServerPrivate {
+ DBusGProxy *dbus_g_proxy;
+
+ /* Introspection data */
+ DBusGProxy *introspection_g_proxy;
+ gchar *introspection_xml;
+};
+
+G_DEFINE_TYPE(OBEXServer, obexserver, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+
+ PROP_DBUS_OBJECT_PATH /* readwrite, construct only */
+};
+
+static void _obexserver_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void _obexserver_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+
+enum {
+ CLOSED,
+ ERROR_OCCURRED,
+ SESSION_CREATED,
+ SESSION_REMOVED,
+ STARTED,
+ STOPPED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void closed_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data);
+static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session_object, gpointer data);
+static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session_object, gpointer data);
+static void started_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void stopped_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+
+static void obexserver_dispose(GObject *gobject)
+{
+ OBEXServer *self = OBEXSERVER(gobject);
+
+ /* DBus signals disconnection */
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Closed", G_CALLBACK(closed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Started", G_CALLBACK(started_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Stopped", G_CALLBACK(stopped_handler), self);
+
+ /* Proxy free */
+ g_object_unref(self->priv->dbus_g_proxy);
+
+ /* Introspection data free */
+ g_free(self->priv->introspection_xml);
+ g_object_unref(self->priv->introspection_g_proxy);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(obexserver_parent_class)->dispose(gobject);
+}
+
+static void obexserver_class_init(OBEXServerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = obexserver_dispose;
+
+ g_type_class_add_private(klass, sizeof(OBEXServerPrivate));
+
+ /* Properties registration */
+ GParamSpec *pspec;
+
+ gobject_class->get_property = _obexserver_get_property;
+ gobject_class->set_property = _obexserver_set_property;
+
+ /* object DBusObjectPath [readwrite, construct only] */
+ pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec);
+
+ /* Signals registation */
+ signals[CLOSED] = g_signal_new("Closed",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[ERROR_OCCURRED] = g_signal_new("ErrorOccurred",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+
+ signals[SESSION_CREATED] = g_signal_new("SessionCreated",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[SESSION_REMOVED] = g_signal_new("SessionRemoved",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[STARTED] = g_signal_new("Started",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[STOPPED] = g_signal_new("Stopped",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void obexserver_init(OBEXServer *self)
+{
+ self->priv = OBEXSERVER_GET_PRIVATE(self);
+
+ g_assert(conn != NULL);
+}
+
+static void obexserver_post_init(OBEXServer *self, const gchar *dbus_object_path)
+{
+ g_assert(dbus_object_path != NULL);
+ g_assert(strlen(dbus_object_path) > 0);
+ g_assert(self->priv->dbus_g_proxy == NULL);
+
+ GError *error = NULL;
+
+ /* Getting introspection XML */
+ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable");
+ self->priv->introspection_xml = NULL;
+ if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+
+ gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXSERVER_INTERFACE, "\">", NULL);
+ if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) {
+ g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXSERVER_INTERFACE, dbus_object_path);
+ g_assert(FALSE);
+ }
+ g_free(check_intf_regex_str);
+ self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXSERVER_INTERFACE);
+
+ /* DBus signals connection */
+
+ /* Closed() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Closed", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Closed", G_CALLBACK(closed_handler), self, NULL);
+
+ /* ErrorOccurred(string error_name, string error_message) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self, NULL);
+
+ /* SessionCreated(object session_object) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionCreated", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionCreated", G_CALLBACK(session_created_handler), self, NULL);
+
+ /* SessionRemoved(object session_object) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "SessionRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "SessionRemoved", G_CALLBACK(session_removed_handler), self, NULL);
+
+ /* Started() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Started", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Started", G_CALLBACK(started_handler), self, NULL);
+
+ /* Stopped() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Stopped", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Stopped", G_CALLBACK(stopped_handler), self, NULL);
+}
+
+static void _obexserver_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ OBEXServer *self = OBEXSERVER(object);
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ g_value_set_string(value, obexserver_get_dbus_object_path(self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void _obexserver_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ OBEXServer *self = OBEXSERVER(object);
+ GError *error = NULL;
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ obexserver_post_init(self, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+
+ if (error != NULL) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+}
+
+/* Methods */
+
+/* void Close() */
+void obexserver_close(OBEXServer *self, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Close", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* dict GetServerSessionInfo(object session_object) */
+GHashTable *obexserver_get_server_session_info(OBEXServer *self, const gchar *session_object, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ GHashTable *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetServerSessionInfo", error, DBUS_TYPE_G_OBJECT_PATH, session_object, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* array{string} GetServerSessionList() */
+gchar **obexserver_get_server_session_list(OBEXServer *self, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ gchar **ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetServerSessionList", error, G_TYPE_INVALID, G_TYPE_STRV, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* boolean IsStarted() */
+gboolean obexserver_is_started(OBEXServer *self, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ gboolean ret = FALSE;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "IsStarted", error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* void SetOption(string name, variant value) */
+void obexserver_set_option(OBEXServer *self, const gchar *name, const GValue *value, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "SetOption", error, G_TYPE_STRING, name, G_TYPE_VALUE, value, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Start(string path, boolean allow_write, boolean auto_accept) */
+void obexserver_start(OBEXServer *self, const gchar *path, const gboolean allow_write, const gboolean auto_accept, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Start", error, G_TYPE_STRING, path, G_TYPE_BOOLEAN, allow_write, G_TYPE_BOOLEAN, auto_accept, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Stop() */
+void obexserver_stop(OBEXServer *self, GError **error)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Stop", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* Properties access methods */
+const gchar *obexserver_get_dbus_object_path(OBEXServer *self)
+{
+ g_assert(OBEXSERVER_IS(self));
+
+ return dbus_g_proxy_get_path(self->priv->dbus_g_proxy);
+}
+
+/* Signals handlers */
+static void closed_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[CLOSED], 0);
+}
+
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[ERROR_OCCURRED], 0, error_name, error_message);
+}
+
+static void session_created_handler(DBusGProxy *dbus_g_proxy, const gchar *session_object, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[SESSION_CREATED], 0, session_object);
+}
+
+static void session_removed_handler(DBusGProxy *dbus_g_proxy, const gchar *session_object, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[SESSION_REMOVED], 0, session_object);
+}
+
+static void started_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[STARTED], 0);
+}
+
+static void stopped_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServer *self = OBEXSERVER(data);
+
+ g_signal_emit(self, signals[STOPPED], 0);
+}
+
diff --git a/src/lib/obexserver.h b/src/lib/obexserver.h
new file mode 100644
index 0000000..dfea764
--- /dev/null
+++ b/src/lib/obexserver.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEXSERVER_H
+#define __OBEXSERVER_H
+
+#include <glib-object.h>
+
+#define BLUEZ_DBUS_OBEXSERVER_INTERFACE "org.openobex.Server"
+
+/*
+ * Type macros
+ */
+#define OBEXSERVER_TYPE (obexserver_get_type())
+#define OBEXSERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXSERVER_TYPE, OBEXServer))
+#define OBEXSERVER_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXSERVER_TYPE))
+#define OBEXSERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXSERVER_TYPE, OBEXServerClass))
+#define OBEXSERVER_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXSERVER_TYPE))
+#define OBEXSERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXSERVER_TYPE, OBEXServerClass))
+
+typedef struct _OBEXServer OBEXServer;
+typedef struct _OBEXServerClass OBEXServerClass;
+typedef struct _OBEXServerPrivate OBEXServerPrivate;
+
+struct _OBEXServer {
+ GObject parent_instance;
+
+ /*< private >*/
+ OBEXServerPrivate *priv;
+};
+
+struct _OBEXServerClass {
+ GObjectClass parent_class;
+};
+
+/* used by OBEXSERVER_TYPE */
+GType obexserver_get_type(void) G_GNUC_CONST;
+
+/*
+ * Method definitions
+ */
+void obexserver_close(OBEXServer *self, GError **error);
+GHashTable *obexserver_get_server_session_info(OBEXServer *self, const gchar *session_object, GError **error);
+gchar **obexserver_get_server_session_list(OBEXServer *self, GError **error);
+gboolean obexserver_is_started(OBEXServer *self, GError **error);
+void obexserver_set_option(OBEXServer *self, const gchar *name, const GValue *value, GError **error);
+void obexserver_start(OBEXServer *self, const gchar *path, const gboolean allow_write, const gboolean auto_accept, GError **error);
+void obexserver_stop(OBEXServer *self, GError **error);
+
+const gchar *obexserver_get_dbus_object_path(OBEXServer *self);
+
+#endif /* __OBEXSERVER_H */
+
diff --git a/src/lib/obexserver_session.c b/src/lib/obexserver_session.c
new file mode 100644
index 0000000..bac86aa
--- /dev/null
+++ b/src/lib/obexserver_session.c
@@ -0,0 +1,350 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+
+#include "dbus-common.h"
+#include "marshallers.h"
+#include "obexserver_session.h"
+
+#define OBEXSERVER_SESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXSERVER_SESSION_TYPE, OBEXServerSessionPrivate))
+
+struct _OBEXServerSessionPrivate {
+ DBusGProxy *dbus_g_proxy;
+
+ /* Introspection data */
+ DBusGProxy *introspection_g_proxy;
+ gchar *introspection_xml;
+};
+
+G_DEFINE_TYPE(OBEXServerSession, obexserver_session, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+
+ PROP_DBUS_OBJECT_PATH /* readwrite, construct only */
+};
+
+static void _obexserver_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void _obexserver_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+
+enum {
+ CANCELLED,
+ DISCONNECTED,
+ ERROR_OCCURRED,
+ TRANSFER_COMPLETED,
+ TRANSFER_PROGRESS,
+ TRANSFER_STARTED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void cancelled_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void disconnected_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data);
+static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void transfer_progress_handler(DBusGProxy *dbus_g_proxy, const guint64 bytes_transferred, gpointer data);
+static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *filename, const gchar *local_path, const guint64 total_bytes, gpointer data);
+
+static void obexserver_session_dispose(GObject *gobject)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(gobject);
+
+ /* DBus signals disconnection */
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Cancelled", G_CALLBACK(cancelled_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Disconnected", G_CALLBACK(disconnected_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferProgress", G_CALLBACK(transfer_progress_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self);
+
+ /* Proxy free */
+ g_object_unref(self->priv->dbus_g_proxy);
+
+ /* Introspection data free */
+ g_free(self->priv->introspection_xml);
+ g_object_unref(self->priv->introspection_g_proxy);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(obexserver_session_parent_class)->dispose(gobject);
+}
+
+static void obexserver_session_class_init(OBEXServerSessionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = obexserver_session_dispose;
+
+ g_type_class_add_private(klass, sizeof(OBEXServerSessionPrivate));
+
+ /* Properties registration */
+ GParamSpec *pspec;
+
+ gobject_class->get_property = _obexserver_session_get_property;
+ gobject_class->set_property = _obexserver_session_set_property;
+
+ /* object DBusObjectPath [readwrite, construct only] */
+ pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec);
+
+ /* Signals registation */
+ signals[CANCELLED] = g_signal_new("Cancelled",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISCONNECTED] = g_signal_new("Disconnected",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[ERROR_OCCURRED] = g_signal_new("ErrorOccurred",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+
+ signals[TRANSFER_COMPLETED] = g_signal_new("TransferCompleted",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[TRANSFER_PROGRESS] = g_signal_new("TransferProgress",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1, G_TYPE_UINT64);
+
+ signals[TRANSFER_STARTED] = g_signal_new("TransferStarted",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING_UINT64,
+ G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64);
+}
+
+static void obexserver_session_init(OBEXServerSession *self)
+{
+ self->priv = OBEXSERVER_SESSION_GET_PRIVATE(self);
+
+ g_assert(conn != NULL);
+}
+
+static void obexserver_session_post_init(OBEXServerSession *self, const gchar *dbus_object_path)
+{
+ g_assert(dbus_object_path != NULL);
+ g_assert(strlen(dbus_object_path) > 0);
+ g_assert(self->priv->dbus_g_proxy == NULL);
+
+ GError *error = NULL;
+
+ /* Getting introspection XML */
+ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable");
+ self->priv->introspection_xml = NULL;
+ if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+
+ gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXSERVER_SESSION_INTERFACE, "\">", NULL);
+ if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) {
+ g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXSERVER_SESSION_INTERFACE, dbus_object_path);
+ g_assert(FALSE);
+ }
+ g_free(check_intf_regex_str);
+ self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXSERVER_SESSION_INTERFACE);
+
+ /* DBus signals connection */
+
+ /* Cancelled() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Cancelled", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Cancelled", G_CALLBACK(cancelled_handler), self, NULL);
+
+ /* Disconnected() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Disconnected", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Disconnected", G_CALLBACK(disconnected_handler), self, NULL);
+
+ /* ErrorOccurred(string error_name, string error_message) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self, NULL);
+
+ /* TransferCompleted() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self, NULL);
+
+ /* TransferProgress(uint64 bytes_transferred) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferProgress", G_TYPE_UINT64, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferProgress", G_CALLBACK(transfer_progress_handler), self, NULL);
+
+ /* TransferStarted(string filename, string local_path, uint64 total_bytes) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferStarted", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self, NULL);
+}
+
+static void _obexserver_session_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(object);
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ g_value_set_string(value, obexserver_session_get_dbus_object_path(self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void _obexserver_session_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(object);
+ GError *error = NULL;
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ obexserver_session_post_init(self, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+
+ if (error != NULL) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+}
+
+/* Methods */
+
+/* void Accept() */
+void obexserver_session_accept(OBEXServerSession *self, GError **error)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Accept", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Cancel() */
+void obexserver_session_cancel(OBEXServerSession *self, GError **error)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Disconnect() */
+void obexserver_session_disconnect(OBEXServerSession *self, GError **error)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* dict GetTransferInfo() */
+GHashTable *obexserver_session_get_transfer_info(OBEXServerSession *self, GError **error)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ GHashTable *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetTransferInfo", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* void Reject() */
+void obexserver_session_reject(OBEXServerSession *self, GError **error)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Reject", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* Properties access methods */
+const gchar *obexserver_session_get_dbus_object_path(OBEXServerSession *self)
+{
+ g_assert(OBEXSERVER_SESSION_IS(self));
+
+ return dbus_g_proxy_get_path(self->priv->dbus_g_proxy);
+}
+
+/* Signals handlers */
+static void cancelled_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[CANCELLED], 0);
+}
+
+static void disconnected_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[DISCONNECTED], 0);
+}
+
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[ERROR_OCCURRED], 0, error_name, error_message);
+}
+
+static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_COMPLETED], 0);
+}
+
+static void transfer_progress_handler(DBusGProxy *dbus_g_proxy, const guint64 bytes_transferred, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_PROGRESS], 0, bytes_transferred);
+}
+
+static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *filename, const gchar *local_path, const guint64 total_bytes, gpointer data)
+{
+ OBEXServerSession *self = OBEXSERVER_SESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_STARTED], 0, filename, local_path, total_bytes);
+}
+
diff --git a/src/lib/obexserver_session.h b/src/lib/obexserver_session.h
new file mode 100644
index 0000000..53072cd
--- /dev/null
+++ b/src/lib/obexserver_session.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEXSERVER_SESSION_H
+#define __OBEXSERVER_SESSION_H
+
+#include <glib-object.h>
+
+#define BLUEZ_DBUS_OBEXSERVER_SESSION_INTERFACE "org.openobex.ServerSession"
+
+/*
+ * Type macros
+ */
+#define OBEXSERVER_SESSION_TYPE (obexserver_session_get_type())
+#define OBEXSERVER_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXSERVER_SESSION_TYPE, OBEXServerSession))
+#define OBEXSERVER_SESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXSERVER_SESSION_TYPE))
+#define OBEXSERVER_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXSERVER_SESSION_TYPE, OBEXServerSessionClass))
+#define OBEXSERVER_SESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXSERVER_SESSION_TYPE))
+#define OBEXSERVER_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXSERVER_SESSION_TYPE, OBEXServerSessionClass))
+
+typedef struct _OBEXServerSession OBEXServerSession;
+typedef struct _OBEXServerSessionClass OBEXServerSessionClass;
+typedef struct _OBEXServerSessionPrivate OBEXServerSessionPrivate;
+
+struct _OBEXServerSession {
+ GObject parent_instance;
+
+ /*< private >*/
+ OBEXServerSessionPrivate *priv;
+};
+
+struct _OBEXServerSessionClass {
+ GObjectClass parent_class;
+};
+
+/* used by OBEXSERVER_SESSION_TYPE */
+GType obexserver_session_get_type(void) G_GNUC_CONST;
+
+/*
+ * Method definitions
+ */
+void obexserver_session_accept(OBEXServerSession *self, GError **error);
+void obexserver_session_cancel(OBEXServerSession *self, GError **error);
+void obexserver_session_disconnect(OBEXServerSession *self, GError **error);
+GHashTable *obexserver_session_get_transfer_info(OBEXServerSession *self, GError **error);
+void obexserver_session_reject(OBEXServerSession *self, GError **error);
+
+const gchar *obexserver_session_get_dbus_object_path(OBEXServerSession *self);
+
+#endif /* __OBEXSERVER_SESSION_H */
+
diff --git a/src/lib/obexsession.c b/src/lib/obexsession.c
new file mode 100644
index 0000000..b8836a7
--- /dev/null
+++ b/src/lib/obexsession.c
@@ -0,0 +1,495 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <string.h>
+
+#include "dbus-common.h"
+#include "marshallers.h"
+#include "obexsession.h"
+
+#define OBEXSESSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OBEXSESSION_TYPE, OBEXSessionPrivate))
+
+struct _OBEXSessionPrivate {
+ DBusGProxy *dbus_g_proxy;
+
+ /* Introspection data */
+ DBusGProxy *introspection_g_proxy;
+ gchar *introspection_xml;
+};
+
+G_DEFINE_TYPE(OBEXSession, obexsession, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+
+ PROP_DBUS_OBJECT_PATH /* readwrite, construct only */
+};
+
+static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+
+enum {
+ CANCELLED,
+ CLOSED,
+ DISCONNECTED,
+ ERROR_OCCURRED,
+ TRANSFER_COMPLETED,
+ TRANSFER_PROGRESS,
+ TRANSFER_STARTED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void cancelled_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void closed_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void disconnected_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data);
+static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, gpointer data);
+static void transfer_progress_handler(DBusGProxy *dbus_g_proxy, const guint64 bytes_transferred, gpointer data);
+static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *filename, const gchar *local_path, const guint64 total_bytes, gpointer data);
+
+static void obexsession_dispose(GObject *gobject)
+{
+ OBEXSession *self = OBEXSESSION(gobject);
+
+ /* DBus signals disconnection */
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Cancelled", G_CALLBACK(cancelled_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Closed", G_CALLBACK(closed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "Disconnected", G_CALLBACK(disconnected_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferProgress", G_CALLBACK(transfer_progress_handler), self);
+ dbus_g_proxy_disconnect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self);
+
+ /* Proxy free */
+ g_object_unref(self->priv->dbus_g_proxy);
+
+ /* Introspection data free */
+ g_free(self->priv->introspection_xml);
+ g_object_unref(self->priv->introspection_g_proxy);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS(obexsession_parent_class)->dispose(gobject);
+}
+
+static void obexsession_class_init(OBEXSessionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = obexsession_dispose;
+
+ g_type_class_add_private(klass, sizeof(OBEXSessionPrivate));
+
+ /* Properties registration */
+ GParamSpec *pspec;
+
+ gobject_class->get_property = _obexsession_get_property;
+ gobject_class->set_property = _obexsession_set_property;
+
+ /* object DBusObjectPath [readwrite, construct only] */
+ pspec = g_param_spec_string("DBusObjectPath", "dbus_object_path", "Adapter D-Bus object path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(gobject_class, PROP_DBUS_OBJECT_PATH, pspec);
+
+ /* Signals registation */
+ signals[CANCELLED] = g_signal_new("Cancelled",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CLOSED] = g_signal_new("Closed",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISCONNECTED] = g_signal_new("Disconnected",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[ERROR_OCCURRED] = g_signal_new("ErrorOccurred",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+
+ signals[TRANSFER_COMPLETED] = g_signal_new("TransferCompleted",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[TRANSFER_PROGRESS] = g_signal_new("TransferProgress",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1, G_TYPE_UINT64);
+
+ signals[TRANSFER_STARTED] = g_signal_new("TransferStarted",
+ G_TYPE_FROM_CLASS(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ g_cclosure_bluez_marshal_VOID__STRING_STRING_UINT64,
+ G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64);
+}
+
+static void obexsession_init(OBEXSession *self)
+{
+ self->priv = OBEXSESSION_GET_PRIVATE(self);
+
+ g_assert(conn != NULL);
+}
+
+static void obexsession_post_init(OBEXSession *self, const gchar *dbus_object_path)
+{
+ g_assert(dbus_object_path != NULL);
+ g_assert(strlen(dbus_object_path) > 0);
+ g_assert(self->priv->dbus_g_proxy == NULL);
+
+ GError *error = NULL;
+
+ /* Getting introspection XML */
+ self->priv->introspection_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, "org.freedesktop.DBus.Introspectable");
+ self->priv->introspection_xml = NULL;
+ if (!dbus_g_proxy_call(self->priv->introspection_g_proxy, "Introspect", &error, G_TYPE_INVALID, G_TYPE_STRING, &self->priv->introspection_xml, G_TYPE_INVALID)) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+
+ gchar *check_intf_regex_str = g_strconcat("<interface name=\"", BLUEZ_DBUS_OBEXSESSION_INTERFACE, "\">", NULL);
+ if (!g_regex_match_simple(check_intf_regex_str, self->priv->introspection_xml, 0, 0)) {
+ g_critical("Interface \"%s\" does not exist in \"%s\"", BLUEZ_DBUS_OBEXSESSION_INTERFACE, dbus_object_path);
+ g_assert(FALSE);
+ }
+ g_free(check_intf_regex_str);
+ self->priv->dbus_g_proxy = dbus_g_proxy_new_for_name(conn, BLUEZ_DBUS_NAME, dbus_object_path, BLUEZ_DBUS_OBEXSESSION_INTERFACE);
+
+ /* DBus signals connection */
+
+ /* Cancelled() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Cancelled", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Cancelled", G_CALLBACK(cancelled_handler), self, NULL);
+
+ /* Closed() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Closed", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Closed", G_CALLBACK(closed_handler), self, NULL);
+
+ /* Disconnected() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "Disconnected", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "Disconnected", G_CALLBACK(disconnected_handler), self, NULL);
+
+ /* ErrorOccurred(string error_name, string error_message) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "ErrorOccurred", G_CALLBACK(error_occurred_handler), self, NULL);
+
+ /* TransferCompleted() */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferCompleted", G_CALLBACK(transfer_completed_handler), self, NULL);
+
+ /* TransferProgress(uint64 bytes_transferred) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferProgress", G_TYPE_UINT64, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferProgress", G_CALLBACK(transfer_progress_handler), self, NULL);
+
+ /* TransferStarted(string filename, string local_path, uint64 total_bytes) */
+ dbus_g_proxy_add_signal(self->priv->dbus_g_proxy, "TransferStarted", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(self->priv->dbus_g_proxy, "TransferStarted", G_CALLBACK(transfer_started_handler), self, NULL);
+}
+
+static void _obexsession_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ OBEXSession *self = OBEXSESSION(object);
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ g_value_set_string(value, obexsession_get_dbus_object_path(self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void _obexsession_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ OBEXSession *self = OBEXSESSION(object);
+ GError *error = NULL;
+
+ switch (property_id) {
+ case PROP_DBUS_OBJECT_PATH:
+ obexsession_post_init(self, g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+
+ if (error != NULL) {
+ g_critical("%s", error->message);
+ }
+ g_assert(error == NULL);
+}
+
+/* Methods */
+
+/* void Cancel() */
+void obexsession_cancel(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Cancel", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void ChangeCurrentFolder(string path) */
+void obexsession_change_current_folder(OBEXSession *self, const gchar *path, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "ChangeCurrentFolder", error, G_TYPE_STRING, path, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void ChangeCurrentFolderBackward() */
+void obexsession_change_current_folder_backward(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "ChangeCurrentFolderBackward", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void ChangeCurrentFolderToRoot() */
+void obexsession_change_current_folder_to_root(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "ChangeCurrentFolderToRoot", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Close() */
+void obexsession_close(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Close", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void CopyRemoteFile(string remote_filename, string local_path) */
+void obexsession_copy_remote_file(OBEXSession *self, const gchar *remote_filename, const gchar *local_path, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CopyRemoteFile", error, G_TYPE_STRING, remote_filename, G_TYPE_STRING, local_path, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void CopyRemoteFileByType(string type, string local_path) */
+void obexsession_copy_remote_file_by_type(OBEXSession *self, const gchar *type, const gchar *local_path, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CopyRemoteFileByType", error, G_TYPE_STRING, type, G_TYPE_STRING, local_path, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void CreateFolder(string folder_name) */
+void obexsession_create_folder(OBEXSession *self, const gchar *folder_name, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "CreateFolder", error, G_TYPE_STRING, folder_name, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void DeleteRemoteFile(string remote_filename) */
+void obexsession_delete_remote_file(OBEXSession *self, const gchar *remote_filename, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "DeleteRemoteFile", error, G_TYPE_STRING, remote_filename, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void Disconnect() */
+void obexsession_disconnect(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "Disconnect", error, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* string GetCapability() */
+gchar *obexsession_get_capability(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetCapability", error, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* string GetCurrentPath() */
+gchar *obexsession_get_current_path(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetCurrentPath", error, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* dict GetTransferInfo() */
+GHashTable *obexsession_get_transfer_info(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ GHashTable *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "GetTransferInfo", error, G_TYPE_INVALID, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* boolean IsBusy() */
+gboolean obexsession_is_busy(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ gboolean ret = FALSE;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "IsBusy", error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* void RemoteCopy(string remote_source, string remote_destination) */
+void obexsession_remote_copy(OBEXSession *self, const gchar *remote_source, const gchar *remote_destination, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoteCopy", error, G_TYPE_STRING, remote_source, G_TYPE_STRING, remote_destination, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void RemoteMove(string remote_source, string remote_destination) */
+void obexsession_remote_move(OBEXSession *self, const gchar *remote_source, const gchar *remote_destination, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "RemoteMove", error, G_TYPE_STRING, remote_source, G_TYPE_STRING, remote_destination, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* string RetrieveFolderListing() */
+gchar *obexsession_retrieve_folder_listing(OBEXSession *self, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ gchar *ret = NULL;
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "RetrieveFolderListing", error, G_TYPE_INVALID, G_TYPE_STRING, &ret, G_TYPE_INVALID);
+
+ return ret;
+}
+
+/* void SendFile(string local_path) */
+void obexsession_send_file(OBEXSession *self, const gchar *local_path, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "SendFile", error, G_TYPE_STRING, local_path, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* void SendFileExt(string local_path, string remote_filename, string type) */
+void obexsession_send_file_ext(OBEXSession *self, const gchar *local_path, const gchar *remote_filename, const gchar *type, GError **error)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ dbus_g_proxy_call(self->priv->dbus_g_proxy, "SendFileExt", error, G_TYPE_STRING, local_path, G_TYPE_STRING, remote_filename, G_TYPE_STRING, type, G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+/* Properties access methods */
+const gchar *obexsession_get_dbus_object_path(OBEXSession *self)
+{
+ g_assert(OBEXSESSION_IS(self));
+
+ return dbus_g_proxy_get_path(self->priv->dbus_g_proxy);
+}
+
+/* Signals handlers */
+static void cancelled_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[CANCELLED], 0);
+}
+
+static void closed_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[CLOSED], 0);
+}
+
+static void disconnected_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[DISCONNECTED], 0);
+}
+
+static void error_occurred_handler(DBusGProxy *dbus_g_proxy, const gchar *error_name, const gchar *error_message, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[ERROR_OCCURRED], 0, error_name, error_message);
+}
+
+static void transfer_completed_handler(DBusGProxy *dbus_g_proxy, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_COMPLETED], 0);
+}
+
+static void transfer_progress_handler(DBusGProxy *dbus_g_proxy, const guint64 bytes_transferred, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_PROGRESS], 0, bytes_transferred);
+}
+
+static void transfer_started_handler(DBusGProxy *dbus_g_proxy, const gchar *filename, const gchar *local_path, const guint64 total_bytes, gpointer data)
+{
+ OBEXSession *self = OBEXSESSION(data);
+
+ g_signal_emit(self, signals[TRANSFER_STARTED], 0, filename, local_path, total_bytes);
+}
+
diff --git a/src/lib/obexsession.h b/src/lib/obexsession.h
new file mode 100644
index 0000000..a42ff67
--- /dev/null
+++ b/src/lib/obexsession.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * bluez-tools - a set of tools to manage bluetooth devices for linux
+ *
+ * Copyright (C) 2010 Alexander Orlenko <zxteam@gmail.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEXSESSION_H
+#define __OBEXSESSION_H
+
+#include <glib-object.h>
+
+#define BLUEZ_DBUS_OBEXSESSION_INTERFACE "org.openobex.Session"
+
+/*
+ * Type macros
+ */
+#define OBEXSESSION_TYPE (obexsession_get_type())
+#define OBEXSESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), OBEXSESSION_TYPE, OBEXSession))
+#define OBEXSESSION_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), OBEXSESSION_TYPE))
+#define OBEXSESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), OBEXSESSION_TYPE, OBEXSessionClass))
+#define OBEXSESSION_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), OBEXSESSION_TYPE))
+#define OBEXSESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), OBEXSESSION_TYPE, OBEXSessionClass))
+
+typedef struct _OBEXSession OBEXSession;
+typedef struct _OBEXSessionClass OBEXSessionClass;
+typedef struct _OBEXSessionPrivate OBEXSessionPrivate;
+
+struct _OBEXSession {
+ GObject parent_instance;
+
+ /*< private >*/
+ OBEXSessionPrivate *priv;
+};
+
+struct _OBEXSessionClass {
+ GObjectClass parent_class;
+};
+
+/* used by OBEXSESSION_TYPE */
+GType obexsession_get_type(void) G_GNUC_CONST;
+
+/*
+ * Method definitions
+ */
+void obexsession_cancel(OBEXSession *self, GError **error);
+void obexsession_change_current_folder(OBEXSession *self, const gchar *path, GError **error);
+void obexsession_change_current_folder_backward(OBEXSession *self, GError **error);
+void obexsession_change_current_folder_to_root(OBEXSession *self, GError **error);
+void obexsession_close(OBEXSession *self, GError **error);
+void obexsession_copy_remote_file(OBEXSession *self, const gchar *remote_filename, const gchar *local_path, GError **error);
+void obexsession_copy_remote_file_by_type(OBEXSession *self, const gchar *type, const gchar *local_path, GError **error);
+void obexsession_create_folder(OBEXSession *self, const gchar *folder_name, GError **error);
+void obexsession_delete_remote_file(OBEXSession *self, const gchar *remote_filename, GError **error);
+void obexsession_disconnect(OBEXSession *self, GError **error);
+gchar *obexsession_get_capability(OBEXSession *self, GError **error);
+gchar *obexsession_get_current_path(OBEXSession *self, GError **error);
+GHashTable *obexsession_get_transfer_info(OBEXSession *self, GError **error);
+gboolean obexsession_is_busy(OBEXSession *self, GError **error);
+void obexsession_remote_copy(OBEXSession *self, const gchar *remote_source, const gchar *remote_destination, GError **error);
+void obexsession_remote_move(OBEXSession *self, const gchar *remote_source, const gchar *remote_destination, GError **error);
+gchar *obexsession_retrieve_folder_listing(OBEXSession *self, GError **error);
+void obexsession_send_file(OBEXSession *self, const gchar *local_path, GError **error);
+void obexsession_send_file_ext(OBEXSession *self, const gchar *local_path, const gchar *remote_filename, const gchar *type, GError **error);
+
+const gchar *obexsession_get_dbus_object_path(OBEXSession *self);
+
+#endif /* __OBEXSESSION_H */
+