Example #1
0
static Eina_Bool
_eldbus_message_arguments_vappend(Eldbus_Message *msg, const char *signature, va_list *aq)
{
   DBusSignatureIter signature_iter;
   Eldbus_Message_Iter *iter;
   int type;
   Eina_Bool r = EINA_TRUE;

   if (!signature[0]) return EINA_TRUE;
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL),
                                   EINA_FALSE);

   iter = eldbus_message_iter_get(msg);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);

   dbus_signature_iter_init(&signature_iter, signature);
   while ((type = dbus_signature_iter_get_current_type(&signature_iter)))
     {
        if (dbus_type_is_basic(type))
          r = append_basic(type, aq, &iter->dbus_iterator);
        else
          {
             ERR("sig = %s | eldbus_message_arguments_append() and \
                  eldbus_message_arguments_vappend() only support basic types, \
                  to complex types use eldbus_message_iter_* functions",
                  signature);
             r = EINA_FALSE;
          }

        if (!r || !dbus_signature_iter_next(&signature_iter))
          break;
     }

   return r;
}
GType
_dbus_gtype_from_basic_typecode (int typecode)
{
  g_assert (dbus_type_is_basic (typecode));
  g_assert (dbus_typecode_maps_to_basic (typecode));
  return typecode_to_gtype (typecode);
}
Example #3
0
/** Handle connman property changed signals
 *
 * @param msg net.connman.Manager.PropertyChanged D-Bus signal
 */
static void xconnman_handle_property_changed_signal(DBusMessage *msg)
{
	const char  *key = 0;
	dbus_any_t   val = DBUS_ANY_INIT;

	int          vtype;

	DBusMessageIter miter, viter;

	if( !dbus_message_iter_init(msg, &miter) )
		goto EXIT;

	if( dbus_message_iter_get_arg_type(&miter) != DBUS_TYPE_STRING )
		goto EXIT;

	dbus_message_iter_get_basic(&miter, &key);
	dbus_message_iter_next(&miter);

	if( dbus_message_iter_get_arg_type(&miter) != DBUS_TYPE_VARIANT )
		goto EXIT;

	dbus_message_iter_recurse(&miter, &viter);
	vtype = dbus_message_iter_get_arg_type(&viter);
	if( !dbus_type_is_basic(vtype) )
		goto EXIT;

	dbus_message_iter_get_basic(&viter, &val);
	xconnman_property_changed(key, vtype, &val);

EXIT:
	return;
}
Example #4
0
EAPI Eina_Bool
eldbus_message_iter_fixed_array_append(Eldbus_Message_Iter *iter, int type, const void *array, unsigned int size)
{
   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(array, EINA_FALSE);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(iter->writable, EINA_FALSE);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_type_is_basic(type), EINA_FALSE);
   return dbus_message_iter_append_fixed_array(&iter->dbus_iterator, type, &array, (int)size);
}
Example #5
0
/** Handle reply to asynchronous connman properties query
 *
 * @param pc        State data for asynchronous D-Bus method call
 * @param user_data (not used)
 */
static void xconnman_get_properties_cb(DBusPendingCall *pc, void *user_data)
{
	(void)user_data;

	DBusMessage *rsp = 0;
	DBusError    err = DBUS_ERROR_INIT;
	const char  *key = 0;
	dbus_any_t   val = DBUS_ANY_INIT;

	int          vtype;

	DBusMessageIter miter, aiter, diter, viter;

	if( !(rsp = dbus_pending_call_steal_reply(pc)) )
		goto EXIT;

	if( dbus_set_error_from_message(&err, rsp) ) {
		mce_log(LL_WARN, "%s: %s", err.name, err.message);
		goto EXIT;
	}

	if( !dbus_message_iter_init(rsp, &miter) )
		goto EXIT;

	if( dbus_message_iter_get_arg_type(&miter) != DBUS_TYPE_ARRAY )
		goto EXIT;

	dbus_message_iter_recurse(&miter, &aiter);

	while( dbus_message_iter_get_arg_type(&aiter) == DBUS_TYPE_DICT_ENTRY ) {
		dbus_message_iter_recurse(&aiter, &diter);
		dbus_message_iter_next(&aiter);

		if( dbus_message_iter_get_arg_type(&diter) != DBUS_TYPE_STRING )
			goto EXIT;

		dbus_message_iter_get_basic(&diter, &key);
		dbus_message_iter_next(&diter);

		if( dbus_message_iter_get_arg_type(&diter) != DBUS_TYPE_VARIANT )
			goto EXIT;

		dbus_message_iter_recurse(&diter, &viter);
		vtype = dbus_message_iter_get_arg_type(&viter);
		if( !dbus_type_is_basic(vtype) )
			continue;

		dbus_message_iter_get_basic(&viter, &val);
		xconnman_property_changed(key, vtype, &val);
	}

EXIT:
	if( rsp ) dbus_message_unref(rsp);
	dbus_error_free(&err);
}
Example #6
0
void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) {
    DBusMessageIter variant_iter;

    pa_assert(iter);
    pa_assert(dbus_type_is_basic(type));
    pa_assert(data);

    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, signature_from_basic_type(type), &variant_iter));
    pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
}
Example #7
0
/**
 * Useful when iterating over arrays
 */
EAPI Eina_Bool
eldbus_message_iter_get_and_next(Eldbus_Message_Iter *iter, char signature, ...)
{
   char type;
   va_list vl;

   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
   va_start(vl, signature);

   type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
   if (type == DBUS_TYPE_INVALID)
     {
        va_end(vl);
        return EINA_FALSE;
     }
   if (type != signature)
     {
        if (signature == '(') signature = 'r';
        else if (signature == '{') signature = 'e';
        if (type != signature)
          {
             va_end(vl);
             return EINA_FALSE;
          }
     }

   if (dbus_type_is_basic(type))
     get_basic(type, &iter->dbus_iterator, &vl);
   else
     {
        Eldbus_Message_Iter *sub;
        Eldbus_Message_Iter **iter_var = va_arg(vl, Eldbus_Message_Iter**);

        sub = _message_iterator_new(EINA_FALSE);
        if (!sub)
          {
             va_end(vl);
             return EINA_FALSE;
          }
        dbus_message_iter_recurse(&iter->dbus_iterator,
                                  &sub->dbus_iterator);
        iter->iterators = eina_inlist_append(iter->iterators,
                                             EINA_INLIST_GET(sub));

        *iter_var = sub;
     }
   va_end(vl);

   dbus_message_iter_next(&iter->dbus_iterator);
   return EINA_TRUE;
}
Example #8
0
void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data) {
    DBusMessageIter dict_entry_iter;

    pa_assert(dict_iter);
    pa_assert(key);
    pa_assert(dbus_type_is_basic(type));
    pa_assert(data);

    pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
    pa_dbus_append_basic_variant(&dict_entry_iter, type, data);
    pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
}
Example #9
0
void pa_dbus_send_basic_value_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
    DBusMessage *reply = NULL;

    pa_assert(c);
    pa_assert(in_reply_to);
    pa_assert(dbus_type_is_basic(type));
    pa_assert(data);

    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
    pa_assert_se(dbus_message_append_args(reply, type, data, DBUS_TYPE_INVALID));
    pa_assert_se(dbus_connection_send(c, reply, NULL));
    dbus_message_unref(reply);
}
Example #10
0
void tst_QDBusType::isValidBasicType()
{
    QFETCH(QString, data);
    QFETCH(bool, result);
    QFETCH(bool, isValid);
    QVERIFY2(data.length() == 1, "Test is malformed, this function must test only one-letter types");
    QVERIFY(isValid || (!isValid && !result));

    int type = data.at(0).unicode();
    if (isValid)
        QCOMPARE(bool(dbus_type_is_basic(type)), result);
    QCOMPARE(QDBusUtil::isValidBasicType(type), result);
}
Example #11
0
static Eina_Bool
_eldbus_message_iter_arguments_vget(Eldbus_Message_Iter *iter, const char *signature, va_list *aq)
{
   int iter_type;
   DBusSignatureIter sig_iter;

   ELDBUS_MESSAGE_ITERATOR_CHECK_RETVAL(iter, EINA_FALSE);
   EINA_SAFETY_ON_TRUE_RETURN_VAL(iter->writable, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(signature, EINA_FALSE);
   EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate(signature, NULL), EINA_FALSE);

   dbus_signature_iter_init(&sig_iter, signature);
   iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);

   while (iter_type != DBUS_TYPE_INVALID)
     {
        int sig_type = dbus_signature_iter_get_current_type(&sig_iter);

        if (sig_type == DBUS_TYPE_INVALID)
          break;

        if (sig_type != iter_type)
          {
             ERR("Type in iterator different of signature expected:%c got %c", iter_type, sig_type);
             return EINA_FALSE;
          }

        if (dbus_type_is_basic(iter_type))
          get_basic(iter_type, &iter->dbus_iterator, aq);
        else
          {
             Eldbus_Message_Iter **user_itr = va_arg(*aq, Eldbus_Message_Iter **);
             Eldbus_Message_Iter *sub_itr;

             sub_itr = _message_iterator_new(EINA_FALSE);
             EINA_SAFETY_ON_NULL_RETURN_VAL(sub_itr, EINA_FALSE);
             dbus_message_iter_recurse(&iter->dbus_iterator,
                                       &sub_itr->dbus_iterator);
             iter->iterators = eina_inlist_append(iter->iterators,
                                                  EINA_INLIST_GET(sub_itr));
             *user_itr = sub_itr;
          }

        dbus_message_iter_next(&iter->dbus_iterator);
        dbus_signature_iter_next(&sig_iter);
        iter_type = dbus_message_iter_get_arg_type(&iter->dbus_iterator);
     }

   return dbus_signature_iter_get_current_type(&sig_iter) == DBUS_TYPE_INVALID;

}
Example #12
0
void pa_dbus_append_basic_array_variant(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
    DBusMessageIter variant_iter;
    char *array_signature;

    pa_assert(iter);
    pa_assert(dbus_type_is_basic(item_type));
    pa_assert(array || n == 0);

    array_signature = pa_sprintf_malloc("a%c", *signature_from_basic_type(item_type));

    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, array_signature, &variant_iter));
    pa_dbus_append_basic_array(&variant_iter, item_type, array, n);
    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));

    pa_xfree(array_signature);
}
Example #13
0
void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
    DBusMessageIter array_iter;
    unsigned i;
    unsigned item_size;

    pa_assert(iter);
    pa_assert(dbus_type_is_basic(item_type));
    pa_assert(array || n == 0);

    item_size = basic_type_size(item_type);

    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, signature_from_basic_type(item_type), &array_iter));

    for (i = 0; i < n; ++i)
        pa_assert_se(dbus_message_iter_append_basic(&array_iter, item_type, &((uint8_t*) array)[i * item_size]));

    pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
}
Example #14
0
void pa_dbus_append_basic_array_variant_dict_entry(
        DBusMessageIter *dict_iter,
        const char *key,
        int item_type,
        const void *array,
        unsigned n) {
    DBusMessageIter dict_entry_iter;

    pa_assert(dict_iter);
    pa_assert(key);
    pa_assert(dbus_type_is_basic(item_type));
    pa_assert(array || n == 0);

    pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
    pa_dbus_append_basic_array_variant(&dict_entry_iter, item_type, array, n);
    pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
}
Example #15
0
void pa_dbus_send_basic_array_variant_reply(
        DBusConnection *c,
        DBusMessage *in_reply_to,
        int item_type,
        void *array,
        unsigned n) {
    DBusMessage *reply = NULL;
    DBusMessageIter msg_iter;

    pa_assert(c);
    pa_assert(in_reply_to);
    pa_assert(dbus_type_is_basic(item_type));
    pa_assert(array || n == 0);

    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
    dbus_message_iter_init_append(reply, &msg_iter);
    pa_dbus_append_basic_array_variant(&msg_iter, item_type, array, n);
    pa_assert_se(dbus_connection_send(c, reply, NULL));
    dbus_message_unref(reply);
}
Example #16
0
static void iter_append_iter(DBusMessageIter *base, DBusMessageIter *iter)
{
	int type;

	type = dbus_message_iter_get_arg_type(iter);

	if (dbus_type_is_basic(type)) {
		const void *value;

		dbus_message_iter_get_basic(iter, &value);
		dbus_message_iter_append_basic(base, type, &value);
	} else if (dbus_type_is_container(type)) {
		DBusMessageIter iter_sub, base_sub;
		char *sig;

		dbus_message_iter_recurse(iter, &iter_sub);

		switch (type) {
		case DBUS_TYPE_ARRAY:
		case DBUS_TYPE_VARIANT:
			sig = dbus_message_iter_get_signature(&iter_sub);
			break;
		default:
			sig = NULL;
			break;
		}

		dbus_message_iter_open_container(base, type, sig, &base_sub);

		if (sig != NULL)
			dbus_free(sig);

		while (dbus_message_iter_get_arg_type(&iter_sub) !=
							DBUS_TYPE_INVALID) {
			iter_append_iter(&base_sub, &iter_sub);
			dbus_message_iter_next(&iter_sub);
		}

		dbus_message_iter_close_container(base, &base_sub);
	}
}
Example #17
0
void pa_dbus_send_basic_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
    DBusMessage *reply = NULL;
    DBusMessageIter msg_iter;
    DBusMessageIter variant_iter;

    pa_assert(c);
    pa_assert(in_reply_to);
    pa_assert(dbus_type_is_basic(type));
    pa_assert(data);

    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
    dbus_message_iter_init_append(reply, &msg_iter);
    pa_assert_se(dbus_message_iter_open_container(&msg_iter,
                                                  DBUS_TYPE_VARIANT,
                                                  signature_from_basic_type(type),
                                                  &variant_iter));
    pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &variant_iter));
    pa_assert_se(dbus_connection_send(c, reply, NULL));
    dbus_message_unref(reply);
}
Example #18
0
/** Get property value from dbus message iterator
 *
 * @param self property
 * @param iter dbus message parse position
 */
static bool uprop_set_from_iter(uprop_t *self, DBusMessageIter *iter)
{
    bool res  = false;
    int  type = dbus_message_iter_get_arg_type(iter);

    uprop_set_invalid(self);

    if( dbus_type_is_basic(type) ) {
        dbus_message_iter_get_basic(iter, &self->p_val);
        switch( dbus_message_iter_get_arg_type(iter) ) {
        case DBUS_TYPE_STRING:
        case DBUS_TYPE_OBJECT_PATH:
        case DBUS_TYPE_SIGNATURE:
            self->p_val.s = strdup(self->p_val.s);
            break;
        default:
            break;
        }
        self->p_type = type, res = true;
    }
    return res;
}
int main()
{
 	if(!dbus_type_is_basic(DBUS_TYPE_BOOLEAN))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_BOOLEAN");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_INT16))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_INT16");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_BYTE))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_BYTE");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_UINT16))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_UINT16");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_INT32))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_UINT32");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_UINT32))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_UINT32");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_INT64))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_INT64");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_UINT64))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_UINT64");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_DOUBLE))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_DOUBLE");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_STRING))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_STRING");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_OBJECT_PATH))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_OBJECT_PATH");
		create_xml(1);
		return 1;
	}
	if(!dbus_type_is_basic(DBUS_TYPE_SIGNATURE))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_SIGNATURE");
		create_xml(1);
		return 1;
	}
	if(dbus_type_is_basic(DBUS_TYPE_ARRAY))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_ARRAY");
		create_xml(1);
		return 1;
	}
	if(dbus_type_is_basic(DBUS_TYPE_VARIANT))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_VARIANT");
		create_xml(1);
		return 1;
	}
	if(dbus_type_is_basic(DBUS_TYPE_STRUCT))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_STRUCT");
		create_xml(1);
		return 1;
	}
	if(dbus_type_is_basic(DBUS_TYPE_DICT_ENTRY))	
	{
		std_log(LOG_FILENAME_LINE, "Fail for %s","DBUS_TYPE_DICT_ENTRY");
		create_xml(1);
		return 1;
	} 
	
	std_log(LOG_FILENAME_LINE, "Success");
		create_xml(0);
	return 0;
}
int bridge_request_dbus_params_element(bridge_request_t *self,
				       struct json_object *element,
				       DBusSignatureIter *sigIt,
				       DBusMessageIter *it)
{
	int type;
	int ret = 0;

	type = dbus_signature_iter_get_current_type(sigIt);

	if (dbus_type_is_basic(type)) {
		if ((ret = bridge_request_dbus_params_basic(self,
				 element, type, it)) != 0) {
			return ret;
		}
	}
	else if (type == DBUS_TYPE_VARIANT) {
		struct json_object *tmp;
		DBusMessageIter args;
		const char *vSig;

		if (json_object_get_type(element) != json_type_array) {
			bridge_request_error(self,
				"array expected.");
			return EINVAL;
		}
		tmp = json_object_array_get_idx(element, 0);
		if (!tmp) {
			bridge_request_error(self,
				"variant signature expected.");
			return EINVAL;
		}
		if (json_object_get_type(tmp) != json_type_string) {
			bridge_request_error(self,
				"variant signature expected.");
			return EINVAL;
		}
		vSig = json_object_get_string(tmp);
		if (!dbus_signature_validate_single(vSig, 0)) {
			bridge_request_error(self,
				"invalid variant signature.");
			return EINVAL;
		}
		dbus_message_iter_open_container(it, type,
			 vSig, &args);
		ret = bridge_request_dbus_params_array(self,
			element, 1, vSig, &args);
		dbus_message_iter_close_container(it, &args);
		if (ret != 0)
			return EINVAL;
	}
	else if (type == DBUS_TYPE_STRUCT) {
		DBusMessageIter args;
		DBusSignatureIter sigArgs;

		if (json_object_get_type(element) != json_type_array) {
			bridge_request_error(self, "array expected.");
			return EINVAL;
		}

		dbus_signature_iter_recurse(sigIt, &sigArgs);
		dbus_message_iter_open_container(it, 
			type, NULL, &args);
		ret = bridge_request_dbus_params_struct(self,
			element, &sigArgs, &args);
		dbus_message_iter_close_container(it, &args);
		if (ret != 0)
			return EINVAL;
	}
	else if (type == DBUS_TYPE_ARRAY) {
		DBusMessageIter args;
		DBusSignatureIter sigArgs;
		int cType;
		char *cSig;

		dbus_signature_iter_recurse(sigIt, &sigArgs);
		cType = dbus_signature_iter_get_current_type(&sigArgs);
		cSig = dbus_signature_iter_get_signature(&sigArgs);

		dbus_message_iter_open_container(it, type, cSig, &args);
		dbus_free(cSig);

		if (cType == DBUS_TYPE_DICT_ENTRY) {
			ret = bridge_request_dbus_params_dict(self,
				element, &sigArgs, &args);
		}
		else {
			int i, len;

			if (json_object_get_type(element) != json_type_array) {
				bridge_request_error(self,
					"array expected.");
				ret = EINVAL;
			}
			else {
				len = json_object_array_length(element);
				for (i = 0; i < len; ++i) {
					struct json_object *tmp;
					DBusSignatureIter tmpSigArgs = sigArgs;

					tmp = json_object_array_get_idx(element, i);
					if (!tmp) {
						bridge_request_error(self,
							"unexpected 'null' element in json array.");
						return EINVAL;
					}
					ret = bridge_request_dbus_params_element(self,
						tmp, &tmpSigArgs, &args);
				}
			}
		}
		dbus_message_iter_close_container(it, &args);
	}
	else {
		bridge_request_error(self,
			"unsupported json argument type.");
		return EINVAL;
	}
	return ret;
}
/**
 * Verifies that the range of type_str from type_pos to type_end is a
 * valid signature.  If this function returns #TRUE, it will be safe
 * to iterate over the signature with a types-only #DBusTypeReader.
 * The range passed in should NOT include the terminating
 * nul/DBUS_TYPE_INVALID.
 *
 * @param type_str the string
 * @param type_pos where the typecodes start
 * @param len length of typecodes
 * @returns #DBUS_VALID if valid, reason why invalid otherwise
 */
DBusValidity
_dbus_validate_signature_with_reason (const DBusString *type_str,
                                      int               type_pos,
                                      int               len)
{
  const unsigned char *p;
  const unsigned char *end;
  int last;
  int struct_depth;
  int array_depth;
  int dict_entry_depth;
  DBusValidity result;

  int element_count;
  DBusList *element_count_stack;

  result = DBUS_VALID;
  element_count_stack = NULL;

  if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
    {
      result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
      goto out;
    }

  _dbus_assert (type_str != NULL);
  _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
  _dbus_assert (len >= 0);
  _dbus_assert (type_pos >= 0);

  if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
    {
      result = DBUS_INVALID_SIGNATURE_TOO_LONG;
      goto out;
    }

  p = _dbus_string_get_const_data_len (type_str, type_pos, 0);

  end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
  struct_depth = 0;
  array_depth = 0;
  dict_entry_depth = 0;
  last = DBUS_TYPE_INVALID;

  while (p != end)
    {
      switch (*p)
        {
        case DBUS_TYPE_BYTE:
        case DBUS_TYPE_BOOLEAN:
        case DBUS_TYPE_INT16:
        case DBUS_TYPE_UINT16:
        case DBUS_TYPE_INT32:
        case DBUS_TYPE_UINT32:
        case DBUS_TYPE_INT64:
        case DBUS_TYPE_UINT64:
        case DBUS_TYPE_DOUBLE:
        case DBUS_TYPE_STRING:
        case DBUS_TYPE_OBJECT_PATH:
        case DBUS_TYPE_SIGNATURE:
        case DBUS_TYPE_VARIANT:
          break;

        case DBUS_TYPE_ARRAY:
          array_depth += 1;
          if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
              goto out;
            }
          break;

        case DBUS_STRUCT_BEGIN_CHAR:
          struct_depth += 1;

          if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
              goto out;
            }
          
          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (0)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }

          break;

        case DBUS_STRUCT_END_CHAR:
          if (struct_depth == 0)
            {
              result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
              goto out;
            }

          if (last == DBUS_STRUCT_BEGIN_CHAR)
            {
              result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
              goto out;
            }

          _dbus_list_pop_last (&element_count_stack);

          struct_depth -= 1;
          break;

        case DBUS_DICT_ENTRY_BEGIN_CHAR:
          if (last != DBUS_TYPE_ARRAY)
            {
              result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
              goto out;
            }
            
          dict_entry_depth += 1;

          if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
            {
              result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
              goto out;
            }

          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (0)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }

          break;

        case DBUS_DICT_ENTRY_END_CHAR:
          if (dict_entry_depth == 0)
            {
              result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
              goto out;
            }
            
          dict_entry_depth -= 1;

          element_count = 
            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));

          if (element_count != 2)
            {
              if (element_count == 0)
                result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
              else if (element_count == 1)
                result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
              else
                result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
              
              goto out;
            }
          break;
          
        case DBUS_TYPE_STRUCT:     /* doesn't appear in signatures */
        case DBUS_TYPE_DICT_ENTRY: /* ditto */
        default:
          result = DBUS_INVALID_UNKNOWN_TYPECODE;
	  goto out;
        }

      if (*p != DBUS_TYPE_ARRAY && 
          *p != DBUS_DICT_ENTRY_BEGIN_CHAR && 
	  *p != DBUS_STRUCT_BEGIN_CHAR) 
        {
          element_count = 
            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));

          ++element_count;

          if (!_dbus_list_append (&element_count_stack, 
                             _DBUS_INT_TO_POINTER (element_count)))
            {
              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
              goto out;
            }
        }
      
      if (array_depth > 0)
        {
          if (*p == DBUS_TYPE_ARRAY && p != end)
            {
	       const char *p1;
	       p1 = p + 1;
               if (*p1 == DBUS_STRUCT_END_CHAR ||
                   *p1 == DBUS_DICT_ENTRY_END_CHAR)
                 {
                   result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
                   goto out;
                 }
            }
          else
	    {
              array_depth = 0;
	    }
        }

      if (last == DBUS_DICT_ENTRY_BEGIN_CHAR &&
          !dbus_type_is_basic (*p))
        {
          result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
          goto out;
        }
        
      last = *p;
      ++p;
    }


  if (array_depth > 0)
    {
      result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
      goto out;
    }
    
  if (struct_depth > 0)
    {
       result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
       goto out;
    }
    
  if (dict_entry_depth > 0)
    {
      result =  DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
      goto out;
    }
    
  _dbus_assert (last != DBUS_TYPE_ARRAY);
  _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
  _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);

  result = DBUS_VALID;

out:
  _dbus_list_clear (&element_count_stack);
  return result;
}
Example #22
0
gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
				const char *name, int type, const void *value,
				size_t size, GDBusResultFunction function,
				void *user_data, GDBusDestroyFunction destroy)
{
	struct set_property_data *data;
	GDBusClient *client;
	DBusMessage *msg;
	DBusMessageIter iter, variant, array;
	DBusPendingCall *call;
	char array_sig[3];
	char type_sig[2];

	if (!proxy || !name || !value)
		return FALSE;

	if (!dbus_type_is_basic(type))
		return FALSE;

	client = proxy->client;
	if (!client)
		return FALSE;

	data = g_try_new0(struct set_property_data, 1);
	if (!data)
		return FALSE;

	data->function = function;
	data->user_data = user_data;
	data->destroy = destroy;

	msg = dbus_message_new_method_call(client->service_name,
						proxy->obj_path,
						DBUS_INTERFACE_PROPERTIES,
						"Set");
	if (!msg) {
		g_free(data);
		return FALSE;
	}

	array_sig[0] = DBUS_TYPE_ARRAY;
	array_sig[1] = (char) type;
	array_sig[2] = '\0';

	type_sig[0] = (char) type;
	type_sig[1] = '\0';

	dbus_message_iter_init_append(msg, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
							&proxy->interface);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
							array_sig, &variant);

	dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
							type_sig, &array);

	if (dbus_type_is_fixed(type))
		dbus_message_iter_append_fixed_array(&array, type, &value,
									size);
	else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
		const char **str = (const char **) value;
		size_t i;

		for (i = 0; i < size; i++)
			dbus_message_iter_append_basic(&array, type, &str[i]);
	}

	dbus_message_iter_close_container(&variant, &array);
	dbus_message_iter_close_container(&iter, &variant);

	if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		g_free(data);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, set_property_reply, data, g_free);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}
Example #23
0
gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
				const char *name, int type, const void *value,
				GDBusResultFunction function, void *user_data,
				GDBusDestroyFunction destroy)
{
	struct set_property_data *data;
	GDBusClient *client;
	DBusMessage *msg;
	DBusMessageIter iter, variant;
	DBusPendingCall *call;
	char type_as_str[2];

	if (proxy == NULL || name == NULL || value == NULL)
		return FALSE;

	if (dbus_type_is_basic(type) == FALSE)
		return FALSE;

	client = proxy->client;
	if (client == NULL)
		return FALSE;

	data = g_try_new0(struct set_property_data, 1);
	if (data == NULL)
		return FALSE;

	data->function = function;
	data->user_data = user_data;
	data->destroy = destroy;

	msg = dbus_message_new_method_call(client->service_name,
			proxy->obj_path, DBUS_INTERFACE_PROPERTIES, "Set");
	if (msg == NULL) {
		g_free(data);
		return FALSE;
	}

	type_as_str[0] = (char) type;
	type_as_str[1] = '\0';

	dbus_message_iter_init_append(msg, &iter);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
							&proxy->interface);
	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
						type_as_str, &variant);
	dbus_message_iter_append_basic(&variant, type, value);
	dbus_message_iter_close_container(&iter, &variant);

	if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
							&call, -1) == FALSE) {
		dbus_message_unref(msg);
		g_free(data);
		return FALSE;
	}

	dbus_pending_call_set_notify(call, set_property_reply, data, g_free);
	dbus_pending_call_unref(call);

	dbus_message_unref(msg);

	return TRUE;
}