Exemplo n.º 1
0
static bool jobject_to_string_append (jvalue_ref jref, JStreamRef generating)
{
	SANITY_CHECK_POINTER(jref);

	if (UNLIKELY(!generating->o_begin (generating))) {
		PJ_LOG_ERR("Schema validation error, objects are not allowed.");
		return false;
	}
	if (!jis_object (jref)) {
		const char *asStr = jvalue_tostring_internal_layer2 (jref, NULL, false);
		generating->string (generating, J_CSTR_TO_BUF("Internal error - not an object"));
		generating->string (generating, j_cstr_to_buffer(asStr));
		// create invalid JSON on purpose
		return false;
	}

	jobject_iter it;
	jobject_iter_init(&it, jref);
	jobject_key_value key_value;
	while (jobject_iter_next(&it, &key_value))
	{
		assert(jis_string(key_value.key));
		if(UNLIKELY(!key_value_to_string_append(key_value, generating)))
		{
			return false;
		}
	}

	if (UNLIKELY(!generating->o_end (generating))) {
		PJ_LOG_ERR("Schema validation error, object did not validate against schema");
		return false;
	}

	return true;
}
Exemplo n.º 2
0
bool luna_service_message_validate_and_send(LSHandle *handle, LSMessage *message, jvalue_ref reply_obj)
{
	jschema_ref response_schema = NULL;
	LSError lserror;
	bool success = true;

	LSErrorInit(&lserror);

	response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!response_schema) {
		luna_service_message_reply_error_internal(handle, message);
		return false;
	}

	if (!LSMessageReply(handle, message,
					jvalue_tostring(reply_obj, response_schema), &lserror)) {
		LSErrorPrint(&lserror, stderr);
		LSErrorFree(&lserror);
		success = false;
	}

	jschema_release(&response_schema);

	return success;
}
Exemplo n.º 3
0
jvalue_ref luna_service_message_parse_and_validate(const char *payload)
{
	jschema_ref input_schema = NULL;
	jvalue_ref parsed_obj = NULL;
	JSchemaInfo schema_info;

	input_schema = jschema_parse(j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	jschema_info_init(&schema_info, input_schema, NULL, NULL);

	parsed_obj = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT, &schema_info);

	jschema_release(&input_schema);
	if (jis_null(parsed_obj))
		return NULL;

	return parsed_obj;
}
Exemplo n.º 4
0
/**
* @brief If message contains subscribe:true, add the message
         to subscription list using the default key '/category/method'.
*
*        This is equivalent to LSSubscriptionAdd(sh, key, message, lserror)
*        where the key is LSMessageGetKind(message).
*
* @param  sh
* @param  message
* @param  subscribed
* @param  lserror
*
* @retval
*/
bool
LSSubscriptionProcess (LSHandle *sh, LSMessage *message, bool *subscribed,
                       LSError *lserror)
{
    JSchemaInfo schemaInfo;
    jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL);

    bool retVal = false;
    bool subscribePayload = false;
    jvalue_ref subObj = NULL;

    const char *payload = LSMessageGetPayload(message);
    jvalue_ref object = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT,
                                   &schemaInfo);

    if (jis_null(object))
    {
        _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -1, "Unable to parse JSON: %s", payload);
        goto exit;
    }

    if (!jobject_get_exists(object, J_CSTR_TO_BUF("subscribe"), &subObj) ||
            subObj == NULL || !jis_boolean(subObj))
    {
        subscribePayload = false;
        /* FIXME: I think retVal should be false, but I don't know if anyone
         * is relying on this behavior. If set to false, make sure to set
         * LSError */
        retVal = true;
    }
    else
    {
        (void)jboolean_get(subObj, &subscribePayload);/* TODO: handle appropriately */
        retVal = true;
    }

    if (subscribePayload)
    {
        const char *key = LSMessageGetKind(message);
        retVal = LSSubscriptionAdd(sh, key, message, lserror);
    }

    if (retVal && subscribePayload)
    {
        *subscribed = true;
    }
    else
    {
        *subscribed = false;
    }

exit:
    j_release(&object);

    return retVal;
}
static bool handle_get_info_command(LSHandle *sh, LSMessage *message, void* context)
{
	jvalue_ref reply = jobject_create();
	LSError lserror;
	LSErrorInit(&lserror);
	char wifi_mac_address[32]={0}, wired_mac_address[32]={0};

	jobject_put(reply, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true));

	if(get_wifi_mac_address(CONNMAN_WIFI_INTERFACE_NAME, wifi_mac_address) == 0)
	{
		jvalue_ref wifi_info = jobject_create();
		jobject_put(wifi_info, J_CSTR_TO_JVAL("macAddress"),jstring_create(wifi_mac_address));
		jobject_put(reply, J_CSTR_TO_JVAL("wifiInfo"), wifi_info);
	}
	else
		WCA_LOG_ERROR("Error in fetching mac address for wifi interface");


	if(get_wifi_mac_address(CONNMAN_WIRED_INTERFACE_NAME, wired_mac_address) == 0)
	{
		jvalue_ref wired_info = jobject_create();
		jobject_put(wired_info, J_CSTR_TO_JVAL("macAddress"),jstring_create(wired_mac_address));
		jobject_put(reply, J_CSTR_TO_JVAL("wiredInfo"), wired_info);
	}
	else
		WCA_LOG_ERROR("Error in fetching mac address for wired interface");

	jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!response_schema)
	{
		LSMessageReplyErrorUnknown(sh,message);
		goto cleanup;
	}

	if (!LSMessageReply(sh, message, jvalue_tostring(reply, response_schema), &lserror))
	{
		LSErrorPrint(&lserror, stderr);
		LSErrorFree(&lserror);
	}

	jschema_release(&response_schema);

cleanup:
	if (LSErrorIsSet(&lserror))
	{
		LSErrorPrint(&lserror, stderr);
		LSErrorFree(&lserror);
	}

	j_release(&reply);
	return true;
}
Exemplo n.º 6
0
bool
_CatalogHandleCancel(_Catalog *catalog, LSMessage *cancelMsg,
                     LSError *lserror)
{
    JSchemaInfo schemaInfo;
    jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL);

    const char *sender;
    int token;
    jvalue_ref tokenObj = NULL;

    const char *payload = LSMessageGetPayload(cancelMsg);

    jvalue_ref object = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT,
                                   &schemaInfo);
    if (jis_null(object))
    {
        _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json");
        goto error;
    }

    sender = LSMessageGetSender(cancelMsg);

    if (!jobject_get_exists(object, J_CSTR_TO_BUF("token"), &tokenObj) ||
            tokenObj == NULL || !jis_number(tokenObj))
    {
        _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json");
        goto error;
    }

    (void)jnumber_get_i32(tokenObj, &token);/* TODO: handle appropriately */

    char *uniqueToken = g_strdup_printf("%s.%d", sender, token);

    _CatalogCallCancelNotifications(catalog, uniqueToken);
    _CatalogRemoveToken(catalog, uniqueToken, true);

    g_free(uniqueToken);
    j_release(&object);
    return true;

error:
    j_release(&object);
    return false;
}
static bool handle_get_status_command(LSHandle* sh, LSMessage *message, void* context)
{

	jvalue_ref reply = jobject_create();
	LSError lserror;
	LSErrorInit(&lserror);
	bool subscribed = false;

	if (LSMessageIsSubscription(message))
	{
		if (!LSSubscriptionProcess(sh, message, &subscribed, &lserror))
		{
			LSErrorPrint(&lserror, stderr);
			LSErrorFree(&lserror);
		}
		jobject_put(reply, J_CSTR_TO_JVAL("subscribed"), jboolean_create(subscribed));
		if(!connman_manager_is_manager_available(manager))
			goto response;
	}
	if(!connman_status_check(manager, sh, message))
		goto cleanup;

	send_connection_status(&reply);

response:
	{
		jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
		if(!response_schema)
		{
			LSMessageReplyErrorUnknown(sh,message);
			goto cleanup;
		}
		if (!LSMessageReply(sh, message, jvalue_tostring(reply, response_schema), &lserror)) {
			LSErrorPrint(&lserror, stderr);
			LSErrorFree(&lserror);
		}
		jschema_release(&response_schema);
	}
cleanup:
	j_release(&reply);
	return true;
}
Exemplo n.º 8
0
/**
 *******************************************************************************
 * @brief Get the service name from a "ServceStatus" message. The name is
 * allocated and should be freed.
 *
 * @param  message  IN  message
 *
 * @retval name string on success
 * @retval NULL on error
 *******************************************************************************
 */
char*
LSTransportServiceStatusSignalGetServiceName(_LSTransportMessage *message)
{
    JSchemaInfo schemaInfo;
    jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL);

    LS_ASSERT(_LSTransportMessageGetType(message) == _LSTransportMessageTypeServiceDownSignal
              || _LSTransportMessageGetType(message) == _LSTransportMessageTypeServiceUpSignal);

    char *service_name = NULL;
    jvalue_ref service_name_obj = NULL;
    const char *payload = _LSTransportMessageGetPayload(message);

    if (!payload)
    {
        LOG_LS_ERROR(MSGID_LS_INVALID_JSON, 0, "Unable to get payload from message");
        return NULL;
    }

    /* get the serviceName part of the JSON object */
    jvalue_ref payload_json = jdom_parse(j_cstr_to_buffer(payload),
                                         DOMOPT_NOOPT, &schemaInfo);

    bool ret = jobject_get_exists(payload_json,
                                  J_CSTR_TO_BUF(SERVICE_STATUS_SERVICE_NAME),
                                  &service_name_obj);

    if (ret)
    {
        raw_buffer service_name_buf = jstring_get_fast(service_name_obj);
        service_name = g_strndup(service_name_buf.m_str, service_name_buf.m_len);
    }
    else
    {
        LOG_LS_ERROR(MSGID_LS_INVALID_JSON, 0, "Unable to get service name string from payload: %s", payload);
    }

    j_release(&payload_json);

    return service_name;
}
Exemplo n.º 9
0
void luna_service_post_subscription(LSHandle *handle, const char *path, const char *method, jvalue_ref reply_obj)
{
	jschema_ref response_schema = NULL;
	LSError lserror;

	LSErrorInit(&lserror);

	response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!response_schema)
		goto cleanup;

	if (!LSSubscriptionPost(handle, path, method,
						jvalue_tostring(reply_obj, response_schema), &lserror)) {
		LSErrorPrint(&lserror, stderr);
		LSErrorFree(&lserror);
	}

cleanup:
	if (response_schema)
		jschema_release(&response_schema);
}
void connectionmanager_send_status(void)
{
	jvalue_ref reply = jobject_create();
	jobject_put(reply, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true));

	send_connection_status(&reply);

	jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(response_schema)
	{
		const char *payload = jvalue_tostring(reply, response_schema);
		LSError lserror;
		LSErrorInit(&lserror);
		WCA_LOG_INFO("Sending payload %s",payload);
		if (!LSSubscriptionPost(pLsHandle, "/", "getstatus", payload, &lserror))
		{
			LSErrorPrint(&lserror, stderr);
			LSErrorFree(&lserror);
		}
		jschema_release(&response_schema);
	}
	j_release(&reply);
}
static bool handle_set_state_command(LSHandle *sh, LSMessage *message, void* context)
{
	if(!connman_status_check(manager, sh, message))
		return true;

	jvalue_ref parsedObj = {0};
	jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!input_schema)
		return false;

	JSchemaInfo schemaInfo;
	jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers
	parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo);
	jschema_release(&input_schema);

	if (jis_null(parsedObj))
	{
		LSMessageReplyErrorBadJSON(sh, message);
		return true;
	}

	jvalue_ref wifiObj = {0}, wiredObj = {0};
	gboolean enable_wifi = FALSE, enable_wired = FALSE;
	gboolean invalidArg = TRUE;

	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("wifi"), &wifiObj))
	{
		if (jstring_equal2(wifiObj, J_CSTR_TO_BUF("enabled")))
		{
			enable_wifi = TRUE;
		}
		else if (jstring_equal2(wifiObj, J_CSTR_TO_BUF("disabled")))
		{
			enable_wifi = FALSE;
		}
		else
		{
			goto invalid_params;
		}
		/*
		 *  Check if we are enabling an already enabled service,
		 *  or disabling an already disabled service
		 */

		if((enable_wifi && is_wifi_powered()) || (!enable_wifi && !is_wifi_powered()))
		{
			WCA_LOG_DEBUG("Wifi technology already enabled/disabled");
		}
		else
		{
			set_wifi_state(enable_wifi);
		}
		invalidArg = FALSE;
	}

	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("wired"), &wiredObj))
	{
		if (jstring_equal2(wiredObj, J_CSTR_TO_BUF("enabled")))
		{
			enable_wired = TRUE;
		}
		else if (jstring_equal2(wiredObj, J_CSTR_TO_BUF("disabled")))
		{
			enable_wired = FALSE;
		}
		else
		{
			goto invalid_params;
		}
		/*
		 *  Check if we are enabling an already enabled service,
		 *  or disabling an already disabled service
		 */
		if((enable_wired && is_ethernet_powered()) || (!enable_wired && !is_ethernet_powered()))
		{
			WCA_LOG_DEBUG("Wired technology already enabled/disabled");
		}
		else
		{
			set_ethernet_state(enable_wired);
		}
		invalidArg = FALSE;
	}
	if(invalidArg == TRUE)
	{
		goto invalid_params;
	}

	LSMessageReplySuccess(sh,message);
	goto cleanup;

invalid_params:
	LSMessageReplyErrorInvalidParams(sh, message);
cleanup:
	j_release(&parsedObj);
	return true;

}
static bool handle_set_dns_command(LSHandle *sh, LSMessage *message, void* context)
{
	if(!connman_status_check(manager, sh, message))
		return true;

	jvalue_ref parsedObj = {0};
	jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!input_schema)
		return false;

	JSchemaInfo schemaInfo;
	jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers
	parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo);
	jschema_release(&input_schema);

	if (jis_null(parsedObj))
	{
		LSMessageReplyErrorBadJSON(sh, message);
		return true;
	}

	jvalue_ref ssidObj = {0}, dnsObj = {0};
	GStrv dns = NULL;
	gchar *ssid = NULL;

	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("dns"), &dnsObj))
	{
		int i, dns_arrsize = jarray_size(dnsObj);
		dns = (GStrv) g_new0(GStrv, 1);
		for(i = 0; i < dns_arrsize; i++)
		{
			raw_buffer dns_buf = jstring_get(jarray_get(dnsObj, i));
			dns[i] = g_strdup(dns_buf.m_str);
			jstring_free_buffer(dns_buf);
		}
	}
	else
	{
		LSMessageReplyErrorInvalidParams(sh, message);
		goto Exit;
	}

	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("ssid"), &ssidObj))
	{
		raw_buffer ssid_buf = jstring_get(ssidObj);
		ssid = g_strdup(ssid_buf.m_str);
		jstring_free_buffer(ssid_buf);
	}

	connman_service_t *service = get_connman_service(ssid);
	if(NULL != service)
	{
		if(connman_service_set_nameservers(service, dns))
			LSMessageReplySuccess(sh, message);
		else
			LSMessageReplyErrorUnknown(sh, message);
		goto Exit;
	}
	else
		LSMessageReplyCustomError(sh, message, "No connected network");
Exit:
	g_strfreev(dns);
	g_free(ssid);
	j_release(&parsedObj);
	return true;
}
static bool handle_set_ipv4_command(LSHandle *sh, LSMessage *message, void* context)
{
	if(!connman_status_check(manager, sh, message))
		return true;

	jvalue_ref parsedObj = {0};
	jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL);
	if(!input_schema)
	return false;

	JSchemaInfo schemaInfo;
	jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers
	parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo);
	jschema_release(&input_schema);

	if (jis_null(parsedObj))
	{
		LSMessageReplyErrorBadJSON(sh, message);
		return true;
	}

	jvalue_ref ssidObj = {0}, methodObj = {0}, addressObj = {0}, netmaskObj = {0}, gatewayObj = {0};
	ipv4info_t ipv4 = {0};
	gchar *ssid = NULL;
	gboolean invalidArg = TRUE;

	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("method"), &methodObj))
	{
		raw_buffer method_buf = jstring_get(methodObj);
		ipv4.method = g_strdup(method_buf.m_str);
		jstring_free_buffer(method_buf);
		invalidArg = FALSE;
	}
	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("address"), &addressObj))
	{
		raw_buffer address_buf = jstring_get(addressObj);
		ipv4.address = g_strdup(address_buf.m_str);
		jstring_free_buffer(address_buf);
		invalidArg = FALSE;
	}
	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("netmask"), &netmaskObj))
	{
		raw_buffer netmask_buf = jstring_get(netmaskObj);
		ipv4.netmask = g_strdup(netmask_buf.m_str);
		jstring_free_buffer(netmask_buf);
		invalidArg = FALSE;
	}
	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("gateway"), &gatewayObj))
	{
		raw_buffer gateway_buf = jstring_get(gatewayObj);
		ipv4.gateway = g_strdup(gateway_buf.m_str);
		jstring_free_buffer(gateway_buf);
		invalidArg = FALSE;
	}
	if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("ssid"), &ssidObj))
	{
		raw_buffer ssid_buf = jstring_get(ssidObj);
		ssid = g_strdup(ssid_buf.m_str);
		jstring_free_buffer(ssid_buf);
		invalidArg = FALSE;
	}
	if(invalidArg == TRUE)
	{
		LSMessageReplyErrorInvalidParams(sh, message);
		goto Exit;
	}

	connman_service_t *service = get_connman_service(ssid);
	if(NULL != service)
	{
		if(connman_service_set_ipv4(service, &ipv4))
			LSMessageReplySuccess(sh, message);
		else
			LSMessageReplyErrorUnknown(sh, message);
		goto Exit;
	}
	else
	{
		LSMessageReplyCustomError(sh, message, "Network not found");
	}

Exit:
	g_free(ipv4.method);
	g_free(ipv4.address);
	g_free(ipv4.netmask);
	g_free(ipv4.gateway);
	g_free(ssid);
	j_release(&parsedObj);
	return true;
}
Exemplo n.º 14
0
bool
_LSSubscriptionGetJson(LSHandle *sh, jvalue_ref *ret_obj, LSError *lserror)
{
    _Catalog *catalog = sh->catalog;
    const char *key = NULL;
    _SubList *sub_list = NULL;
    GHashTableIter iter;

    jvalue_ref true_obj = NULL;
    jvalue_ref array = NULL;
    jvalue_ref cur_obj = NULL;
    jvalue_ref sub_array = NULL;
    jvalue_ref key_name = NULL;
    jvalue_ref message_obj = NULL;
    jvalue_ref sub_array_item = NULL;
    jvalue_ref unique_name_obj = NULL;
    jvalue_ref service_name_obj = NULL;

    *ret_obj = jobject_create();
    if (*ret_obj == NULL) goto error;

    true_obj = jboolean_create(true);
    if (true_obj == NULL) goto error;

    array = jarray_create(NULL);
    if (array == NULL) goto error;

    /* returnValue: true,
     * subscriptions: [
     *  { key: key_name, subscribers: [{unique_name: , service_name: }, ...] },
     *  ...
     * ]
     */
    _CatalogLock(catalog);

    g_hash_table_iter_init(&iter, catalog->subscription_lists);

    while (g_hash_table_iter_next(&iter, (gpointer)&key, (gpointer)&sub_list))
    {
        cur_obj = jobject_create();
        if (cur_obj == NULL) goto error;

        sub_array = jarray_create(NULL);
        if (sub_array == NULL) goto error;

        key_name = jstring_create_copy(j_cstr_to_buffer(key));
        if (key_name == NULL) goto error;

        /* iterate over SubList */
        int i = 0;
        const char *token = NULL;
        const int len = _SubListLen(sub_list);
        for (i = 0; i < len; i++)
        {
            token = _SubListGet(sub_list, i);

            if (token)
            {
                _Subscription *sub = g_hash_table_lookup(catalog->token_map, token);

                if (!sub) continue;

                LSMessage *msg = sub->message;
                const char *unique_name = LSMessageGetSender(msg);
                const char *service_name = LSMessageGetSenderServiceName(msg);
                const char *message_body = LSMessageGetPayload(msg);

                /* create subscribers item and add to sub_array */
                sub_array_item = jobject_create();
                if (sub_array_item == NULL) goto error;

                unique_name_obj = unique_name ? jstring_create_copy(j_cstr_to_buffer(unique_name))
                                  : jstring_empty();
                if (unique_name_obj == NULL) goto error;

                service_name_obj = service_name ? jstring_create_copy(j_cstr_to_buffer(service_name))
                                   : jstring_empty();
                if (service_name_obj == NULL) goto error;

                message_obj = message_body ? jstring_create_copy(j_cstr_to_buffer(message_body))
                              : jstring_empty();
                if (message_obj == NULL) goto error;

                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("unique_name"),
                            unique_name_obj);
                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("service_name"),
                            service_name_obj);
                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("subscription_message"),
                            message_obj);
                jarray_append(sub_array, sub_array_item);

                sub_array_item = NULL;
                unique_name_obj = NULL;
                service_name_obj = NULL;
                message_obj = NULL;
            }
        }
        jobject_put(cur_obj, J_CSTR_TO_JVAL("key"),
                    key_name);
        jobject_put(cur_obj,
                    J_CSTR_TO_JVAL("subscribers"),
                    sub_array);
        jarray_append(array, cur_obj);
        key_name = NULL;
        cur_obj = NULL;
        sub_array = NULL;
    }

    jobject_put(*ret_obj,
                J_CSTR_TO_JVAL("returnValue"),
                true_obj);
    jobject_put(*ret_obj,
                J_CSTR_TO_JVAL("subscriptions"), array);

    _CatalogUnlock(catalog);

    return true;

error:
    _CatalogUnlock(catalog);

    j_release(ret_obj);
    j_release(&true_obj);
    j_release(&array);

    j_release(&cur_obj);
    j_release(&sub_array);
    j_release(&key_name);

    j_release(&sub_array_item);
    j_release(&unique_name_obj);
    j_release(&service_name_obj);

    return false;
}