int obex_disconnect(int od) { obex_t *handle = obex_handles[0]; struct obex_context *context; int err; obex_object_t *object; if (!(context = OBEX_GetUserData(handle))) return -1; if (!(object = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT))) return -1; context->state = OBEX_DISCONN; if ((err = OBEX_Request(handle, object)) < 0) return err; while (1) { OBEX_HandleInput(handle, OBEX_TIMEOUT); if (context->state == OBEX_CLOSED) break; } return err; }
// // Incoming event from OpenOBEX. // static void cli_obex_event(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp) { ircp_client_t *cli; cli = OBEX_GetUserData(handle); switch (event) { case OBEX_EV_PROGRESS: break; case OBEX_EV_REQDONE: cli->finished = TRUE; if(obex_rsp == OBEX_RSP_SUCCESS) cli->success = TRUE; else cli->success = FALSE; cli->obex_rsp = obex_rsp; break; case OBEX_EV_LINKERR: cli->finished = 1; cli->success = FALSE; break; case OBEX_EV_STREAMEMPTY: cli_fillstream(cli, object); break; default: DEBUG(1, "Unknown event %d\n", event); break; } }
// // 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; }
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; }
static void obex_readstream(obex_t *handle, obex_object_t *object) { obex_context_t *context = OBEX_GetUserData(handle); const uint8_t *buf; int actual, free_space; if (context->counter == 0) get_target_size_and_time(handle, object, context); actual = OBEX_ObjectReadStream(handle, object, &buf); if (actual <= 0) { debug("Error or no data on OBEX stream"); return; } context->counter += actual; debug("obex_readstream: got %d bytes (%d in total)", actual, context->counter); free_space = sizeof(context->buf) - (context->data_start + context->data_length); if (actual > free_space) { /* This should never happen */ debug("Out of buffer space: actual=%d, free=%d", actual, free_space); return; } memcpy(&context->buf[context->data_start], buf, actual); context->data_length += actual; debug("OBEX_SuspendRequest"); OBEX_SuspendRequest(handle, object); queue_event(context, OBEX_EV_STREAMAVAIL); }
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 obex_disconnect_done(obex_t *handle, obex_object_t *object, int response) { obex_context_t *context = OBEX_GetUserData(handle); context->state = OBEX_CLOSED; }
int obex_read(obex_t *handle, char *buf, size_t count, size_t *bytes_read) { obex_context_t *context = OBEX_GetUserData(handle); if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_GET) return -EINVAL; if (context->data_length == 0) return -EAGAIN; *bytes_read = count < context->data_length ? count : context->data_length; memcpy(buf, &context->buf[context->data_start], *bytes_read); context->data_length -= *bytes_read; if (context->data_length) context->data_start += *bytes_read; else { context->data_start = 0; debug("OBEX_ResumeRequest"); OBEX_ResumeRequest(handle); } return 0; }
static void obex_progress(obex_t *handle, obex_object_t *object) { obex_context_t *context = OBEX_GetUserData(handle); if (context->callback && context->callback->progress_ind) context->callback->progress_ind(handle, context->user_data); }
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; }
// // Read data from stream. // static int readstream(obex_t *handle, obex_object_t *object) { int actual; obexsrv_t *srv = OBEX_GetUserData(handle); const uint8_t *buf; int len; if (srv->sfd < 0) { /* create temporary storage for an object */ srv->name = strdup("/tmp/obex_tmp_XXXXXX"); if (!srv->name) return -1; srv->sfd = mkstemp(srv->name); if (srv->sfd < 0) { DBPRT("unable to create tmp file: %s\n", srv->name); free(srv->name); srv->name = NULL; return srv->sfd; } DBPRT("created tmp file: %s\n", srv->name); srv->flags = 0x01; } srv->streamming = TRUE; actual = OBEX_ObjectReadStream(handle, object, &buf); DBPRT("got stream: %d\n", actual); if (actual > 0) { len = write(srv->sfd, buf, actual); } return actual; }
void obexsrv_reqdone(obex_t *handle, obex_object_t *object, int obex_cmd, int obex_rsp) { obexsrv_t *srv = OBEX_GetUserData(handle); DBPRT("Server request finished!"); switch (obex_cmd) { case OBEX_CMD_DISCONNECT: DBPRT("Disconnect done!"); srv->state = SRVSTATE_CLOSED; srv->disconnect(srv); break; default: DBPRT(" Command (%02x) has now finished", obex_cmd); srv->serverdone = TRUE; break; } /* cleanup resources */ if (srv->sfd >= 0) { close(srv->sfd); srv->sfd = -1; } if (srv->name) { if (srv->flags & 0x01) unlink(srv->name); free(srv->name); srv->name = NULL; } if (srv->buf) { free(srv->buf); srv->buf = NULL; } srv->streamming = FALSE; /* disable streaming */ }
int obex_get_response(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); int rsp; rsp = context->obex_rsp; context->obex_rsp = OBEX_RSP_SUCCESS; return rsp; }
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); } } }
void obex_poll(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); unsigned long state = context->state; while (1) { OBEX_HandleInput(handle, OBEX_TIMEOUT); if (context->state != state) break; } obex_do_callback(handle); }
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; }
static int obex_send_or_queue(obex_t *handle, obex_object_t *object) { obex_context_t *context = OBEX_GetUserData(handle); int err; err = OBEX_Request(handle, object); if (err == -EBUSY && !context->pending) { context->pending = object; return 0; } return err; }
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); }
int obex_flush(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_PUT) return -EINVAL; if (context->data_length) { debug("OBEX_ResumeRequest"); OBEX_ResumeRequest(handle); } return 0; }
int obex_close_transfer(obex_t *handle) { obex_context_t *context = OBEX_GetUserData(handle); int cmd; cmd = OBEX_ObjectGetCommand(handle, NULL); if (cmd != OBEX_CMD_PUT && cmd != OBEX_CMD_GET) return -EINVAL; context->close = 1; debug("OBEX_ResumeRequest"); OBEX_ResumeRequest(handle); return 0; }
void obex_do_callback(obex_t *handle) { GSList *l; obex_context_t *context = OBEX_GetUserData(handle); if (!context->events || ! context->callback || ! context->callback->command_ind) return; for (l = context->events; l != NULL; l = l->next) { obex_ev_t *event = l->data; context->callback->command_ind(handle, event->event, context->user_data); free(event); } g_slist_free(context->events); context->events = NULL; }
void obex_close(int od) { obex_t *handle = obex_handles[0]; struct obex_context *context; context = OBEX_GetUserData(handle); if (context->state == OBEX_CONNECTED) obex_disconnect(od); OBEX_SetUserData(handle, NULL); free(context); obex_handles[0] = NULL; OBEX_Cleanup(handle); }
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; }
// // Called by the obex-layer when some event occurs. // void obexsrv_event(obex_t *handle, obex_object_t *object, int mode, int event, int obex_cmd, int obex_rsp) { obexsrv_t *srv = OBEX_GetUserData(handle); //DBPRT("event: %d, cmd: %x, rsp: %x\n", event, obex_cmd, obex_rsp); switch (event) { case OBEX_EV_PROGRESS: //DBPRT("Made some progress..."); break; case OBEX_EV_ABORT: BTERROR("Request aborted!"); break; case OBEX_EV_REQDONE: obexsrv_reqdone(handle, object, obex_cmd, obex_rsp); break; case OBEX_EV_REQHINT: obexsrv_reqhint(handle, object, obex_cmd); break; case OBEX_EV_REQ: obexsrv_req(handle, object, obex_cmd); break; case OBEX_EV_LINKERR: if (srv->state != SRVSTATE_CLOSED) { BTERROR("Link broken!"); srv->state = SRVSTATE_CLOSED; srv->disconnect(srv); } srv->serverdone = TRUE; break; case OBEX_EV_PARSEERR: BTERROR("Parse error!"); break; case OBEX_EV_STREAMEMPTY: writestream(handle, object); break; case OBEX_EV_STREAMAVAIL: readstream(handle, object); break; default: BTERROR("Unknown event %02x!", event); break; } }
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; }
static void obex_connect_done(obex_t *handle, obex_object_t *object, int response) { obex_context_t *context = OBEX_GetUserData(handle); obex_headerdata_t hd; uint32_t hl; uint8_t hi, *ptr; if (response != OBEX_RSP_SUCCESS) return; context->state = OBEX_CONNECTED; if (OBEX_ObjectGetNonHdrData(object, &ptr) == sizeof(obex_connect_hdr_t)) { obex_connect_hdr_t *chdr = (obex_connect_hdr_t *) ptr; uint16_t mtu = ntohs(chdr->mtu); int new_size; debug("Connect success. Version: 0x%02x. Flags: 0x%02x OBEX packet length: %d", chdr->version, chdr->flags, mtu); /* Leave space for headers */ new_size = mtu - 200; if (new_size < context->tx_max) { debug("Resizing stream chunks to %d", new_size); context->tx_max = new_size; } } while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hd, &hl)) { switch (hi) { case OBEX_HDR_CONNECTION: context->cid = hd.bq4; break; case OBEX_HDR_WHO: break; } } if (context->callback && context->callback->connect_cfm) context->callback->connect_cfm(handle, context->user_data); }
/** Handle incoming event from OpenOBEX. */ static void cli_obex_event(obex_t *handle, obex_object_t *object, int UNUSED(mode), int event, int obex_cmd, int obex_rsp) { /*@temp@*/ obexftp_client_t *cli; cli = OBEX_GetUserData(handle); switch (event) { case OBEX_EV_PROGRESS: cli->infocb(OBEXFTP_EV_PROGRESS, "", 0, cli->infocb_data); break; case OBEX_EV_REQDONE: cli->finished = TRUE; if(obex_rsp == OBEX_RSP_SUCCESS) cli->success = TRUE; else { cli->success = FALSE; DEBUG(2, "%s() OBEX_EV_REQDONE: obex_rsp=%02x\n", __func__, obex_rsp); } cli->obex_rsp = obex_rsp; client_done(handle, object, obex_cmd, obex_rsp); break; case OBEX_EV_LINKERR: cli->finished = TRUE; cli->success = FALSE; DEBUG(2, "%s() OBEX_EV_LINKERR\n", __func__); break; case OBEX_EV_STREAMEMPTY: if (cli->out_data) (void) cli_fillstream_from_memory(cli, object); else (void) cli_fillstream_from_file(cli, object); break; default: DEBUG(1, "%s() Unknown event %d\n", __func__, event); break; } }
/* can this be static? */ void obexserver_event(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp) { DEBUG("%s()\n", __func__); DEBUG("\tEvent: %d Command: %d\n", event, obex_cmd); OBEXServer *self = (OBEXServer *)OBEX_GetUserData(handle); switch (event) { case OBEX_EV_LINKERR: case OBEX_EV_PARSEERR: DEBUG("\tOBEX_EV_LINKERR or OBEX_EV_PARSEERR\n"); obexserver_errorstr(self, PyExc_IOError, (event == OBEX_EV_LINKERR ? "connection error" : "parse error")); break; case OBEX_EV_REQHINT: DEBUG("\tOBEX_EV_REQHINT\n"); obexserver_incomingrequest(self, obj, obex_cmd); break; case OBEX_EV_REQ: DEBUG("\tOBEX_EV_REQ\n"); obexserver_receivedrequest(self, obj, obex_cmd); break; case OBEX_EV_STREAMAVAIL: DEBUG("\tOBEX_EV_STREAMAVAIL\n"); obexserver_streamavailable(self, obj); break; case OBEX_EV_STREAMEMPTY: DEBUG("\tOBEX_EV_STREAMEMPTY\n"); obexserver_streamempty(self, obj); break; case OBEX_EV_REQDONE: DEBUG("\tOBEX_EV_REQDONE\n"); obexserver_requestdone(self, obj, obex_cmd); break; default: DEBUG("\tNot handling event\n"); break; } }
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); } }
int obex_write(obex_t *handle, const char *buf, size_t count, size_t *bytes_written) { obex_context_t *context = OBEX_GetUserData(handle); int free_space; if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_PUT) return -EINVAL; free_space = sizeof(context->buf) - (context->data_start + context->data_length); *bytes_written = count > free_space ? free_space : count; memcpy(&context->buf[context->data_start + context->data_length], buf, *bytes_written); context->data_length += *bytes_written; if (context->data_length >= context->tx_max || *bytes_written == free_space) { debug("OBEX_ResumeRequest"); OBEX_ResumeRequest(handle); } return 0; }