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; }
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; }
// // 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; }
int obex_disconnect(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); obex_object_t *object; int ret; g_return_val_if_fail(context != NULL, -1); if (context->state != OBEX_CONNECTED) return -ENOTCONN; object = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT); if (!object) return -ENOMEM; context->state = OBEX_DISCONN; if (context->callback && context->callback->disconn_ind) context->callback->disconn_ind(handle, context->user_data); ret = obex_send_or_queue(handle, object); if (ret < 0) OBEX_ObjectDelete(handle, object); return ret; }
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); } }
void obex_close(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); g_return_if_fail(context != NULL); OBEX_SetUserData(handle, NULL); if (context->pending) OBEX_ObjectDelete(handle, context->pending); free(context); OBEX_Cleanup(handle); }
// // 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; }
// // 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; }
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; }
/** 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; }
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; }
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; }
int obex_put(obex_t *handle, const char *type, const char *name, int size, time_t mtime) { 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 = size; context->modtime = mtime; context->close = 0; 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 (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); } /* Add a time header if possible */ if (context->modtime >= 0) { char tstr[17]; int len; len = make_iso8601(context->modtime, tstr, sizeof(tstr)); if (len >= 0) { debug("Adding time header: %s", tstr); hd.bs = (uint8_t *) tstr; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TIME, hd, len, 0); } } /* Add a length header if possible */ if (context->target_size > 0) { debug("Adding length header: %d", context->target_size); hd.bq4 = (uint32_t) context->target_size; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hd, 4, 0); } hd.bs = NULL; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hd, 0, OBEX_FL_STREAM_START); /* We need to suspend until the user has provided some data * by calling obex_client_write */ debug("OBEX_SuspendRequest"); OBEX_SuspendRequest(handle, object); err = obex_send_or_queue(handle, object); if (err < 0) OBEX_ObjectDelete(handle, object); return err; }
int obex_get(int od, const char *type, const char *name, unsigned char **data, size_t *size) { obex_t *handle = obex_handles[0]; struct obex_context *context; char *unicode; int err, len, ulen; 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->command = OBEX_CMD_GET; context->response = 0; if (!(object = OBEX_ObjectNew(handle, OBEX_CMD_GET))) 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 (type) { hd.bs = (uint8_t *) type; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TYPE, hd, strlen(type) + 1, OBEX_FL_FIT_ONE_PACKET); } if (name) { ulen = (strlen(name) + 1) * 2; unicode = malloc(ulen); if (!unicode) { OBEX_ObjectDelete(handle, object); return -1; } len = OBEX_CharToUnicode((uint8_t *) unicode, (uint8_t *) name, ulen); hd.bs = (uint8_t *) unicode; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET); free(unicode); } if ((err = OBEX_Request(handle, object)) < 0) return err; context->time = time(0); while (1) { OBEX_HandleInput(handle, OBEX_TIMEOUT); if (context->response) break; } //printf("Rsp: %02x\n", context->response); //printf("Err: %s\n", strerror(obex_error(context->response))); if (context->response == OBEX_RSP_SUCCESS) { *data = context->data_buf; *size = context->data_len; } else { free(context->data_buf); err = -1; } context->mode = OBEX_IDLE; return err; }