INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/..)
IF (BUILD_EXAMPLES)
- ADD_EXECUTABLE(server server.c)
+ ADD_EXECUTABLE(server server.c count.c)
TARGET_LINK_LIBRARIES(server ubus ubox blobmsg_json)
- ADD_EXECUTABLE(client client.c)
+ ADD_EXECUTABLE(client client.c count.c)
TARGET_LINK_LIBRARIES(client ubus ubox)
ENDIF()
#include <libubox/ustream.h>
#include "libubus.h"
+#include "count.h"
static struct ubus_context *ctx;
static struct blob_buf b;
uloop_timeout_set(timeout, 1000);
}
+enum {
+ RETURN_CODE,
+ __RETURN_MAX,
+};
+
+static const struct blobmsg_policy return_policy[__RETURN_MAX] = {
+ [RETURN_CODE] = { .name = "rc", .type = BLOBMSG_TYPE_INT32 },
+};
+
+static void test_count_data_cb(struct ubus_request *req,
+ int type, struct blob_attr *msg)
+{
+ struct blob_attr *tb[__RETURN_MAX];
+ int rc;
+ uint32_t count_to = *(uint32_t *)req->priv;
+
+ blobmsg_parse(return_policy, __RETURN_MAX, tb, blob_data(msg), blob_len(msg));
+
+ if (!tb[RETURN_CODE]) {
+ fprintf(stderr, "No return code received from server\n");
+ return;
+ }
+ rc = blobmsg_get_u32(tb[RETURN_CODE]);
+ if (rc)
+ fprintf(stderr, "Corruption of data with count up to '%u'\n", count_to);
+ else
+ fprintf(stderr, "Server validated our count up to '%u'\n", count_to);
+}
+
+static void test_count(struct uloop_timeout *timeout)
+{
+ enum {
+ COUNT_TO_MIN = 10000,
+ COUNT_TO_MAX = 1000000,
+ PROGRESSION = 100,
+ };
+
+ uint32_t id;
+ static uint32_t count_to = 100000;
+ static int count_progression = PROGRESSION;
+ char *s;
+
+ if (count_to <= COUNT_TO_MIN)
+ count_progression = PROGRESSION;
+ else if (count_to >= COUNT_TO_MAX)
+ count_progression = -PROGRESSION;
+
+ count_to += count_progression;
+
+ s = count_to_number(count_to);
+ if (!s)
+ fprintf(stderr, "Could not allocate memory to count up to '%u'\n", count_to);
+
+ fprintf(stderr, "Sending count up to '%u'; string has length '%u'\n",
+ count_to, (uint32_t)strlen(s));
+ blob_buf_init(&b, 0);
+ blobmsg_add_u32(&b, "to", count_to);
+ blobmsg_add_string(&b, "string", s);
+
+ if (ubus_lookup_id(ctx, "test", &id)) {
+ fprintf(stderr, "Failed to look up test object\n");
+ return;
+ }
+
+ ubus_invoke(ctx, id, "count", b.head, test_count_data_cb, &count_to, 5000);
+
+ free(s);
+
+ uloop_timeout_set(timeout, 2000);
+}
+
static struct uloop_timeout notify_timer = {
.cb = test_client_notify_cb,
};
+static struct uloop_timeout count_timer = {
+ .cb = test_count,
+};
+
static void test_client_fd_data_cb(struct ustream *s, int bytes)
{
char *data, *sep;
req.complete_cb = test_client_complete_cb;
ubus_complete_request_async(ctx, &req);
+ uloop_timeout_set(&count_timer, 2000);
+
uloop_run();
}
--- /dev/null
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "count.h"
+
+char *count_to_number(uint32_t num)
+{
+ uint32_t ptr = 0, size = 0;
+ uint32_t written = 0, i;
+ int new_line_every_n_numbers = 30;
+ char *s;
+
+ for (i=0; i < num; ++i) {
+ size += snprintf(NULL, 0, "%u ", i);
+ if (i > 0 && i % new_line_every_n_numbers == 0)
+ size++;
+ }
+ size++; /* one for null char */
+
+ s = calloc(size, sizeof(char));
+ if (!s)
+ goto out;
+
+ for (i=0; i < num; ++i) {
+ written = sprintf(&s[ptr], "%u ", i);
+ ptr += written;
+ if (i > 0 && i % new_line_every_n_numbers == 0) {
+ sprintf(&s[ptr], "\n");
+ ptr++;
+ }
+ }
+
+out:
+ return s;
+}
--- /dev/null
+/*
+ * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __COUNT_H
+#define __COUNT_H
+
+char *count_to_number(uint32_t num);
+
+#endif
#include <libubox/blobmsg_json.h>
#include "libubus.h"
+#include "count.h"
static struct ubus_context *ctx;
static struct ubus_subscriber test_event;
return ret;
}
+enum {
+ COUNT_TO,
+ COUNT_STRING,
+ __COUNT_MAX
+};
+
+static const struct blobmsg_policy count_policy[__COUNT_MAX] = {
+ [COUNT_TO] = { .name = "to", .type = BLOBMSG_TYPE_INT32 },
+ [COUNT_STRING] = { .name = "string", .type = BLOBMSG_TYPE_STRING },
+};
+
+static int test_count(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct blob_attr *tb[__COUNT_MAX];
+ char *s1, *s2;
+ uint32_t num;
+
+ blobmsg_parse(count_policy, __COUNT_MAX, tb, blob_data(msg), blob_len(msg));
+ if (!tb[COUNT_TO] || !tb[COUNT_STRING])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ num = blobmsg_get_u32(tb[COUNT_TO]);
+ s1 = blobmsg_get_string(tb[COUNT_STRING]);
+ s2 = count_to_number(num);
+ if (!s1 || !s2) {
+ free(s2);
+ return UBUS_STATUS_UNKNOWN_ERROR;
+ }
+ blob_buf_init(&b, 0);
+ blobmsg_add_u32(&b, "rc", strcmp(s1, s2));
+ ubus_send_reply(ctx, req, b.head);
+ free(s2);
+
+ return 0;
+}
+
static const struct ubus_method test_methods[] = {
UBUS_METHOD("hello", test_hello, hello_policy),
UBUS_METHOD("watch", test_watch, watch_policy),
+ UBUS_METHOD("count", test_count, count_policy),
};
static struct ubus_object_type test_object_type =