diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-10-03 13:50:35 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-10-03 13:50:35 +0000 |
commit | 653dc47fa8ab2e2f36c4ca494fcb6510cdc9d46a (patch) | |
tree | 2f2dca0370c0713e508fe188eedae1efb8d65671 /src | |
parent | 4954b2047093f62c866d145ece0d2304b76a428f (diff) | |
download | gnunet-653dc47fa8ab2e2f36c4ca494fcb6510cdc9d46a.tar.gz gnunet-653dc47fa8ab2e2f36c4ca494fcb6510cdc9d46a.zip |
-finishing first round of conversation phone API implementation
Diffstat (limited to 'src')
-rw-r--r-- | src/conversation/Makefile.am | 1 | ||||
-rw-r--r-- | src/conversation/conversation.h | 29 | ||||
-rw-r--r-- | src/conversation/conversation_api2.c | 487 | ||||
-rw-r--r-- | src/include/gnunet_client_lib.h | 7 | ||||
-rw-r--r-- | src/include/gnunet_conversation_service.h | 14 | ||||
-rw-r--r-- | src/include/gnunet_mq_lib.h | 3 | ||||
-rw-r--r-- | src/include/gnunet_namestore_service.h | 6 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 30 |
8 files changed, 558 insertions, 19 deletions
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am index 913acf9af..a91e6a40c 100644 --- a/src/conversation/Makefile.am +++ b/src/conversation/Makefile.am | |||
@@ -48,6 +48,7 @@ libgnunetconversation_la_LIBADD = \ | |||
48 | libgnunetspeaker.la \ | 48 | libgnunetspeaker.la \ |
49 | $(top_builddir)/src/gns/libgnunetgns.la \ | 49 | $(top_builddir)/src/gns/libgnunetgns.la \ |
50 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 50 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
51 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
51 | $(top_builddir)/src/util/libgnunetutil.la | 52 | $(top_builddir)/src/util/libgnunetutil.la |
52 | 53 | ||
53 | libgnunetconversation_la_LDFLAGS = \ | 54 | libgnunetconversation_la_LDFLAGS = \ |
diff --git a/src/conversation/conversation.h b/src/conversation/conversation.h index 73052dfcf..ff4795ef8 100644 --- a/src/conversation/conversation.h +++ b/src/conversation/conversation.h | |||
@@ -444,6 +444,19 @@ struct ClientPhoneRingMessage | |||
444 | 444 | ||
445 | 445 | ||
446 | /** | 446 | /** |
447 | * Service -> Client message for phone is busy. | ||
448 | */ | ||
449 | struct ClientPhoneBusyMessage | ||
450 | { | ||
451 | /** | ||
452 | * Type is: #GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_BUSY | ||
453 | */ | ||
454 | struct GNUNET_MessageHeader header; | ||
455 | |||
456 | }; | ||
457 | |||
458 | |||
459 | /** | ||
447 | * Client -> Service pick up phone that is ringing. | 460 | * Client -> Service pick up phone that is ringing. |
448 | */ | 461 | */ |
449 | struct ClientPhonePickupMessage | 462 | struct ClientPhonePickupMessage |
@@ -459,7 +472,7 @@ struct ClientPhonePickupMessage | |||
459 | 472 | ||
460 | 473 | ||
461 | /** | 474 | /** |
462 | * Client -> Service hang up phone that may or may not be ringing. | 475 | * Client <-> Service hang up phone that may or may not be ringing. |
463 | * Also sent in response to a (failed) `struct ClientCallMessage`. | 476 | * Also sent in response to a (failed) `struct ClientCallMessage`. |
464 | */ | 477 | */ |
465 | struct ClientPhoneHangupMessage | 478 | struct ClientPhoneHangupMessage |
@@ -609,6 +622,20 @@ struct MeshPhonePickupMessage | |||
609 | 622 | ||
610 | 623 | ||
611 | /** | 624 | /** |
625 | * Mesh message for phone busy. | ||
626 | */ | ||
627 | struct MeshPhoneBusyMessage | ||
628 | { | ||
629 | /** | ||
630 | * Type is: #GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_BUSY | ||
631 | */ | ||
632 | struct GNUNET_MessageHeader header; | ||
633 | |||
634 | /* followed by variable-size 0-terminated metadata string??? */ | ||
635 | }; | ||
636 | |||
637 | |||
638 | /** | ||
612 | * Mesh message to transmit the audio. | 639 | * Mesh message to transmit the audio. |
613 | */ | 640 | */ |
614 | struct MeshAudioMessage | 641 | struct MeshAudioMessage |
diff --git a/src/conversation/conversation_api2.c b/src/conversation/conversation_api2.c index 3c19828a4..236bd5734 100644 --- a/src/conversation/conversation_api2.c +++ b/src/conversation/conversation_api2.c | |||
@@ -27,6 +27,8 @@ | |||
27 | */ | 27 | */ |
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_conversation_service.h" | 29 | #include "gnunet_conversation_service.h" |
30 | #include "gnunet_gns_service.h" | ||
31 | #include "conversation.h" | ||
30 | 32 | ||
31 | 33 | ||
32 | /** | 34 | /** |
@@ -52,11 +54,37 @@ struct PhoneRecord | |||
52 | /** | 54 | /** |
53 | * Identity of the peer hosting the phone service. | 55 | * Identity of the peer hosting the phone service. |
54 | */ | 56 | */ |
55 | struct GNUNET_PeerIdentity my_peer; | 57 | struct GNUNET_PeerIdentity peer; |
56 | 58 | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | 61 | ||
62 | /** | ||
63 | * Possible states of the phone. | ||
64 | */ | ||
65 | enum PhoneState | ||
66 | { | ||
67 | /** | ||
68 | * We still need to register the phone. | ||
69 | */ | ||
70 | PS_REGISTER = 0, | ||
71 | |||
72 | /** | ||
73 | * We are waiting for a call. | ||
74 | */ | ||
75 | PS_WAITING, | ||
76 | |||
77 | /** | ||
78 | * The phone is ringing. | ||
79 | */ | ||
80 | PS_RINGING, | ||
81 | |||
82 | /** | ||
83 | * The phone is in an active conversation. | ||
84 | */ | ||
85 | PS_ACTIVE | ||
86 | }; | ||
87 | |||
60 | 88 | ||
61 | /** | 89 | /** |
62 | * A phone is a device that can ring to signal an incoming call and | 90 | * A phone is a device that can ring to signal an incoming call and |
@@ -75,6 +103,11 @@ struct GNUNET_CONVERSATION_Phone | |||
75 | * Our configuration. | 103 | * Our configuration. |
76 | */ | 104 | */ |
77 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 105 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
106 | |||
107 | /** | ||
108 | * Handle to talk with CONVERSATION service. | ||
109 | */ | ||
110 | struct GNUNET_CLIENT_Connection *client; | ||
78 | 111 | ||
79 | /** | 112 | /** |
80 | * Function to call for phone events. | 113 | * Function to call for phone events. |
@@ -89,35 +122,340 @@ struct GNUNET_CONVERSATION_Phone | |||
89 | /** | 122 | /** |
90 | * Speaker, or NULL if none is attached. | 123 | * Speaker, or NULL if none is attached. |
91 | */ | 124 | */ |
92 | struct GNUNET_CONVERSATION_Speaker *speaker; | 125 | struct GNUNET_SPEAKER_Handle *speaker; |
93 | 126 | ||
94 | /** | 127 | /** |
95 | * Microphone, or NULL if none is attached. | 128 | * Microphone, or NULL if none is attached. |
96 | */ | 129 | */ |
97 | struct GNUNET_CONVERSATION_Microphone *mic; | 130 | struct GNUNET_MICROPHONE_Handle *mic; |
131 | |||
132 | /** | ||
133 | * Connection to NAMESTORE (for reverse lookup). | ||
134 | */ | ||
135 | struct GNUNET_NAMESTORE_Handle *ns; | ||
136 | |||
137 | /** | ||
138 | * Active NAMESTORE lookup (or NULL). | ||
139 | */ | ||
140 | struct GNUNET_NAMESTORE_QueueEntry *qe; | ||
141 | |||
142 | /** | ||
143 | * Handle for transmitting to the CONVERSATION service. | ||
144 | */ | ||
145 | struct GNUNET_MQ_Handle *mq; | ||
98 | 146 | ||
99 | /** | 147 | /** |
100 | * This phone's record. | 148 | * This phone's record. |
101 | */ | 149 | */ |
102 | struct PhoneRecord my_record; | 150 | struct PhoneRecord my_record; |
151 | |||
152 | /** | ||
153 | * My GNS zone. | ||
154 | */ | ||
155 | struct GNUNET_CRYPTO_EccPrivateKey my_zone; | ||
156 | |||
157 | /** | ||
158 | * Identity of the person calling us (valid while in state #PS_RINGING). | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_EccPublicSignKey caller_id; | ||
161 | |||
162 | /** | ||
163 | * State machine for the phone. | ||
164 | */ | ||
165 | enum PhoneState state; | ||
103 | 166 | ||
104 | }; | 167 | }; |
105 | 168 | ||
106 | 169 | ||
107 | /** | 170 | /** |
171 | * The phone got disconnected, reconnect to the service. | ||
172 | * | ||
173 | * @param phone phone to reconnect | ||
174 | */ | ||
175 | static void | ||
176 | reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone); | ||
177 | |||
178 | |||
179 | /** | ||
180 | * We have resolved the caller ID using our name service. | ||
181 | * | ||
182 | * @param cls the `struct GNUNET_CONVERSATION_Phone` | ||
183 | * @param zone our zone used for resolution | ||
184 | * @param label name of the caller | ||
185 | * @param rd_count number of records we have in @a rd | ||
186 | * @param rd records we have for the caller's label | ||
187 | */ | ||
188 | static void | ||
189 | handle_caller_name (void *cls, | ||
190 | const struct GNUNET_CRYPTO_EccPrivateKey *zone, | ||
191 | const char *label, | ||
192 | unsigned int rd_count, | ||
193 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
194 | { | ||
195 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
196 | char *name; | ||
197 | |||
198 | phone->qe = NULL; | ||
199 | if (NULL == label) | ||
200 | name = GNUNET_strdup (GNUNET_NAMESTORE_pkey_to_zkey (&phone->caller_id)); | ||
201 | else | ||
202 | GNUNET_asprintf (&name, "%.gnu", label); | ||
203 | phone->event_handler (phone->event_handler_cls, | ||
204 | GNUNET_CONVERSATION_EC_RING, | ||
205 | name); | ||
206 | GNUNET_free (name); | ||
207 | } | ||
208 | |||
209 | |||
210 | /** | ||
211 | * We received a `struct ClientPhoneRingMessage` | ||
212 | * | ||
213 | * @param cls the `struct GNUNET_CONVERSATION_Phone` | ||
214 | * @param msg the message | ||
215 | */ | ||
216 | static void | ||
217 | handle_phone_ring (void *cls, | ||
218 | const struct GNUNET_MessageHeader *msg) | ||
219 | { | ||
220 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
221 | const struct ClientPhoneRingMessage *ring; | ||
222 | |||
223 | ring = (const struct ClientPhoneRingMessage *) msg; | ||
224 | switch (phone->state) | ||
225 | { | ||
226 | case PS_REGISTER: | ||
227 | GNUNET_assert (0); | ||
228 | break; | ||
229 | case PS_WAITING: | ||
230 | phone->state = PS_RINGING; | ||
231 | phone->caller_id = ring->caller_id; | ||
232 | phone->qe = GNUNET_NAMESTORE_zone_to_name (phone->ns, | ||
233 | &phone->my_zone, | ||
234 | &ring->caller_id, | ||
235 | &handle_caller_name, | ||
236 | phone); | ||
237 | break; | ||
238 | case PS_RINGING: | ||
239 | GNUNET_break (0); | ||
240 | reconnect_phone (phone); | ||
241 | break; | ||
242 | case PS_ACTIVE: | ||
243 | GNUNET_break (0); | ||
244 | reconnect_phone (phone); | ||
245 | break; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
251 | * We received a `struct ClientPhoneHangupMessage`. | ||
252 | * | ||
253 | * @param cls the `struct GNUNET_CONVERSATION_Phone` | ||
254 | * @param msg the message | ||
255 | */ | ||
256 | static void | ||
257 | handle_phone_hangup (void *cls, | ||
258 | const struct GNUNET_MessageHeader *msg) | ||
259 | { | ||
260 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
261 | const struct ClientPhoneHangupMessage *hang; | ||
262 | size_t len; | ||
263 | const char *reason; | ||
264 | |||
265 | hang = (const struct ClientPhoneHangupMessage *) msg; | ||
266 | reason = (const char *) &hang[1]; | ||
267 | len = htons (hang->header.size) - sizeof (struct ClientPhoneHangupMessage); | ||
268 | if ( (0 == len) || | ||
269 | ('\0' != reason[len-1]) ) | ||
270 | { | ||
271 | GNUNET_break (0); | ||
272 | reconnect_phone (phone); | ||
273 | return; | ||
274 | } | ||
275 | switch (phone->state) | ||
276 | { | ||
277 | case PS_REGISTER: | ||
278 | GNUNET_assert (0); | ||
279 | break; | ||
280 | case PS_WAITING: | ||
281 | GNUNET_break (0); | ||
282 | reconnect_phone (phone); | ||
283 | break; | ||
284 | case PS_RINGING: | ||
285 | if (NULL != phone->qe) | ||
286 | { | ||
287 | GNUNET_NAMESTORE_cancel (phone->qe); | ||
288 | phone->qe = NULL; | ||
289 | phone->state = PS_WAITING; | ||
290 | break; | ||
291 | } | ||
292 | phone->state = PS_WAITING; | ||
293 | phone->event_handler (phone->event_handler_cls, | ||
294 | GNUNET_CONVERSATION_EC_TERMINATED, | ||
295 | reason); | ||
296 | break; | ||
297 | case PS_ACTIVE: | ||
298 | GNUNET_break (NULL == phone->qe); | ||
299 | phone->state = PS_WAITING; | ||
300 | phone->event_handler (phone->event_handler_cls, | ||
301 | GNUNET_CONVERSATION_EC_TERMINATED, | ||
302 | reason); | ||
303 | break; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * We received a `struct ClientAudioMessage` | ||
310 | * | ||
311 | * @param cls the `struct GNUNET_CONVERSATION_Phone` | ||
312 | * @param msg the message | ||
313 | */ | ||
314 | static void | ||
315 | handle_audio_message (void *cls, | ||
316 | const struct GNUNET_MessageHeader *msg) | ||
317 | { | ||
318 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
319 | const struct ClientAudioMessage *am; | ||
320 | |||
321 | am = (const struct ClientAudioMessage *) msg; | ||
322 | switch (phone->state) | ||
323 | { | ||
324 | case PS_REGISTER: | ||
325 | GNUNET_assert (0); | ||
326 | break; | ||
327 | case PS_WAITING: | ||
328 | GNUNET_break (0); | ||
329 | reconnect_phone (phone); | ||
330 | break; | ||
331 | case PS_RINGING: | ||
332 | GNUNET_break (0); | ||
333 | reconnect_phone (phone); | ||
334 | break; | ||
335 | case PS_ACTIVE: | ||
336 | phone->speaker->play (phone->speaker->cls, | ||
337 | ntohs (msg->size) - sizeof (struct ClientAudioMessage), | ||
338 | &am[1]); | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | |||
344 | /** | ||
345 | * We encountered an error talking with the conversation service. | ||
346 | * | ||
347 | * @param cls the `struct GNUNET_CONVERSATION_Phone` | ||
348 | * @param error details about the error | ||
349 | */ | ||
350 | static void | ||
351 | error_handler (void *cls, | ||
352 | enum GNUNET_MQ_Error error) | ||
353 | { | ||
354 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
355 | |||
356 | GNUNET_break (0); | ||
357 | reconnect_phone (phone); | ||
358 | } | ||
359 | |||
360 | |||
361 | /** | ||
362 | * The phone got disconnected, reconnect to the service. | ||
363 | * | ||
364 | * @param phone phone to reconnect | ||
365 | */ | ||
366 | static void | ||
367 | reconnect_phone (struct GNUNET_CONVERSATION_Phone *phone) | ||
368 | { | ||
369 | static struct GNUNET_MQ_MessageHandler handlers[] = | ||
370 | { | ||
371 | { &handle_phone_ring, | ||
372 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING, | ||
373 | sizeof (struct ClientPhoneRingMessage) }, | ||
374 | { &handle_phone_hangup, | ||
375 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP, | ||
376 | 0 }, | ||
377 | { &handle_audio_message, | ||
378 | GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO, | ||
379 | 0 }, | ||
380 | { NULL, 0, 0 } | ||
381 | }; | ||
382 | struct GNUNET_MQ_Envelope *e; | ||
383 | struct ClientPhoneRegisterMessage *reg; | ||
384 | |||
385 | if (NULL != phone->mq) | ||
386 | { | ||
387 | GNUNET_MQ_destroy (phone->mq); | ||
388 | phone->mq = NULL; | ||
389 | } | ||
390 | if (NULL != phone->client) | ||
391 | { | ||
392 | GNUNET_CLIENT_disconnect (phone->client); | ||
393 | phone->client = NULL; | ||
394 | } | ||
395 | phone->state = PS_REGISTER; | ||
396 | phone->client = GNUNET_CLIENT_connect ("conversation", phone->cfg); | ||
397 | if (NULL == phone->client) | ||
398 | return; | ||
399 | phone->mq = GNUNET_MQ_queue_for_connection_client (phone->client, | ||
400 | handlers, | ||
401 | &error_handler, | ||
402 | phone); | ||
403 | e = GNUNET_MQ_msg (reg, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER); | ||
404 | reg->line = phone->my_record.line; | ||
405 | GNUNET_MQ_send (phone->mq, e); | ||
406 | phone->state = PS_WAITING; | ||
407 | } | ||
408 | |||
409 | |||
410 | /** | ||
108 | * Create a new phone. | 411 | * Create a new phone. |
109 | * | 412 | * |
110 | * @param cfg configuration for the phone; specifies the phone service and | 413 | * @param cfg configuration for the phone; specifies the phone service and |
111 | * which line the phone is to be connected to | 414 | * which line the phone is to be connected to |
415 | * @param ego ego to use for name resolution (when determining caller ID) | ||
112 | * @param event_handler how to notify the owner of the phone about events | 416 | * @param event_handler how to notify the owner of the phone about events |
113 | * @param event_handler_cls closure for @a event_handler | 417 | * @param event_handler_cls closure for @a event_handler |
114 | */ | 418 | */ |
115 | struct GNUNET_CONVERSATION_Phone * | 419 | struct GNUNET_CONVERSATION_Phone * |
116 | GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | 420 | GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, |
117 | GNUNET_CONVERSATION_EventHandler event_handler, | 421 | const struct GNUNET_IDENTITY_Ego *ego, |
422 | GNUNET_CONVERSATION_EventHandler event_handler, | ||
118 | void *event_handler_cls) | 423 | void *event_handler_cls) |
119 | { | 424 | { |
120 | return NULL; | 425 | struct GNUNET_CONVERSATION_Phone *phone; |
426 | unsigned long long line; | ||
427 | |||
428 | if (GNUNET_OK != | ||
429 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
430 | "CONVERSATION", | ||
431 | "LINE", | ||
432 | &line)) | ||
433 | return NULL; | ||
434 | phone = GNUNET_new (struct GNUNET_CONVERSATION_Phone); | ||
435 | if (GNUNET_OK != | ||
436 | GNUNET_CRYPTO_get_host_identity (cfg, | ||
437 | &phone->my_record.peer)) | ||
438 | { | ||
439 | GNUNET_break (0); | ||
440 | GNUNET_free (phone); | ||
441 | return NULL; | ||
442 | } | ||
443 | phone->cfg = cfg; | ||
444 | phone->my_zone = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
445 | phone->event_handler = event_handler; | ||
446 | phone->event_handler_cls = event_handler_cls; | ||
447 | phone->ns = GNUNET_NAMESTORE_connect (cfg); | ||
448 | phone->my_record.line = htonl ((uint32_t) line); | ||
449 | phone->my_record.version = htonl (0); | ||
450 | reconnect_phone (phone); | ||
451 | if ( (NULL == phone->client) || | ||
452 | (NULL == phone->ns) ) | ||
453 | { | ||
454 | GNUNET_break (0); | ||
455 | GNUNET_CONVERSATION_phone_destroy (phone); | ||
456 | return NULL; | ||
457 | } | ||
458 | return phone; | ||
121 | } | 459 | } |
122 | 460 | ||
123 | 461 | ||
@@ -133,7 +471,33 @@ void | |||
133 | GNUNET_CONVERSATION_phone_get_record (struct GNUNET_CONVERSATION_Phone *phone, | 471 | GNUNET_CONVERSATION_phone_get_record (struct GNUNET_CONVERSATION_Phone *phone, |
134 | struct GNUNET_NAMESTORE_RecordData *rd) | 472 | struct GNUNET_NAMESTORE_RecordData *rd) |
135 | { | 473 | { |
136 | GNUNET_assert (0); | 474 | rd->data = &phone->my_record; |
475 | rd->expiration_time = 0; | ||
476 | rd->data_size = sizeof (struct PhoneRecord); | ||
477 | rd->record_type = GNUNET_NAMESTORE_TYPE_PHONE; | ||
478 | rd->flags = GNUNET_NAMESTORE_RF_NONE; | ||
479 | } | ||
480 | |||
481 | |||
482 | /** | ||
483 | * Process recorded audio data. | ||
484 | * | ||
485 | * @param cls closure with the `struct GNUNET_CONVERSATION_Phone` | ||
486 | * @param data_size number of bytes in @a data | ||
487 | * @param data audio data to play | ||
488 | */ | ||
489 | static void | ||
490 | transmit_audio (void *cls, | ||
491 | size_t data_size, | ||
492 | const void *data) | ||
493 | { | ||
494 | struct GNUNET_CONVERSATION_Phone *phone = cls; | ||
495 | struct GNUNET_MQ_Envelope *e; | ||
496 | struct ClientAudioMessage *am; | ||
497 | |||
498 | GNUNET_assert (PS_ACTIVE == phone->state); | ||
499 | e = GNUNET_MQ_msg_extra (am, data_size, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO); | ||
500 | GNUNET_MQ_send (phone->mq, e); | ||
137 | } | 501 | } |
138 | 502 | ||
139 | 503 | ||
@@ -152,7 +516,22 @@ GNUNET_CONVERSTATION_phone_pick_up (struct GNUNET_CONVERSATION_Phone *phone, | |||
152 | struct GNUNET_SPEAKER_Handle *speaker, | 516 | struct GNUNET_SPEAKER_Handle *speaker, |
153 | struct GNUNET_MICROPHONE_Handle *mic) | 517 | struct GNUNET_MICROPHONE_Handle *mic) |
154 | { | 518 | { |
155 | GNUNET_assert (0); | 519 | struct GNUNET_MQ_Envelope *e; |
520 | struct ClientPhonePickupMessage *pick; | ||
521 | size_t slen; | ||
522 | |||
523 | GNUNET_assert (PS_RINGING == phone->state); | ||
524 | phone->speaker = speaker; | ||
525 | phone->mic = mic; | ||
526 | slen = strlen (metadata) + 1; | ||
527 | e = GNUNET_MQ_msg_extra (pick, slen, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP); | ||
528 | memcpy (&pick[1], metadata, slen); | ||
529 | GNUNET_MQ_send (phone->mq, e); | ||
530 | phone->state = PS_ACTIVE; | ||
531 | phone->speaker->enable_speaker (phone->speaker->cls); | ||
532 | phone->mic->enable_microphone (phone->mic->cls, | ||
533 | &transmit_audio, | ||
534 | phone); | ||
156 | } | 535 | } |
157 | 536 | ||
158 | 537 | ||
@@ -167,7 +546,21 @@ void | |||
167 | GNUNET_CONVERSTATION_phone_hang_up (struct GNUNET_CONVERSATION_Phone *phone, | 546 | GNUNET_CONVERSTATION_phone_hang_up (struct GNUNET_CONVERSATION_Phone *phone, |
168 | const char *reason) | 547 | const char *reason) |
169 | { | 548 | { |
170 | GNUNET_assert (0); | 549 | struct GNUNET_MQ_Envelope *e; |
550 | struct ClientPhoneHangupMessage *hang; | ||
551 | size_t slen; | ||
552 | |||
553 | GNUNET_assert ( (PS_RINGING == phone->state) || | ||
554 | (PS_ACTIVE == phone->state) ); | ||
555 | phone->speaker->disable_speaker (phone->speaker->cls); | ||
556 | phone->mic->disable_microphone (phone->mic->cls); | ||
557 | phone->speaker = NULL; | ||
558 | phone->mic = NULL; | ||
559 | slen = strlen (reason) + 1; | ||
560 | e = GNUNET_MQ_msg_extra (hang, slen, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | ||
561 | memcpy (&hang[1], reason, slen); | ||
562 | GNUNET_MQ_send (phone->mq, e); | ||
563 | phone->state = PS_WAITING; | ||
171 | } | 564 | } |
172 | 565 | ||
173 | 566 | ||
@@ -179,30 +572,104 @@ GNUNET_CONVERSTATION_phone_hang_up (struct GNUNET_CONVERSATION_Phone *phone, | |||
179 | void | 572 | void |
180 | GNUNET_CONVERSATION_phone_destroy (struct GNUNET_CONVERSATION_Phone *phone) | 573 | GNUNET_CONVERSATION_phone_destroy (struct GNUNET_CONVERSATION_Phone *phone) |
181 | { | 574 | { |
182 | GNUNET_assert (0); | 575 | if (NULL != phone->speaker) |
576 | { | ||
577 | phone->speaker->disable_speaker (phone->speaker->cls); | ||
578 | phone->speaker = NULL; | ||
579 | } | ||
580 | if (NULL != phone->mic) | ||
581 | { | ||
582 | phone->mic->disable_microphone (phone->mic->cls); | ||
583 | phone->mic = NULL; | ||
584 | } | ||
585 | if (NULL != phone->qe) | ||
586 | { | ||
587 | GNUNET_NAMESTORE_cancel (phone->qe); | ||
588 | phone->qe = NULL; | ||
589 | } | ||
590 | if (NULL != phone->ns) | ||
591 | { | ||
592 | GNUNET_NAMESTORE_disconnect (phone->ns); | ||
593 | phone->ns = NULL; | ||
594 | } | ||
595 | if (NULL != phone->mq) | ||
596 | { | ||
597 | GNUNET_MQ_destroy (phone->mq); | ||
598 | phone->mq = NULL; | ||
599 | } | ||
600 | if (NULL != phone->client) | ||
601 | { | ||
602 | GNUNET_CLIENT_disconnect (phone->client); | ||
603 | phone->client = NULL; | ||
604 | } | ||
605 | GNUNET_free (phone); | ||
183 | } | 606 | } |
184 | 607 | ||
185 | 608 | ||
609 | /* ******************************* Call API *************************** */ | ||
610 | |||
611 | |||
186 | /** | 612 | /** |
187 | * Handle for an outgoing call. | 613 | * Handle for an outgoing call. |
188 | */ | 614 | */ |
189 | struct GNUNET_CONVERSATION_Call | 615 | struct GNUNET_CONVERSATION_Call |
190 | { | 616 | { |
191 | 617 | ||
618 | /** | ||
619 | * Our configuration. | ||
620 | */ | ||
192 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 621 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
193 | 622 | ||
623 | /** | ||
624 | * Handle to talk with CONVERSATION service. | ||
625 | */ | ||
626 | struct GNUNET_CLIENT_Handle *client; | ||
627 | |||
628 | /** | ||
629 | * Our caller identity. | ||
630 | */ | ||
194 | struct GNUNET_IDENTITY_Ego *caller_id; | 631 | struct GNUNET_IDENTITY_Ego *caller_id; |
195 | 632 | ||
633 | /** | ||
634 | * Target callee as a GNS address/name. | ||
635 | */ | ||
196 | char *callee; | 636 | char *callee; |
197 | 637 | ||
638 | /** | ||
639 | * Our speaker. | ||
640 | */ | ||
198 | struct GNUNET_CONVERSATION_Speaker *speaker; | 641 | struct GNUNET_CONVERSATION_Speaker *speaker; |
199 | 642 | ||
643 | /** | ||
644 | * Our microphone. | ||
645 | */ | ||
200 | struct GNUNET_CONVERSATION_Microphone *mic; | 646 | struct GNUNET_CONVERSATION_Microphone *mic; |
201 | 647 | ||
648 | /** | ||
649 | * Function to call with events. | ||
650 | */ | ||
202 | GNUNET_CONVERSATION_EventHandler event_handler; | 651 | GNUNET_CONVERSATION_EventHandler event_handler; |
203 | 652 | ||
653 | /** | ||
654 | * Closure for @e event_handler | ||
655 | */ | ||
204 | void *event_handler_cls; | 656 | void *event_handler_cls; |
205 | 657 | ||
658 | /** | ||
659 | * Connection to GNS (can be NULL). | ||
660 | */ | ||
661 | struct GNUNET_GNS_Handle *gns; | ||
662 | |||
663 | /** | ||
664 | * Active GNS lookup (or NULL). | ||
665 | */ | ||
666 | struct GNUNET_GNS_LookupRequest *gns_lookup; | ||
667 | |||
668 | /** | ||
669 | * Target phone record, only valid after the lookup is done. | ||
670 | */ | ||
671 | struct PhoneRecord phone_record; | ||
672 | |||
206 | }; | 673 | }; |
207 | 674 | ||
208 | 675 | ||
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h index e4cdd26cc..37f152d97 100644 --- a/src/include/gnunet_client_lib.h +++ b/src/include/gnunet_client_lib.h | |||
@@ -80,8 +80,7 @@ GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client); | |||
80 | * @param msg message received, NULL on timeout or fatal error | 80 | * @param msg message received, NULL on timeout or fatal error |
81 | */ | 81 | */ |
82 | typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls, | 82 | typedef void (*GNUNET_CLIENT_MessageHandler) (void *cls, |
83 | const struct GNUNET_MessageHeader | 83 | const struct GNUNET_MessageHeader *msg); |
84 | *msg); | ||
85 | 84 | ||
86 | 85 | ||
87 | /** | 86 | /** |
@@ -129,8 +128,8 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client, | |||
129 | size_t size, | 128 | size_t size, |
130 | struct GNUNET_TIME_Relative timeout, | 129 | struct GNUNET_TIME_Relative timeout, |
131 | int auto_retry, | 130 | int auto_retry, |
132 | GNUNET_CONNECTION_TransmitReadyNotify | 131 | GNUNET_CONNECTION_TransmitReadyNotify notify, |
133 | notify, void *notify_cls); | 132 | void *notify_cls); |
134 | 133 | ||
135 | 134 | ||
136 | /** | 135 | /** |
diff --git a/src/include/gnunet_conversation_service.h b/src/include/gnunet_conversation_service.h index 677c40244..d4a48b2b8 100644 --- a/src/include/gnunet_conversation_service.h +++ b/src/include/gnunet_conversation_service.h | |||
@@ -24,6 +24,10 @@ | |||
24 | * @author Simon Dieterle | 24 | * @author Simon Dieterle |
25 | * @author Andreas Fuchs | 25 | * @author Andreas Fuchs |
26 | * @author Christian Grothoff | 26 | * @author Christian Grothoff |
27 | * | ||
28 | * TODO: | ||
29 | * - call waiting | ||
30 | * - put on hold | ||
27 | */ | 31 | */ |
28 | #ifndef GNUNET_CONVERSATION_SERVICE_H | 32 | #ifndef GNUNET_CONVERSATION_SERVICE_H |
29 | #define GNUNET_CONVERSATION_SERVICE_H | 33 | #define GNUNET_CONVERSATION_SERVICE_H |
@@ -232,7 +236,8 @@ GNUNET_CONVERSATION_reject (struct GNUNET_CONVERSATION_Handle *handle); | |||
232 | As this is supposed to be a "secure" service, caller ID is of | 236 | As this is supposed to be a "secure" service, caller ID is of |
233 | course provided as part of the basic implementation, as only the | 237 | course provided as part of the basic implementation, as only the |
234 | CONVERSATION service can know for sure who it is that we are | 238 | CONVERSATION service can know for sure who it is that we are |
235 | talking to.x */ | 239 | talking to. |
240 | */ | ||
236 | 241 | ||
237 | 242 | ||
238 | #include "gnunet_util_lib.h" | 243 | #include "gnunet_util_lib.h" |
@@ -254,6 +259,11 @@ enum GNUNET_CONVERSATION_EventCode | |||
254 | * a `const char *`. The caller ID will be a GNS name. | 259 | * a `const char *`. The caller ID will be a GNS name. |
255 | */ | 260 | */ |
256 | GNUNET_CONVERSATION_EC_RING, | 261 | GNUNET_CONVERSATION_EC_RING, |
262 | |||
263 | /** | ||
264 | * The phone is busy. Varargs will be empty. | ||
265 | */ | ||
266 | GNUNET_CONVERSATION_EC_BUSY, | ||
257 | 267 | ||
258 | /** | 268 | /** |
259 | * We are ready to talk, metadata about the call may be supplied | 269 | * We are ready to talk, metadata about the call may be supplied |
@@ -301,11 +311,13 @@ struct GNUNET_CONVERSATION_Phone; | |||
301 | * | 311 | * |
302 | * @param cfg configuration for the phone; specifies the phone service and | 312 | * @param cfg configuration for the phone; specifies the phone service and |
303 | * which line the phone is to be connected to | 313 | * which line the phone is to be connected to |
314 | * @param ego ego to use for name resolution (when determining caller ID) | ||
304 | * @param event_handler how to notify the owner of the phone about events | 315 | * @param event_handler how to notify the owner of the phone about events |
305 | * @param event_handler_cls closure for @a event_handler | 316 | * @param event_handler_cls closure for @a event_handler |
306 | */ | 317 | */ |
307 | struct GNUNET_CONVERSATION_Phone * | 318 | struct GNUNET_CONVERSATION_Phone * |
308 | GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, | 319 | GNUNET_CONVERSATION_phone_create (const struct GNUNET_CONFIGURATION_Handle *cfg, |
320 | const struct GNUNET_IDENTITY_Ego *ego, | ||
309 | GNUNET_CONVERSATION_EventHandler event_handler, | 321 | GNUNET_CONVERSATION_EventHandler event_handler, |
310 | void *event_handler_cls); | 322 | void *event_handler_cls); |
311 | 323 | ||
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index f88017fbe..fd28f3de6 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h | |||
@@ -28,8 +28,6 @@ | |||
28 | #ifndef GNUNET_MQ_H | 28 | #ifndef GNUNET_MQ_H |
29 | #define GNUNET_MQ_H | 29 | #define GNUNET_MQ_H |
30 | 30 | ||
31 | #include "gnunet_common.h" | ||
32 | |||
33 | 31 | ||
34 | /** | 32 | /** |
35 | * Allocate an envelope, with extra space allocated after the space needed | 33 | * Allocate an envelope, with extra space allocated after the space needed |
@@ -246,7 +244,6 @@ struct GNUNET_MQ_MessageHandler | |||
246 | */ | 244 | */ |
247 | GNUNET_MQ_MessageCallback cb; | 245 | GNUNET_MQ_MessageCallback cb; |
248 | 246 | ||
249 | |||
250 | /** | 247 | /** |
251 | * Type of the message this handler covers. | 248 | * Type of the message this handler covers. |
252 | */ | 249 | */ |
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index 4b3a6fcb9..6763c05fc 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h | |||
@@ -77,6 +77,12 @@ extern "C" | |||
77 | #define GNUNET_NAMESTORE_TYPE_PLACE 65541 | 77 | #define GNUNET_NAMESTORE_TYPE_PLACE 65541 |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * Record type for a phone (of CONVERSATION). | ||
81 | */ | ||
82 | #define GNUNET_NAMESTORE_TYPE_PHONE 65542 | ||
83 | |||
84 | |||
85 | /** | ||
80 | * Entry in the queue. | 86 | * Entry in the queue. |
81 | */ | 87 | */ |
82 | struct GNUNET_NAMESTORE_QueueEntry; | 88 | struct GNUNET_NAMESTORE_QueueEntry; |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 60ad23097..a2b3ae60d 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2230,6 +2230,36 @@ extern "C" | |||
2230 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO 751 | 2230 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO 751 |
2231 | 2231 | ||
2232 | 2232 | ||
2233 | |||
2234 | |||
2235 | |||
2236 | /** | ||
2237 | * Client -> Server message register a phone. | ||
2238 | */ | ||
2239 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_REGISTER 730 | ||
2240 | |||
2241 | /** | ||
2242 | * Client -> Server meessage to reject/hangup a call | ||
2243 | */ | ||
2244 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICK_UP 731 | ||
2245 | |||
2246 | /** | ||
2247 | * Client -> Server meessage to reject/hangup a call | ||
2248 | */ | ||
2249 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP 732 | ||
2250 | |||
2251 | /** | ||
2252 | * Client <- Server message to indicate a ringing phone | ||
2253 | */ | ||
2254 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING 733 | ||
2255 | |||
2256 | /** | ||
2257 | * Client <-> Server message to send audio data. | ||
2258 | */ | ||
2259 | #define GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO 734 | ||
2260 | |||
2261 | |||
2262 | |||
2233 | /******************************************************************************* | 2263 | /******************************************************************************* |
2234 | * MULTICAST message types | 2264 | * MULTICAST message types |
2235 | ******************************************************************************/ | 2265 | ******************************************************************************/ |