2011-06-21 22:24:14

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 Luiz's changes.

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 | 39 +++++++++++++++
gwobex/obex-priv.c | 135 +++++++++++++++++++++++++++++++++++----------------
gwobex/obex-priv.h | 29 +++++++++++
gwobex/obex-xfer.c | 97 +++++++++++++++++++++++++++++++++++++
gwobex/obex-xfer.h | 18 +++++++
5 files changed, 275 insertions(+), 43 deletions(-)



2011-06-22 07:35:49

by Luiz Augusto von Dentz

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

Hi,

On Wed, Jun 22, 2011 at 10:33 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
> Hi Jakub,
>
> On Wed, Jun 22, 2011 at 1:24 AM, Jakub Adamek <[email protected]> wrote:
>> 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 Luiz's changes.
>>
>> 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 ? | ? 39 +++++++++++++++
>> ?gwobex/obex-priv.c | ?135 +++++++++++++++++++++++++++++++++++----------------
>> ?gwobex/obex-priv.h | ? 29 +++++++++++
>> ?gwobex/obex-xfer.c | ? 97 +++++++++++++++++++++++++++++++++++++
>> ?gwobex/obex-xfer.h | ? 18 +++++++
>> ?5 files changed, 275 insertions(+), 43 deletions(-)
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to [email protected]
>> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
>
> I didn't spot more problems with code itself, but you should fix the
> function parameter alignment, try to make them similar to what have
> been used in code e.g.:
>
> 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);
>

Obviously copy-past screw the alignment, but if you look at the code
you gonna see how the alignment should be.



--
Luiz Augusto von Dentz

2011-06-22 07:33:33

by Luiz Augusto von Dentz

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

Hi Jakub,

On Wed, Jun 22, 2011 at 1:24 AM, Jakub Adamek <[email protected]> wrote:
> 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 Luiz's changes.
>
> 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 ? | ? 39 +++++++++++++++
> ?gwobex/obex-priv.c | ?135 +++++++++++++++++++++++++++++++++++----------------
> ?gwobex/obex-priv.h | ? 29 +++++++++++
> ?gwobex/obex-xfer.c | ? 97 +++++++++++++++++++++++++++++++++++++
> ?gwobex/obex-xfer.h | ? 18 +++++++
> ?5 files changed, 275 insertions(+), 43 deletions(-)
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html


I didn't spot more problems with code itself, but you should fix the
function parameter alignment, try to make them similar to what have
been used in code e.g.:

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);

--
Luiz Augusto von Dentz

2011-06-22 07:05:46

by Luiz Augusto von Dentz

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

Hi Jakub,

On Wed, Jun 22, 2011 at 1:24 AM, Jakub Adamek <[email protected]> wrote:
> ---
> ?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..55ea842 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) {

Align this to right until you cross the parentesis or reaches the 80
columns limit, iirc the gwobex uses a different code style but I guess
this is also valid here.

> + ? ?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..7c59827 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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>



--
Luiz Augusto von Dentz

2011-06-21 22:24:25

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 0ce476f..7779d4f 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -499,6 +499,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 844d726..66717b9 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-21 22:24:24

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 fc85fbf..0ce476f 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -475,6 +475,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 7c59827..844d726 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-21 22:24:23

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 c92160d..259400b 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-21 22:24:22

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 420d9bc..c92160d 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -882,11 +882,6 @@ gboolean gw_obex_get_with_aheaders(GwObex *ctx,
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);
@@ -923,6 +918,11 @@ gboolean gw_obex_get_with_aheaders(GwObex *ctx,
}
}

+ 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;
@@ -1057,6 +1057,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);
@@ -1064,11 +1069,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-21 22:24:21

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 | 32 ++++++++++++++++++++++++++++++++
gwobex/obex-xfer.c | 28 ++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/gwobex/gw-obex.h b/gwobex/gw-obex.h
index 0638f45..238d695 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,20 @@ 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 55ea842..fc85fbf 100644
--- a/gwobex/obex-xfer.c
+++ b/gwobex/obex-xfer.c
@@ -124,6 +124,20 @@ 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 +161,20 @@ 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-21 22:24:20

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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 005e656..420d9bc 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-21 22:24:19

by Jakub Adamek

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

These are for internal use by gwobex.
---
gwobex/obex-priv.c | 40 ++++++++++++++++++++++++++++++++++++++++
gwobex/obex-priv.h | 29 +++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/gwobex/obex-priv.c b/gwobex/obex-priv.c
index 7d85045..005e656 100644
--- a/gwobex/obex-priv.c
+++ b/gwobex/obex-priv.c
@@ -847,6 +847,15 @@ 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 +920,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 +984,15 @@ 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 +1071,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..c0548b0 100644
--- a/gwobex/obex-priv.h
+++ b/gwobex/obex-priv.h
@@ -214,4 +214,33 @@ 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


2011-06-21 22:24:18

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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-21 22:24:17

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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..55ea842 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..7c59827 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-21 22:24:16

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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-21 22:24:15

by Jakub Adamek

[permalink] [raw]
Subject: [PATCH obexd v2 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