Exemplo n.º 1
0
//
// Add more data to stream.
//
static int writestream(obex_t *handle, obex_object_t *object)
{
	int 			actual;
	obexsrv_t		*srv = OBEX_GetUserData(handle);
	obex_headerdata_t	hv;
		
	actual = read(srv->sfd, srv->buf, OBEX_STREAM_CHUNK);
	DBPRT("sent %d bytes\n", actual);
	if(actual > 0) {
		/* Read was ok! */
		hv.bs = srv->buf;
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hv, actual, OBEX_FL_STREAM_DATA);
	} else if(actual == 0) {
		/* EOF */
		hv.bs = srv->buf;
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATAEND);
	} else {
		/* Error */
		hv.bs = NULL;
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATA);
	}
	return actual;
}
Exemplo n.º 2
0
/**
	Add more data from memory to stream.
 */
static int cli_fillstream_from_memory(obexftp_client_t *cli, obex_object_t *object)
{
	obex_headerdata_t hv;
	int actual = cli->out_size - cli->out_pos;
	if (actual > STREAM_CHUNK)
		actual = STREAM_CHUNK;
	DEBUG(3, "%s() Read %d bytes\n", __func__, actual);
	
	if(actual > 0) {
		/* Read was ok! */
		hv.bs = (const uint8_t *) &cli->out_data[cli->out_pos];
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, actual, OBEX_FL_STREAM_DATA);
		cli->out_pos += actual;
	}
	else if(actual == 0) {
		/* EOF */
		cli->out_data = NULL; /* dont free, isnt ours */
		hv.bs = (const uint8_t *) &cli->out_data[cli->out_pos];
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATAEND);
	}
	else {
		/* Error */
		cli->out_data = NULL; /* dont free, isnt ours */
		hv.bs = (const uint8_t *) NULL;
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATA);
	}

	return actual;
}
Exemplo n.º 3
0
int obex_setpath(int od, const char *path, uint8_t flags)
{
	unsigned char taildata[2] = { 0x00, 0x00 };
	obex_t *handle = obex_handles[0];
	struct obex_context *context;
	char unicode[200];
	int err, size;

	obex_object_t *object;
	obex_headerdata_t hd;

	if (!(context = OBEX_GetUserData(handle)))
		return -1;

	if (context->state != OBEX_CONNECTED)
		return -1;

	if (context->mode != OBEX_IDLE)
		return -1;

	context->mode = OBEX_REQUEST;

	if (!(object = OBEX_ObjectNew(handle, OBEX_CMD_SETPATH)))
		return -1;

	if (context->cid > 0) {
		hd.bq4 = context->cid;
		OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
	}

	if (path) {
		size = OBEX_CharToUnicode((uint8_t *) unicode, (uint8_t *) path, sizeof(unicode));
		hd.bs = (uint8_t *) unicode;
		OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_NAME, hd, size, OBEX_FL_FIT_ONE_PACKET);
	}

	taildata[0] = flags;
	OBEX_ObjectSetNonHdrData(object, taildata, sizeof(taildata));

	if ((err = OBEX_Request(handle, object)) < 0)
		return err;

	while (1) {
		OBEX_HandleInput(handle, OBEX_TIMEOUT);

		if (context->mode == OBEX_ERROR) {
			err = -EIO;
			break;
		}

		if (context->mode == OBEX_DONE)
			break;
	}

	context->mode = OBEX_IDLE;

	return err;
}
Exemplo n.º 4
0
obex_object_t*
BuildObjFromFile(obex_t* handle, const char* filename)
{
    obex_headerdata_t hdd;
    uint8_t unicodebuf[200];
    int namebuflen;
    obex_object_t *object;
    uint32_t creatorid = MEMO_PAD;
    int filesize;
    char* name = NULL;
    uint8_t* buf;

    buf = ReadEasily(filename, &filesize);
    if (buf == NULL)
        return NULL;

    creatorid = MEMO_PAD;
    name = strchr(filename, '.');
    if (name) {
        name++;
        if (strcmp(name, "vcf") == 0) {
            printf( "This is a Address Book file\n");
            creatorid = ADDRESS_BOOK;
        } else if (strcmp(name, "vcs") == 0) {
            printf( "This is a Date Book file\n");
            creatorid = DATE_BOOK;
        } else if (strcmp(name, "txt") == 0) {
            printf("This is a Memo pad file\n");
            creatorid = MEMO_PAD;
        } else if (strcmp(name, "prc") == 0) {
            printf("This is a Pilot resource file\n");
            creatorid = PILOT_RESOURCE;
        }
    }

    object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
    // makhtar
    //namebuflen = OBEX_CharToUnicode(unicodebuf, (const uint8_t *)filename, sizeof(unicodebuf));
    strcpy(unicodebuf, filename);
    namebuflen = sizeof(unicodebuf);

    hdd.bs = unicodebuf;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hdd, namebuflen, 0);

    hdd.bq4 = filesize;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hdd, sizeof(uint32_t), 0);

    if (obexProtocolType != 1) {
        hdd.bq4 = creatorid;
        OBEX_ObjectAddHeader(handle, object, HEADER_CREATOR_ID, hdd, sizeof(uint32_t), 0);
    }

    hdd.bs = buf;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hdd, filesize, 0);
    free(buf);
    return object;
}
Exemplo n.º 5
0
PyObject *lightblueobex_filetostream(obex_t *obex, obex_object_t *obj, PyObject *fileobj, int bufsize)
{
    const void *data;
    Py_ssize_t datalen;        /* or unsigned int? */
    obex_headerdata_t hv;
    PyObject *buf;

    DEBUG("%s()\n", __func__);

    if (fileobj == NULL) {
        DEBUG("\tgiven file object is NULL\n");
        hv.bs = NULL;
        OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hv, 0,
                OBEX_FL_STREAM_DATAEND);
        return NULL;
    }

    buf = PyObject_CallMethod(fileobj, "read", "i", bufsize);
    if (buf == NULL) {
        if (PyErr_Occurred()) {
            PyErr_Print();
            PyErr_Clear();  /* let caller set exception */
        }
        DEBUG("\terror calling file object read()\n");
    }

    if (buf != NULL && !PyObject_CheckReadBuffer(buf)) {
        DEBUG("\tfile object read() returned non-buffer object\n");
        Py_DECREF(buf);
        buf = NULL;
    }

    if (buf != NULL && PyObject_AsReadBuffer(buf, &data, &datalen) < 0) {
        DEBUG("\terror reading file object contents\n");
        Py_DECREF(buf);
        buf = NULL;
    }

    if (buf == NULL) {
        hv.bs = NULL;
        OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hv, 0,
                OBEX_FL_STREAM_DATAEND);
        return NULL;
    }

    hv.bs = (uint8_t*)data;
    if (OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hv, datalen,
           (datalen == 0 ? OBEX_FL_STREAM_DATAEND : OBEX_FL_STREAM_DATA)) < 0) {
        DEBUG("\terror adding body data\n");
        Py_DECREF(buf);
        buf = NULL;
    }

    return buf;
}
Exemplo n.º 6
0
void obexsrv_connect(obex_t *handle, obex_object_t *object)
{
	obex_headerdata_t 	hv;
	uint8_t			hi;
	int			hlen;
	uint8_t			*nonhdrdata;
	obex_target_t		target = {0, NULL};
	obexsrv_t		*srv = OBEX_GetUserData(handle);
	int			err;

	DBPRT("");

	if(OBEX_ObjectGetNonHdrData(object, &nonhdrdata) == 4) {
#ifdef CONFIG_AFFIX_DEBUG
		obex_connect_hdr_t	*hdr = (obex_connect_hdr_t*)nonhdrdata;
		DBPRT("Version: 0x%02x. Flags: 0x%02x  OBEX packet length:%d",
			hdr->version, hdr->flags, ntohs(hdr->mtu));
#endif
	} else {
		BTERROR("Invalid packet content.");
	}
	while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) {
		switch (hi) {
			case OBEX_HDR_TARGET:
				target.data = (void*)hv.bs;
				target.len = hlen;
				if (hlen == 16)
					DBPRT("got TARGET. uuid_t: %08X-%04X-%04X-%04X-%08X%04X",
							*(uint32_t *)&target.data[0], *(uint16_t *)&target.data[4],
							*(uint16_t *)&target.data[6], *(uint16_t *)&target.data[8],
							*(uint32_t *)&target.data[10], *(uint16_t *)&target.data[14]);
				else
					DBPRT("got TARGET. unknown fmt");
				break;
			default:	
				DBPRT(" Skipped header %02x", hi);
				break;
		}
	}

	// call handler
	err = srv->connect(srv, &target);
	if (err < 0) {
		/* error */
		OBEX_ObjectSetRsp(object, OBEX_RSP_INTERNAL_SERVER_ERROR, OBEX_RSP_INTERNAL_SERVER_ERROR);
	} else {
		OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS);
		if (target.data) {
			hv.bq4 = err;	/* set connection id */
			OBEX_ObjectAddHeader(handle, object, OBEX_HDR_CONNECTION, hv, 4, 0);
			hv.bs = target.data;
			OBEX_ObjectAddHeader(handle, object, OBEX_HDR_WHO, hv, target.len, 0);
		}
	}
}
Exemplo n.º 7
0
int obex_delete(obex_t *handle, const char *name)
{
	obex_context_t *context = OBEX_GetUserData(handle);
	obex_object_t *object;
	obex_headerdata_t hd;
	int err;
	g_return_val_if_fail(context != NULL, -1);

	if (context->state != OBEX_OPEN && context->state != OBEX_CONNECT
					&& context->state != OBEX_CONNECTED)
		return -ENOTCONN;

	object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
	if (!object)
		return -ENOMEM;

	if (context->cid != CID_INVALID) {
		hd.bq4 = context->cid;
		OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
	}

	if (name) {
		int len, ulen = (strlen(name) + 1) * 2;
		uint8_t *unicode = malloc(ulen);

		if (!unicode) {
			OBEX_ObjectDelete(handle, object);
			return -ENOMEM;
		}

		len = OBEX_CharToUnicode(unicode, (uint8_t *) name, ulen);
		hd.bs = unicode;

		err = OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET);
		if (err < 0) {
			OBEX_ObjectDelete(handle, object);
			free(unicode);
			return err;
                }

                free(unicode);
        }

	err = obex_send_or_queue(handle, object);
	if (err < 0)
		OBEX_ObjectDelete(handle, object);

	return err;
}
Exemplo n.º 8
0
//
// Create an object from a file. Attach some info-headers to it
//
obex_object_t *build_object_from_file(obex_t *handle, const char *localname, const char *remotename)
{
    obex_object_t *object = NULL;
    obex_headerdata_t hdd;
    uint8_t *ucname;
    int ucname_len, size;
    int i;
    char lastmod[21*2] = {"1970-01-01T00:00:00Z"};

    /* Get filesize and modification-time */
    size = get_fileinfo(localname, lastmod);

    object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
    if(object == NULL)
        return NULL;

    ucname_len = strlen(remotename)*2 + 2;
    ucname = malloc(ucname_len);
    if(ucname == NULL)
        goto err;

    ucname_len = strcpy_utf8_to_unicode(ucname, remotename, ucname_len);

    //ucname_len = OBEX_CharToUnicode(ucname, remotename, ucname_len);
    //printf("ucname len %d\n", ucname_len);
    //for(i=0; i< ucname_len; i++)
    //	printf("%d ", ucname[i]);

    //printf("\n");

    hdd.bs = ucname;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hdd, ucname_len, 0);
    free(ucname);

    hdd.bq4 = size;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hdd, sizeof(uint32_t), 0);

    hdd.bs = NULL;
    OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
                         hdd, 0, OBEX_FL_STREAM_START);

    DEBUG(4, "Lastmod = %s\n", lastmod);
    return object;

err:
    if(object != NULL)
        OBEX_ObjectDelete(handle, object);
    return NULL;
}
Exemplo n.º 9
0
//
// Create an object from a file. Attach some info-headers to it
//
obex_object_t *build_object_from_file(obex_t *handle, const char *localname, const char *remotename)
{
	obex_object_t *object = NULL;
	obex_headerdata_t hdd;
	uint8_t *ucname;
	int ucname_len, size;
	char lastmod[21*2] = {"1970-01-01T00:00:00Z"};
		
	/* Get filesize and modification-time */
	size = get_fileinfo(localname, lastmod);

	object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
	if(object == NULL)
		return NULL;

	ucname_len = strlen(remotename)*2 + 2;
	ucname = malloc(ucname_len);
	if(ucname == NULL)
		goto err;

	ucname_len = OBEX_CharToUnicode(ucname, remotename, ucname_len);

	hdd.bs = ucname;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hdd, ucname_len, 0);
	free(ucname);

	hdd.bq4 = size;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hdd, sizeof(uint32_t), 0);

#if 0
	/* Win2k excpects this header to be in unicode. I suspect this in
	   incorrect so this will have to wait until that's investigated */
	hdd.bs = lastmod;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TIME, hdd, strlen(lastmod)+1, 0);
#endif
		
	hdd.bs = NULL;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hdd, 0, OBEX_FL_STREAM_START);

	DEBUG(4, "Lastmod = %s\n", lastmod);
	return object;

err:
	if(object != NULL)
		OBEX_ObjectDelete(handle, object);
	return NULL;
}
Exemplo n.º 10
0
int obex_connect(obex_t *handle, const unsigned char *target, size_t size)
{
	obex_context_t *context = OBEX_GetUserData(handle);
	obex_object_t *object;
	obex_headerdata_t hd;
	int err, ret;
	g_return_val_if_fail(context != NULL, -1);

	if (context->state != OBEX_OPEN && context->state != OBEX_CLOSED)
		return -EISCONN;

	object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT);
	if (!object)
		return -ENOMEM;

	if (target) {
                hd.bs = target;

		err = OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_TARGET, hd, size, OBEX_FL_FIT_ONE_PACKET);
		if (err < 0) {
			OBEX_ObjectDelete(handle, object);
			return err;
                }
	}

	context->state = OBEX_CONNECT;

	ret = obex_send_or_queue(handle, object);	
	if (ret < 0)
		OBEX_ObjectDelete(handle, object);

	return ret;
}
Exemplo n.º 11
0
static int lightblueobex_add4byteheader(obex_t *obex, obex_object_t *obj, uint8_t hi, PyObject *value)
{
    obex_headerdata_t hv;
    uint32_t intvalue;

    DEBUG("%s()\n", __func__);

    if (value == NULL)
        return -1;

    if (PyInt_Check(value)) {
        intvalue = PyInt_AsLong(value);
        if (PyErr_Occurred()) {
            DEBUG("\tcan't convert header 0x%02x int value to long", hi);
            PyErr_Clear();
            return -1;
        }
    } else if (PyLong_Check(value)) {
        intvalue = PyLong_AsUnsignedLong(value);
        if (PyErr_Occurred()) {
            DEBUG("\tcan't convert header 0x%02x long value to long", hi);
            PyErr_Clear();
            return -1;
        }
    } else {
        DEBUG("\theader value for id 0x%02x must be int or long, was %s\n",
                hi, value->ob_type->tp_name);
        return -1;
    }

    hv.bq4 = intvalue;
    return OBEX_ObjectAddHeader(obex, obj, hi, hv, 4, OBEX_FL_FIT_ONE_PACKET);
}
Exemplo n.º 12
0
//
// Do OBEX SetPath
//
static int ircp_setpath(ircp_client_t *cli, char *name, int up)
{
	obex_object_t *object;
	obex_headerdata_t hdd;

	uint8_t setpath_nohdr_data[2] = {0,};
	uint8_t *ucname;
	int ucname_len;
	int ret;

	DEBUG(4, "%s\n", name);

	object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_SETPATH);

	if(up) {
		setpath_nohdr_data[0] = 1;
	}
	else {
		ucname_len = strlen(name)*2 + 2;
		ucname = malloc(ucname_len);
		if(ucname == NULL) {
			OBEX_ObjectDelete(cli->obexhandle, object);
			return -1;
		}
		ucname_len = OBEX_CharToUnicode(ucname, (uint8_t *) name, ucname_len);

		hdd.bs = ucname;
		OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_NAME, hdd, ucname_len, 0);
		free(ucname);
	}

	OBEX_ObjectSetNonHdrData(object, setpath_nohdr_data, 2);
	ret = cli_sync_request(cli, object);
	return ret;
}
Exemplo n.º 13
0
/**
	Disconnect this ObexFTP client by sending an OBEX DISCONNECT request.

	\param cli an obexftp_client_t created by obexftp_open().

	\return the result of the DISCONNECT request
 */
int obexftp_disconnect(obexftp_client_t *cli)
{
	obex_object_t *object;
	obex_headerdata_t hv;
	int ret;

	DEBUG(3, "%s()\n", __func__);
	return_val_if_fail(cli != NULL, -EINVAL);

	cli->infocb(OBEXFTP_EV_DISCONNECTING, "", 0, cli->infocb_data);

	object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_DISCONNECT);
	if(cli->connection_id != 0xffffffff) {
		hv.bq4 = cli->connection_id;
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_CONNECTION,
				    hv, sizeof(uint32_t), OBEX_FL_FIT_ONE_PACKET);
	}
	ret = cli_sync_request(cli, object);

	if(ret < 0)
		cli->infocb(OBEXFTP_EV_ERR, "disconnect", 0, cli->infocb_data);
	else
		cli->infocb(OBEXFTP_EV_OK, "", 0, cli->infocb_data);

	/* don't -- obexftp_close will handle this with OBEX_Cleanup */
	/* OBEX_TransportDisconnect(cli->obexhandle); */
	return ret;
}
Exemplo n.º 14
0
static void connect_server(obex_t *handle, obex_object_t *object)
{
	obex_headerdata_t hv;
	uint8_t hi;
	uint32_t hlen;
	uint8_t *target = NULL;
	int target_len = 0;

	//printf("%s()\n", __FUNCTION__);

	while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) {
		switch(hi) {
		case OBEX_HDR_TARGET:
			if (0 < hlen)
			{
				if( (target = malloc(hlen))) {
					target_len = hlen;
					memcpy(target,hv.bs,target_len);
				}
			}
			break;
		default:	
			printf("%s() Skipped header %02x\n", __FUNCTION__, hi);
			break;
		}
	}

	OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS);
	hv.bq4 = connection_id;
	if(OBEX_ObjectAddHeader(handle, object, OBEX_HDR_CONNECTION,
              		hv, sizeof(hv.bq4),
                            OBEX_FL_FIT_ONE_PACKET) < 0 )    {
                fprintf(stderr, "Error adding header CONNECTION\n");
                OBEX_ObjectDelete(handle, object);
                return;
        }
	if (target && target_len) {
		hv.bs = target;
		if(OBEX_ObjectAddHeader(handle,object,OBEX_HDR_WHO,
					hv,target_len,OBEX_FL_FIT_ONE_PACKET) < 0 ) {
			fprintf(stderr, "Error adding header WHO\n");
			OBEX_ObjectDelete(handle, object);
			return;
		}
		free(target);
	} 
}
Exemplo n.º 15
0
static char *get_named_object(obex_t *handle, char *name, int *len)
{
	struct obex_state *state;
	int req_done;
	obex_object_t *obj;
	obex_headerdata_t hd;
	int size, i;
	glong num;

	state = OBEX_GetUserData(handle);

	obj = OBEX_ObjectNew(handle, OBEX_CMD_GET);
	hd.bq4 = state->connid;
	size = 4;
	OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_CONNECTION,
			     hd, size, OBEX_FL_FIT_ONE_PACKET);

	hd.bs = (unsigned char *)g_utf8_to_utf16(name, strlen(name),
						 NULL, &num, NULL);

	for (i=0; i<num; i++) {
		uint16_t *wchar = (uint16_t*)&hd.bs[i*2];
		*wchar = ntohs(*wchar);
	}
	size = (num+1) * sizeof(uint16_t);
	OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_NAME, hd, size, OBEX_FL_FIT_ONE_PACKET);

	if (OBEX_Request(handle, obj) < 0)
		return NULL;

	req_done = state->req_done;
	while (state->req_done == req_done) {
		OBEX_HandleInput(handle, 100);
	}

	if (state->body) {
		*len = state->body_len;
		state->body[state->body_len] = '\0';
	} else {
		*len = 0;
	}
	return state->body;
}
Exemplo n.º 16
0
static int lightblueobex_addbytestreamheader(obex_t *obex, obex_object_t *obj, uint8_t hi, PyObject *bufObject)
{
    obex_headerdata_t hv;
    uint32_t hv_size;

    DEBUG("%s()\n", __func__);

    if (PyObject_AsReadBuffer(bufObject, (const void**)&hv.bs, (Py_ssize_t*)&hv_size) < 0) {
        DEBUG("\theader value for id 0x%02x must be readable buffer\n", hi);
        return -1;
    }
    return OBEX_ObjectAddHeader(obex, obj, hi, hv, hv_size, OBEX_FL_FIT_ONE_PACKET);
}
Exemplo n.º 17
0
/**
	Add more data from file to stream.
 */
static int cli_fillstream_from_file(obexftp_client_t *cli, obex_object_t *object)
{
	obex_headerdata_t hv;
	int actual;
		
	DEBUG(3, "%s()\n", __func__);
	
	actual = read(cli->fd, cli->stream_chunk, STREAM_CHUNK);
	
	DEBUG(3, "%s() Read %d bytes\n", __func__, actual);
	
	if(actual > 0) {
		/* Read was ok! */
		hv.bs = (const uint8_t *) cli->stream_chunk;
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, actual, OBEX_FL_STREAM_DATA);
	}
	else if(actual == 0) {
		/* EOF */
		(void) close(cli->fd);
		cli->fd = -1;
		hv.bs = (const uint8_t *) cli->stream_chunk;
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATAEND);
	}
        else {
		/* Error */
		(void) close(cli->fd);
		cli->fd = -1;
		hv.bs = (const uint8_t *) NULL;
		(void) OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hv, 0, OBEX_FL_STREAM_DATA);
	}

	return actual;
}
Exemplo n.º 18
0
static void obex_writestream(obex_t *handle, obex_object_t *object)
{
	obex_context_t *context = OBEX_GetUserData(handle);
	obex_headerdata_t hv;

	if (context->data_length > 0) {
		int send_size = context->data_length > context->tx_max ?
						context->tx_max : context->data_length;

		hv.bs = (uint8_t *) &context->buf[context->data_start];
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hv, send_size, OBEX_FL_STREAM_DATA);

		context->counter += send_size;
		context->data_length -= send_size;

		if (context->data_length == 0)
			context->data_start = 0;
		else
			context->data_start += send_size;

		if (!context->close && context->data_length == 0) {
			debug("OBEX_SuspendRequest");
			OBEX_SuspendRequest(handle, object);
			queue_event(context, OBEX_EV_STREAMEMPTY);
		}
	}
	else {
		if (context->counter < context->target_size)
			debug("Sending stream end but only %d/%d bytes sent",
					context->counter, context->target_size);
		hv.bs = NULL;
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, 0,
					OBEX_FL_STREAM_DATAEND);
	}
}
Exemplo n.º 19
0
static void
obexserver_receivedrequest(OBEXServer *self, obex_object_t *obj, int obex_cmd)
{
    int respcode;
    PyObject *respheaders;

    DEBUG("%s()\n", __func__);

    // Put requests are taken care of in obexserver_streamavailable()
    if (obex_cmd == OBEX_CMD_PUT && self->hasbodydata) {
#ifdef LIGHTBLUEOBEX_SERVER_TEST
        obex_headerdata_t hv;
        hv.bq4 = self->puttotal;
        OBEX_ObjectAddHeader(self->obex, obj, OBEX_HDR_LENGTH, hv, 4, 0);
#endif
        return;
    }

    respheaders = obexserver_notifynewrequest(self, obj, obex_cmd, &respcode);
    if (respheaders == NULL) {
        obexserver_setresponse(self, obj, OBEX_RSP_INTERNAL_SERVER_ERROR, NULL);
    } else {
        int result;
        result = obexserver_setresponse(self, obj, respcode, respheaders);

        /* for Get requests, indicate we want OBEX_EV_STREAMEMPTY events */
        if (result >= 0 && obex_cmd == OBEX_CMD_GET &&
                (respcode == OBEX_RSP_CONTINUE || respcode == OBEX_RSP_SUCCESS)) {
            obex_headerdata_t hv;
            hv.bs = NULL;
            OBEX_ObjectAddHeader(self->obex, obj, OBEX_HDR_BODY, hv, 0,
                                 OBEX_FL_STREAM_START);
        }
    }
    Py_XDECREF(respheaders);
}
Exemplo n.º 20
0
//
// Add more data to stream.
//
static int cli_fillstream(ircp_client_t *cli, obex_object_t *object)
{
	int actual;
	obex_headerdata_t hdd;
		
	DEBUG(4, "\n");

	actual = read(cli->fd, cli->buf, STREAM_CHUNK);

	DEBUG(4, "Read %d bytes\n", actual);
	
	if(actual > 0) {
		/* Read was ok! */
		hdd.bs = cli->buf;
		OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hdd, actual, OBEX_FL_STREAM_DATA);
	}
	else if(actual == 0) {
		/* EOF */
		hdd.bs = cli->buf;
		close(cli->fd);
		cli->fd = -1;
		OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hdd, 0, OBEX_FL_STREAM_DATAEND);
	}
        else {
		/* Error */
		hdd.bs = NULL;
		close(cli->fd);
		cli->fd = -1;
		OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_BODY,
				hdd, 0, OBEX_FL_STREAM_DATA);
	}

	return actual;
}
Exemplo n.º 21
0
static int lightblueobex_addunicodeheader(obex_t *obex, obex_object_t *obj, uint8_t hi, PyObject *utf16string)
{
    obex_headerdata_t hv;
    Py_ssize_t len = PyUnicode_GET_SIZE(utf16string);
    uint8_t bytes[len+2];

    DEBUG("%s()\n", __func__);

    /* need to add 2-byte null terminator */
    memcpy(bytes, (const uint8_t*)PyString_AsString(utf16string), len);
    bytes[len] = 0x00;
    bytes[len+1] = 0x00;

    hv.bs = bytes;
    return OBEX_ObjectAddHeader(obex, obj, (uint8_t)hi, hv, len+2,
            OBEX_FL_FIT_ONE_PACKET);
}
Exemplo n.º 22
0
int obex_connect(int od, int mode)
{
	obex_t *handle = obex_handles[0];
	struct obex_context *context;
	int err;

	obex_object_t *object;
	obex_headerdata_t hd;

	if (!(context = OBEX_GetUserData(handle)))
		return -1;

	if (!(object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT)))
		return -1;

	if (mode == OBEX_FILE_TRANSFER) {
		hd.bs = target_ftseq;
		if (OBEX_ObjectAddHeader(handle, object,
				OBEX_HDR_TARGET, hd, 16, OBEX_FL_FIT_ONE_PACKET) < 0) {
			OBEX_ObjectDelete(handle, object);
			return -1;
		}
	} else
		context->cid = 0;

	if ((err = OBEX_Request(handle, object)) < 0)
		return err;

	while (1) {
		OBEX_HandleInput(handle, OBEX_TIMEOUT);

		if (context->state == OBEX_CLOSED) {
			err = -ENODEV;
			break;
		}

		if (context->state == OBEX_CONNECTED)
			break;
	}

	return err;
}
Exemplo n.º 23
0
void smartpen_disconnect (obex_t *handle)
{
	struct obex_state *state;
	int req_done;
	obex_object_t *obj;
	obex_headerdata_t hd;
	int size;

	state = OBEX_GetUserData(handle);
	obj = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT);
	hd.bq4 = state->connid;
	size = 4;
	OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_CONNECTION,
			     hd, size, OBEX_FL_FIT_ONE_PACKET);

	if (OBEX_Request(handle, obj) < 0)
		return;

	req_done = state->req_done;
	while (state->req_done == req_done) {
		OBEX_HandleInput(handle, 100);
	}
}
Exemplo n.º 24
0
static void obex_event (obex_t *hdl, obex_object_t *obj, int mode,
			int event, int obex_cmd, int obex_rsp)
{
	struct obex_state *state;
	obex_headerdata_t hd;
	int size;
	int rc;

	state = OBEX_GetUserData(hdl);

	if (event == OBEX_EV_PROGRESS) {
		hd.bq4 = state->connid;
		size = 4;
		rc = OBEX_ObjectAddHeader(hdl, obj, OBEX_HDR_CONNECTION,
					  hd, size, 0);
		if (rc < 0) {
			printf("oah fail %d\n", rc);
		}
		return;
	}

	if (obex_rsp != OBEX_RSP_SUCCESS && obex_rsp != OBEX_RSP_CONTINUE) {
		printf("FAIL %x %x\n", obex_rsp, event);
		assert(0);
		state->req_done++;
		return;
	}

	switch (event) {
		case OBEX_EV_REQDONE:
			obex_requestdone(state, hdl, obj, obex_cmd, obex_rsp);
			break;

		default:
			printf("Funny event\n");
	}
}
Exemplo n.º 25
0
int obex_get(obex_t *handle, const char *type, const char *name)
{
	obex_context_t *context = OBEX_GetUserData(handle);
	obex_object_t *object;
	obex_headerdata_t hd;
	int err, cmd;
	g_return_val_if_fail(context != NULL, -1);

	if (context->state != OBEX_OPEN && context->state != OBEX_CONNECT
					&& context->state != OBEX_CONNECTED)
		return -ENOTCONN;

	cmd = OBEX_ObjectGetCommand(handle, NULL);
	if (cmd == OBEX_CMD_GET || cmd == OBEX_CMD_PUT)
		return -EBUSY;

	/* Initialize transfer variables */
	context->data_start = 0;
	context->data_length = 0;
	context->counter = 0;
	context->target_size = -1;
	context->modtime = -1;
	context->close = 0;

	object = OBEX_ObjectNew(handle, OBEX_CMD_GET);
	if (!object)
		return -ENOMEM;

	if (context->cid != CID_INVALID) {
		hd.bq4 = context->cid;
		OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
	}

	if (type) {
		int len = strlen(type) + 1;

		hd.bs = (uint8_t *) type;

		err = OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_TYPE, hd, len, OBEX_FL_FIT_ONE_PACKET);
		if (err < 0) {
			OBEX_ObjectDelete(handle, object);
			return err;
                }
        }

	if (name) {
		int len, ulen = (strlen(name) + 1) * 2;
		uint8_t *unicode = malloc(ulen);

		if (!unicode) {
			OBEX_ObjectDelete(handle, object);
			return -ENOMEM;
		}

		len = OBEX_CharToUnicode(unicode, (uint8_t *) name, ulen);
		hd.bs = unicode;

		err = OBEX_ObjectAddHeader(handle, object,
			OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET);
		if (err < 0) {
			OBEX_ObjectDelete(handle, object);
			free(unicode);
			return err;
                }

                free(unicode);
        }

	OBEX_ObjectReadStream(handle, object, NULL);

	err = obex_send_or_queue(handle, object);
	if (err < 0)
		OBEX_ObjectDelete(handle, object);

	return err;
}
Exemplo n.º 26
0
obex_object_t *build_object_from_file(obex_t *handle, const char *filename, uint32_t creator_id)
{
	obex_headerdata_t hdd;
	uint8_t unicode_buf[200];
	int namebuf_len;
 	obex_object_t *object;
	//uint32_t creator_id;
	int file_size;
	char *name = NULL;
	uint8_t *buf;


	buf = easy_readfile(filename, &file_size);
	if(buf == NULL)
		return NULL;

	/* Set Memopad as the default creator ID */
	if(creator_id == 0)
		creator_id = MEMO_PAD;

	/* Find the . in the filename */
	name = strchr(filename, '.');
	if (name) {
		name++;
		if (strcmp(name, "vcf") == 0) {
			printf( "This is a Address Book file\n");
			creator_id = ADDRESS_BOOK;
		} else if (strcmp(name, "vcs") == 0) {
			printf( "This is a Date Book file\n");
			creator_id = DATE_BOOK;
		} else if (strcmp(name, "txt") == 0) {
			printf("This is a Memo pad file\n");
			creator_id = MEMO_PAD;
		} else if (strcmp(name, "prc") == 0) {
			printf("This is a Pilot resource file\n");
			creator_id = PILOT_RESOURCE;
		}
	}
	/* Build object */
	object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);

	namebuf_len = OBEX_CharToUnicode(unicode_buf, (uint8_t *) filename, sizeof(unicode_buf));

	hdd.bs = unicode_buf;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME,
				hdd, namebuf_len, 0);

	hdd.bq4 = file_size;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH,
				hdd, sizeof(uint32_t), 0);

#if 0
	/* Optional header for win95 irxfer, allows date to be set on file */
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TIME2,
				(obex_headerdata_t) (uint32_t) stats.st_mtime,
				sizeof(uint32_t), 0);
#endif
	if (obex_protocol_type != 1) {
		/* Optional header for Palm Pilot */
		/* win95 irxfer does not seem to like this one */
		hdd.bq4 = creator_id;
		OBEX_ObjectAddHeader(handle, object, HEADER_CREATOR_ID,
					hdd, sizeof(uint32_t), 0);
	}

	hdd.bs = buf;
	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
				hdd, file_size, 0);

	free(buf);
	return object;
}
Exemplo n.º 27
0
int obex_setpath(obex_t *handle, const char *path, int create)
{
	obex_context_t *context = OBEX_GetUserData(handle);
	obex_object_t *object;
	obex_headerdata_t hd;
	obex_setpath_hdr_t sphdr;
	int ret;
	g_return_val_if_fail(context != NULL, -1);

	if (context->state != OBEX_CONNECTED)
		return -ENOTCONN;

	object = OBEX_ObjectNew(handle, OBEX_CMD_SETPATH);
	if (!object)
		return -ENOMEM;

	if (context->cid != CID_INVALID) {
		hd.bq4 = context->cid;
		OBEX_ObjectAddHeader(handle, object, OBEX_HDR_CONNECTION, hd, 4, 0);
	}

	memset(&sphdr, 0, sizeof(obex_setpath_hdr_t));

	if (strcmp(path, "..") == 0) {
		/* Can't create parent dir */
		if (create)
			return -EINVAL;
		sphdr.flags = 0x03;
	} else {
		int len, ulen = (strlen(path) + 1) * 2;
		uint8_t *unicode = malloc(ulen);

		if (!create)
			sphdr.flags = 0x02;

		if (!unicode) {
			OBEX_ObjectDelete(handle, object);
			return -ENOMEM;
		}

		len = OBEX_CharToUnicode(unicode, (uint8_t *) path, ulen);
		hd.bs = unicode;

		ret = OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hd, len, 0);
		if (ret < 0) {
			OBEX_ObjectDelete(handle, object);
			free(unicode);
			return ret;
		}

		free(unicode);
	}

	OBEX_ObjectSetNonHdrData(object, (uint8_t *) &sphdr, 2);

	ret = obex_send_or_queue(handle, object);
	if (ret < 0)
		OBEX_ObjectDelete(handle, object);

	return ret;
}
Exemplo n.º 28
0
obex_t *smartpen_connect(short vendor, short product)
{
	obex_t *handle;
	obex_object_t *obj;
	int rc, num, i;
	struct obex_state *state;
	obex_interface_t *obex_intf;
	obex_headerdata_t hd;
	int size, count;
	char *buf;

again:
	handle = OBEX_Init(OBEX_TRANS_USB, obex_event, 0);
	if (!handle)
		goto out;

        num = OBEX_EnumerateInterfaces(handle);
	for (i=0; i<num; i++) {
                obex_intf = OBEX_GetInterfaceByIndex(handle, i);
		if (!strcmp(obex_intf->usb.manufacturer, "Livescribe"))
			break;
	}

        if (i == num) {
		printf("No such device\n");
		handle = NULL;
		goto out;
        }

	state = malloc(sizeof(struct obex_state));
	if (!state) {
		handle = NULL;
		goto out;
	}
	memset(state, 0, sizeof(struct obex_state));

	if (!swizzle_usb(vendor, product)) {
		handle = NULL;
		goto out;
	}

        rc = OBEX_InterfaceConnect(handle, obex_intf);
        if (rc < 0) {
		printf("Connect failed %d\n", rc);
		handle = NULL;
		goto out;
	}

        OBEX_SetUserData(handle, state);
        OBEX_SetTransportMTU(handle, 0x400, 0x400);

        obj = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT);
        hd.bs = (unsigned char *)"LivescribeService";
        size = strlen((char*)hd.bs)+1;
        OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_TARGET, hd, size, 0);

        rc = OBEX_Request(handle, obj);

	count = state->req_done;
        while (rc == 0 && state->req_done <= count) {
            OBEX_HandleInput(handle, 100);
        }

	if (rc < 0 || !state->got_connid) {
		printf("Retry connection...\n");
		OBEX_Cleanup(handle);
		goto again;
	}

	buf = get_named_object(handle, "ppdata?key=pp0000", &rc);
	if (!buf) {
		printf("Retry connection...\n");
		OBEX_Cleanup(handle);
		pen_reset(vendor, product);
		goto again;
	}

out:
	return handle;
}
Exemplo n.º 29
0
/*!
    \internal
    Takes all the headers contained in \a header and adds them as headers into
    \a obj. If \a fitOnePacket is \c true, the OBEX_FL_FIT_ONE_PACKET flag
    is used.

    Returns whether the headers were written successfully.
 */
bool QObexHeaderPrivate::writeOpenObexHeaders(obex_t* handle, obex_object_t *obj, bool fitOnePacket, const QObexHeader &header)
{
    if (!handle || !obj)
        return false;

    int flags = ( fitOnePacket ? OBEX_FL_FIT_ONE_PACKET : 0 );
    obex_headerdata_t hv;

    // Handle Target & Connection Id headers separately:
    // Target must be the first header in operation, and Connection Id
    // must be 1st header in a request (spec 2.2.7 & 2.2.11).
    // This doesn't conflict cos they shouldn't both be in the same request
    // (and for responses it doesn't say)

    if (header.contains(QObexHeader::ConnectionId)) {
        hv.bq4 = header.connectionId();
        if (OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_CONNECTION, hv, 4,
                                flags) < 0) {
            return false;
        }
    }
    if (header.contains(QObexHeader::Target)) {
        QByteArray bytes = header.target();
        hv.bs = reinterpret_cast<const uchar *>(bytes.constData());
        if (OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_TARGET, hv, bytes.size(),
                             flags) < 0) {
            return false;
        }
    }

    // now go through all the other headers
    QList<int> headerIds = header.headerIds();

    for (int i=0; i<headerIds.size(); i++) {
        int headerId = headerIds[i];

        // skip the previously handled headers
        if (headerId == QObexHeader::ConnectionId ||
                headerId == QObexHeader::Target) {
            continue;
        }

        switch (headerId & QObexHeaderPrivate::HeaderEncodingMask) {

            case QObexHeaderPrivate::HeaderUnicodeEncoding:
            {
                QByteArray bytes;
                QObexHeaderPrivate::unicodeBytesFromString(bytes,
                        header.value(headerId).toString());
                hv.bs = reinterpret_cast<const uchar *>(bytes.constData());

                if (OBEX_ObjectAddHeader(handle, obj, headerId, hv,
                            bytes.size(), flags) < 0) {
                    return false;
                }
                break;
            }

            case QObexHeaderPrivate::HeaderByteSequenceEncoding:
            {
                if (headerId == QObexHeader::Type) {
                    // Handle Type header separately because it must be null terminated
                    // ascii. Use +1 when adding header to add a null terminator byte.
                    QByteArray bytes = header.type().toAscii();
                    hv.bs = reinterpret_cast<const uint8_t*>(bytes.constData());
                    if (OBEX_ObjectAddHeader(handle, obj, OBEX_HDR_TYPE, hv,
                                        bytes.size() + 1, flags) < 0) {
                        return false;
                    }

                    // Add PalmOS-style application id header
                    if (!bytes.isEmpty() && header.type().compare("text/x-vCalendar",
                                Qt::CaseInsensitive) == 0) {
                        hv.bq4 = 0x64617465;
                        if (OBEX_ObjectAddHeader(handle, obj, 0xcf, hv, 4, flags) < 0) {
                            return false;
                        }
                    }
                } else {
                    QByteArray bytes = header.value(headerId).toByteArray();
                    hv.bs = reinterpret_cast<const uchar *>(bytes.constData());
                    if (OBEX_ObjectAddHeader(handle, obj, headerId, hv, bytes.size(),
                                        flags) < 0) {
                        return false;
                    }
                }
                break;
            }

            case QObexHeaderPrivate::HeaderByteEncoding:
            {
                QVariant v = header.value(headerId);
                if (v.canConvert<quint8>()) {
                    hv.bq1 = v.value<quint8>();
                    if (OBEX_ObjectAddHeader(handle, obj, headerId, hv, 1,
                                         flags) < 0) {
                        return false;
                    }
                } else {
                    // this shouldn't happen since setValue() does a check
                    return false;
                }
                break;
            }

            case QObexHeaderPrivate::HeaderIntEncoding:
            {
                QVariant v = header.value(headerId);
                if (v.canConvert<quint32>()) {
                    hv.bq4 = v.value<quint32>();
                    if (OBEX_ObjectAddHeader(handle, obj, headerId, hv, 4,
                                         flags) < 0) {
                        return false;
                    }
                } else {
                    // this shouldn't happen since setValue() does a check
                    return false;
                }
                break;
            }

            default:
                return false;
        }
    }

    return true;
}
Exemplo n.º 30
0
/**
	Connect this ObexFTP client using a given source address by sending an OBEX CONNECT request.

	\param cli an obexftp_client_t created by obexftp_open().
	\param src optional local source interface address (transport specific)
	\param device the device address to connect to (transport specific)
	\param port the port/channel for the device address
	\param uuid UUID string for CONNECT (no default)
	\param uuid_len length of the UUID string (excluding terminating zero)

	\return the result of the CONNECT request, -1 on error

	\note Always use a UUID (except for OBEX PUSH)
 */
int obexftp_connect_src(obexftp_client_t *cli, const char *src, const char *device, int port, const uint8_t uuid[], uint32_t uuid_len)
{
	struct sockaddr_in peer;
#ifdef HAVE_BLUETOOTH
	char *devicedup, *devicep;
	bdaddr_t bdaddr, src_addr;
#endif
#ifdef HAVE_USB
	int obex_intf_cnt;
	obex_interface_t *obex_intf;
#endif
	obex_object_t *object;
	obex_headerdata_t hv;
	int ret = -1; /* no connection yet */

	DEBUG(3, "%s()\n", __func__);
	return_val_if_fail(cli != NULL, -EINVAL);

	cli->infocb(OBEXFTP_EV_CONNECTING, "", 0, cli->infocb_data);

	switch (cli->transport) {

	case OBEX_TRANS_IRDA:
		ret = IrOBEX_TransportConnect(cli->obexhandle, "OBEX");
		DEBUG(3, "%s() IR %d\n", __func__, ret);
		break;
		
	case OBEX_TRANS_INET:
		if (!device) {
			ret = -EINVAL;
			break;
		}
#ifdef _WIN32
		peer.sin_addr.s_addr = inet_addr(device);
		ret = (peer.sin_addr.s_addr == INADDR_NONE) ? 0 : 1;
#else
		ret = inet_aton(device, &peer.sin_addr);
#endif
		if (ret) {
			peer.sin_family = AF_INET;
			peer.sin_port = htons(port); /* overridden with OBEX_PORT 650 anyhow */
			ret = InOBEX_TransportConnect(cli->obexhandle, (struct sockaddr *) &peer,
						  sizeof(struct sockaddr_in));
			DEBUG(3, "%s() TCP %d\n", __func__, ret);
		} else
			ret = -EINVAL; /* is there a better errno? */
		break;

	case OBEX_TRANS_CUSTOM:
		/* don't change the custom transport once it is in place */
		if (cli->ctrans == NULL) {
			cli->ctrans = cobex_ctrans (device);
                	if(OBEX_RegisterCTransport(cli->obexhandle, cli->ctrans) < 0) {
                        	DEBUG(1, "Custom transport callback-registration failed\n");
	                }
	        }
		ret = OBEX_TransportConnect(cli->obexhandle, NULL, 0);
		DEBUG(3, "%s() TC %d\n", __func__, ret);
		break;

#ifdef HAVE_BLUETOOTH
	case OBEX_TRANS_BLUETOOTH:
		if (!src) {
			bacpy(&src_addr, BDADDR_ANY);
		}
#ifdef HAVE_SDPLIB
		else if (!strncmp(src, "hci", 3)) {
			hci_devba(atoi(src + 3), &src_addr);
		}
		else if (atoi(src) != 0) {
			hci_devba(atoi(src), &src_addr);
		}
#endif
		else {
			str2ba(src, &src_addr);
		}
		if (!device) {
			ret = -EINVAL;
			break;
		}
		if (port < 1) {
			port = obexftp_browse_bt(device, OBEX_FTP_SERVICE);
		}
		/* transform some chars to colons */
		devicedup = devicep = strdup(device);
		for (; *devicep; devicep++) {
			if (*devicep == '-') *devicep = ':';
			if (*devicep == '_') *devicep = ':';
			if (*devicep == '/') *devicep = ':';
		}
		(void) str2ba(devicedup, &bdaddr);
		free(devicedup);
		ret = BtOBEX_TransportConnect(cli->obexhandle, &src_addr, &bdaddr, (uint8_t)port);
		DEBUG(3, "%s() BT %d\n", __func__, ret);
		break;
#endif /* HAVE_BLUETOOTH */

#ifdef HAVE_USB
	case OBEX_TRANS_USB:
		obex_intf_cnt = OBEX_FindInterfaces(cli->obexhandle, &obex_intf);
		DEBUG(3, "%s() \n", __func__);
		if (obex_intf_cnt <= 0) {
			DEBUG(1, "%s() there are no valid USB interfaces\n", __func__);
			ret = -EINVAL; /* is there a better errno? */
		}
		else if (port >= obex_intf_cnt) {
			DEBUG(1, "%s() %d is an invalid USB interface number\n", __func__, port);
			ret = -EINVAL; /* is there a better errno? */
		} else
			ret = OBEX_InterfaceConnect(cli->obexhandle, &obex_intf[port]);
		DEBUG(3, "%s() USB %d\n", __func__, ret);
		break;
#endif /* HAVE_USB */

	default:
		ret = -ESOCKTNOSUPPORT;
		break;
	}

	if (ret < 0) {
		/* could be -EBUSY or -ESOCKTNOSUPPORT */
		cli->infocb(OBEXFTP_EV_ERR, "connect", 0, cli->infocb_data);
		return ret;
	}

#ifdef COMPAT_S45
	// try S45 UUID first.
	object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_CONNECT);
	hv.bs = UUID_S45;
	if(OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_TARGET,
                                hv, sizeof(UUID_S45), OBEX_FL_FIT_ONE_PACKET) < 0) {
                DEBUG(1, "Error adding header\n");
                OBEX_ObjectDelete(cli->obexhandle, object);
                return -1;
        }
	cli->connection_id = 0xffffffff;
	ret = cli_sync_request(cli, object);

	if(ret < 0) {
		cli->infocb(OBEXFTP_EV_ERR, "S45 UUID", 0, cli->infocb_data);
#endif
		object = OBEX_ObjectNew(cli->obexhandle, OBEX_CMD_CONNECT);
		if (uuid) {
			hv.bs = uuid;
			if(OBEX_ObjectAddHeader(cli->obexhandle, object, OBEX_HDR_TARGET,
        	        	                hv, uuid_len, OBEX_FL_FIT_ONE_PACKET) < 0) {
	        	        DEBUG(1, "Error adding header\n");
		                OBEX_ObjectDelete(cli->obexhandle, object);
                		return -1;
	        	}
		}
		cli->connection_id = 0xffffffff;
		ret = cli_sync_request(cli, object);
		if (!OBEXFTP_USE_CONN_HEADER(cli->quirks))
			cli->connection_id = 0xffffffff;
#ifdef COMPAT_S45
	}
#endif

	if(ret < 0)
		cli->infocb(OBEXFTP_EV_ERR, "send UUID", 0, cli->infocb_data);
	else
		cli->infocb(OBEXFTP_EV_OK, "", 0, cli->infocb_data);

	return ret;
}