mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-12 13:34:41 +08:00
obexd: Remove gwobex
Not needed anymore since obex-client now uses gobex.
This commit is contained in:
parent
0e31d0f56b
commit
15f6d2e1f8
@ -1,404 +0,0 @@
|
||||
/**
|
||||
@file gw-obex.c
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "gw-obex.h"
|
||||
#include "utils.h"
|
||||
#include "obex-xfer.h"
|
||||
#include "obex-priv.h"
|
||||
|
||||
|
||||
gboolean gw_obex_get_file(GwObex *ctx,
|
||||
const gchar *local,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, local, remote, type, NULL, 0, NULL, NULL, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_get_fd(GwObex *ctx,
|
||||
gint fd,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, remote, type, NULL, 0, NULL, NULL, fd, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_put_fd(GwObex *ctx,
|
||||
gint fd,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_put(ctx, NULL, remote, type, NULL, 0, NULL, 0, -1, fd, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_put_file(GwObex *ctx,
|
||||
const gchar *local,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_put(ctx, local, remote, type, NULL, 0, NULL, 0, -1, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_get_buf(GwObex *ctx,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gchar **buf,
|
||||
gint *buf_size,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, remote, type, NULL, 0, buf, buf_size, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_put_buf(GwObex *ctx,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
const gchar *buf,
|
||||
gint buf_size,
|
||||
gint time,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_put(ctx, NULL, remote, type, NULL, 0, buf, buf_size, time, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_get_buf_with_apparam(GwObex *ctx,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
const guint8 *apparam,
|
||||
gint apparam_size,
|
||||
gchar **buf,
|
||||
gint *buf_size,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, remote, type, apparam, apparam_size, buf, buf_size, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_put_buf_with_apparam(GwObex *ctx,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
const guint8 *apparam,
|
||||
gint apparam_size,
|
||||
const gchar *buf,
|
||||
gint buf_size,
|
||||
gint time,
|
||||
gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_put(ctx, NULL, remote, type, apparam, apparam_size, buf, buf_size, time, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_chdir(GwObex *ctx, const gchar *dir, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_setpath(ctx, dir ? dir : "", 0);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_mkdir(GwObex *ctx, const gchar *dir, gint *error) {
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
if (!gw_obex_setpath(ctx, dir ? dir : "", SETPATH_CREATE)) {
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return FALSE;
|
||||
}
|
||||
(void) gw_obex_setpath(ctx, "..", 0);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean gw_obex_read_dir(GwObex *ctx, const gchar *dir,
|
||||
gchar **buf, gint *buf_size, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, dir ? dir : "", LST_TYPE, NULL, 0, buf, buf_size, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
else if (*buf_size > 0) {
|
||||
/* Hack for some OBEX implementations which send nul's
|
||||
* at the end of the listing */
|
||||
int i;
|
||||
|
||||
for (i = *buf_size - 1; i > 0; i--) {
|
||||
if ((*buf)[i] == '\0')
|
||||
(*buf_size)--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_delete(GwObex *ctx, const gchar *name, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_put(ctx, NULL, name, NULL, NULL, 0, NULL, 0, -1, -1, FALSE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_move(GwObex *ctx, const gchar *src, const gchar *dst, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_action_op(ctx, src, dst, OBEX_ACTION_MOVE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_copy(GwObex *ctx, const gchar *src, const gchar *dst, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_action_op(ctx, src, dst, OBEX_ACTION_COPY);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_get_capability(GwObex *ctx, gchar **cap, gint *cap_len, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(FALSE, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, NULL, CAP_TYPE, NULL, 0, cap, cap_len, -1, FALSE);
|
||||
if (ret == FALSE) {
|
||||
*cap = NULL;
|
||||
*cap_len = 0;
|
||||
gw_obex_get_error(ctx, error);
|
||||
}
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gw_obex_set_disconnect_callback(GwObex *ctx, gw_obex_disconnect_cb_t callback, gpointer data) {
|
||||
GW_OBEX_LOCK(ctx);
|
||||
ctx->dc_cb = callback;
|
||||
ctx->dc_data = data;
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
void gw_obex_set_progress_callback(GwObex *ctx, gw_obex_progress_cb_t callback, gpointer data) {
|
||||
GW_OBEX_LOCK(ctx);
|
||||
ctx->pr_cb = callback;
|
||||
ctx->pr_data = data;
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
void gw_obex_set_cancel_callback(GwObex *ctx, gw_obex_cancel_cb_t callback, gpointer data) {
|
||||
GW_OBEX_LOCK(ctx);
|
||||
ctx->cancel_cb = callback;
|
||||
ctx->cancel_data = data;
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
void gw_obex_close(GwObex *ctx) {
|
||||
GW_OBEX_LOCK(ctx);
|
||||
if (ctx->xfer) {
|
||||
GwObexXfer *xfer = ctx->xfer;
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
gw_obex_xfer_close(ctx->xfer, NULL);
|
||||
GW_OBEX_LOCK(ctx);
|
||||
/* In the async case the caller of put/get_async owns the xfer object */
|
||||
if (!xfer->async)
|
||||
_gw_obex_xfer_free(xfer);
|
||||
ctx->xfer = NULL;
|
||||
}
|
||||
if (ctx->conn_fd >= 0) {
|
||||
if (!gw_obex_disconnect(ctx))
|
||||
debug("OBEX Disconnect command failed\n");
|
||||
OBEX_TransportDisconnect(ctx->handle);
|
||||
close(ctx->conn_fd);
|
||||
ctx->conn_fd = -1;
|
||||
}
|
||||
if (ctx->handle) {
|
||||
OBEX_Cleanup(ctx->handle);
|
||||
ctx->handle = NULL;
|
||||
}
|
||||
if (ctx->gio) {
|
||||
g_io_channel_unref(ctx->gio);
|
||||
ctx->gio = NULL;
|
||||
}
|
||||
if (ctx->gio_source) {
|
||||
g_source_destroy(ctx->gio_source);
|
||||
ctx->gio_source = NULL;
|
||||
}
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
#ifdef GW_OBEX_THREADS_ENABLED
|
||||
g_mutex_free(ctx->mutex);
|
||||
ctx->mutex = NULL;
|
||||
#endif
|
||||
g_free(ctx);
|
||||
}
|
||||
|
||||
GwObex *gw_obex_setup_fd(int fd, const gchar *uuid, gint uuid_len,
|
||||
GMainContext *context, gint *error) {
|
||||
obex_t *handle;
|
||||
GwObex *ctx;
|
||||
|
||||
if (!gw_obex_transport_setup(fd, &handle)) {
|
||||
debug("gw_obex_open() failed\n");
|
||||
if (error)
|
||||
*error = GW_OBEX_ERROR_CONNECT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
debug("Transport connection opened.\n");
|
||||
|
||||
ctx = make_context(handle);
|
||||
|
||||
#ifdef GW_OBEX_THREADS_ENABLED
|
||||
if (!g_thread_supported())
|
||||
g_thread_init(NULL);
|
||||
ctx->mutex = g_mutex_new();
|
||||
#endif
|
||||
|
||||
OBEX_SetUserData(handle, ctx);
|
||||
|
||||
debug("Connecting to OBEX service\n");
|
||||
if (!gw_obex_connect(ctx, uuid, uuid_len)) {
|
||||
debug("Unable to connect to OBEX service\n");
|
||||
#ifdef GW_OBEX_THREADS_ENABLED
|
||||
g_mutex_free(ctx->mutex);
|
||||
ctx->mutex = NULL;
|
||||
#endif
|
||||
g_free(ctx);
|
||||
OBEX_Cleanup(handle);
|
||||
if (error)
|
||||
*error = GW_OBEX_ERROR_NO_SERVICE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
debug("Connected (Connection ID: %#x)\n", ctx->conid);
|
||||
|
||||
ctx->gio = g_io_channel_unix_new(ctx->conn_fd);
|
||||
ctx->gio_source = g_io_create_watch (ctx->gio,
|
||||
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL);
|
||||
g_source_set_callback(ctx->gio_source, (GSourceFunc)gw_obex_cb, ctx, NULL);
|
||||
(void) g_source_attach(ctx->gio_source, context);
|
||||
g_source_unref(ctx->gio_source);
|
||||
|
||||
ctx->main_ctx = context;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
GwObex *gw_obex_setup_dev(const char *dev, const gchar *uuid, gint uuid_len,
|
||||
GMainContext *context, gint *error) {
|
||||
GwObex *ctx;
|
||||
int fd;
|
||||
|
||||
fd = open(dev, O_RDWR | O_NOCTTY | O_SYNC);
|
||||
if (fd < 0) {
|
||||
debug("open(\"%s\"): %s\n", dev, strerror(errno));
|
||||
if (error)
|
||||
*error = GW_OBEX_ERROR_CONNECT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!fd_raw_mode(fd)) {
|
||||
debug("setting raw mode failed\n");
|
||||
close(fd);
|
||||
if (error)
|
||||
*error = GW_OBEX_ERROR_CONNECT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = gw_obex_setup_fd(fd, uuid, uuid_len, context, error);
|
||||
if (ctx == NULL) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
@ -1,683 +0,0 @@
|
||||
/**
|
||||
@file gw-obex.h
|
||||
|
||||
OSSO GW OBEX Connectivity Library and API
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2005 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef _GW_OBEX_H_
|
||||
#define _GW_OBEX_H_
|
||||
|
||||
#include <glib.h>
|
||||
#include <openobex/obex.h>
|
||||
|
||||
/**
|
||||
* @name GW OBEX Error Codes
|
||||
* The error codes returned by many of the functions refer either to an OBEX
|
||||
* Protocol error or to a GW OBEX error. If the error code is less that 256, it
|
||||
* refers to an OBEX error, othervice it refers to a GW_OBEX_ERROR_* error.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Transport connection was disconnected */
|
||||
#define GW_OBEX_ERROR_DISCONNECT 256
|
||||
|
||||
/** Operation was aborted */
|
||||
#define GW_OBEX_ERROR_ABORT 257
|
||||
|
||||
/** GW OBEX internal error */
|
||||
#define GW_OBEX_ERROR_INTERNAL 258
|
||||
|
||||
/** Unable to connecto to the specified service (UUID) */
|
||||
#define GW_OBEX_ERROR_NO_SERVICE 259
|
||||
|
||||
/** Unable to create connection */
|
||||
#define GW_OBEX_ERROR_CONNECT_FAILED 260
|
||||
|
||||
/** Timeout while waiting for data from the remote device */
|
||||
#define GW_OBEX_ERROR_TIMEOUT 261
|
||||
|
||||
/** Remote device returned invalid/corrupted data */
|
||||
#define GW_OBEX_ERROR_INVALID_DATA 262
|
||||
|
||||
/** Invalid parameters given to gwobex */
|
||||
#define GW_OBEX_ERROR_INVALID_PARAMS 263
|
||||
|
||||
/** Local access error (e.g. read/write/open failed for local file) */
|
||||
#define GW_OBEX_ERROR_LOCAL_ACCESS 264
|
||||
|
||||
/** Another operation is in progress */
|
||||
#define GW_OBEX_ERROR_BUSY 265
|
||||
|
||||
/** No data currently available */
|
||||
#define GW_OBEX_ERROR_NO_DATA 266
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Value used if target length for put or get is not known */
|
||||
#define GW_OBEX_UNKNOWN_LENGTH -1
|
||||
|
||||
/** Standard folder browsing service UUID (give this as a parameter to
|
||||
* gw_obex_setup_* to connect to folder browsing service */
|
||||
#define OBEX_FTP_UUID \
|
||||
"\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
|
||||
/** Length of OBEX_FTP_UUID */
|
||||
#define OBEX_FTP_UUID_LEN 16
|
||||
|
||||
/** Phone Book Access Profile UUID */
|
||||
#define OBEX_PBAP_UUID \
|
||||
"\x79\x61\x35\xF0\xF0\xC5\x11\xD8\x09\x66\x08\x00\x20\x0C\x9A\x66"
|
||||
/** Length of OBEX_PBAP_UUID */
|
||||
#define OBEX_PBAP_UUID_LEN 16
|
||||
|
||||
/** IrMC Sync Profile UUID */
|
||||
#define OBEX_SYNC_UUID \
|
||||
"IRMC-SYNC"
|
||||
/** Length of OBEX_SYNC_UUID */
|
||||
#define OBEX_SYNC_UUID_LEN 9
|
||||
|
||||
/** Struct containing the context of a gwobex connection */
|
||||
typedef struct gw_obex GwObex;
|
||||
|
||||
/** Objecct transfer handle */
|
||||
typedef struct gw_obex_xfer GwObexXfer;
|
||||
|
||||
/** Callback type for ongoing transfers
|
||||
* @param ctx GwObexXfer pointer for the transfer
|
||||
* @param data Optional pointer to user data
|
||||
*/
|
||||
typedef void (*gw_obex_xfer_cb_t) (GwObexXfer *xfer,
|
||||
gpointer data);
|
||||
|
||||
/** Callback type for transport connection loss
|
||||
* @param ctx GwObex pointer for the connection
|
||||
* @param data Optional pointer to user data
|
||||
*/
|
||||
typedef void (*gw_obex_disconnect_cb_t) (GwObex *ctx,
|
||||
gpointer data);
|
||||
|
||||
/** Callback type for progress information
|
||||
* Only used for the synchronous transfer functions.
|
||||
* @param ctx GwObex pointer for the connection
|
||||
* @param obex_cmd eg. OBEX_CMD_PUT
|
||||
* @param current Bytes transfered
|
||||
* @param target Total length (or GW_OBEX_UNKNOWN_LENGTH)
|
||||
* @param data Optional pointer to user data
|
||||
*/
|
||||
typedef void (*gw_obex_progress_cb_t) (GwObex *ctx, gint obex_cmd,
|
||||
gint current, gint target,
|
||||
gpointer data);
|
||||
|
||||
/** Callback type for checking if the operation should be canceled.
|
||||
* Only used for the synchronous functions.
|
||||
* In the GNOME VFS case the callback function should be
|
||||
* gnome_vfs_cancellation_check().
|
||||
* @param data Optional pointer to user data
|
||||
* @returns TRUE if the operation should be canceled, FALSE othervice
|
||||
*/
|
||||
typedef gboolean (*gw_obex_cancel_cb_t) (gpointer data);
|
||||
|
||||
|
||||
/**
|
||||
* @name Functions for connecting and disconnecting
|
||||
* With these functions you can create and and disconnect connections. You can
|
||||
* either connect using a filename (e.g. "/dev/rfcomm0") or using a file
|
||||
* descriptor (e.g. a RFCOMM socket).
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Open connection using a local device node and setup parameters.
|
||||
* This function should be called before calling any other functions. The
|
||||
* pointer returned by this function should be passed to the other functions.
|
||||
*
|
||||
* @param device The local device which should be opened for the connection
|
||||
* @param uuid UUID of service to connect to. NULL for the default service
|
||||
* (INBOX).
|
||||
* @param uuid_len Length (in bytes) of UUID
|
||||
* @param context GMainContext to attach to (or NULL for the default one)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns A pointer, NULL on failure
|
||||
* This pointer should be passed to the other obex_* functions.
|
||||
**/
|
||||
GwObex *gw_obex_setup_dev(const gchar *device,
|
||||
const gchar *uuid,
|
||||
gint uuid_len,
|
||||
GMainContext *context,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Setup OBEX connection using an opened file descriptor
|
||||
* This function should be called before calling any other functions. The
|
||||
* pointer returned by this function should be passed to the other functions.
|
||||
*
|
||||
* @param fd Opened file descriptor to use for the connection
|
||||
* @param uuid UUID of service to connect to. NULL for the default service
|
||||
* (INBOX).
|
||||
* @param uuid_len Length (in bytes) of UUID
|
||||
* @param context GMainContext to attach to (or NULL for the default one)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns A pointer, NULL on failure
|
||||
* This pointer should be passed to the other obex_* functions.
|
||||
**/
|
||||
GwObex *gw_obex_setup_fd(int fd,
|
||||
const gchar *uuid,
|
||||
gint uuid_len,
|
||||
GMainContext *context,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Close GW OBEX connection and free all memory associated with it.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup().
|
||||
* Cannot be used anymore after this calling this function.
|
||||
*/
|
||||
void gw_obex_close(GwObex *ctx);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Registering callback functions
|
||||
* With these functions you can register your own callback functions
|
||||
* to gwobex to receive indications about special events.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Set function to be called when a disconnection happens.
|
||||
* You may (and probably should) call gw_obex_close() if this function is
|
||||
* called.
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param callback Function to call
|
||||
* @param data Optional data to pass to the callback function
|
||||
*/
|
||||
void gw_obex_set_disconnect_callback(GwObex *ctx,
|
||||
gw_obex_disconnect_cb_t callback,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/** Set function to be called when progress for a put or get operation happens.
|
||||
* Only used for the synchronous transfer functions.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param callback Function to call
|
||||
* @param data Optional data to pass to the callback function
|
||||
*/
|
||||
void gw_obex_set_progress_callback(GwObex *ctx,
|
||||
gw_obex_progress_cb_t callback,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/** Set function to be called to check if the current operation should be
|
||||
* canceled. In the GNOME VFS case the callback function should be
|
||||
* gnome_vfs_cancellation_check(). The callback function should return TRUE if
|
||||
* the operation should be canceled and FALSE othervice.
|
||||
*
|
||||
* Only used for the synchronous transfer functions.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param callback Function to call
|
||||
* @param data Pointer to pass to the callback function
|
||||
*/
|
||||
void gw_obex_set_cancel_callback(GwObex *ctx,
|
||||
gw_obex_cancel_cb_t callback,
|
||||
gpointer data);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Functions for performing synchronous remote operations
|
||||
* Once you have setup a connection using one of the gw_obex_setup_* functions,
|
||||
* you can perform different remote transactions using these functions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Get the capability object from the connected remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param cap Place to store the fetched object.
|
||||
* g_free() when not needed anymore.
|
||||
* @param cap_len Place to store the size of the fetched object
|
||||
* @param error Place to store a possible error code
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get_capability(GwObex *ctx,
|
||||
gchar **cap,
|
||||
gint *cap_len,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Get a file from the remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param local Local filename (null terminated UTF-8)
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get_file(GwObex *ctx,
|
||||
const gchar *local,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Send a file to the remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param local Local filename (null terminated UTF-8)
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_put_file(GwObex *ctx,
|
||||
const gchar *local,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Get a file from the remote device and write it to a file descriptor
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param fd File descriptor to write the file into
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get_fd(GwObex *ctx, gint fd,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error);
|
||||
|
||||
/** Read data from a file descriptor and send it to the remote device
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param fd File descriptor to read the data from
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_put_fd(GwObex *ctx, gint fd,
|
||||
const gchar *remote,
|
||||
const gchar *type,
|
||||
gint *error);
|
||||
|
||||
/** Get an object from the remote device and store it in a memory buffer.
|
||||
* Either remote filename or type must be supplied (or both).
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param buf Buffer to store the object in.
|
||||
* g_free() when not needed anymore.
|
||||
* @param buf_size Place to store length of fetched object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get_buf(GwObex *ctx, const gchar *remote, const gchar *type,
|
||||
gchar **buf, gint *buf_size, gint *error);
|
||||
|
||||
|
||||
/** Send a object located in a memory buffer to the remote device.
|
||||
* Either remote filename or type must be supplied (or both)
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param buf Buffer containing the object
|
||||
* @param buf_size Buffer (object) size
|
||||
* @param time Last modification time of object (or -1 if not known)
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_put_buf(GwObex *ctx, const gchar *remote, const gchar *type,
|
||||
const gchar *buf, gint buf_size, gint time, gint *error);
|
||||
|
||||
|
||||
/** Get an object from the remote device and store it in a memory buffer.
|
||||
* Either remote filename or type must be supplied (or both).
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param apparam Application parameters of the object
|
||||
* @param apparam_size Application parameters size
|
||||
* @param buf Buffer to store the object in.
|
||||
* g_free() when not needed anymore.
|
||||
* @param buf_size Place to store length of fetched object
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get_buf_with_apparam(GwObex *ctx, const gchar *remote, const gchar *type,
|
||||
const guint8 *apparam, gint apparam_size,
|
||||
gchar **buf, gint *buf_size, gint *error);
|
||||
|
||||
|
||||
/** Send a object located in a memory buffer to the remote device.
|
||||
* Either remote filename or type must be supplied (or both)
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param remote Remote filename (null terminated UTF-8)
|
||||
* @param type MIME-type of the object
|
||||
* @param apparam Application parameters of the object
|
||||
* @param apparam_size Application parameters size
|
||||
* @param buf Buffer containing the object
|
||||
* @param buf_size Buffer (object) size
|
||||
* @param time Last modification time of object (or -1 if not known)
|
||||
* @param error Place to store error code on failure
|
||||
* (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_put_buf_with_apparam(GwObex *ctx, const gchar *remote, const gchar *type,
|
||||
const guint8 *apparam, gint apparam_size,
|
||||
const gchar *buf, gint buf_size, gint time, gint *error);
|
||||
|
||||
|
||||
/** Change directory (relative to the current one).
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param dir New directory to change to (null terminated UTF-8),
|
||||
* ".." to go up, NULL to go to the root folder
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_chdir(GwObex *ctx, const gchar *dir, gint *error);
|
||||
|
||||
|
||||
/** Create a new directory.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param dir Directory to create (null terminated UTF-8)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_mkdir(GwObex *ctx, const gchar *dir, gint *error);
|
||||
|
||||
|
||||
/** Get folder listing for the specified directory.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param dir Directory to list (null terminated UTF-8),
|
||||
* NULL to list current directory
|
||||
* @param buf Place to store the folder-listing object
|
||||
* @param buf_size Place to store the size for the retrieved object
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_read_dir(GwObex *ctx, const gchar *dir,
|
||||
gchar **buf, gint *buf_size, gint *error);
|
||||
|
||||
|
||||
/** Remove a file from the remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param name Filename to remove (null terminated UTF-8)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_delete(GwObex *ctx, const gchar *name, gint *error);
|
||||
|
||||
|
||||
/** Move/Rename a file on the remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param src Source filename (null terminated UTF-8)
|
||||
* @param dst Destination filename (null terminated UTF-8)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_move(GwObex *ctx, const gchar *src, const gchar *dst,
|
||||
gint *error);
|
||||
|
||||
|
||||
/** Copy a file on the remote device.
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param src Source filename (null terminated UTF-8)
|
||||
* @param dst Destination filename (null terminated UTF-8)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_copy(GwObex *ctx, const gchar *src, const gchar *dst,
|
||||
gint *error);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Functions for performing transfers in an asynchronous manner
|
||||
* With these functions you can do transfers in smaller steps. The steps
|
||||
* are split up in a open, read/write, close manner.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Start a PUT operation asynchronously
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param name Name of the object (null terminated UTF-8)
|
||||
* @param type Type of the object (null terminated UTF-8), or NULL
|
||||
* @param size Size of the object (GW_OBEX_UNKNOWN_LENGTH if not known)
|
||||
* @param time Last modification time of the object (-1 if not known)
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns a new GwObexXfer object on success, NULL on failure
|
||||
*/
|
||||
GwObexXfer *gw_obex_put_async(GwObex *ctx, const char *name, const char *type,
|
||||
gint size, time_t time, gint *error);
|
||||
|
||||
|
||||
/** Start a GET operation asynchronously
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param name Name of the object (null terminated UTF-8)
|
||||
* @param type Type of the object (null terminated UTF-8), or NULL
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns a new GwObexXfer object on success, NULL on failure
|
||||
*/
|
||||
GwObexXfer *gw_obex_get_async(GwObex *ctx, const char *name, const char *type, gint *error);
|
||||
|
||||
/** Start a GET operation asynchronously with application parameters
|
||||
*
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param name Name of the object (null terminated UTF-8)
|
||||
* @param type Type of the object (null terminated UTF-8), or NULL
|
||||
* @param apparam Application parameters of the object
|
||||
* @param apparam_size Application paramters' size
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns a new GwObexXfer object on success, NULL on failure
|
||||
*/
|
||||
|
||||
GwObexXfer *gw_obex_get_async_with_apparam(GwObex *ctx, const char *name, const char *type,
|
||||
const guint8 *apparam, gint apparam_size, gint *error);
|
||||
|
||||
|
||||
/** Set a callback function for a GwObexXfer object
|
||||
* The callback function will be called in the following situations:
|
||||
* <ul>
|
||||
* <li>Data can be written (i.e. xfer_write will succeed)</li>
|
||||
* <li>Data can be read (i.e. xfer_read will succees)</li>
|
||||
* <li>An error ocured</li>
|
||||
* <li>The transfer is finished</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param cb Pointer to the callback function
|
||||
* @param user_data Optional user data which will be passed to the callback function
|
||||
*
|
||||
* @returns a new GwObexXfer object on success, NULL on failure
|
||||
*/
|
||||
void gw_obex_xfer_set_callback(GwObexXfer *xfer, gw_obex_xfer_cb_t cb, gpointer user_data);
|
||||
|
||||
|
||||
/** Get the last modification time of the object being transfered
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
*
|
||||
* @returns The modification time or -1 if it is not known.
|
||||
*/
|
||||
time_t gw_obex_xfer_object_time(GwObexXfer *xfer);
|
||||
|
||||
|
||||
/** Get the size of the object being transfered
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
*
|
||||
* @returns The size or GW_OBEX_UNKNOWN_LENGTH if it is not known.
|
||||
*/
|
||||
gint gw_obex_xfer_object_size(GwObexXfer *xfer);
|
||||
|
||||
|
||||
/** Get the contents of the application parameters header
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param apparam_size Return value for the size of the application parameters header.
|
||||
*
|
||||
* @returns The pointer to the buffer that hold the contents.
|
||||
*/
|
||||
unsigned char *gw_obex_xfer_object_apparam(GwObexXfer *xfer, size_t *apparam_size);
|
||||
|
||||
|
||||
/** Returns if a transfer is already done
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
*
|
||||
* @returns whether the current transfer is done
|
||||
*/
|
||||
gboolean gw_obex_xfer_object_done(GwObexXfer *xfer);
|
||||
|
||||
|
||||
/** Supply more data to a transfer
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param buf Buffer containing the data
|
||||
* @param buf_size Size of the buffer
|
||||
* @param bytes_written Return value for the number of bytes that were written
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_xfer_write(GwObexXfer *xfer, const char *buf, gint buf_size,
|
||||
gint *bytes_written, gint *error);
|
||||
|
||||
/** Read data from a transfer
|
||||
*
|
||||
* The function will report EOF by returning success with zero bytes read.
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param buf Buffer where the data should be stored
|
||||
* @param buf_size Size of the buffer
|
||||
* @param bytes_read Return value for the number of bytes that were read
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_xfer_read(GwObexXfer *xfer, char *buf, gint buf_size,
|
||||
gint *bytes_read, gint *error);
|
||||
|
||||
|
||||
/** Force all data remaining in buffers to be sent
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_xfer_flush(GwObexXfer *xfer, gint *error);
|
||||
|
||||
|
||||
/** Close an ongoing transfer
|
||||
*
|
||||
* You still need to call gw_obex_xfer_free after this to free the actual
|
||||
* memory allocated for the GwObexXfer object.
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_xfer_close(GwObexXfer *xfer, gint *error);
|
||||
|
||||
|
||||
/** Abort an ongoing transfer
|
||||
*
|
||||
* You still need to call gw_obex_xfer_free after this to free the actual
|
||||
* memory allocated for the GwObexXfer object. xfer_close and xfer_abort are
|
||||
* mutually exclusive (only call one of them for a transfer).
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param error Place to store error code on failure (NULL if not interested)
|
||||
*
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_xfer_abort(GwObexXfer *xfer, gint *error);
|
||||
|
||||
|
||||
/** Free the data allocated for a GwObexXfer object
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
*/
|
||||
void gw_obex_xfer_free(struct gw_obex_xfer *xfer);
|
||||
|
||||
|
||||
/** Set blocking behaviour for a GwObexXfer object when calling xfer_read and xfer_write
|
||||
*
|
||||
* When blocking is enabled xfer_read will return only after it has been able
|
||||
* to read some data (i.e. GW_OBEX_ERROR_NO_DATA will not be returned). For xfer_write
|
||||
* blocking guarantees that *some* data will be written.
|
||||
*
|
||||
* @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
|
||||
* @param block TRUE to enable blocking behaviour
|
||||
*/
|
||||
void gw_obex_xfer_set_blocking(GwObexXfer *xfer, gboolean block);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _GW_OBEX_H_ */
|
||||
|
@ -1,38 +0,0 @@
|
||||
/**
|
||||
@file log.h
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
|
||||
#ifdef DEBUG
|
||||
# ifdef DEBUG_STDOUT
|
||||
# include <glib.h>
|
||||
# define debug(...) g_print(__VA_ARGS__)
|
||||
# else
|
||||
# include <syslog.h>
|
||||
# define debug(fmt, arg...) syslog(LOG_DEBUG, "gwobex: " fmt, ## arg)
|
||||
# endif
|
||||
#else
|
||||
# define debug(...) ((void)(0))
|
||||
#endif
|
||||
|
||||
#endif /* _LOG_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,217 +0,0 @@
|
||||
/**
|
||||
@file obex-priv.h
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef _OBEX_PRIV_H_
|
||||
#define _OBEX_PRIV_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <openobex/obex.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gw-obex.h"
|
||||
#include "obex-xfer.h"
|
||||
|
||||
#define CHECK_DISCONNECT(ret, err, ctx) do { \
|
||||
if ((ctx)->conn_fd < 0) { \
|
||||
if (err) \
|
||||
*(err) = GW_OBEX_ERROR_DISCONNECT; \
|
||||
GW_OBEX_UNLOCK(ctx); \
|
||||
return (ret); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifndef OBEX_CMD_ACTION
|
||||
# define OBEX_CMD_ACTION 0x06
|
||||
|
||||
# define OBEX_HDR_ACTION_ID 0x94
|
||||
# define OBEX_HDR_DESTNAME 0x15
|
||||
# define OBEX_HDR_PERMISSIONS 0xD6
|
||||
|
||||
#endif /* OBEX_CMD_ACTION */
|
||||
|
||||
#define OBEX_ACTION_COPY 0x00
|
||||
#define OBEX_ACTION_MOVE 0x01
|
||||
#define OBEX_ACTION_SETPERM 0x02
|
||||
|
||||
#define CONID_INVALID 0xFFFFFFFF
|
||||
|
||||
#define OBEX_CMD_NONE 0x10
|
||||
|
||||
#define GW_OBEX_RX_MTU 4096
|
||||
#define GW_OBEX_TX_MTU 32767
|
||||
|
||||
#define SETPATH_CREATE 0x0001
|
||||
|
||||
#define CAP_TYPE "x-obex/capability"
|
||||
#define OBP_TYPE "x-obex/object-profile"
|
||||
#define LST_TYPE "x-obex/folder-listing"
|
||||
|
||||
#ifdef GW_OBEX_THREADS_ENABLED
|
||||
# ifdef DEBUG
|
||||
# define GW_OBEX_LOCK(ctx) do { \
|
||||
debug("Attempting GW_OBEX_LOCK at %s:%d (%s)...", __FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
||||
fflush(stdout); \
|
||||
g_mutex_lock((ctx)->mutex); \
|
||||
debug("got it!\n"); \
|
||||
} while (0)
|
||||
# define GW_OBEX_UNLOCK(ctx) do { \
|
||||
debug("Unlocking GW_OBEX_LOCK at %s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
||||
g_mutex_unlock((ctx)->mutex); \
|
||||
} while (0)
|
||||
# else
|
||||
# define GW_OBEX_LOCK(ctx) g_mutex_lock((ctx)->mutex)
|
||||
# define GW_OBEX_UNLOCK(ctx) g_mutex_unlock((ctx)->mutex)
|
||||
# endif
|
||||
#else
|
||||
# define GW_OBEX_LOCK(ctx) ((void)(0))
|
||||
# define GW_OBEX_UNLOCK(ctx) ((void)(0))
|
||||
#endif
|
||||
|
||||
typedef struct obex_setpath_hdr {
|
||||
uint8_t flags;
|
||||
uint8_t constants;
|
||||
} __attribute__ ((packed)) obex_setpath_hdr_t;
|
||||
|
||||
typedef struct obex_connect_hdr {
|
||||
uint8_t version;
|
||||
uint8_t flags;
|
||||
uint16_t mtu;
|
||||
} __attribute__ ((packed)) obex_connect_hdr_t;
|
||||
|
||||
struct gw_obex {
|
||||
#ifdef GW_OBEX_THREADS_ENABLED
|
||||
/* To get rid of race conditions in multithreaded apps */
|
||||
GMutex *mutex;
|
||||
#endif
|
||||
|
||||
/* Main OpenOBEX handle */
|
||||
obex_t *handle;
|
||||
|
||||
/* Exception callback and associated data */
|
||||
gw_obex_disconnect_cb_t dc_cb;
|
||||
gpointer dc_data;
|
||||
|
||||
/* Progress callback and associated data */
|
||||
gw_obex_progress_cb_t pr_cb;
|
||||
gpointer pr_data;
|
||||
|
||||
/* Whether calling pr_cb is necessary or not */
|
||||
gboolean report_progress;
|
||||
|
||||
/* Cancel callback and associated data */
|
||||
gw_obex_cancel_cb_t cancel_cb;
|
||||
gpointer cancel_data;
|
||||
|
||||
/* For checking if the current operation is finished */
|
||||
gboolean done;
|
||||
|
||||
/* TRUE if a link error has hapened */
|
||||
gboolean link_err;
|
||||
|
||||
/* FD for the transport connection */
|
||||
int conn_fd;
|
||||
|
||||
GMainContext *main_ctx;
|
||||
|
||||
/* The transport connection's GIOChannel */
|
||||
GIOChannel *gio;
|
||||
|
||||
/* The transport connection's GSource */
|
||||
GSource *gio_source;
|
||||
|
||||
/* OBEX Connection ID */
|
||||
uint32_t conid;
|
||||
|
||||
/* The last OBEX response code */
|
||||
uint8_t obex_rsp;
|
||||
|
||||
/* The current OBEX operation */
|
||||
uint8_t obex_op;
|
||||
|
||||
/* This is set if some operation fails */
|
||||
gint error;
|
||||
|
||||
/* Bytes to read at a time when doing a put */
|
||||
uint16_t tx_max;
|
||||
|
||||
/* How many bytes to allocate for incomming object data */
|
||||
uint16_t rx_max;
|
||||
|
||||
/* Current object transfer handle */
|
||||
struct gw_obex_xfer *xfer;
|
||||
};
|
||||
|
||||
GwObex *make_context(obex_t *handle);
|
||||
|
||||
gboolean gw_obex_set_error(GwObex *ctx);
|
||||
|
||||
void gw_obex_get_error(GwObex *ctx, gint *error);
|
||||
|
||||
void obex_link_error(GwObex *ctx);
|
||||
|
||||
gboolean gw_obex_cb(GIOChannel *chan, GIOCondition cond, gpointer data);
|
||||
|
||||
gboolean gw_obex_connect(GwObex *ctx, const char *target, size_t target_len);
|
||||
|
||||
gboolean gw_obex_disconnect(GwObex *ctx);
|
||||
|
||||
gboolean gw_obex_transport_setup(int fd, obex_t **handle);
|
||||
|
||||
gboolean gw_obex_action_op(GwObex *ctx, const gchar *src, const gchar *dst,
|
||||
uint8_t action);
|
||||
|
||||
gboolean gw_obex_setpath(GwObex *ctx, const gchar *path, int flags);
|
||||
|
||||
/** Get an object from the server
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param local Local filename which contains the object
|
||||
* @param remote Remote filename to store the object in
|
||||
* @param type MIME-type of the object (NULL if not known)
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_get(GwObex *ctx,
|
||||
const gchar *local, const gchar *remote, const gchar *type,
|
||||
const guint8 *apparam, gint apparam_size,
|
||||
gchar **buf, gint *buf_size, int stream_fd,
|
||||
gboolean async);
|
||||
|
||||
/** Send an object to the server
|
||||
* @param ctx Pointer returned by gw_obex_setup()
|
||||
* @param local Local filename to store the objec in
|
||||
* @param remote Remote filename which contains the object
|
||||
* @param type MIME-type of the object (NULL if not known)
|
||||
* @returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
gboolean gw_obex_put(GwObex *ctx,
|
||||
const gchar *local, const gchar *remote, const gchar *type,
|
||||
const guint8 *apparam, gint apparam_size,
|
||||
const gchar *buf, gint buf_size, time_t object_time,
|
||||
int stream_fd, gboolean async);
|
||||
|
||||
#endif /* _OBEX_PRIV_H_ */
|
@ -1,524 +0,0 @@
|
||||
/**
|
||||
@file obex-xfer.c
|
||||
|
||||
Object transfer related functions for the GW OBEX Library
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1 as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <openobex/obex.h>
|
||||
|
||||
#include "obex-priv.h"
|
||||
#include "obex-xfer.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "obex-priv.h"
|
||||
#include "obex-xfer.h"
|
||||
#include "gw-obex.h"
|
||||
|
||||
static gboolean handle_input(GwObex *ctx, gint *err) {
|
||||
gboolean ret = TRUE;
|
||||
int r;
|
||||
|
||||
r = OBEX_HandleInput(ctx->handle, 10);
|
||||
|
||||
if (r < 0) {
|
||||
debug("OBEX_HandleInput() failed\n");
|
||||
obex_link_error(ctx);
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INTERNAL;
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (r == 0) { /* Timeout */
|
||||
debug("OBEX_HandleInput(): timeout\n");
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_TIMEOUT;
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct gw_obex_xfer *gw_obex_xfer_new(struct gw_obex *ctx, gboolean async, int stream_fd) {
|
||||
struct gw_obex_xfer *xfer;
|
||||
size_t buf_size = (ctx->obex_op == OBEX_CMD_GET) ? ctx->rx_max : ctx->tx_max;
|
||||
|
||||
xfer = g_new0(struct gw_obex_xfer, 1);
|
||||
|
||||
xfer->ctx = ctx;
|
||||
xfer->async = async;
|
||||
xfer->stream_fd = stream_fd;
|
||||
xfer->target_size = GW_OBEX_UNKNOWN_LENGTH;
|
||||
xfer->modtime = -1;
|
||||
|
||||
if (async || (stream_fd >= 0 && ctx->obex_op == OBEX_CMD_PUT)) {
|
||||
xfer->buf = g_malloc(buf_size);
|
||||
xfer->buf_size = buf_size;
|
||||
}
|
||||
|
||||
if (async && ctx->obex_op == OBEX_CMD_PUT)
|
||||
xfer->do_cb = TRUE;
|
||||
|
||||
return xfer;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_do_abort(struct gw_obex_xfer *xfer) {
|
||||
debug("gw_obex_xfer_do_abort()\n");
|
||||
|
||||
if (xfer->ctx->conn_fd < 0 || xfer->ctx->xfer == NULL || xfer->ctx->done)
|
||||
return FALSE;
|
||||
|
||||
if (xfer->abort)
|
||||
return TRUE;
|
||||
|
||||
xfer->abort = TRUE;
|
||||
|
||||
debug("Performing nice abort\n");
|
||||
if (OBEX_CancelRequest(xfer->ctx->handle, TRUE) != 0)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GwObexXfer *gw_obex_put_async(GwObex *ctx, const char *name, const char *type,
|
||||
gint size, time_t time, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(NULL, error, ctx);
|
||||
ret = gw_obex_put(ctx, NULL, name, type, NULL, 0, NULL, size, time, -1, TRUE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret ? ctx->xfer : NULL;
|
||||
}
|
||||
|
||||
GwObexXfer *gw_obex_get_async(GwObex *ctx, const char *name, const char *type, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(NULL, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, name, type, NULL, 0, NULL, NULL, -1, TRUE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret ? ctx->xfer : NULL;
|
||||
}
|
||||
|
||||
GwObexXfer *gw_obex_get_async_with_apparam(GwObex *ctx, const char *name, const char *type,
|
||||
const guint8 *apparam, gint apparam_size, gint *error) {
|
||||
gboolean ret;
|
||||
GW_OBEX_LOCK(ctx);
|
||||
CHECK_DISCONNECT(NULL, error, ctx);
|
||||
ret = gw_obex_get(ctx, NULL, name, type, apparam, apparam_size, NULL, NULL, -1, TRUE);
|
||||
if (ret == FALSE)
|
||||
gw_obex_get_error(ctx, error);
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret ? ctx->xfer : NULL;
|
||||
}
|
||||
|
||||
static gboolean gw_obex_put_idle(GwObexXfer *xfer) {
|
||||
struct gw_obex *ctx = xfer->ctx;
|
||||
|
||||
g_source_destroy(xfer->idle_source);
|
||||
xfer->idle_source = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return FALSE;
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
if (xfer->cb && xfer->do_cb) {
|
||||
xfer->do_cb = FALSE;
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
xfer->cb(xfer, xfer->cb_data);
|
||||
GW_OBEX_LOCK(ctx);
|
||||
}
|
||||
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void gw_obex_xfer_set_callback(GwObexXfer *xfer, gw_obex_xfer_cb_t cb, gpointer user_data) {
|
||||
GwObex *ctx = xfer->ctx;
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
xfer->cb = cb;
|
||||
xfer->cb_data = user_data;
|
||||
|
||||
if (xfer->do_cb && xfer->idle_source == NULL) {
|
||||
xfer->idle_source = g_idle_source_new();
|
||||
g_source_set_callback(xfer->idle_source, (GSourceFunc)gw_obex_put_idle, xfer, NULL);
|
||||
(void) g_source_attach(xfer->idle_source, ctx->main_ctx);
|
||||
g_source_unref(xfer->idle_source);
|
||||
}
|
||||
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
time_t gw_obex_xfer_object_time(GwObexXfer *xfer) {
|
||||
return xfer->modtime;
|
||||
}
|
||||
|
||||
gint gw_obex_xfer_object_size(GwObexXfer *xfer) {
|
||||
return xfer->target_size;
|
||||
}
|
||||
|
||||
unsigned char *gw_obex_xfer_object_apparam(GwObexXfer *xfer, size_t *apparam_size) {
|
||||
if (apparam_size)
|
||||
*apparam_size = xfer->apparam_size;
|
||||
return xfer->apparam_buf;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_object_done(GwObexXfer *xfer) {
|
||||
return xfer->ctx->done;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_write(GwObexXfer *xfer, const char *buf, gint buf_size,
|
||||
gint *bytes_written, gint *err) {
|
||||
GwObex *ctx = xfer->ctx;
|
||||
gboolean ret = TRUE;
|
||||
gint free_space;
|
||||
|
||||
debug("gw_obex_xfer_write(buf_size=%d): entered\n", buf_size);
|
||||
|
||||
if (!ctx) {
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INVALID_PARAMS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
if (ctx->obex_op != OBEX_CMD_PUT) {
|
||||
ret = FALSE;
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INVALID_PARAMS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (gw_obex_set_error(ctx)) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
free_space = xfer->buf_size - (xfer->data_start + xfer->data_length);
|
||||
|
||||
*bytes_written = buf_size > free_space ? free_space : buf_size;
|
||||
|
||||
memcpy(&xfer->buf[xfer->data_start + xfer->data_length], buf, *bytes_written);
|
||||
|
||||
xfer->data_length += *bytes_written;
|
||||
free_space -= *bytes_written;
|
||||
|
||||
if (xfer->object) {
|
||||
if (OBEX_Request(ctx->handle, xfer->object) < 0) {
|
||||
debug("OBEX_Request() failed\n");
|
||||
xfer->data_length -= *bytes_written;
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
xfer->object = NULL;
|
||||
|
||||
/* Recalculate free space */
|
||||
free_space = xfer->buf_size - (xfer->data_start + xfer->data_length);
|
||||
}
|
||||
|
||||
if (xfer->data_length >= ctx->tx_max || !free_space) {
|
||||
guint old_length = xfer->data_length;
|
||||
|
||||
debug("OBEX_ResumeRequest at %s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||
OBEX_ResumeRequest(ctx->handle);
|
||||
|
||||
if (!xfer->block)
|
||||
goto out;
|
||||
|
||||
/* Call OBEX_HandleInput if the xfer is blocking and no data could be sent */
|
||||
while (old_length == xfer->data_length) {
|
||||
if (gw_obex_set_error(ctx)) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!handle_input(ctx, err)) {
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (xfer->cb && xfer->do_cb && xfer->idle_source == NULL) {
|
||||
xfer->idle_source = g_idle_source_new();
|
||||
g_source_set_callback(xfer->idle_source, (GSourceFunc)gw_obex_put_idle, xfer, NULL);
|
||||
(void) g_source_attach(xfer->idle_source, ctx->main_ctx);
|
||||
g_source_unref(xfer->idle_source);
|
||||
}
|
||||
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
if (ret)
|
||||
debug("gw_obex_xfer_write(): returning, %d bytes written\n", *bytes_written);
|
||||
else
|
||||
debug("gw_obex_xfer_write(): returning, failed (%d)\n", err ? *err : 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_read(GwObexXfer *xfer, char *buf, gint buf_size,
|
||||
gint *bytes_read, gint *err) {
|
||||
GwObex *ctx = xfer->ctx;
|
||||
gint data_length;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
debug("gw_obex_xfer_read(buf_size=%d): entered\n", buf_size);
|
||||
|
||||
if (!ctx) {
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INVALID_PARAMS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
if (ctx->obex_op != OBEX_CMD_GET) {
|
||||
ret = FALSE;
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INVALID_PARAMS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
if (gw_obex_set_error(ctx)) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xfer->data_length)
|
||||
break;
|
||||
|
||||
if (ctx->done) {
|
||||
*bytes_read = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xfer->block) {
|
||||
if (!handle_input(ctx, err)) {
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = FALSE;
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_NO_DATA;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
data_length = xfer->data_length;
|
||||
*bytes_read = buf_size < data_length ? buf_size : data_length;
|
||||
|
||||
memcpy(buf, &xfer->buf[xfer->data_start], *bytes_read);
|
||||
|
||||
xfer->data_length -= *bytes_read;
|
||||
|
||||
if (xfer->data_length)
|
||||
xfer->data_start += *bytes_read;
|
||||
else {
|
||||
xfer->data_start = 0;
|
||||
debug("OBEX_ResumeRequest at %s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||
OBEX_ResumeRequest(ctx->handle);
|
||||
}
|
||||
|
||||
out:
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
if (ret)
|
||||
debug("gw_obex_xfer_read(): returning, %d bytes read\n", *bytes_read);
|
||||
else
|
||||
debug("gw_obex_xfer_read(): returning, failed (%d)\n", err ? *err : 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_flush(GwObexXfer *xfer, gint *err) {
|
||||
gboolean ret = TRUE;
|
||||
struct gw_obex *ctx = xfer->ctx;
|
||||
|
||||
if (!ctx) {
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INVALID_PARAMS;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
if (ctx->obex_op != OBEX_CMD_PUT)
|
||||
goto out;
|
||||
|
||||
if (gw_obex_set_error(ctx)) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (xfer->data_length) {
|
||||
debug("OBEX_ResumeRequest at %s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||
OBEX_ResumeRequest(ctx->handle);
|
||||
|
||||
if (gw_obex_set_error(ctx)) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xfer->data_length) {
|
||||
if (!handle_input(ctx, err)) {
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _gw_obex_xfer_free(struct gw_obex_xfer *xfer) {
|
||||
g_free(xfer->buf);
|
||||
g_free(xfer->apparam_buf);
|
||||
g_free(xfer);
|
||||
}
|
||||
|
||||
void gw_obex_xfer_free(struct gw_obex_xfer *xfer) {
|
||||
if (xfer->ctx)
|
||||
gw_obex_xfer_close(xfer, NULL);
|
||||
_gw_obex_xfer_free(xfer);
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_close(GwObexXfer *xfer, gint *err) {
|
||||
gboolean ret = TRUE;
|
||||
struct gw_obex *ctx = xfer->ctx;
|
||||
|
||||
/* If previous close() failed, just signal success so caller can continue */
|
||||
if (!ctx)
|
||||
return TRUE;
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
xfer->close = TRUE;
|
||||
|
||||
if (ctx->obex_op == OBEX_CMD_GET && !ctx->done)
|
||||
gw_obex_xfer_do_abort(xfer);
|
||||
|
||||
if (ctx->obex_op == OBEX_CMD_PUT) {
|
||||
if (xfer->object) {
|
||||
if (OBEX_Request(ctx->handle, xfer->object) < 0) {
|
||||
debug("OBEX_Request() failed\n");
|
||||
ctx->done = TRUE;
|
||||
}
|
||||
xfer->object = NULL;
|
||||
}
|
||||
else {
|
||||
debug("OBEX_ResumeRequest at %s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||
OBEX_ResumeRequest(ctx->handle);
|
||||
}
|
||||
}
|
||||
|
||||
while (!ctx->done) {
|
||||
if (!handle_input(ctx, err)) {
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for error but ignore ERROR_ABORT since we can still do a proper
|
||||
* xfer_close() in that case */
|
||||
if (gw_obex_set_error(ctx) && ctx->error != GW_OBEX_ERROR_ABORT) {
|
||||
gw_obex_get_error(ctx, err);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
/* Remove the idle function related to this transfer (if there is one) */
|
||||
if (xfer->idle_source) {
|
||||
g_source_destroy(xfer->idle_source);
|
||||
xfer->idle_source = NULL;
|
||||
}
|
||||
|
||||
/* Disassociate from the GwObex object */
|
||||
ctx->xfer = NULL;
|
||||
xfer->ctx = NULL;
|
||||
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean gw_obex_xfer_abort(GwObexXfer *xfer, gint *err) {
|
||||
GwObex *ctx = xfer->ctx;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
/* If previous call failed just signal success so caller can continue */
|
||||
if (!ctx)
|
||||
return TRUE;
|
||||
|
||||
GW_OBEX_LOCK(ctx);
|
||||
|
||||
/* Return if abort has already been sent */
|
||||
if (xfer->abort)
|
||||
goto out;
|
||||
|
||||
/* Return if actual request hasn't been sent */
|
||||
if (xfer->object) {
|
||||
OBEX_ObjectDelete(ctx->handle, xfer->object);
|
||||
xfer->object = NULL;
|
||||
ctx->done = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!gw_obex_xfer_do_abort(xfer)) {
|
||||
ret = FALSE;
|
||||
if (err)
|
||||
*err = GW_OBEX_ERROR_INTERNAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
GW_OBEX_UNLOCK(ctx);
|
||||
|
||||
gw_obex_xfer_close(xfer, err);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gw_obex_xfer_set_blocking(GwObexXfer *xfer, gboolean block) {
|
||||
GW_OBEX_LOCK(xfer->ctx);
|
||||
xfer->block = block;
|
||||
GW_OBEX_UNLOCK(xfer->ctx);
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/**
|
||||
@file obex-xfer.h
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef _OBEX_XFER_H_
|
||||
#define _OBEX_XFER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <openobex/obex.h>
|
||||
|
||||
#include "gw-obex.h"
|
||||
#include "obex-priv.h"
|
||||
|
||||
struct gw_obex_xfer {
|
||||
/* Pointer to parent gw_obex struct */
|
||||
struct gw_obex *ctx;
|
||||
|
||||
/* Used only for async PUT transfers */
|
||||
obex_object_t *object;
|
||||
|
||||
/* Sync or async transfer */
|
||||
gboolean async;
|
||||
|
||||
/* If read and write operations should block for an async transfer */
|
||||
gboolean block;
|
||||
|
||||
/* When doing a get or put for a local file */
|
||||
int stream_fd;
|
||||
|
||||
/* TRUE if the current operation was aborted */
|
||||
gboolean abort;
|
||||
|
||||
/* Transfer should be closed when no more data to send */
|
||||
gboolean close;
|
||||
|
||||
/* Temporary buffer when doing a put or get */
|
||||
unsigned char *buf;
|
||||
size_t buf_size;
|
||||
|
||||
/* Buffer and size for Application parameters */
|
||||
unsigned char *apparam_buf;
|
||||
size_t apparam_size;
|
||||
|
||||
/* These two elements are only used for async transfers */
|
||||
size_t data_start;
|
||||
size_t data_length;
|
||||
|
||||
/* Bytes read or written for the current get/put operation */
|
||||
size_t counter;
|
||||
|
||||
/* Target length of the current get/put operation */
|
||||
gint target_size;
|
||||
|
||||
/* Modification time of last file transfered */
|
||||
time_t modtime;
|
||||
|
||||
gboolean do_cb;
|
||||
gw_obex_xfer_cb_t cb;
|
||||
gpointer cb_data;
|
||||
|
||||
GSource *idle_source;
|
||||
};
|
||||
|
||||
struct gw_obex_xfer *gw_obex_xfer_new(struct gw_obex *ctx, gboolean async, int stream_fd);
|
||||
|
||||
void _gw_obex_xfer_free(struct gw_obex_xfer *xfer);
|
||||
|
||||
gboolean gw_obex_xfer_do_abort(struct gw_obex_xfer *xfer);
|
||||
|
||||
#endif /* _OBEX_XFER_H_ */
|
@ -1,185 +0,0 @@
|
||||
/**
|
||||
@file utils.c
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
#include <termios.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
char *bytestr(const uint8_t *uuid, int len) {
|
||||
int i;
|
||||
char *str = g_malloc((len << 1) + 1);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
sprintf(str + (2*i), "%02X", uuid[i]);
|
||||
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean fd_raw_mode(int fd) {
|
||||
struct termios mode;
|
||||
|
||||
memset(&mode, 0, sizeof(mode));
|
||||
if (tcgetattr(fd, &mode) < 0) {
|
||||
debug("tcgetattr(%d, &mode): %s", fd, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mode.c_iflag = 0;
|
||||
mode.c_oflag &= ~OPOST;
|
||||
mode.c_lflag &= ~(ISIG | ICANON | ECHO
|
||||
#ifdef XCASE
|
||||
| XCASE
|
||||
#endif
|
||||
);
|
||||
mode.c_cc[VMIN] = 1;
|
||||
mode.c_cc[VTIME] = 0;
|
||||
|
||||
if (tcsetattr(fd, TCSADRAIN, &mode) < 0) {
|
||||
debug("tcsetattr(%d, TCSADRAIN, &mode): %s", fd, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
glong get_uname(gunichar2 **uname, const gchar *name) {
|
||||
glong uname_len;
|
||||
|
||||
if (*name == '\0') {
|
||||
*uname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*uname = g_utf8_to_utf16(name, -1, NULL, &uname_len, NULL);
|
||||
|
||||
if (*uname == NULL)
|
||||
uname_len = -1;
|
||||
else {
|
||||
int i;
|
||||
/* g_utf8_to_utf16 produces host-byteorder UTF-16,
|
||||
* but OBEX requires network byteorder (big endian) */
|
||||
for (i = 0; i < uname_len; i++)
|
||||
(*uname)[i] = g_htons((*uname)[i]);
|
||||
uname_len = (uname_len + 1) << 1;
|
||||
}
|
||||
|
||||
return uname_len;
|
||||
}
|
||||
|
||||
int make_iso8601(time_t time, char *str, int len) {
|
||||
struct tm tm;
|
||||
#if defined(HAVE_TIMEZONE) && defined(USE_LOCALTIME)
|
||||
time_t tz_offset = 0;
|
||||
|
||||
tz_offset = -timezone;
|
||||
if (daylight > 0)
|
||||
tz_offset += 3600;
|
||||
time += tz_offset;
|
||||
#endif
|
||||
|
||||
if (gmtime_r(&time, &tm) == NULL)
|
||||
return -1;
|
||||
|
||||
tm.tm_year += 1900;
|
||||
tm.tm_mon++;
|
||||
|
||||
return snprintf(str, len,
|
||||
#ifdef USE_LOCALTIME
|
||||
"%04u%02u%02uT%02u%02u%02u",
|
||||
#else
|
||||
"%04u%02u%02uT%02u%02u%02uZ",
|
||||
#endif
|
||||
tm.tm_year, tm.tm_mon, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
}
|
||||
|
||||
/* From Imendio's GnomeVFS OBEX module (om-utils.c) */
|
||||
time_t parse_iso8601(const gchar *str, int len) {
|
||||
gchar *tstr;
|
||||
struct tm tm;
|
||||
gint nr;
|
||||
gchar tz;
|
||||
time_t time;
|
||||
time_t tz_offset = 0;
|
||||
|
||||
memset(&tm, 0, sizeof(struct tm));
|
||||
|
||||
/* According to spec the time doesn't have to be null terminated */
|
||||
if (str[len - 1] != '\0') {
|
||||
tstr = g_malloc(len + 1);
|
||||
strncpy(tstr, str, len);
|
||||
tstr[len] = '\0';
|
||||
}
|
||||
else
|
||||
tstr = g_strdup(str);
|
||||
|
||||
nr = sscanf(tstr, "%04u%02u%02uT%02u%02u%02u%c",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
|
||||
&tm.tm_hour, &tm.tm_min, &tm.tm_sec,
|
||||
&tz);
|
||||
|
||||
g_free(tstr);
|
||||
|
||||
/* Fixup the tm values */
|
||||
tm.tm_year -= 1900; /* Year since 1900 */
|
||||
tm.tm_mon--; /* Months since January, values 0-11 */
|
||||
tm.tm_isdst = -1; /* Daylight savings information not avail */
|
||||
|
||||
if (nr < 6) {
|
||||
/* Invalid time format */
|
||||
return -1;
|
||||
}
|
||||
|
||||
time = mktime(&tm);
|
||||
|
||||
#if defined(HAVE_TM_GMTOFF)
|
||||
tz_offset = tm.tm_gmtoff;
|
||||
#elif defined(HAVE_TIMEZONE)
|
||||
tz_offset = -timezone;
|
||||
if (tm.tm_isdst > 0) {
|
||||
tz_offset += 3600;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nr == 7) { /* Date/Time was in localtime (to remote device)
|
||||
* already. Since we don't know anything about the
|
||||
* timezone on that one we won't try to apply UTC offset
|
||||
*/
|
||||
time += tz_offset;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
/**
|
||||
@file utils.h
|
||||
|
||||
@author Johan Hedberg <johan.hedberg@nokia.com>
|
||||
|
||||
Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License, version 2.1, as published by the Free Software Foundation.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
/** Create ISO8601 time format string from time_t
|
||||
* @param time Time to convert
|
||||
* @param str Pointer where result is stored
|
||||
* @param len Maximum amount of chars written
|
||||
* @returns length of created string.
|
||||
*/
|
||||
int make_iso8601(time_t time, char *str, int len);
|
||||
|
||||
/** Convert a time string in ISO8601 format to time_t
|
||||
* @param str Time string in ISO8601 format
|
||||
* @param len Length of string
|
||||
* @returns time as time_t format
|
||||
*/
|
||||
time_t parse_iso8601(const gchar *str, int len);
|
||||
|
||||
#ifdef DEBUG
|
||||
char *bytestr(const uint8_t *uuid, int len);
|
||||
#endif
|
||||
|
||||
/** Convert an UTF-8 string to UTF-16 (Network byte order)
|
||||
* @param uname, Place to store the new UTF-16 string
|
||||
* @param name, Original UTF-8 string
|
||||
* @returns Size in bytes allocated for the UTF-16 string (uname)
|
||||
*/
|
||||
glong get_uname(gunichar2 **uname, const gchar *name);
|
||||
|
||||
gboolean fd_raw_mode(int fd);
|
||||
|
||||
#endif /* _UTILS_H */
|
Loading…
Reference in New Issue
Block a user