static void setup_srm(GObex *obex, GObexPacket *pkt, gboolean outgoing) { GObexHeader *hdr; guint8 op; gboolean final; if (!obex->use_srm) return; op = g_obex_packet_get_operation(pkt, &final); hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRM); if (hdr != NULL) { guint8 srm; g_obex_header_get_uint8(hdr, &srm); g_obex_debug(G_OBEX_DEBUG_COMMAND, "srm 0x%02x", srm); set_srm(obex, op, srm); } hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRMP); if (hdr != NULL) { guint8 srmp; g_obex_header_get_uint8(hdr, &srmp); g_obex_debug(G_OBEX_DEBUG_COMMAND, "srmp 0x%02x", srmp); set_srmp(obex, srmp, outgoing); } else set_srmp(obex, -1, outgoing); if (final) check_srm_final(obex, op); }
GObexHeader *g_obex_packet_get_body(GObexPacket *pkt) { GObexHeader *body; body = g_obex_packet_get_header(pkt, G_OBEX_HDR_BODY); if (body != NULL) return body; return g_obex_packet_get_header(pkt, G_OBEX_HDR_BODY_END); }
static void handle_get(GObex *obex, GObexPacket *req, gpointer user_data) { GError *err = NULL; struct transfer_data *data; const char *type, *name; GObexHeader *hdr; gsize type_len; hdr = g_obex_packet_get_header(req, G_OBEX_HDR_TYPE); if (hdr != NULL) { g_obex_header_get_bytes(hdr, (const guint8 **) &type, &type_len); if (type[type_len - 1] != '\0') { g_printerr("non-nul terminated type header\n"); type = NULL; } } else type = NULL; hdr = g_obex_packet_get_header(req, G_OBEX_HDR_NAME); if (hdr != NULL) g_obex_header_get_unicode(hdr, &name); else name = NULL; g_print("get type \"%s\" name \"%s\"\n", type ? type : "", name ? name : ""); data = g_new0(struct transfer_data, 1); data->fd = open(name, O_RDONLY | O_NOCTTY, 0); if (data->fd < 0) { g_printerr("open(%s): %s\n", name, strerror(errno)); g_free(data); g_obex_send_rsp(obex, G_OBEX_RSP_FORBIDDEN, NULL, G_OBEX_HDR_INVALID); return; } g_obex_get_rsp(obex, send_data, transfer_complete, data, &err, G_OBEX_HDR_INVALID); if (err != NULL) { g_printerr("Unable to send response: %s\n", err->message); g_error_free(err); g_free(data); } }
static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp, gpointer user_data) { struct obc_transfer *transfer = user_data; struct transfer_callback *callback = transfer->callback; GObexPacket *req; GObexHeader *hdr; const guint8 *buf; gsize len; guint8 rspcode; gboolean final; if (err != NULL) { get_buf_xfer_complete(obex, err, transfer); return; } rspcode = g_obex_packet_get_operation(rsp, &final); if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) { err = g_error_new(OBEX_IO_ERROR, rspcode, "Transfer failed (0x%02x)", rspcode); get_buf_xfer_complete(obex, err, transfer); g_error_free(err); return; } hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_APPARAM); if (hdr) { g_obex_header_get_bytes(hdr, &buf, &len); if (len != 0) { transfer->params->data = g_memdup(buf, len); transfer->params->size = len; } } hdr = g_obex_packet_get_body(rsp); if (hdr) { g_obex_header_get_bytes(hdr, &buf, &len); if (len != 0) obc_transfer_read(transfer, buf, len); } if (rspcode == G_OBEX_RSP_SUCCESS) { get_buf_xfer_complete(obex, err, transfer); return; } req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID); transfer->xfer = g_obex_send_req(obex, req, -1, get_buf_xfer_progress, transfer, &err); if (callback) callback->func(transfer, transfer->transferred, err, callback->data); }
guint g_obex_send_req(GObex *obex, GObexPacket *req, gint timeout, GObexResponseFunc func, gpointer user_data, GError **err) { GObexHeader *hdr; struct pending_pkt *p; static guint id = 1; guint8 op; g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id); op = g_obex_packet_get_operation(req, NULL); if (op == G_OBEX_OP_PUT || op == G_OBEX_OP_GET) { /* Only enable SRM automatically for GET and PUT */ prepare_srm_req(obex, req); } if (obex->conn_id == CONNID_INVALID) goto create_pending; if (obex->rx_last_op == G_OBEX_RSP_CONTINUE) goto create_pending; if (g_obex_srm_active(obex) && obex->pending_req != NULL) goto create_pending; hdr = g_obex_packet_get_header(req, G_OBEX_HDR_CONNECTION); if (hdr != NULL) goto create_pending; hdr = g_obex_header_new_uint32(G_OBEX_HDR_CONNECTION, obex->conn_id); g_obex_packet_prepend_header(req, hdr); create_pending: p = g_new0(struct pending_pkt, 1); p->pkt = req; p->id = id++; p->rsp_func = func; p->rsp_data = user_data; if (timeout < 0) p->timeout = G_OBEX_DEFAULT_TIMEOUT; else p->timeout = timeout; if (!g_obex_send_internal(obex, p, err)) { pending_pkt_free(p); return 0; } return p->id; }
static gboolean check_connid(GObex *obex, GObexPacket *pkt) { GObexHeader *hdr; guint32 id; if (obex->conn_id == CONNID_INVALID) return TRUE; hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_CONNECTION); if (hdr == NULL) return TRUE; g_obex_header_get_uint32(hdr, &id); return obex->conn_id == id; }
static void prepare_srm_req(GObex *obex, GObexPacket *pkt) { GObexHeader *hdr; if (!obex->use_srm) return; if (obex->srm != NULL && obex->srm->enabled) return; hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRM); if (hdr != NULL) return; hdr = g_obex_header_new_uint8(G_OBEX_HDR_SRM, G_OBEX_SRM_ENABLE); g_obex_packet_prepend_header(pkt, hdr); }
static void test_decode_pkt_header(void) { GObexPacket *pkt; GObexHeader *header; GError *err = NULL; gboolean ret; guint8 val; pkt = g_obex_packet_decode(pkt_put_action, sizeof(pkt_put_action), 0, G_OBEX_DATA_REF, &err); g_assert_no_error(err); header = g_obex_packet_get_header(pkt, G_OBEX_HDR_ACTION); g_assert(header != NULL); ret = g_obex_header_get_uint8(header, &val); g_assert(ret == TRUE); g_assert(val == 0xab); g_obex_packet_free(pkt); }
static void prepare_connect_rsp(GObex *obex, GObexPacket *rsp) { GObexHeader *connid; struct connect_data data; static guint32 next_connid = 1; init_connect_data(obex, &data); g_obex_packet_set_data(rsp, &data, sizeof(data), G_OBEX_DATA_COPY); connid = g_obex_packet_get_header(rsp, G_OBEX_HDR_CONNECTION); if (connid != NULL) { g_obex_header_get_uint32(connid, &obex->conn_id); return; } obex->conn_id = next_connid++; connid = g_obex_header_new_uint32(G_OBEX_HDR_CONNECTION, obex->conn_id); g_obex_packet_prepend_header(rsp, connid); }
static void parse_connect_data(GObex *obex, GObexPacket *pkt) { const struct connect_data *data; GObexHeader *connid; guint16 u16; size_t data_len; data = g_obex_packet_get_data(pkt, &data_len); if (data == NULL || data_len != sizeof(*data)) return; memcpy(&u16, &data->mtu, sizeof(u16)); obex->tx_mtu = g_ntohs(u16); if (obex->io_tx_mtu > 0 && obex->tx_mtu > obex->io_tx_mtu) obex->tx_mtu = obex->io_tx_mtu; obex->tx_buf = g_realloc(obex->tx_buf, obex->tx_mtu); connid = g_obex_packet_get_header(pkt, G_OBEX_HDR_CONNECTION); if (connid != NULL) g_obex_header_get_uint32(connid, &obex->conn_id); }
static void test_decode_connect(void) { GObexPacket *pkt; GObexHeader *header; GError *err = NULL; gboolean ret; const guint8 *buf; guint8 target[] = { 0xab, 0xcd }; gsize len; pkt = g_obex_packet_decode(pkt_connect, sizeof(pkt_connect), 4, G_OBEX_DATA_REF, &err); g_assert_no_error(err); g_assert(pkt != NULL); header = g_obex_packet_get_header(pkt, G_OBEX_HDR_TARGET); g_assert(header != NULL); ret = g_obex_header_get_bytes(header, &buf, &len); g_assert(ret == TRUE); assert_memequal(target, sizeof(target), buf, len); g_obex_packet_free(pkt); }