2011-06-24 00:39:06

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 00/11] Support user defined headers in gwobex

Hi,

these patches will enable sending and receiving of user defined headers
in gwobex.

Two new functions will enable to start an asynchronous get or put
transfer, taking as an argument a list of structures describing
the headers to be sent. The headers are sent out in the order
of appearance on the list.

Likewise all response headers that would have been previously ignored
by gwobex are now inserted to a list in the current gw_obex_xfer
object, and so can be retrieved later after the asynchrous transfer
has finished.

Additionally, the order of sending headers in gwobex is changed
to the one mandated by BIP, i.e.:
Connection ID->Type->Name->Application Parameters->User Defined Headers.

This series incorporates the most recent of Luiz's suggestions.

Jakub Adamek (11):
Add a_header struct for additional header data
Add list to store received headers
Add function to create fresh a_header
Store received headers in gw_obex_xfer object
Add functions to get, put w. a_header list
Parse headers in a PUT response packet
Add functions for async requests w a_header list
Reorder headers to conform to BIP's requirements
Handle partial content response from server
Convenience method to make deep copy of a_header
Add func for fetching header by id from list

gwobex/gw-obex.h | 38 ++++++++++++++
gwobex/obex-priv.c | 142 ++++++++++++++++++++++++++++++++++++----------------
gwobex/obex-priv.h | 34 ++++++++++++
gwobex/obex-xfer.c | 106 ++++++++++++++++++++++++++++++++++++++
gwobex/obex-xfer.h | 18 +++++++
5 files changed, 295 insertions(+), 43 deletions(-)



2011-06-24 00:39:08

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 02/11] Add list to store received headers

The list is a GSList of a_header structs added to gw_obex_xfer for
storing received a_header objects.
---
gwobex/gw-obex.h | 7 +++++++
gwobex/obex-xfer.c | 20 ++++++++++++++++++++
gwobex/obex-xfer.h | 5 +++++
3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/gwobex/gw-obex.h b/gwobex/gw-obex.h
index c858341..0638f45 100644
--- a/gwobex/gw-obex.h
+++ b/gwobex/gw-obex.h
@@ -583,6 +583,13 @@ gint gw_obex_xfer_object_size(GwObexXfer *xfer);
*/
unsigned char *gw_obex_xfer_object_apparam(GwObexXfer *xfer, size_t *apparam_size);

+/** Get the additional header list
+ *
+ * @param xfer Pointer returned by gw_obex_put_async or gw_obex_get_async
+ *
+ * @returns The pointer to the GSList that contains the headers
+ */
+GSList *gw_obex_xfer_object_aheaders(GwObexXfer *xfer);

/** Returns if a transfer is already done
*
diff --git a/gwobex/obex-xfer.c b/gwobex/obex-xfer.c
index 4013687..1430f10 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -202,6 +202,10 @@ unsigned char *gw_obex_xfer_object_apparam(GwObexXfer *xfer, size_t *apparam_siz
return xfer->apparam_buf;
}

+GSList *gw_obex_xfer_object_aheaders(GwObexXfer *xfer) {
+ return xfer->aheaders;
+}
+
gboolean gw_obex_xfer_object_done(GwObexXfer *xfer) {
return xfer->ctx->done;
}
@@ -418,7 +422,23 @@ out:
return ret;
}

+void a_header_free(struct a_header *ah) {
+ switch (ah->hi & OBEX_HDR_TYPE_MASK) {
+ case OBEX_HDR_TYPE_BYTES:
+ case OBEX_HDR_TYPE_UNICODE:
+ g_free((gpointer) ah->hv.bs);
+ break;
+ }
+ g_free(ah);
+}
+
void _gw_obex_xfer_free(struct gw_obex_xfer *xfer) {
+ GSList *aheaders = xfer->aheaders;
+ while (aheaders) {
+ a_header_free(aheaders->data);
+ aheaders = g_slist_next(aheaders);
+ }
+ g_slist_free(xfer->aheaders);
g_free(xfer->buf);
g_free(xfer->apparam_buf);
g_free(xfer);
diff --git a/gwobex/obex-xfer.h b/gwobex/obex-xfer.h
index 9bc832d..b1e2ff0 100644
--- a/gwobex/obex-xfer.h
+++ b/gwobex/obex-xfer.h
@@ -62,6 +62,9 @@ struct gw_obex_xfer {
unsigned char *apparam_buf;
size_t apparam_size;

+ /* Additional headers, in the order they were received */
+ GSList *aheaders;
+
/* These two elements are only used for async transfers */
size_t data_start;
size_t data_length;
@@ -88,6 +91,8 @@ struct a_header {
uint32_t hv_size;
};

+void a_header_free(struct a_header *ah);
+
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);
--
1.7.0.4


2011-06-24 00:39:07

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 01/11] Add a_header struct for additional header data

---
gwobex/obex-xfer.h | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-xfer.h b/gwobex/obex-xfer.h
index 5a88b13..9bc832d 100644
--- a/gwobex/obex-xfer.h
+++ b/gwobex/obex-xfer.h
@@ -82,6 +82,12 @@ struct gw_obex_xfer {
GSource *idle_source;
};

+struct a_header {
+ uint8_t hi;
+ obex_headerdata_t hv;
+ uint32_t hv_size;
+};
+
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);
--
1.7.0.4


2011-06-24 00:39:09

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 03/11] Add function to create fresh a_header

---
gwobex/obex-xfer.c | 25 +++++++++++++++++++++++++
gwobex/obex-xfer.h | 3 +++
2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-xfer.c b/gwobex/obex-xfer.c
index 1430f10..90fe803 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -422,6 +422,31 @@ out:
return ret;
}

+struct a_header *make_a_header(uint8_t hi, obex_headerdata_t hv,
+ unsigned int hlen) {
+ struct a_header *ah = g_new0(struct a_header, 1);
+ ah->hi = hi;
+ ah->hv_size = hlen;
+ switch (hi & OBEX_HDR_TYPE_MASK) {
+ case OBEX_HDR_TYPE_UINT8:
+ case OBEX_HDR_TYPE_UINT32:
+ ah->hv = hv;
+ break;
+ case OBEX_HDR_TYPE_BYTES:
+ case OBEX_HDR_TYPE_UNICODE:
+ ah->hv.bs = g_try_malloc(hlen);
+ if (ah->hv.bs != NULL)
+ memcpy((void *) ah->hv.bs, hv.bs, hlen);
+ else if (hlen > 0) {
+ g_free(ah);
+ return NULL;
+ }
+ ah->hv_size = hlen;
+ break;
+ }
+ return ah;
+}
+
void a_header_free(struct a_header *ah) {
switch (ah->hi & OBEX_HDR_TYPE_MASK) {
case OBEX_HDR_TYPE_BYTES:
diff --git a/gwobex/obex-xfer.h b/gwobex/obex-xfer.h
index b1e2ff0..6c92ef6 100644
--- a/gwobex/obex-xfer.h
+++ b/gwobex/obex-xfer.h
@@ -93,6 +93,9 @@ struct a_header {

void a_header_free(struct a_header *ah);

+struct a_header *make_a_header(uint8_t hi, obex_headerdata_t hv,
+ unsigned int hlen);
+
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);
--
1.7.0.4


2011-06-24 00:39:12

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 06/11] Parse headers in a PUT response packet

---
gwobex/obex-priv.c | 69 +++++++++++++++++++++++++++-------------------------
1 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index 2073c2c..7e3068b 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -298,39 +298,6 @@ static void obex_abort_done(GwObex *ctx, obex_object_t *object,
optostr((uint8_t)obex_cmd), (uint8_t)obex_cmd);
}

-static void obex_request_done(GwObex *ctx, obex_object_t *object,
- int obex_cmd, int obex_rsp) {
- ctx->done = TRUE;
- if (ctx->xfer)
- ctx->xfer->do_cb = TRUE;
-
- ctx->obex_rsp = obex_rsp;
-
- if (obex_rsp != OBEX_RSP_SUCCESS) {
- debug("%s command (0x%02x) failed: %s (0x%02x)\n",
- optostr((uint8_t)obex_cmd), (uint8_t)obex_cmd,
- OBEX_ResponseToString(obex_rsp), (uint8_t)obex_rsp);
-#ifdef DEBUG
- if (obex_rsp == OBEX_RSP_UNAUTHORIZED) {
- debug("Showing headers..\n");
- show_headers(ctx->handle, object);
- }
-#endif
- return;
- }
-
- debug("%s command (0x%02x) succeeded.\n", optostr((uint8_t)obex_cmd),
- (uint8_t)obex_cmd);
-
- switch (obex_cmd) {
- case OBEX_CMD_CONNECT:
- obex_connect_done(ctx, object, obex_rsp);
- break;
- default:
- break;
- }
-}
-
static void get_non_body_headers(obex_t *handle, obex_object_t *object,
struct gw_obex_xfer *xfer) {
obex_headerdata_t hv;
@@ -371,6 +338,42 @@ static void get_non_body_headers(obex_t *handle, obex_object_t *object,
OBEX_ObjectReParseHeaders(handle, object);
}

+static void obex_request_done(GwObex *ctx, obex_object_t *object,
+ int obex_cmd, int obex_rsp) {
+ ctx->done = TRUE;
+ if (ctx->xfer)
+ ctx->xfer->do_cb = TRUE;
+
+ ctx->obex_rsp = obex_rsp;
+
+ if (obex_rsp != OBEX_RSP_SUCCESS) {
+ debug("%s command (0x%02x) failed: %s (0x%02x)\n",
+ optostr((uint8_t)obex_cmd), (uint8_t)obex_cmd,
+ OBEX_ResponseToString(obex_rsp), (uint8_t)obex_rsp);
+#ifdef DEBUG
+ if (obex_rsp == OBEX_RSP_UNAUTHORIZED) {
+ debug("Showing headers..\n");
+ show_headers(ctx->handle, object);
+ }
+#endif
+ return;
+ }
+
+ if (ctx->xfer)
+ get_non_body_headers(ctx->handle, object, ctx->xfer);
+
+ debug("%s command (0x%02x) succeeded.\n", optostr((uint8_t)obex_cmd),
+ (uint8_t)obex_cmd);
+
+ switch (obex_cmd) {
+ case OBEX_CMD_CONNECT:
+ obex_connect_done(ctx, object, obex_rsp);
+ break;
+ default:
+ break;
+ }
+}
+
static void obex_readstream(GwObex *ctx, obex_object_t *object) {
struct gw_obex_xfer *xfer = ctx->xfer;
const uint8_t *buf;
--
1.7.0.4


2011-06-24 00:39:16

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 10/11] Convenience method to make deep copy of a_header

---
gwobex/obex-xfer.c | 14 ++++++++++++++
gwobex/obex-xfer.h | 2 ++
2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-xfer.c b/gwobex/obex-xfer.c
index 4c9b5ee..a48d8e8 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -484,6 +484,20 @@ struct a_header *make_a_header(uint8_t hi, obex_headerdata_t hv,
return ah;
}

+struct a_header *a_header_copy(struct a_header *ah) {
+ struct a_header *res;
+ if (ah == NULL)
+ return NULL;
+ res = g_memdup(ah, sizeof(struct a_header));
+ switch (res->hi & OBEX_HDR_TYPE_MASK) {
+ case OBEX_HDR_TYPE_BYTES:
+ case OBEX_HDR_TYPE_UNICODE:
+ res->hv.bs = g_memdup(ah->hv.bs, ah->hv_size);
+ break;
+ }
+ return res;
+}
+
void a_header_free(struct a_header *ah) {
switch (ah->hi & OBEX_HDR_TYPE_MASK) {
case OBEX_HDR_TYPE_BYTES:
diff --git a/gwobex/obex-xfer.h b/gwobex/obex-xfer.h
index 6c92ef6..25b82b7 100644
--- a/gwobex/obex-xfer.h
+++ b/gwobex/obex-xfer.h
@@ -96,6 +96,8 @@ void a_header_free(struct a_header *ah);
struct a_header *make_a_header(uint8_t hi, obex_headerdata_t hv,
unsigned int hlen);

+struct a_header *a_header_copy(struct a_header *ah);
+
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);
--
1.7.0.4


2011-06-24 00:39:15

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 09/11] Handle partial content response from server

---
gwobex/obex-priv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index 40a2026..e92e207 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -346,7 +346,7 @@ static void obex_request_done(GwObex *ctx, obex_object_t *object,

ctx->obex_rsp = obex_rsp;

- if (obex_rsp != OBEX_RSP_SUCCESS) {
+ if (obex_rsp != OBEX_RSP_SUCCESS && obex_rsp != OBEX_RSP_PARTIAL_CONTENT) {
debug("%s command (0x%02x) failed: %s (0x%02x)\n",
optostr((uint8_t)obex_cmd), (uint8_t)obex_cmd,
OBEX_ResponseToString(obex_rsp), (uint8_t)obex_rsp);
--
1.7.0.4


2011-06-24 00:39:17

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 11/11] Add func for fetching header by id from list

---
gwobex/obex-xfer.c | 10 ++++++++++
gwobex/obex-xfer.h | 2 ++
2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-xfer.c b/gwobex/obex-xfer.c
index a48d8e8..915f756 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -508,6 +508,16 @@ void a_header_free(struct a_header *ah) {
g_free(ah);
}

+struct a_header *a_header_find(GSList *aheaders, uint8_t hi) {
+ while (aheaders) {
+ struct a_header *ah = aheaders->data;
+ if (ah->hi == hi)
+ return aheaders->data;
+ aheaders = g_slist_next(aheaders);
+ }
+ return NULL;
+}
+
void _gw_obex_xfer_free(struct gw_obex_xfer *xfer) {
GSList *aheaders = xfer->aheaders;
while (aheaders) {
diff --git a/gwobex/obex-xfer.h b/gwobex/obex-xfer.h
index 25b82b7..33b3361 100644
--- a/gwobex/obex-xfer.h
+++ b/gwobex/obex-xfer.h
@@ -98,6 +98,8 @@ struct a_header *make_a_header(uint8_t hi, obex_headerdata_t hv,

struct a_header *a_header_copy(struct a_header *ah);

+struct a_header *a_header_find(GSList *aheaders, uint8_t hi);
+
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);
--
1.7.0.4


2011-06-24 00:39:14

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 08/11] Reorder headers to conform to BIP's requirements

---
gwobex/obex-priv.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index 7e3068b..40a2026 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -884,11 +884,6 @@ gboolean gw_obex_get_with_aheaders(GwObex *ctx, const gchar *local,
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_CONNECTION, hv, 4, 0);
}

- if (apparam && apparam_size > 0) {
- hv.bs = (unsigned char *)apparam;
- OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_APPARAM, hv, apparam_size, 0);
- }
-
if (type) {
hv.bs = (unsigned char *)type;
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_TYPE, hv, strlen(type) + 1, 0);
@@ -925,6 +920,11 @@ gboolean gw_obex_get_with_aheaders(GwObex *ctx, const gchar *local,
}
}

+ if (apparam && apparam_size > 0) {
+ hv.bs = (unsigned char *)apparam;
+ OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_APPARAM, hv, apparam_size, 0);
+ }
+
if (aheaders) {
const GSList *hlist = aheaders;
struct a_header *ah;
@@ -1064,6 +1064,11 @@ gboolean gw_obex_put_with_aheaders(GwObex *ctx,
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_CONNECTION, hv, 4, 0);
}

+ if (type) {
+ hv.bs = (unsigned char *)type;
+ OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_TYPE, hv, strlen(type) + 1, 0);
+ }
+
if (uname) {
hv.bs = (unsigned char *)uname;
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_NAME, hv, uname_len, 0);
@@ -1071,11 +1076,6 @@ gboolean gw_obex_put_with_aheaders(GwObex *ctx,
uname = NULL;
}

- if (type) {
- hv.bs = (unsigned char *)type;
- OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_TYPE, hv, strlen(type) + 1, 0);
- }
-
if (apparam && apparam_size > 0) {
hv.bs = (unsigned char *)apparam;
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_APPARAM, hv, apparam_size, 0);
--
1.7.0.4


2011-06-24 00:39:13

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 07/11] Add functions for async requests w a_header list

These are to be used by client for performing async get or put
operations with sending additional headers.
---
gwobex/gw-obex.h | 31 +++++++++++++++++++++++++++++++
gwobex/obex-xfer.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/gwobex/gw-obex.h b/gwobex/gw-obex.h
index 0638f45..060f726 100644
--- a/gwobex/gw-obex.h
+++ b/gwobex/gw-obex.h
@@ -510,6 +510,24 @@ gboolean gw_obex_copy(GwObex *ctx, const gchar *src, const gchar *dst,
GwObexXfer *gw_obex_put_async(GwObex *ctx, const char *name, const char *type,
gint size, time_t time, gint *error);

+/** Start a PUT operation asynchronously with additional headers
+ *
+ * @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 aheaders List of additional headers
+ * @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_with_aheaders(GwObex *ctx, const char *name, const char *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders,
+ gint size, time_t time, gint *error);

/** Start a GET operation asynchronously
*
@@ -537,6 +555,19 @@ GwObexXfer *gw_obex_get_async(GwObex *ctx, const char *name, const char *type, g
GwObexXfer *gw_obex_get_async_with_apparam(GwObex *ctx, const char *name, const char *type,
const guint8 *apparam, gint apparam_size, gint *error);

+/** Start a GET operation asynchronously with additional headers
+ *
+ * @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 aheaders List of additional headers
+ * @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_aheaders(GwObex *ctx, const char *name, const char *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders, gint *error);

/** Set a callback function for a GwObexXfer object
* The callback function will be called in the following situations:
diff --git a/gwobex/obex-xfer.c b/gwobex/obex-xfer.c
index 90fe803..4c9b5ee 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -124,6 +124,25 @@ GwObexXfer *gw_obex_put_async(GwObex *ctx, const char *name, const char *type,
return ret ? ctx->xfer : NULL;
}

+GwObexXfer *gw_obex_put_async_with_aheaders(GwObex *ctx, const char *name,
+ const char *type,
+ const guint8 *apparam,
+ gint apparam_size,
+ const GSList *aheaders,
+ gint size, time_t time,
+ gint *error) {
+ gboolean ret;
+ GW_OBEX_LOCK(ctx);
+ CHECK_DISCONNECT(NULL, error, ctx);
+ ret = gw_obex_put_with_aheaders(ctx, NULL, name, type,
+ apparam, apparam_size,
+ aheaders, 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);
@@ -147,6 +166,24 @@ GwObexXfer *gw_obex_get_async_with_apparam(GwObex *ctx, const char *name, const
return ret ? ctx->xfer : NULL;
}

+GwObexXfer *gw_obex_get_async_with_aheaders(GwObex *ctx, const char *name,
+ const char *type,
+ const guint8 *apparam,
+ gint apparam_size,
+ const GSList *aheaders,
+ gint *error) {
+ gboolean ret;
+ GW_OBEX_LOCK(ctx);
+ CHECK_DISCONNECT(NULL, error, ctx);
+ ret = gw_obex_get_with_aheaders(ctx, NULL, name, type,
+ apparam, apparam_size,
+ aheaders, 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;

--
1.7.0.4


2011-06-24 00:39:10

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 04/11] Store received headers in gw_obex_xfer object

---
gwobex/obex-priv.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index aba7dd7..7d85045 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -39,6 +39,7 @@
#include <sys/socket.h>

#include <openobex/obex.h>
+#include <openobex/obex_const.h>

#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -335,6 +336,7 @@ static void get_non_body_headers(obex_t *handle, obex_object_t *object,
obex_headerdata_t hv;
uint8_t hi;
unsigned int hlen;
+ struct a_header *ah;

xfer->target_size = GW_OBEX_UNKNOWN_LENGTH;
xfer->modtime = -1;
@@ -358,6 +360,10 @@ static void get_non_body_headers(obex_t *handle, obex_object_t *object,
xfer->apparam_size = 0;
break;
default:
+ ah = make_a_header(hi, hv, hlen);
+
+ if (ah != NULL)
+ xfer->aheaders = g_slist_append(xfer->aheaders, ah);
break;
}
}
--
1.7.0.4


2011-06-24 00:39:11

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v3 05/11] Add functions to get, put w. a_header list

---
gwobex/obex-priv.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
gwobex/obex-priv.h | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index 7d85045..2073c2c 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -847,6 +847,17 @@ gboolean gw_obex_get(GwObex *ctx,
const guint8 *apparam, gint apparam_size,
gchar **buf, gint *buf_size, int stream_fd,
gboolean async) {
+ return gw_obex_get_with_aheaders(ctx, local, remote, type,
+ apparam, apparam_size,
+ NULL, buf, buf_size, stream_fd, async);
+}
+
+gboolean gw_obex_get_with_aheaders(GwObex *ctx, const gchar *local,
+ const gchar *remote, const gchar *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders,
+ gchar **buf, gint *buf_size, int stream_fd,
+ gboolean async) {
gboolean ret = FALSE;
obex_headerdata_t hv;
obex_object_t *object;
@@ -911,6 +922,17 @@ gboolean gw_obex_get(GwObex *ctx,
}
}

+ if (aheaders) {
+ const GSList *hlist = aheaders;
+ struct a_header *ah;
+ while (hlist) {
+ ah = hlist->data;
+ hv = ah->hv;
+ OBEX_ObjectAddHeader(ctx->handle, object, ah->hi, hv, ah->hv_size, 0);
+ hlist = g_slist_next(hlist);
+ }
+ }
+
OBEX_ObjectReadStream(ctx->handle, object, NULL);

if (async) {
@@ -964,6 +986,20 @@ gboolean gw_obex_put(GwObex *ctx,
const guint8 *apparam, gint apparam_size,
const gchar *buf, gint object_size, time_t object_time,
int stream_fd, gboolean async) {
+ return gw_obex_put_with_aheaders(ctx, local, remote, type,
+ apparam, apparam_size,
+ NULL, buf, object_size, object_time,
+ stream_fd, async);
+}
+
+gboolean gw_obex_put_with_aheaders(GwObex *ctx,
+ const gchar *local, const gchar *remote,
+ const gchar *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders,
+ const gchar *buf,
+ gint object_size, time_t object_time,
+ int stream_fd, gboolean async) {
gboolean ret = FALSE;
obex_headerdata_t hv;
obex_object_t *object;
@@ -1042,6 +1078,17 @@ gboolean gw_obex_put(GwObex *ctx,
OBEX_ObjectAddHeader(ctx->handle, object, OBEX_HDR_APPARAM, hv, apparam_size, 0);
}

+ if (aheaders) {
+ const GSList *hlist = aheaders;
+ struct a_header *ah;
+ while (hlist) {
+ ah = hlist->data;
+ hv = ah->hv;
+ OBEX_ObjectAddHeader(ctx->handle, object, ah->hi, hv, ah->hv_size, 0);
+ hlist = g_slist_next(hlist);
+ }
+ }
+
/* Try to figure out modification time if none was given */
if (ctx->xfer->stream_fd >= 0) {
struct stat stats;
diff --git a/gwobex/obex-priv.h b/gwobex/obex-priv.h
index f4e3e5b..0ae942c 100644
--- a/gwobex/obex-priv.h
+++ b/gwobex/obex-priv.h
@@ -214,4 +214,38 @@ gboolean gw_obex_put(GwObex *ctx,
const gchar *buf, gint buf_size, time_t object_time,
int stream_fd, gboolean async);

+
+/** Get an object from the server, specifying additional headers
+ * @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)
+ * @param aheaders list of additional headers (NULL if empty)
+ * @returns TRUE on success, FALSE on failure
+ */
+gboolean gw_obex_get_with_aheaders(GwObex *ctx,
+ const gchar *local, const gchar *remote,
+ const gchar *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders,
+ 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)
+ * @param aheaders list of additional headers (NULL if empty)
+ * @returns TRUE on success, FALSE on failure
+ */
+gboolean gw_obex_put_with_aheaders(GwObex *ctx,
+ const gchar *local, const gchar *remote,
+ const gchar *type,
+ const guint8 *apparam, gint apparam_size,
+ const GSList *aheaders,
+ const gchar *buf, gint buf_size,
+ time_t object_time,
+ int stream_fd, gboolean async);
+
#endif /* _OBEX_PRIV_H_ */
--
1.7.0.4