diff options
Diffstat (limited to 'hcid/dbus-sdp.c')
-rw-r--r-- | hcid/dbus-sdp.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/hcid/dbus-sdp.c b/hcid/dbus-sdp.c index fce4cf90..a3a9bc27 100644 --- a/hcid/dbus-sdp.c +++ b/hcid/dbus-sdp.c @@ -455,6 +455,7 @@ static get_record_data_t *get_record_data_new(uint16_t dev_id, const char *dst, static void get_record_data_free(get_record_data_t *d) { + free(d->search_data); free(d->dst); free(d); } @@ -506,24 +507,22 @@ static gboolean search_process_cb(GIOChannel *chan, GIOCondition cond, void *udata) { struct transaction_context *ctxt = udata; - int sk, err = 0; - socklen_t len; + int err = 0; - sk = g_io_channel_unix_get_fd(chan); + if (cond & G_IO_NVAL) { + g_io_channel_unref(chan); + return FALSE; + } - len = sizeof(err); - if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { - error("getsockopt(): %s (%d)", strerror(errno), errno); - err = errno; + if (cond & G_IO_ERR & G_IO_HUP) { + err = EIO; goto failed; } - if (err != 0) { - error("sock error: %s (%d)", strerror(err), err); + + if (sdp_process(ctxt->session) < 0) goto failed; - } - if (!sdp_process(ctxt->session)) - return TRUE; + return TRUE; failed: if (err) { @@ -532,9 +531,11 @@ failed: get_record_data_free(ctxt->priv); } else error_failed(ctxt->conn, ctxt->rq, err); + + transaction_context_free(ctxt); } - g_io_channel_unref(chan); - return FALSE; + + return TRUE; } static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata) @@ -556,24 +557,24 @@ static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp if (sdp_err < 0) { error("search failed: Invalid session!"); error_failed(ctxt->conn, ctxt->rq, EINVAL); - return; + goto failed; } error("search failed: %s (%d)", strerror(sdp_err), sdp_err); error_failed(ctxt->conn, ctxt->rq, sdp_err); - return; + goto failed; } if (type == SDP_ERROR_RSP) { error_sdp_failed(ctxt->conn, ctxt->rq, err); - return; + goto failed; } /* check response PDU ID */ if (type != SDP_SVC_ATTR_RSP) { error("SDP error: %s (%d)", strerror(EPROTO), EPROTO); error_failed(ctxt->conn, ctxt->rq, EPROTO); - return; + goto failed; } dbus_message_get_args(ctxt->rq, NULL, @@ -602,6 +603,8 @@ static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp done: dbus_message_iter_close_container(&iter, &array_iter); send_reply_and_unref(ctxt->conn, reply); +failed: + transaction_context_free(ctxt); } static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata) @@ -621,24 +624,24 @@ static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t if (sdp_err < 0) { error("search failed: Invalid session!"); error_failed(ctxt->conn, ctxt->rq, EINVAL); - return; + goto failed; } error("search failed: %s (%d)", strerror(sdp_err), sdp_err); error_failed(ctxt->conn, ctxt->rq, sdp_err); - return; + goto failed; } if (type == SDP_ERROR_RSP) { error_sdp_failed(ctxt->conn, ctxt->rq, err); - return; + goto failed; } /* check response PDU ID */ if (type != SDP_SVC_SEARCH_RSP) { error("SDP error: %s (%d)", strerror(EPROTO), EPROTO); error_failed(ctxt->conn, ctxt->rq, EPROTO); - return; + goto failed; } reply = dbus_message_new_method_return(ctxt->rq); @@ -656,7 +659,7 @@ static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t scanned = sizeof(uint16_t); csrc = ntohs(bt_get_unaligned((uint16_t *) pdata)); - if (csrc <= 0) + if (csrc <= 0) goto done; pdata += sizeof(uint16_t); @@ -675,6 +678,8 @@ static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t done: dbus_message_iter_close_container(&iter, &array_iter); send_reply_and_unref(ctxt->conn, reply); +failed: + transaction_context_free(ctxt); } static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata) @@ -697,24 +702,24 @@ static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t if (sdp_err < 0) { error("search failed: Invalid session!"); error_failed(ctxt->conn, ctxt->rq, EINVAL); - return; + goto failed; } error("search failed: %s (%d)", strerror(sdp_err), sdp_err); error_failed(ctxt->conn, ctxt->rq, sdp_err); - return; + goto failed; } if (type == SDP_ERROR_RSP) { error_sdp_failed(ctxt->conn, ctxt->rq, err); - return; + goto failed; } /* check response PDU ID */ if (type != SDP_SVC_SEARCH_RSP) { error("SDP error: %s (%d)", strerror(EPROTO), EPROTO); error_failed(ctxt->conn, ctxt->rq, EPROTO); - return; + goto failed; } dbus_message_get_args(ctxt->rq, NULL, @@ -736,7 +741,7 @@ static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t scanned = sizeof(uint16_t); csrc = ntohs(bt_get_unaligned((uint16_t *) pdata)); - if (csrc <= 0) + if (csrc <= 0) goto done; pdata += sizeof(uint16_t); @@ -756,6 +761,8 @@ static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t done: dbus_message_iter_close_container(&iter, &array_iter); send_reply_and_unref(ctxt->conn, reply); +failed: + transaction_context_free(ctxt); } static gboolean sdp_client_connect_cb(GIOChannel *chan, @@ -801,17 +808,15 @@ static gboolean sdp_client_connect_cb(GIOChannel *chan, } /* set the callback responsible for update the transaction data */ - g_io_add_watch_full(chan, 0, G_IO_IN, - search_process_cb, ctxt, transaction_context_free); + g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + search_process_cb, ctxt); goto done; failed: - if (err) { - if (c->priv) - get_record_data_call_cb(c->priv, NULL, err); - else - error_connection_attempt_failed(c->conn, c->rq, err); - } + if (c->priv) + get_record_data_call_cb(c->priv, NULL, err); + else + error_connection_attempt_failed(c->conn, c->rq, err); if (c->priv) get_record_data_free(c->priv); if (ctxt) @@ -854,8 +859,6 @@ static struct pending_connect *connect_request(DBusConnection *conn, } chan = g_io_channel_unix_new(sdp_get_socket(c->session)); - g_io_channel_set_close_on_unref(chan, TRUE); - g_io_add_watch(chan, G_IO_OUT, sdp_client_connect_cb, c); pending_connects = slist_append(pending_connects, c); @@ -1514,6 +1517,7 @@ static void get_rec_with_handle_comp_cb(uint8_t type, uint16_t err, failed: get_record_data_call_cb(ctxt->priv, rec, cb_err); get_record_data_free(ctxt->priv); + transaction_context_free(ctxt); } static int get_rec_with_handle_conn_cb(struct transaction_context *ctxt) @@ -1542,7 +1546,6 @@ static int get_rec_with_handle_conn_cb(struct transaction_context *ctxt) } failed: - free(d->search_data); if (attrids) sdp_list_free(attrids, NULL); @@ -1596,7 +1599,7 @@ static void get_rec_with_uuid_comp_cb(uint8_t type, uint16_t err, get_record_data_t *d = ctxt->priv; int csrc, tsrc, cb_err = 0; sdp_record_t *rec = NULL; - uint32_t handle; + uint32_t *handle; uint8_t *pdata; if (err == 0xffff) { @@ -1628,15 +1631,26 @@ static void get_rec_with_uuid_comp_cb(uint8_t type, uint16_t err, goto failed; pdata += sizeof(uint16_t); - handle = ntohl(bt_get_unaligned((uint32_t*)pdata)); - get_record_with_handle(ctxt->conn, ctxt->rq, d->dev_id, - d->dst, handle, d->cb, d->data); - get_record_data_free(ctxt->priv); + handle = malloc(sizeof(*handle)); + if (!handle) { + cb_err = ENOMEM; + goto failed; + } + *handle = ntohl(bt_get_unaligned((uint32_t*)pdata)); + + free(d->search_data); + d->search_data = handle; + + cb_err = get_rec_with_handle_conn_cb(ctxt); + if (cb_err) + goto failed; + return; failed: - get_record_data_call_cb(ctxt->priv, rec, cb_err); - get_record_data_free(ctxt->priv); + get_record_data_call_cb(d, rec, cb_err); + get_record_data_free(d); + transaction_context_free(ctxt); } static int get_rec_with_uuid_conn_cb(struct transaction_context *ctxt) @@ -1658,10 +1672,10 @@ static int get_rec_with_uuid_conn_cb(struct transaction_context *ctxt) if (sdp_service_search_async(ctxt->session, search, 64) < 0) { error("send request failed: %s (%d)", strerror(errno), errno); err = -sdp_get_error(ctxt->session); + goto failed; } failed: - free(d->search_data); if (search) sdp_list_free(search, NULL); |