Eldbus_Message * _eldbus_connection_send_and_block(Eldbus_Connection *conn, Eldbus_Message *msg, double timeout) { Eldbus_Message *reply = NULL; DBusError err; DBusMessage *dbus_msg; if (ecore_main_loop_nested_get()) WRN("Calling this function may result in dropped frames because the main loop is running"); dbus_error_init(&err); dbus_msg = dbus_connection_send_with_reply_and_block(conn->dbus_conn, msg->dbus_msg, timeout, &err); EINA_SAFETY_ON_TRUE_GOTO(dbus_error_is_set(&err), dbus_error_set); dbus_error_free(&err); reply = eldbus_message_new(EINA_FALSE); EINA_SAFETY_ON_NULL_GOTO(reply, fail); reply->dbus_msg = dbus_msg; dbus_message_iter_init(reply->dbus_msg, &reply->iterator->dbus_iterator); eldbus_message_unref(msg); return reply; dbus_error_set: reply = eldbus_message_error_new(msg, err.name, err.message); dbus_error_free(&err); fail: eldbus_message_unref(msg); return reply; }
static void _efl_net_control_technology_property_set(Eo *o, Efl_Net_Control_Technology_Data *pd, const char *name, const char *signature, ...) { Eldbus_Message *msg; Eldbus_Message_Iter *msg_itr, *var; Eldbus_Pending *p; va_list ap; msg = eldbus_proxy_method_call_new(pd->proxy, "SetProperty"); EINA_SAFETY_ON_NULL_RETURN(msg); msg_itr = eldbus_message_iter_get(msg); EINA_SAFETY_ON_NULL_GOTO(msg_itr, error_send); eldbus_message_iter_basic_append(msg_itr, 's', name); var = eldbus_message_iter_container_new(msg_itr, 'v', signature); va_start(ap, signature); eldbus_message_iter_arguments_vappend(var, signature, ap); va_end(ap); eldbus_message_iter_container_close(msg_itr, var); p = eldbus_proxy_send(pd->proxy, msg, _efl_net_control_technology_property_set_cb, o, DEFAULT_TIMEOUT); EINA_SAFETY_ON_NULL_GOTO(p, error_send); pd->pending = eina_list_append(pd->pending, p); DBG("Setting property %s", name); return; error_send: eldbus_message_unref(msg); }
/* * On success @param msg is unref'd or its ref is stolen by the returned * Eldbus_Pending. */ Eldbus_Pending * _eldbus_connection_send(Eldbus_Connection *conn, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout) { Eldbus_Pending *pending; Eldbus_Message *error_msg; DBG("conn=%p, msg=%p, cb=%p, cb_data=%p, timeout=%f", conn, msg, cb, cb_data, timeout); if (!cb) { dbus_connection_send(conn->dbus_conn, msg->dbus_msg, NULL); eldbus_message_unref(msg); return NULL; } pending = calloc(1, sizeof(Eldbus_Pending)); EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL); pending->cb = cb; pending->cb_data = cb_data; pending->conn = conn; pending->dest = eina_stringshare_add(dbus_message_get_destination(msg->dbus_msg)); pending->interface = eina_stringshare_add(dbus_message_get_interface(msg->dbus_msg)); pending->method = eina_stringshare_add(dbus_message_get_member(msg->dbus_msg)); pending->path = eina_stringshare_add(dbus_message_get_path(msg->dbus_msg)); /* Steal the reference */ pending->msg_sent = msg; EINA_MAGIC_SET(pending, ELDBUS_PENDING_MAGIC); if (!dbus_connection_send_with_reply(conn->dbus_conn, msg->dbus_msg, &pending->dbus_pending, timeout)) { error_msg = _eldbus_message_error_get(msg, "org.enlightenment.DBus.NoConnection", "Eldbus_Connection was closed."); eldbus_pending_dispatch(pending, error_msg); return NULL; } if (!pending->dbus_pending) { error_msg = _eldbus_message_error_get(msg, "org.enlightenment.DBus.Error", "dbus_pending is NULL."); eldbus_pending_dispatch(pending, error_msg); return NULL; } if (dbus_pending_call_set_notify(pending->dbus_pending, cb_pending, pending, NULL)) return pending; dbus_pending_call_cancel(pending->dbus_pending); error_msg = _eldbus_message_error_get(pending->msg_sent, "org.enlightenment.DBus.Error", "Error when try set callback to message."); eldbus_pending_dispatch(pending, error_msg); return NULL; }
static Eldbus_Message * _cb_property_get(const Eldbus_Service_Interface *piface, const Eldbus_Message *msg) { const char *propname, *iface_name; Eldbus_Service_Object *obj = piface->obj; Eldbus_Service_Interface *iface; Property *prop; Eldbus_Message *reply, *error_reply = NULL; Eldbus_Message_Iter *main_iter, *variant; Eina_Bool ret; Eldbus_Property_Get_Cb getter = NULL; if (!eldbus_message_arguments_get(msg, "ss", &iface_name, &propname)) return NULL; iface = eina_hash_find(obj->interfaces, iface_name); if (!iface) return eldbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_INTERFACE, "Interface not found."); prop = eina_hash_find(iface->properties, propname); if (!prop || prop->is_invalidate) goto not_found; if (prop->property->get_func) getter = prop->property->get_func; else if (iface->get_func) getter = iface->get_func; if (!getter) goto not_found; reply = eldbus_message_method_return_new(msg); EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL); main_iter = eldbus_message_iter_get(reply); variant = eldbus_message_iter_container_new(main_iter, 'v', prop->property->type); ret = getter(iface, propname, variant, msg, &error_reply); if (ret) { eldbus_message_iter_container_close(main_iter, variant); return reply; } eldbus_message_unref(reply); return error_reply; not_found: return eldbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_PROPERTY, "Property not found."); }
static void eldbus_pending_dispatch(Eldbus_Pending *pending, Eldbus_Message *msg) { DBG("pending=%p msg=%p", pending, msg); if (pending->cb) pending->cb((void *)pending->cb_data, msg, pending); eldbus_cbs_free_dispatch(&(pending->cbs_free), pending); eldbus_data_del_all(&(pending->data)); if (msg) eldbus_message_unref(msg); eldbus_message_unref(pending->msg_sent); dbus_pending_call_unref(pending->dbus_pending); pending->cb = NULL; pending->dbus_pending = NULL; eina_stringshare_del(pending->dest); eina_stringshare_del(pending->path); eina_stringshare_del(pending->interface); eina_stringshare_del(pending->method); EINA_MAGIC_SET(pending, EINA_MAGIC_NONE); free(pending); }
Eldbus_Message *eldbus_message_new(Eina_Bool writable) { Eldbus_Message *msg = calloc(1, sizeof(Eldbus_Message)); EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL); EINA_MAGIC_SET(msg, ELDBUS_MESSAGE_MAGIC); msg->refcount = 1; msg->iterator = _message_iterator_new(writable); EINA_SAFETY_ON_NULL_GOTO(msg->iterator, fail); return msg; fail: eldbus_message_unref(msg); return NULL; }
EAPI Eldbus_Message * eldbus_message_method_call_new(const char *dest, const char *path, const char *iface, const char *method) { Eldbus_Message *msg; EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(method, NULL); #ifdef DBUS_SYNTAX_H // added to libdbus: // f426c6cddd158d6324923f28117bc8e512d6f64f Fri Feb 24 12:43:55 2012 +0000 if (!dbus_validate_bus_name(dest, NULL)) { ERR("Invalid bus name '%s'", dest); return NULL; } if (!dbus_validate_path(path, NULL)) { ERR("Invalid path '%s'", path); return NULL; } if (!dbus_validate_interface(iface, NULL)) { ERR("Invalid interface '%s'", iface); return NULL; } #endif msg = eldbus_message_new(EINA_TRUE); EINA_SAFETY_ON_NULL_GOTO(msg, fail); msg->dbus_msg = dbus_message_new_method_call(dest, path, iface, method); dbus_message_iter_init_append(msg->dbus_msg, &msg->iterator->dbus_iterator); return msg; fail: eldbus_message_unref(msg); return NULL; }
static void cb_pending(DBusPendingCall *dbus_pending, void *user_data) { Eldbus_Message *msg; Eldbus_Pending *pending = user_data; if (!dbus_pending_call_get_completed(dbus_pending)) { INF("timeout to pending %p", pending); dbus_pending_call_cancel(dbus_pending); msg = eldbus_message_error_new(pending->msg_sent, ELDBUS_ERROR_PENDING_TIMEOUT, "This call was not completed in time."); eldbus_pending_dispatch(pending, msg); return; } msg = eldbus_message_new(EINA_FALSE); EINA_SAFETY_ON_NULL_RETURN(msg); msg->dbus_msg = dbus_pending_call_steal_reply(dbus_pending); if (!msg->dbus_msg) { EINA_SAFETY_ON_NULL_GOTO(pending->cb, cleanup); msg->dbus_msg = dbus_message_new_error(NULL, "org.enlightenment.DBus.NoReply", "There was no reply to this method call."); EINA_SAFETY_ON_NULL_GOTO(msg->dbus_msg, cleanup); } dbus_message_iter_init(msg->dbus_msg, &msg->iterator->dbus_iterator); eldbus_pending_dispatch(pending, msg); return; cleanup: eldbus_message_unref(msg); }