guint obc_session_queue(struct obc_session *session, struct obc_transfer *transfer, session_callback_t func, void *user_data, GError **err) { struct pending_request *p; if (session->obex == NULL) { obc_transfer_unregister(transfer); g_set_error(err, OBEX_IO_ERROR, -ENOTCONN, "Session not connected"); return 0; } if (!obc_transfer_register(transfer, session->conn, session->owner, err)) { obc_transfer_unregister(transfer); return 0; } obc_transfer_set_callback(transfer, transfer_complete, session); p = pending_request_new(session, transfer, func, user_data); g_queue_push_tail(session->queue, p); if (session->queue_complete_id == 0) session->queue_complete_id = g_idle_add( session_queue_complete, session); return p->id; }
int obc_transfer_put(struct obc_transfer *transfer, transfer_callback_t func, void *user_data) { struct obc_session *session = transfer->session; GError *err = NULL; GObex *obex; GObexPacket *req; GObexDataProducer data_cb; struct stat st; int fd; if (transfer->xfer != 0) return -EALREADY; if (transfer->buffer) { data_cb = put_buf_xfer_progress; goto done; } fd = open(transfer->filename, O_RDONLY); if (fd < 0) { error("open(): %s(%d)", strerror(errno), errno); return -errno; } if (fstat(fd, &st) < 0) { close(fd); error("fstat(): %s(%d)", strerror(errno), errno); return -errno; } transfer->fd = fd; transfer->size = st.st_size; data_cb = put_xfer_progress; done: obex = obc_session_get_obex(session); req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID); if (transfer->name != NULL) g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME, transfer->name); if (transfer->type != NULL) g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type, strlen(transfer->type) + 1); if (transfer->size < UINT32_MAX) g_obex_packet_add_uint32(req, G_OBEX_HDR_LENGTH, transfer->size); if (transfer->params != NULL) g_obex_packet_add_bytes(req, G_OBEX_HDR_APPARAM, transfer->params->data, transfer->params->size); transfer->xfer = g_obex_put_req_pkt(obex, req, data_cb, xfer_complete, transfer, &err); if (transfer->xfer == 0) return -ENOTCONN; if (func) obc_transfer_set_callback(transfer, func, user_data); return 0; }
int obc_transfer_get(struct obc_transfer *transfer, transfer_callback_t func, void *user_data) { struct obc_session *session = transfer->session; GError *err = NULL; GObex *obex; GObexPacket *req; GObexDataConsumer data_cb; GObexFunc complete_cb; GObexResponseFunc rsp_cb = NULL; if (transfer->xfer != 0) return -EALREADY; if (transfer->type != NULL && (strncmp(transfer->type, "x-obex/", 7) == 0 || strncmp(transfer->type, "x-bt/", 5) == 0)) { rsp_cb = get_buf_xfer_progress; } else { int fd = open(transfer->name ? : transfer->filename, O_WRONLY | O_CREAT, 0600); if (fd < 0) { error("open(): %s(%d)", strerror(errno), errno); return -errno; } transfer->fd = fd; data_cb = get_xfer_progress; complete_cb = xfer_complete; } obex = obc_session_get_obex(session); req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID); if (transfer->filename != NULL) g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME, transfer->filename); if (transfer->type != NULL) g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type, strlen(transfer->type) + 1); if (transfer->params != NULL) g_obex_packet_add_bytes(req, G_OBEX_HDR_APPARAM, transfer->params->data, transfer->params->size); if (rsp_cb) transfer->xfer = g_obex_send_req(obex, req, -1, rsp_cb, transfer, &err); else transfer->xfer = g_obex_get_req_pkt(obex, req, data_cb, complete_cb, transfer, &err); if (transfer->xfer == 0) return -ENOTCONN; if (func) obc_transfer_set_callback(transfer, func, user_data); return 0; }