use c99
[oweals/gnunet.git] / src / conversation / test_conversation_api_reject.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2013, 2014 GNUnet e.V.
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file conversation/test_conversation_api_reject.c
22  * @brief testcase for conversation_api.c
23  *
24  * This test performs the operations of a call to a phone
25  * where the phone user immediately hangs up (rejecting the
26  * call).
27  */
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testing_lib.h"
31 #include "gnunet_gnsrecord_lib.h"
32 #include "gnunet_conversation_service.h"
33 #include "gnunet_identity_service.h"
34 #include "gnunet_namestore_service.h"
35
36 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 25)
37
38 static int ok = 1;
39
40 static const struct GNUNET_CONFIGURATION_Handle *cfg;
41
42 static struct GNUNET_IDENTITY_Handle *id;
43
44 static struct GNUNET_IDENTITY_Operation *op;
45
46 static struct GNUNET_CONVERSATION_Phone *phone;
47
48 static struct GNUNET_NAMESTORE_Handle *ns;
49
50 static struct GNUNET_CONVERSATION_Call *call;
51
52 static struct GNUNET_NAMESTORE_QueueEntry *qe;
53
54 static char *gns_name;
55
56 static char *gns_caller_id;
57
58
59 static int
60 enable_speaker (void *cls)
61 {
62   GNUNET_break (0);
63   return GNUNET_SYSERR;
64 }
65
66
67 static void
68 disable_speaker (void *cls)
69 {
70   GNUNET_break (0);
71 }
72
73
74 static void
75 play (void *cls,
76       size_t data_size,
77       const void *data)
78 {
79   GNUNET_break (0);
80 }
81
82
83 static void
84 destroy_speaker (void *cls)
85 {
86 }
87
88
89 static struct GNUNET_SPEAKER_Handle call_speaker = {
90   &enable_speaker,
91   &play,
92   &disable_speaker,
93   &destroy_speaker,
94   "caller"
95 };
96
97
98 static int
99 enable_mic (void *cls,
100             GNUNET_MICROPHONE_RecordedDataCallback rdc,
101             void *rdc_cls)
102 {
103   GNUNET_break (0);
104   return GNUNET_SYSERR;
105 }
106
107
108 static void
109 disable_mic (void *cls)
110 {
111   GNUNET_break (0);
112 }
113
114
115 static void
116 destroy_mic (void *cls)
117 {
118 }
119
120
121 static struct GNUNET_MICROPHONE_Handle call_mic = {
122   &enable_mic,
123   &disable_mic,
124   &destroy_mic,
125   "caller"
126 };
127
128
129 /**
130  * Signature of the main function of a task.
131  *
132  * @param cls closure
133  */
134 static void
135 end_test (void *cls)
136 {
137   GNUNET_SCHEDULER_shutdown ();
138   if (NULL != op)
139   {
140     GNUNET_IDENTITY_cancel (op);
141     op = NULL;
142   }
143   if (NULL != call)
144   {
145     GNUNET_CONVERSATION_call_stop (call);
146     call = NULL;
147   }
148   if (NULL != phone)
149   {
150     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from PHONE service.\n");
151     GNUNET_CONVERSATION_phone_destroy (phone);
152     phone = NULL;
153   }
154   if (NULL != id)
155   {
156     GNUNET_IDENTITY_disconnect (id);
157     id = NULL;
158   }
159   if (NULL != qe)
160   {
161     GNUNET_NAMESTORE_cancel (qe);
162     qe = NULL;
163   }
164   if (NULL != ns)
165   {
166     GNUNET_NAMESTORE_disconnect (ns);
167     ns = NULL;
168   }
169 }
170
171
172 static void
173 phone_event_handler (void *cls,
174                      enum GNUNET_CONVERSATION_PhoneEventCode code,
175                      struct GNUNET_CONVERSATION_Caller *caller,
176                      const struct GNUNET_CRYPTO_EcdsaPublicKey *caller_id)
177 {
178   static enum GNUNET_CONVERSATION_PhoneEventCode expect
179     = GNUNET_CONVERSATION_EC_PHONE_RING;
180
181   GNUNET_break (code == expect);
182   switch (code)
183   {
184   case GNUNET_CONVERSATION_EC_PHONE_RING:
185     GNUNET_CONVERSATION_caller_hang_up (caller);
186     break;
187   default:
188     fprintf (stderr, "Unexpected phone code: %d\n", code);
189     break;
190   }
191 }
192
193
194 static void
195 call_event_handler (void *cls,
196                     enum GNUNET_CONVERSATION_CallEventCode code)
197 {
198   static enum GNUNET_CONVERSATION_CallEventCode expect
199     = GNUNET_CONVERSATION_EC_CALL_RINGING;
200
201   GNUNET_break (code == expect);
202   switch (code)
203   {
204   case GNUNET_CONVERSATION_EC_CALL_RINGING:
205     expect = GNUNET_CONVERSATION_EC_CALL_HUNG_UP;
206     break;
207   case GNUNET_CONVERSATION_EC_CALL_HUNG_UP:
208     call = NULL;
209     ok = 0;
210     GNUNET_SCHEDULER_shutdown ();
211     expect = -1;
212     break;
213   case GNUNET_CONVERSATION_EC_CALL_PICKED_UP:
214   case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL:
215   case GNUNET_CONVERSATION_EC_CALL_SUSPENDED:
216   case GNUNET_CONVERSATION_EC_CALL_RESUMED:
217   case GNUNET_CONVERSATION_EC_CALL_ERROR:
218     fprintf (stderr, "Unexpected call code: %d\n", code);
219     break;
220   }
221 }
222
223
224 static void
225 caller_ego_create_cont (void *cls,
226                         const char *emsg)
227 {
228   op = NULL;
229   GNUNET_assert (NULL == emsg);
230 }
231
232
233 static void
234 namestore_put_cont (void *cls,
235                     int32_t success,
236                     const char *emsg)
237 {
238   qe = NULL;
239   GNUNET_assert (GNUNET_YES == success);
240   GNUNET_assert (NULL == emsg);
241   GNUNET_assert (NULL == op);
242   op = GNUNET_IDENTITY_create (id, "caller-ego",
243                                &caller_ego_create_cont, NULL);
244 }
245
246
247 static void
248 identity_cb (void *cls,
249              struct GNUNET_IDENTITY_Ego *ego,
250              void **ctx,
251              const char *name)
252 {
253   struct GNUNET_GNSRECORD_Data rd;
254   struct GNUNET_CRYPTO_EcdsaPublicKey pub;
255
256   if (NULL == name)
257     return;
258   if (NULL == ego)
259     return;
260   if (0 == strcmp (name, "phone-ego"))
261   {
262     GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
263     GNUNET_asprintf (&gns_name,
264                      "phone.%s",
265                      GNUNET_GNSRECORD_pkey_to_zkey (&pub));
266     phone = GNUNET_CONVERSATION_phone_create (cfg,
267                                               ego,
268                                               &phone_event_handler,
269                                               NULL);
270     GNUNET_assert (NULL != phone);
271     memset (&rd, 0, sizeof (rd));
272     GNUNET_CONVERSATION_phone_get_record (phone,
273                                           &rd);
274     GNUNET_assert (rd.record_type == GNUNET_GNSRECORD_TYPE_PHONE);
275     rd.expiration_time = UINT64_MAX;
276     qe = GNUNET_NAMESTORE_records_store (ns,
277                                          GNUNET_IDENTITY_ego_get_private_key (ego),
278                                          "phone" /* GNS label */,
279                                          1,
280                                          &rd,
281                                          &namestore_put_cont,
282                                          NULL);
283     return;
284   }
285   if (0 == strcmp (name, "caller-ego"))
286   {
287     GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
288     GNUNET_asprintf (&gns_caller_id,
289                      "%s",
290                      GNUNET_GNSRECORD_pkey_to_zkey (&pub));
291     call = GNUNET_CONVERSATION_call_start (cfg,
292                                            ego,
293                                            ego,
294                                            gns_name,
295                                            &call_speaker,
296                                            &call_mic,
297                                            &call_event_handler,
298                                            NULL);
299     return;
300   }
301 }
302
303
304 static void
305 phone_ego_create_cont (void *cls,
306                        const char *emsg)
307 {
308   op = NULL;
309   GNUNET_assert (NULL == emsg);
310 }
311
312
313 static void
314 run (void *cls,
315      const struct GNUNET_CONFIGURATION_Handle *c,
316      struct GNUNET_TESTING_Peer *peer)
317 {
318   cfg = c;
319   GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_test,
320                                 NULL);
321   id = GNUNET_IDENTITY_connect (cfg,
322                                 &identity_cb,
323                                 NULL);
324   op = GNUNET_IDENTITY_create (id, "phone-ego", &phone_ego_create_cont, NULL);
325   ns = GNUNET_NAMESTORE_connect (cfg);
326 }
327
328
329 int
330 main (int argc, char *argv[])
331 {
332   if (0 != GNUNET_TESTING_peer_run ("test_conversation_api",
333                                     "test_conversation.conf",
334                                     &run, NULL))
335     return 1;
336   return ok;
337 }
338
339 /* end of test_conversation_api_reject.c */