1 /* 2 * Copyright (C) 2011 Felix Fietkau <nbd@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2.1 6 * as published by the Free Software Foundation 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #include <sys/time.h> 15 #include <unistd.h> 16 17 #include <libubox/ustream.h> 18 19 #include "libubus.h" 20 #include "count.h" 21 22 static struct ubus_context *ctx; 23 static struct blob_buf b; 24 25 static void test_client_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) 26 { 27 fprintf(stderr, "Subscribers active: %d\n", obj->has_subscribers); 28 } 29 30 static struct ubus_object test_client_object = { 31 .subscribe_cb = test_client_subscribe_cb, 32 }; 33 34 static void test_client_notify_cb(struct uloop_timeout *timeout) 35 { 36 static int counter = 0; 37 int err; 38 struct timeval tv1, tv2; 39 int max = 1000; 40 long delta; 41 int i = 0; 42 43 blob_buf_init(&b, 0); 44 blobmsg_add_u32(&b, "counter", counter++); 45 46 gettimeofday(&tv1, NULL); 47 for (i = 0; i < max; i++) 48 err = ubus_notify(ctx, &test_client_object, "ping", b.head, 1000); 49 gettimeofday(&tv2, NULL); 50 if (err) 51 fprintf(stderr, "Notify failed: %s\n", ubus_strerror(err)); 52 53 delta = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); 54 fprintf(stderr, "Avg time per iteration: %ld usec\n", delta / max); 55 56 uloop_timeout_set(timeout, 1000); 57 } 58 59 enum { 60 RETURN_CODE, 61 __RETURN_MAX, 62 }; 63 64 static const struct blobmsg_policy return_policy[__RETURN_MAX] = { 65 [RETURN_CODE] = { .name = "rc", .type = BLOBMSG_TYPE_INT32 }, 66 }; 67 68 static void test_count_data_cb(struct ubus_request *req, 69 int type, struct blob_attr *msg) 70 { 71 struct blob_attr *tb[__RETURN_MAX]; 72 int rc; 73 uint32_t count_to = *(uint32_t *)req->priv; 74 75 blobmsg_parse(return_policy, __RETURN_MAX, tb, blob_data(msg), blob_len(msg)); 76 77 if (!tb[RETURN_CODE]) { 78 fprintf(stderr, "No return code received from server\n"); 79 return; 80 } 81 rc = blobmsg_get_u32(tb[RETURN_CODE]); 82 if (rc) 83 fprintf(stderr, "Corruption of data with count up to '%u'\n", count_to); 84 else 85 fprintf(stderr, "Server validated our count up to '%u'\n", count_to); 86 } 87 88 static void test_count(struct uloop_timeout *timeout) 89 { 90 enum { 91 COUNT_TO_MIN = 10000, 92 COUNT_TO_MAX = 1000000, 93 PROGRESSION = 100, 94 }; 95 96 uint32_t id; 97 static uint32_t count_to = 100000; 98 static int count_progression = PROGRESSION; 99 char *s; 100 101 if (count_to <= COUNT_TO_MIN) 102 count_progression = PROGRESSION; 103 else if (count_to >= COUNT_TO_MAX) 104 count_progression = -PROGRESSION; 105 106 count_to += count_progression; 107 108 s = count_to_number(count_to); 109 if (!s) { 110 fprintf(stderr, "Could not allocate memory to count up to '%u'\n", count_to); 111 return; 112 } 113 114 fprintf(stderr, "Sending count up to '%u'; string has length '%u'\n", 115 count_to, (uint32_t)strlen(s)); 116 blob_buf_init(&b, 0); 117 blobmsg_add_u32(&b, "to", count_to); 118 blobmsg_add_string(&b, "string", s); 119 120 if (ubus_lookup_id(ctx, "test", &id)) { 121 free(s); 122 fprintf(stderr, "Failed to look up test object\n"); 123 return; 124 } 125 126 ubus_invoke(ctx, id, "count", b.head, test_count_data_cb, &count_to, 5000); 127 128 free(s); 129 130 uloop_timeout_set(timeout, 2000); 131 } 132 133 static struct uloop_timeout notify_timer = { 134 .cb = test_client_notify_cb, 135 }; 136 137 static struct uloop_timeout count_timer = { 138 .cb = test_count, 139 }; 140 141 static void test_client_fd_data_cb(struct ustream *s, int bytes) 142 { 143 char *data, *sep; 144 int len; 145 146 data = ustream_get_read_buf(s, &len); 147 if (len < 1) 148 return; 149 150 sep = strchr(data, '\n'); 151 if (!sep) 152 return; 153 154 *sep = 0; 155 fprintf(stderr, "Got line: %s\n", data); 156 ustream_consume(s, sep + 1 - data); 157 } 158 159 static void test_client_fd_cb(struct ubus_request *req, int fd) 160 { 161 static struct ustream_fd test_fd; 162 163 fprintf(stderr, "Got fd from the server, watching...\n"); 164 165 test_fd.stream.notify_read = test_client_fd_data_cb; 166 ustream_fd_init(&test_fd, fd); 167 } 168 169 static void test_client_complete_cb(struct ubus_request *req, int ret) 170 { 171 fprintf(stderr, "completed request, ret: %d\n", ret); 172 } 173 174 static void client_main(void) 175 { 176 static struct ubus_request req; 177 uint32_t id; 178 int ret; 179 180 ret = ubus_add_object(ctx, &test_client_object); 181 if (ret) { 182 fprintf(stderr, "Failed to add_object object: %s\n", ubus_strerror(ret)); 183 return; 184 } 185 186 if (ubus_lookup_id(ctx, "test", &id)) { 187 fprintf(stderr, "Failed to look up test object\n"); 188 return; 189 } 190 191 blob_buf_init(&b, 0); 192 blobmsg_add_u32(&b, "id", test_client_object.id); 193 ubus_invoke(ctx, id, "watch", b.head, NULL, 0, 3000); 194 test_client_notify_cb(¬ify_timer); 195 196 blob_buf_init(&b, 0); 197 blobmsg_add_string(&b, "msg", "blah"); 198 ubus_invoke_async(ctx, id, "hello", b.head, &req); 199 req.fd_cb = test_client_fd_cb; 200 req.complete_cb = test_client_complete_cb; 201 ubus_complete_request_async(ctx, &req); 202 203 uloop_timeout_set(&count_timer, 2000); 204 205 uloop_run(); 206 } 207 208 int main(int argc, char **argv) 209 { 210 const char *ubus_socket = NULL; 211 int ch; 212 213 while ((ch = getopt(argc, argv, "cs:")) != -1) { 214 switch (ch) { 215 case 's': 216 ubus_socket = optarg; 217 break; 218 default: 219 break; 220 } 221 } 222 223 uloop_init(); 224 225 ctx = ubus_connect(ubus_socket); 226 if (!ctx) { 227 fprintf(stderr, "Failed to connect to ubus\n"); 228 return -1; 229 } 230 231 ubus_add_uloop(ctx); 232 233 client_main(); 234 235 ubus_free(ctx); 236 uloop_done(); 237 238 return 0; 239 } 240
This page was automatically generated by LXR 0.3.1. • OpenWrt