aboutsummaryrefslogtreecommitdiff
path: root/src/psyc/psyc_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/psyc/psyc_api.c')
-rw-r--r--src/psyc/psyc_api.c414
1 files changed, 334 insertions, 80 deletions
diff --git a/src/psyc/psyc_api.c b/src/psyc/psyc_api.c
index ca25b1b01..8cce89704 100644
--- a/src/psyc/psyc_api.c
+++ b/src/psyc/psyc_api.c
@@ -43,6 +43,33 @@
43#define LOG(kind,...) GNUNET_log_from (kind, "psyc-api",__VA_ARGS__) 43#define LOG(kind,...) GNUNET_log_from (kind, "psyc-api",__VA_ARGS__)
44 44
45 45
46struct OperationListItem
47{
48 struct OperationListItem *prev;
49 struct OperationListItem *next;
50
51 /**
52 * Operation ID.
53 */
54 uint64_t op_id;
55
56 /**
57 * Continuation to invoke with the result of an operation.
58 */
59 GNUNET_PSYC_ResultCallback result_cb;
60
61 /**
62 * State variable result callback.
63 */
64 GNUNET_PSYC_StateVarCallback state_var_cb;
65
66 /**
67 * Closure for the callbacks.
68 */
69 void *cls;
70};
71
72
46/** 73/**
47 * Handle to access PSYC channel operations for both the master and slaves. 74 * Handle to access PSYC channel operations for both the master and slaves.
48 */ 75 */
@@ -84,6 +111,21 @@ struct GNUNET_PSYC_Channel
84 void *disconnect_cls; 111 void *disconnect_cls;
85 112
86 /** 113 /**
114 * First operation in the linked list.
115 */
116 struct OperationListItem *op_head;
117
118 /**
119 * Last operation in the linked list.
120 */
121 struct OperationListItem *op_tail;
122
123 /**
124 * Last operation ID used.
125 */
126 uint64_t last_op_id;
127
128 /**
87 * Are we polling for incoming messages right now? 129 * Are we polling for incoming messages right now?
88 */ 130 */
89 uint8_t in_receive; 131 uint8_t in_receive;
@@ -163,21 +205,82 @@ struct GNUNET_PSYC_SlaveTransmitHandle
163 205
164 206
165/** 207/**
166 * Handle to a story telling operation. 208 * Get a fresh operation ID to distinguish between PSYCstore requests.
209 *
210 * @param h Handle to the PSYCstore service.
211 * @return next operation id to use
167 */ 212 */
168struct GNUNET_PSYC_Story 213static uint64_t
214op_get_next_id (struct GNUNET_PSYC_Channel *chn)
169{ 215{
170 216 return ++chn->last_op_id;
171}; 217}
172 218
173 219
174/** 220/**
175 * Handle for a state query operation. 221 * Find operation by ID.
222 *
223 * @return Operation, or NULL if none found.
176 */ 224 */
177struct GNUNET_PSYC_StateQuery 225static struct OperationListItem *
226op_find_by_id (struct GNUNET_PSYC_Channel *chn, uint64_t op_id)
178{ 227{
228 struct OperationListItem *op = chn->op_head;
229 while (NULL != op)
230 {
231 if (op->op_id == op_id)
232 return op;
233 op = op->next;
234 }
235 return NULL;
236}
179 237
180}; 238
239static uint64_t
240op_add (struct GNUNET_PSYC_Channel *chn, GNUNET_PSYC_ResultCallback result_cb,
241 void *cls)
242{
243 if (NULL == result_cb)
244 return 0;
245
246 struct OperationListItem *op = GNUNET_malloc (sizeof (*op));
247 op->op_id = op_get_next_id (chn);
248 op->result_cb = result_cb;
249 op->cls = cls;
250 GNUNET_CONTAINER_DLL_insert_tail (chn->op_head, chn->op_tail, op);
251
252 LOG (GNUNET_ERROR_TYPE_DEBUG,
253 "%p Added operation #%" PRIu64 "\n", chn, op->op_id);
254 return op->op_id;
255}
256
257
258static int
259op_result (struct GNUNET_PSYC_Channel *chn, uint64_t op_id,
260 int64_t result_code, const char *err_msg)
261{
262 LOG (GNUNET_ERROR_TYPE_DEBUG,
263 "%p Received result for operation #%" PRIu64 ": %" PRId64 " (%s)\n",
264 chn, op_id, result_code, err_msg);
265 if (0 == op_id)
266 return GNUNET_NO;
267
268 struct OperationListItem *op = op_find_by_id (chn, op_id);
269 if (NULL == op)
270 {
271 LOG (GNUNET_ERROR_TYPE_WARNING,
272 "Could not find operation #%" PRIu64 "\n", op_id);
273 return GNUNET_NO;
274 }
275
276 GNUNET_CONTAINER_DLL_remove (chn->op_head, chn->op_tail, op);
277
278 if (NULL != op->result_cb)
279 op->result_cb (op->cls, result_code, err_msg);
280
281 GNUNET_free (op);
282 return GNUNET_YES;
283}
181 284
182 285
183static void 286static void
@@ -203,6 +306,79 @@ channel_recv_disconnect (void *cls,
203 306
204 307
205static void 308static void
309channel_recv_result (void *cls,
310 struct GNUNET_CLIENT_MANAGER_Connection *client,
311 const struct GNUNET_MessageHeader *msg)
312{
313 struct GNUNET_PSYC_Channel *
314 chn = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*chn));
315
316 uint16_t size = ntohs (msg->size);
317 const struct OperationResult *res = (const struct OperationResult *) msg;
318 const char *err_msg = NULL;
319
320 if (sizeof (struct OperationResult) < size)
321 {
322 err_msg = (const char *) &res[1];
323 if ('\0' != err_msg[size - sizeof (struct OperationResult) - 1])
324 {
325 GNUNET_break (0);
326 err_msg = NULL;
327 }
328 }
329
330 op_result (chn, GNUNET_ntohll (res->op_id),
331 GNUNET_ntohll (res->result_code) + INT64_MIN, err_msg);
332}
333
334
335static void
336channel_recv_state_result (void *cls,
337 struct GNUNET_CLIENT_MANAGER_Connection *client,
338 const struct GNUNET_MessageHeader *msg)
339{
340 struct GNUNET_PSYC_Channel *
341 chn = GNUNET_CLIENT_MANAGER_get_user_context_ (client, sizeof (*chn));
342
343 const struct OperationResult *res = (const struct OperationResult *) msg;
344 struct OperationListItem *op = op_find_by_id (chn, GNUNET_ntohll (res->op_id));
345 if (NULL == op || NULL == op->state_var_cb)
346 return;
347
348 const struct GNUNET_MessageHeader *modc = (struct GNUNET_MessageHeader *) &op[1];
349 uint16_t modc_size = ntohs (modc->size);
350 if (ntohs (msg->size) - sizeof (*msg) != modc_size)
351 {
352 GNUNET_break (0);
353 return;
354 }
355 switch (ntohs (modc->type))
356 {
357 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
358 {
359 const struct GNUNET_PSYC_MessageModifier *
360 mod = (const struct GNUNET_PSYC_MessageModifier *) modc;
361
362 const char *name = (const char *) &mod[1];
363 uint16_t name_size = ntohs (mod->name_size);
364 if ('\0' != name[name_size - 1])
365 {
366 GNUNET_break (0);
367 return;
368 }
369 op->state_var_cb (op->cls, name, name + name_size, ntohs (mod->value_size));
370 break;
371 }
372
373 case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
374 op->state_var_cb (op->cls, NULL, (const char *) &modc[1],
375 modc_size - sizeof (*modc));
376 break;
377 }
378}
379
380
381static void
206channel_recv_message (void *cls, 382channel_recv_message (void *cls,
207 struct GNUNET_CLIENT_MANAGER_Connection *client, 383 struct GNUNET_CLIENT_MANAGER_Connection *client,
208 const struct GNUNET_MessageHeader *msg) 384 const struct GNUNET_MessageHeader *msg)
@@ -234,9 +410,16 @@ master_recv_start_ack (void *cls,
234 mst = GNUNET_CLIENT_MANAGER_get_user_context_ (client, 410 mst = GNUNET_CLIENT_MANAGER_get_user_context_ (client,
235 sizeof (struct GNUNET_PSYC_Channel)); 411 sizeof (struct GNUNET_PSYC_Channel));
236 412
237 struct CountersResult *cres = (struct CountersResult *) msg; 413 struct GNUNET_PSYC_CountersResultMessage *
414 cres = (struct GNUNET_PSYC_CountersResultMessage *) msg;
415 int32_t result = ntohl (cres->result_code) + INT32_MIN;
416 if (GNUNET_OK != result && GNUNET_NO != result)
417 {
418 LOG (GNUNET_ERROR_TYPE_ERROR, "Could not start master.\n");
419 GNUNET_break (0);
420 }
238 if (NULL != mst->start_cb) 421 if (NULL != mst->start_cb)
239 mst->start_cb (mst->cb_cls, GNUNET_ntohll (cres->max_message_id)); 422 mst->start_cb (mst->cb_cls, result, GNUNET_ntohll (cres->max_message_id));
240} 423}
241 424
242 425
@@ -279,9 +462,16 @@ slave_recv_join_ack (void *cls,
279 struct GNUNET_PSYC_Slave * 462 struct GNUNET_PSYC_Slave *
280 slv = GNUNET_CLIENT_MANAGER_get_user_context_ (client, 463 slv = GNUNET_CLIENT_MANAGER_get_user_context_ (client,
281 sizeof (struct GNUNET_PSYC_Channel)); 464 sizeof (struct GNUNET_PSYC_Channel));
282 struct CountersResult *cres = (struct CountersResult *) msg; 465 struct GNUNET_PSYC_CountersResultMessage *
466 cres = (struct GNUNET_PSYC_CountersResultMessage *) msg;
467 int32_t result = ntohl (cres->result_code) + INT32_MIN;
468 if (GNUNET_YES != result && GNUNET_NO != result)
469 {
470 LOG (GNUNET_ERROR_TYPE_ERROR, "Could not join slave.\n");
471 GNUNET_break (0);
472 }
283 if (NULL != slv->connect_cb) 473 if (NULL != slv->connect_cb)
284 slv->connect_cb (slv->cb_cls, GNUNET_ntohll (cres->max_message_id)); 474 slv->connect_cb (slv->cb_cls, result, GNUNET_ntohll (cres->max_message_id));
285} 475}
286 476
287 477
@@ -317,12 +507,20 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler master_handlers[] =
317 507
318 { &master_recv_start_ack, NULL, 508 { &master_recv_start_ack, NULL,
319 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK, 509 GNUNET_MESSAGE_TYPE_PSYC_MASTER_START_ACK,
320 sizeof (struct CountersResult), GNUNET_NO }, 510 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO },
321 511
322 { &master_recv_join_request, NULL, 512 { &master_recv_join_request, NULL,
323 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST, 513 GNUNET_MESSAGE_TYPE_PSYC_JOIN_REQUEST,
324 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES }, 514 sizeof (struct GNUNET_PSYC_JoinRequestMessage), GNUNET_YES },
325 515
516 { &channel_recv_state_result, NULL,
517 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT,
518 sizeof (struct OperationResult), GNUNET_YES },
519
520 { &channel_recv_result, NULL,
521 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE,
522 sizeof (struct OperationResult), GNUNET_YES },
523
326 { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 524 { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO },
327 525
328 { NULL, NULL, 0, 0, GNUNET_NO } 526 { NULL, NULL, 0, 0, GNUNET_NO }
@@ -341,12 +539,20 @@ static struct GNUNET_CLIENT_MANAGER_MessageHandler slave_handlers[] =
341 539
342 { &slave_recv_join_ack, NULL, 540 { &slave_recv_join_ack, NULL,
343 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK, 541 GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN_ACK,
344 sizeof (struct CountersResult), GNUNET_NO }, 542 sizeof (struct GNUNET_PSYC_CountersResultMessage), GNUNET_NO },
345 543
346 { &slave_recv_join_decision, NULL, 544 { &slave_recv_join_decision, NULL,
347 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION, 545 GNUNET_MESSAGE_TYPE_PSYC_JOIN_DECISION,
348 sizeof (struct GNUNET_PSYC_JoinDecisionMessage), GNUNET_YES }, 546 sizeof (struct GNUNET_PSYC_JoinDecisionMessage), GNUNET_YES },
349 547
548 { &channel_recv_state_result, NULL,
549 GNUNET_MESSAGE_TYPE_PSYC_STATE_RESULT,
550 sizeof (struct OperationResult), GNUNET_YES },
551
552 { &channel_recv_result, NULL,
553 GNUNET_MESSAGE_TYPE_PSYC_RESULT_CODE,
554 sizeof (struct OperationResult), GNUNET_YES },
555
350 { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO }, 556 { &channel_recv_disconnect, NULL, 0, 0, GNUNET_NO },
351 557
352 { NULL, NULL, 0, 0, GNUNET_NO } 558 { NULL, NULL, 0, 0, GNUNET_NO }
@@ -808,7 +1014,9 @@ void
808GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *chn, 1014GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *chn,
809 const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, 1015 const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
810 uint64_t announced_at, 1016 uint64_t announced_at,
811 uint64_t effective_since) 1017 uint64_t effective_since,
1018 GNUNET_PSYC_ResultCallback result_cb,
1019 void *cls)
812{ 1020{
813 struct ChannelMembershipStoreRequest *req = GNUNET_malloc (sizeof (*req)); 1021 struct ChannelMembershipStoreRequest *req = GNUNET_malloc (sizeof (*req));
814 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE); 1022 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE);
@@ -817,6 +1025,8 @@ GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *chn,
817 req->announced_at = GNUNET_htonll (announced_at); 1025 req->announced_at = GNUNET_htonll (announced_at);
818 req->effective_since = GNUNET_htonll (effective_since); 1026 req->effective_since = GNUNET_htonll (effective_since);
819 req->did_join = GNUNET_YES; 1027 req->did_join = GNUNET_YES;
1028 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
1029
820 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header); 1030 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
821} 1031}
822 1032
@@ -845,7 +1055,9 @@ GNUNET_PSYC_channel_slave_add (struct GNUNET_PSYC_Channel *chn,
845void 1055void
846GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *chn, 1056GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *chn,
847 const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key, 1057 const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
848 uint64_t announced_at) 1058 uint64_t announced_at,
1059 GNUNET_PSYC_ResultCallback result_cb,
1060 void *cls)
849{ 1061{
850 struct ChannelMembershipStoreRequest *req = GNUNET_malloc (sizeof (*req)); 1062 struct ChannelMembershipStoreRequest *req = GNUNET_malloc (sizeof (*req));
851 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE); 1063 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE);
@@ -853,57 +1065,85 @@ GNUNET_PSYC_channel_slave_remove (struct GNUNET_PSYC_Channel *chn,
853 req->slave_key = *slave_key; 1065 req->slave_key = *slave_key;
854 req->announced_at = GNUNET_htonll (announced_at); 1066 req->announced_at = GNUNET_htonll (announced_at);
855 req->did_join = GNUNET_NO; 1067 req->did_join = GNUNET_NO;
1068 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
1069
856 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header); 1070 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
857} 1071}
858 1072
859 1073
860/** 1074/**
861 * Request to be told the message history of the channel. 1075 * Request to replay a part of the message history of the channel.
862 * 1076 *
863 * Historic messages (but NOT the state at the time) will be replayed (given to 1077 * Historic messages (but NOT the state at the time) will be replayed (given to
864 * the normal method handlers) if available and if access is permitted. 1078 * the normal method handlers) if available and if access is permitted.
865 * 1079 *
866 * To get the latest message, use 0 for both the start and end message ID. 1080 * @param channel
867 * 1081 * Which channel should be replayed?
868 * @param channel Which channel should be replayed? 1082 * @param start_message_id
869 * @param start_message_id Earliest interesting point in history. 1083 * Earliest interesting point in history.
870 * @param end_message_id Last (exclusive) interesting point in history. 1084 * @param end_message_id
871 * @param message_cb Function to invoke on message parts received from the story. 1085 * Last (inclusive) interesting point in history.
872 * @param finish_cb Function to call when the requested story has been fully 1086 * FIXME: @param method_prefix
873 * told (counting message IDs might not suffice, as some messages 1087 * Retrieve only messages with a matching method prefix.
874 * might be secret and thus the listener would not know the story is 1088 * @param result_cb
875 * finished without being told explicitly) once this function 1089 * Function to call when the requested history has been fully replayed.
876 * has been called, the client must not call 1090 * @param cls
877 * GNUNET_PSYC_channel_story_tell_cancel() anymore. 1091 * Closure for the callbacks.
878 * @param cls Closure for the callbacks. 1092 *
879 * 1093 * @return Handle to cancel history replay operation.
880 * @return Handle to cancel story telling operation.
881 */ 1094 */
882struct GNUNET_PSYC_Story * 1095void
883GNUNET_PSYC_channel_story_tell (struct GNUNET_PSYC_Channel *channel, 1096GNUNET_PSYC_channel_history_replay (struct GNUNET_PSYC_Channel *chn,
884 uint64_t start_message_id, 1097 uint64_t start_message_id,
885 uint64_t end_message_id, 1098 uint64_t end_message_id,
886 GNUNET_PSYC_MessageCallback message_cb, 1099 /* FIXME: const char *method_prefix, */
887 GNUNET_PSYC_MessagePartCallback message_part_cb, 1100 GNUNET_PSYC_ResultCallback result_cb,
888 GNUNET_PSYC_FinishCallback finish_cb, 1101 void *cls)
889 void *cls)
890{ 1102{
891 return NULL; 1103 struct HistoryRequest *req = GNUNET_malloc (sizeof (*req));
1104 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_HISTORY_REPLAY);
1105 req->header.size = htons (sizeof (*req));
1106 req->start_message_id = GNUNET_htonll (start_message_id);
1107 req->end_message_id = GNUNET_htonll (end_message_id);
1108 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
1109
1110 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
892} 1111}
893 1112
894 1113
895/** 1114/**
896 * Abort story telling. 1115 * Request to replay the latest messages from the message history of the channel.
897 * 1116 *
898 * This function must not be called from within method handlers (as given to 1117 * Historic messages (but NOT the state at the time) will be replayed (given to
899 * GNUNET_PSYC_slave_join()) of the slave. 1118 * the normal method handlers) if available and if access is permitted.
900 * 1119 *
901 * @param story Story telling operation to stop. 1120 * @param channel
1121 * Which channel should be replayed?
1122 * @param message_limit
1123 * Maximum number of messages to replay.
1124 * FIXME: @param method_prefix
1125 * Retrieve only messages with a matching method prefix.
1126 * @param result_cb
1127 * Function to call when the requested history has been fully replayed.
1128 * @param cls
1129 * Closure for the callbacks.
1130 *
1131 * @return Handle to cancel history replay operation.
902 */ 1132 */
903void 1133void
904GNUNET_PSYC_channel_story_tell_cancel (struct GNUNET_PSYC_Story *story) 1134GNUNET_PSYC_channel_history_replay_latest (struct GNUNET_PSYC_Channel *chn,
1135 uint64_t message_limit,
1136 /* FIXME: const char *method_prefix, */
1137 GNUNET_PSYC_ResultCallback result_cb,
1138 void *cls)
905{ 1139{
1140 struct HistoryRequest *req = GNUNET_malloc (sizeof (*req));
1141 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_HISTORY_REPLAY);
1142 req->header.size = htons (sizeof (*req));
1143 req->message_limit = GNUNET_htonll (message_limit);
1144 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
906 1145
1146 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
907} 1147}
908 1148
909 1149
@@ -914,22 +1154,35 @@ GNUNET_PSYC_channel_story_tell_cancel (struct GNUNET_PSYC_Story *story)
914 * less-specific name is matched; for example, requesting "_a_b" will match "_a" 1154 * less-specific name is matched; for example, requesting "_a_b" will match "_a"
915 * if "_a_b" does not exist. 1155 * if "_a_b" does not exist.
916 * 1156 *
917 * @param channel Channel handle. 1157 * @param channel
918 * @param full_name Full name of the requested variable, the actual variable 1158 * Channel handle.
919 * returned might have a shorter name.. 1159 * @param full_name
920 * @param cb Function called once when a matching state variable is found. 1160 * Full name of the requested variable.
1161 * The actual variable returned might have a shorter name.
1162 * @param var_cb
1163 * Function called once when a matching state variable is found.
921 * Not called if there's no matching state variable. 1164 * Not called if there's no matching state variable.
922 * @param cb_cls Closure for the callbacks. 1165 * @param result_cb
923 * 1166 * Function called after the operation finished.
924 * @return Handle that can be used to cancel the query operation. 1167 * (i.e. all state variables have been returned via @a state_cb)
1168 * @param cls
1169 * Closure for the callbacks.
925 */ 1170 */
926struct GNUNET_PSYC_StateQuery * 1171void
927GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *channel, 1172GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *chn,
928 const char *full_name, 1173 const char *full_name,
929 GNUNET_PSYC_StateCallback cb, 1174 GNUNET_PSYC_StateVarCallback var_cb,
930 void *cb_cls) 1175 GNUNET_PSYC_ResultCallback result_cb,
1176 void *cls)
931{ 1177{
932 return NULL; 1178 size_t name_size = strlen (full_name) + 1;
1179 struct StateRequest *req = GNUNET_malloc (sizeof (*req) + name_size);
1180 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_STATE_GET);
1181 req->header.size = htons (sizeof (*req) + name_size);
1182 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
1183 memcpy (&req[1], full_name, name_size);
1184
1185 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
933} 1186}
934 1187
935 1188
@@ -943,33 +1196,34 @@ GNUNET_PSYC_channel_state_get (struct GNUNET_PSYC_Channel *channel,
943 * The @a state_cb is invoked on all matching state variables asynchronously, as 1196 * The @a state_cb is invoked on all matching state variables asynchronously, as
944 * the state is stored in and retrieved from the PSYCstore, 1197 * the state is stored in and retrieved from the PSYCstore,
945 * 1198 *
946 * @param channel Channel handle. 1199 * @param channel
947 * @param name_prefix Prefix of the state variable name to match. 1200 * Channel handle.
948 * @param cb Function to call with the matching state variables. 1201 * @param name_prefix
949 * @param cb_cls Closure for the callbacks. 1202 * Prefix of the state variable name to match.
950 * 1203 * @param var_cb
951 * @return Handle that can be used to cancel the query operation. 1204 * Function called once when a matching state variable is found.
952 */ 1205 * Not called if there's no matching state variable.
953struct GNUNET_PSYC_StateQuery * 1206 * @param result_cb
954GNUNET_PSYC_channel_state_get_prefix (struct GNUNET_PSYC_Channel *channel, 1207 * Function called after the operation finished.
955 const char *name_prefix, 1208 * (i.e. all state variables have been returned via @a state_cb)
956 GNUNET_PSYC_StateCallback cb, 1209 * @param cls
957 void *cb_cls) 1210 * Closure for the callbacks.
958{
959 return NULL;
960}
961
962
963/**
964 * Cancel a state query operation.
965 *
966 * @param query Handle for the operation to cancel.
967 */ 1211 */
968void 1212void
969GNUNET_PSYC_channel_state_get_cancel (struct GNUNET_PSYC_StateQuery *query) 1213GNUNET_PSYC_channel_state_get_prefix (struct GNUNET_PSYC_Channel *chn,
1214 const char *name_prefix,
1215 GNUNET_PSYC_StateVarCallback var_cb,
1216 GNUNET_PSYC_ResultCallback result_cb,
1217 void *cls)
970{ 1218{
1219 size_t name_size = strlen (name_prefix) + 1;
1220 struct StateRequest *req = GNUNET_malloc (sizeof (*req) + name_size);
1221 req->header.type = htons (GNUNET_MESSAGE_TYPE_PSYC_STATE_GET);
1222 req->header.size = htons (sizeof (*req) + name_size);
1223 req->op_id = GNUNET_htonll (op_add (chn, result_cb, cls));
1224 memcpy (&req[1], name_prefix, name_size);
971 1225
1226 GNUNET_CLIENT_MANAGER_transmit (chn->client, &req->header);
972} 1227}
973 1228
974
975/* end of psyc_api.c */ 1229/* end of psyc_api.c */