diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/conversation/Makefile.am | 18 | ||||
-rw-r--r-- | src/conversation/conversation_api2.c | 12 | ||||
-rw-r--r-- | src/conversation/gnunet-conversation-new.c | 533 |
3 files changed, 333 insertions, 230 deletions
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am index a348c1df8..d336d93e6 100644 --- a/src/conversation/Makefile.am +++ b/src/conversation/Makefile.am | |||
@@ -44,8 +44,6 @@ libgnunetconversation_la_SOURCES = \ | |||
44 | conversation_api.c \ | 44 | conversation_api.c \ |
45 | conversation_api2.c | 45 | conversation_api2.c |
46 | libgnunetconversation_la_LIBADD = \ | 46 | libgnunetconversation_la_LIBADD = \ |
47 | libgnunetmicrophone.la \ | ||
48 | libgnunetspeaker.la \ | ||
49 | $(top_builddir)/src/gns/libgnunetgns.la \ | 47 | $(top_builddir)/src/gns/libgnunetgns.la \ |
50 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 48 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
51 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 49 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
@@ -110,8 +108,13 @@ gnunet_service_conversation_LDFLAGS = \ | |||
110 | gnunet_service_conversation_new_SOURCES = \ | 108 | gnunet_service_conversation_new_SOURCES = \ |
111 | gnunet-service-conversation-new.c | 109 | gnunet-service-conversation-new.c |
112 | gnunet_service_conversation_new_LDADD = \ | 110 | gnunet_service_conversation_new_LDADD = \ |
113 | -lgnunetutil -lgnunetmesh \ | 111 | libgnunetconversation.la \ |
114 | $(INTLLIBS) | 112 | libgnunetspeaker.la \ |
113 | libgnunetmicrophone.la \ | ||
114 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
115 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
116 | $(INTLLIBS) | ||
117 | |||
115 | gnunet_service_conversation_new_LDFLAGS = \ | 118 | gnunet_service_conversation_new_LDFLAGS = \ |
116 | $(GNUNET_LDFLAGS) $(WINFLAGS) | 119 | $(GNUNET_LDFLAGS) $(WINFLAGS) |
117 | 120 | ||
@@ -127,8 +130,13 @@ gnunet_conversation_LDFLAGS = \ | |||
127 | gnunet_conversation_new_SOURCES = \ | 130 | gnunet_conversation_new_SOURCES = \ |
128 | gnunet-conversation-new.c | 131 | gnunet-conversation-new.c |
129 | gnunet_conversation_new_LDADD = \ | 132 | gnunet_conversation_new_LDADD = \ |
133 | libgnunetmicrophone.la \ | ||
134 | libgnunetspeaker.la \ | ||
130 | libgnunetconversation.la \ | 135 | libgnunetconversation.la \ |
131 | -lgnunetutil \ | 136 | $(top_builddir)/src/gns/libgnunetgns.la \ |
137 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
138 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
139 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
132 | $(INTLLIBS) | 140 | $(INTLLIBS) |
133 | gnunet_conversation_new_LDFLAGS = \ | 141 | gnunet_conversation_new_LDFLAGS = \ |
134 | $(GNUNET_LDFLAGS) $(WINFLAGS) | 142 | $(GNUNET_LDFLAGS) $(WINFLAGS) |
diff --git a/src/conversation/conversation_api2.c b/src/conversation/conversation_api2.c index 69e54c13b..dfba3366c 100644 --- a/src/conversation/conversation_api2.c +++ b/src/conversation/conversation_api2.c | |||
@@ -514,10 +514,10 @@ transmit_phone_audio (void *cls, | |||
514 | * @param mic microphone to use | 514 | * @param mic microphone to use |
515 | */ | 515 | */ |
516 | void | 516 | void |
517 | GNUNET_CONVERSTATION_phone_pick_up (struct GNUNET_CONVERSATION_Phone *phone, | 517 | GNUNET_CONVERSATION_phone_pick_up (struct GNUNET_CONVERSATION_Phone *phone, |
518 | const char *metadata, | 518 | const char *metadata, |
519 | struct GNUNET_SPEAKER_Handle *speaker, | 519 | struct GNUNET_SPEAKER_Handle *speaker, |
520 | struct GNUNET_MICROPHONE_Handle *mic) | 520 | struct GNUNET_MICROPHONE_Handle *mic) |
521 | { | 521 | { |
522 | struct GNUNET_MQ_Envelope *e; | 522 | struct GNUNET_MQ_Envelope *e; |
523 | struct ClientPhonePickupMessage *pick; | 523 | struct ClientPhonePickupMessage *pick; |
@@ -546,8 +546,8 @@ GNUNET_CONVERSTATION_phone_pick_up (struct GNUNET_CONVERSATION_Phone *phone, | |||
546 | * @param reason text we give to the other party about why we terminated the conversation | 546 | * @param reason text we give to the other party about why we terminated the conversation |
547 | */ | 547 | */ |
548 | void | 548 | void |
549 | GNUNET_CONVERSTATION_phone_hang_up (struct GNUNET_CONVERSATION_Phone *phone, | 549 | GNUNET_CONVERSATION_phone_hang_up (struct GNUNET_CONVERSATION_Phone *phone, |
550 | const char *reason) | 550 | const char *reason) |
551 | { | 551 | { |
552 | struct GNUNET_MQ_Envelope *e; | 552 | struct GNUNET_MQ_Envelope *e; |
553 | struct ClientPhoneHangupMessage *hang; | 553 | struct ClientPhoneHangupMessage *hang; |
diff --git a/src/conversation/gnunet-conversation-new.c b/src/conversation/gnunet-conversation-new.c index a4088984b..d8b25ef78 100644 --- a/src/conversation/gnunet-conversation-new.c +++ b/src/conversation/gnunet-conversation-new.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 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 | 16 | along with GNUnet; see the file COPYING. If not, write to the |
17 | Free Software Foundation, InGNUNET_SERVERc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
@@ -32,9 +32,19 @@ | |||
32 | #define MAX_MESSAGE_LENGTH (32 * 1024) | 32 | #define MAX_MESSAGE_LENGTH (32 * 1024) |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * CONVERSATION handle | 35 | * Phone handle |
36 | */ | 36 | */ |
37 | static struct GNUNET_CONVERSATION_Handle *conversation; | 37 | static struct GNUNET_CONVERSATION_Phone *phone; |
38 | |||
39 | /** | ||
40 | * Call handle | ||
41 | */ | ||
42 | static struct GNUNET_CONVERSATION_Call *call; | ||
43 | |||
44 | /** | ||
45 | * Desired phone line. | ||
46 | */ | ||
47 | static unsigned int line; | ||
38 | 48 | ||
39 | /** | 49 | /** |
40 | * Task which handles the commands | 50 | * Task which handles the commands |
@@ -42,231 +52,265 @@ static struct GNUNET_CONVERSATION_Handle *conversation; | |||
42 | static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task; | 52 | static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task; |
43 | 53 | ||
44 | /** | 54 | /** |
45 | * Function declareation for executing a action | 55 | * Our speaker. |
46 | */ | 56 | */ |
47 | typedef int (*ActionFunction) (const char *argumetns, | 57 | static struct GNUNET_SPEAKER_Handle *speaker; |
48 | const void *xtra); | ||
49 | 58 | ||
50 | /** | 59 | /** |
51 | * Structure which defines a command | 60 | * Our microphone. |
52 | */ | 61 | */ |
53 | struct VoipCommand | 62 | static struct GNUNET_MICROPHONE_Handle *mic; |
54 | { | ||
55 | const char *command; | ||
56 | ActionFunction Action; | ||
57 | const char *helptext; | ||
58 | }; | ||
59 | 63 | ||
64 | /** | ||
65 | * Our configuration. | ||
66 | */ | ||
67 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
60 | 68 | ||
61 | static int | 69 | /** |
62 | do_help (const char *args, | 70 | * Our ego. |
63 | const void *xtra); | 71 | */ |
72 | static struct GNUNET_IDENTITY_Ego *caller_id; | ||
64 | 73 | ||
74 | /** | ||
75 | * Handle to identity service. | ||
76 | */ | ||
77 | static struct GNUNET_IDENTITY_Handle *id; | ||
65 | 78 | ||
66 | /** | 79 | /** |
67 | * Method called whenever a call is incoming | 80 | * Name of our ego. |
68 | * | ||
69 | * @param cls closure | ||
70 | * @param handle to the conversation session | ||
71 | * @param caller peer that calls you | ||
72 | */ | 81 | */ |
73 | static void | 82 | static char *ego_name; |
74 | call_handler (void *cls, | ||
75 | struct GNUNET_CONVERSATION_Handle *handle, | ||
76 | const struct GNUNET_PeerIdentity *caller) | ||
77 | { | ||
78 | FPRINTF (stdout, | ||
79 | _("Incoming call from peer: %s\n"), | ||
80 | GNUNET_i2s_full (caller)); | ||
81 | } | ||
82 | 83 | ||
83 | 84 | ||
84 | /** | 85 | /** |
85 | * Method called whenever a call is rejected | 86 | * Function called with an event emitted by a phone. |
86 | * | 87 | * |
87 | * @param cls closure | 88 | * @param cls closure |
88 | * @param handle to the conversation session | 89 | * @param code type of the event on the phone |
89 | * @param reason given reason why the call was rejected | 90 | * @param ... additional information, depends on @a code |
90 | * @param peer peer that rejected your call | ||
91 | */ | 91 | */ |
92 | static void | 92 | static void |
93 | reject_handler (void *cls, | 93 | phone_event_handler (void *cls, |
94 | struct GNUNET_CONVERSATION_Handle *handle, | 94 | enum GNUNET_CONVERSATION_EventCode code, |
95 | enum GNUNET_CONVERSATION_RejectReason reason, | 95 | ...) |
96 | const struct GNUNET_PeerIdentity *peer) | ||
97 | { | 96 | { |
98 | FPRINTF (stdout, | 97 | va_list va; |
99 | _("Peer %s rejected your call. Reason: %d\n"), | 98 | |
100 | GNUNET_i2s_full (peer), reason); | 99 | va_start (va, code); |
100 | switch (code) | ||
101 | { | ||
102 | case GNUNET_CONVERSATION_EC_RING: | ||
103 | FPRINTF (stdout, | ||
104 | _("Incoming call from `%s'. Enter /accept to take it.\n"), | ||
105 | va_arg (va, const char *)); | ||
106 | break; | ||
107 | case GNUNET_CONVERSATION_EC_RINGING: | ||
108 | GNUNET_break (0); | ||
109 | break; | ||
110 | case GNUNET_CONVERSATION_EC_READY: | ||
111 | GNUNET_break (0); | ||
112 | break; | ||
113 | case GNUNET_CONVERSATION_EC_GNS_FAIL: | ||
114 | GNUNET_break (0); | ||
115 | break; | ||
116 | case GNUNET_CONVERSATION_EC_BUSY: | ||
117 | GNUNET_break (0); | ||
118 | break; | ||
119 | case GNUNET_CONVERSATION_EC_TERMINATED: | ||
120 | FPRINTF (stdout, | ||
121 | _("Call terminated: %s\n"), | ||
122 | va_arg (va, const char *)); | ||
123 | break; | ||
124 | } | ||
125 | va_end (va); | ||
101 | } | 126 | } |
102 | 127 | ||
103 | 128 | ||
104 | /** | 129 | /** |
105 | * Method called whenever a notification is there | 130 | * Function called with an event emitted by a phone. |
106 | * | 131 | * |
107 | * @param cls closure | 132 | * @param cls closure |
108 | * @param handle to the conversation session | 133 | * @param code type of the event on the phone |
109 | * @param type the type of the notification | 134 | * @param ... additional information, depends on @a code |
110 | * @param peer peer that the notification is about | ||
111 | */ | 135 | */ |
112 | static void | 136 | static void |
113 | notification_handler (void *cls, | 137 | call_event_handler (void *cls, |
114 | struct GNUNET_CONVERSATION_Handle *handle, | 138 | enum GNUNET_CONVERSATION_EventCode code, |
115 | enum GNUNET_CONVERSATION_NotificationType type, | 139 | ...) |
116 | const struct GNUNET_PeerIdentity *peer) | ||
117 | { | 140 | { |
118 | switch (type) | 141 | va_list va; |
142 | |||
143 | va_start (va, code); | ||
144 | switch (code) | ||
119 | { | 145 | { |
120 | case GNUNET_CONVERSATION_NT_SERVICE_BLOCKED: | 146 | case GNUNET_CONVERSATION_EC_RING: |
147 | GNUNET_break (0); | ||
148 | break; | ||
149 | case GNUNET_CONVERSATION_EC_RINGING: | ||
121 | FPRINTF (stdout, | 150 | FPRINTF (stdout, |
122 | _("The service is already in use. Try again later.")); | 151 | "%s", |
123 | break; | 152 | _("Ringing other party\n")); |
124 | case GNUNET_CONVERSATION_NT_NO_PEER: | 153 | break; |
125 | FPRINTF (stdout, | 154 | case GNUNET_CONVERSATION_EC_READY: |
126 | _("The Peer you were calling is no correct peer.\n")); | ||
127 | break; | ||
128 | case GNUNET_CONVERSATION_NT_NO_ANSWER: | ||
129 | FPRINTF (stdout, | ||
130 | _("Peer %s did not answer your call.\n"), | ||
131 | GNUNET_i2s_full (peer)); | ||
132 | break; | ||
133 | case GNUNET_CONVERSATION_NT_AVAILABLE_AGAIN: | ||
134 | FPRINTF (stdout, | 155 | FPRINTF (stdout, |
135 | _("Peer %s is now available.\n"), | 156 | _("Connection established: %s\n"), |
136 | GNUNET_i2s_full (peer)); | 157 | va_arg (va, const char *)); |
137 | break; | 158 | break; |
138 | case GNUNET_CONVERSATION_NT_CALL_ACCEPTED: | 159 | case GNUNET_CONVERSATION_EC_GNS_FAIL: |
139 | FPRINTF (stdout, | ||
140 | _("Peer %s has accepted your call.\n"), | ||
141 | GNUNET_i2s_full (peer)); | ||
142 | break; | ||
143 | case GNUNET_CONVERSATION_NT_CALL_TERMINATED: | ||
144 | FPRINTF (stdout, | 160 | FPRINTF (stdout, |
145 | _("Peer %s has terminated the call.\n"), | 161 | "%s", |
146 | GNUNET_i2s_full (peer)); | 162 | _("Failed to resolve name\n")); |
147 | break; | 163 | break; |
148 | default: | 164 | case GNUNET_CONVERSATION_EC_BUSY: |
149 | GNUNET_break (0); | 165 | FPRINTF (stdout, |
150 | } | 166 | "%s", |
167 | _("Line busy\n")); | ||
168 | break; | ||
169 | case GNUNET_CONVERSATION_EC_TERMINATED: | ||
170 | FPRINTF (stdout, | ||
171 | _("Call terminated: %s\n"), | ||
172 | va_arg (va, const char *)); | ||
173 | GNUNET_CONVERSATION_call_stop (call, NULL); | ||
174 | call = NULL; | ||
175 | if (NULL == caller_id) | ||
176 | { | ||
177 | FPRINTF (stderr, | ||
178 | _("Ego `%s' no longer available, phone is now down.\n"), | ||
179 | ego_name); | ||
180 | return; | ||
181 | } | ||
182 | phone = GNUNET_CONVERSATION_phone_create (cfg, | ||
183 | caller_id, | ||
184 | &phone_event_handler, NULL); | ||
185 | break; | ||
186 | } | ||
187 | va_end (va); | ||
151 | } | 188 | } |
152 | 189 | ||
153 | 190 | ||
154 | /** | 191 | /** |
155 | * Method called whenever a notification for missed calls is there | 192 | * Function declareation for executing a action |
156 | * | 193 | * |
157 | * @param cls closure | 194 | * @param arguments arguments given to the function |
158 | * @param handle to the conversation session | ||
159 | * @param missed_calls a list of missed calls | ||
160 | */ | 195 | */ |
161 | static void | 196 | typedef void (*ActionFunction) (const char *arguments); |
162 | missed_call_handler (void *cls, | ||
163 | struct GNUNET_CONVERSATION_Handle *handle, | ||
164 | struct GNUNET_CONVERSATION_MissedCallNotification *missed_calls) | ||
165 | { | ||
166 | FPRINTF (stdout, | ||
167 | _("You have missed calls.\n")); | ||
168 | } | ||
169 | 197 | ||
170 | 198 | ||
171 | /** | 199 | /** |
172 | * Terminating the client | 200 | * Structure which defines a command |
173 | */ | 201 | */ |
174 | static int | 202 | struct VoipCommand |
175 | do_quit (const char *args, | ||
176 | const void *xtra) | ||
177 | { | 203 | { |
178 | return GNUNET_SYSERR; | 204 | /** |
179 | } | 205 | * Command the user needs to enter. |
206 | */ | ||
207 | const char *command; | ||
208 | |||
209 | /** | ||
210 | * Function to call on command. | ||
211 | */ | ||
212 | ActionFunction Action; | ||
213 | |||
214 | /** | ||
215 | * Help text for the command. | ||
216 | */ | ||
217 | const char *helptext; | ||
218 | }; | ||
180 | 219 | ||
181 | 220 | ||
182 | /** | 221 | /** |
222 | * Action function to print help for the command shell. | ||
183 | * | 223 | * |
224 | * @param arguments arguments given to the command | ||
184 | */ | 225 | */ |
185 | static int | 226 | static void |
186 | do_unknown (const char *msg, | 227 | do_help (const char *args); |
187 | const void *xtra) | ||
188 | { | ||
189 | FPRINTF (stderr, | ||
190 | _("Unknown command `%s'\n"), | ||
191 | msg); | ||
192 | return GNUNET_OK; | ||
193 | } | ||
194 | 228 | ||
195 | 229 | ||
196 | /** | 230 | /** |
197 | * Initiating a new call | 231 | * Terminate the client |
232 | * | ||
233 | * @param args arguments given to the command | ||
198 | */ | 234 | */ |
199 | static int | 235 | static void |
200 | do_call (const char *arg, | 236 | do_quit (const char *args) |
201 | const void *xtra) | ||
202 | { | 237 | { |
203 | FPRINTF (stdout, | 238 | GNUNET_SCHEDULER_shutdown (); |
204 | _("Initiating call to: %s\n"), | ||
205 | arg); | ||
206 | GNUNET_CONVERSATION_call (conversation, | ||
207 | arg, | ||
208 | GNUNET_YES); | ||
209 | return GNUNET_OK; | ||
210 | } | 239 | } |
211 | 240 | ||
212 | 241 | ||
213 | /** | 242 | /** |
214 | * Initiating a new call | 243 | * Handler for unknown command. |
244 | * | ||
245 | * @param args arguments given to the command | ||
215 | */ | 246 | */ |
216 | static int | 247 | static void |
217 | do_call_peer (const char *arg, | 248 | do_unknown (const char *msg) |
218 | const void *xtra) | ||
219 | { | 249 | { |
220 | FPRINTF (stdout, | 250 | FPRINTF (stderr, |
221 | _("Initiating call to: %s\n"), | 251 | _("Unknown command `%s'\n"), |
222 | arg); | 252 | msg); |
223 | GNUNET_CONVERSATION_call (conversation, | ||
224 | arg, | ||
225 | GNUNET_NO); | ||
226 | return GNUNET_OK; | ||
227 | } | 253 | } |
228 | 254 | ||
229 | 255 | ||
230 | /** | 256 | /** |
231 | * Accepting an incoming call | 257 | * Initiating a new call |
258 | * | ||
259 | * @param args arguments given to the command | ||
232 | */ | 260 | */ |
233 | static int | 261 | static void |
234 | do_accept (const char *args, | 262 | do_call (const char *arg) |
235 | const void *xtra) | ||
236 | { | 263 | { |
237 | FPRINTF (stdout, | 264 | if (NULL != call) |
238 | _("Accepting the call\n")); | 265 | return; |
239 | GNUNET_CONVERSATION_accept (conversation); | 266 | if (NULL == caller_id) |
240 | 267 | { | |
241 | return GNUNET_OK; | 268 | FPRINTF (stderr, |
269 | _("Ego `%s' not available\n"), | ||
270 | ego_name); | ||
271 | return; | ||
272 | } | ||
273 | /* FIXME: also check that we do NOT have a running conversation or ring */ | ||
274 | GNUNET_CONVERSATION_phone_destroy (phone); | ||
275 | phone = NULL; | ||
276 | call = GNUNET_CONVERSATION_call_start (cfg, | ||
277 | caller_id, | ||
278 | arg, | ||
279 | speaker, | ||
280 | mic, | ||
281 | &call_event_handler, NULL); | ||
242 | } | 282 | } |
243 | 283 | ||
244 | 284 | ||
245 | /** | 285 | /** |
246 | * Rejecting a call | 286 | * Accepting an incoming call |
287 | * | ||
288 | * @param args arguments given to the command | ||
247 | */ | 289 | */ |
248 | static int | 290 | static void |
249 | do_reject (const char *args, | 291 | do_accept (const char *args) |
250 | const void *xtra) | ||
251 | { | 292 | { |
252 | FPRINTF (stdout, | 293 | if (NULL == phone) |
253 | _("Rejecting the call\n")); | 294 | return; |
254 | GNUNET_CONVERSATION_reject (conversation); | 295 | /* FIXME: also check that we don't have a running conversation */ |
255 | return GNUNET_OK; | 296 | GNUNET_CONVERSATION_phone_pick_up (phone, |
297 | args, | ||
298 | speaker, | ||
299 | mic); | ||
256 | } | 300 | } |
257 | 301 | ||
258 | 302 | ||
259 | /** | 303 | /** |
260 | * Terminating a call | 304 | * Rejecting a call |
305 | * | ||
306 | * @param args arguments given to the command | ||
261 | */ | 307 | */ |
262 | static int | 308 | static void |
263 | do_hang_up (const char *args, | 309 | do_reject (const char *args) |
264 | const void *xtra) | ||
265 | { | 310 | { |
266 | FPRINTF (stdout, | 311 | /* FIXME: also check that we do have a running conversation or ring */ |
267 | _("Terminating the call\n")); | 312 | GNUNET_CONVERSATION_phone_hang_up (phone, |
268 | GNUNET_CONVERSATION_hangup (conversation); | 313 | args); |
269 | return GNUNET_OK; | ||
270 | } | 314 | } |
271 | 315 | ||
272 | 316 | ||
@@ -274,36 +318,36 @@ do_hang_up (const char *args, | |||
274 | * List of supported commands. | 318 | * List of supported commands. |
275 | */ | 319 | */ |
276 | static struct VoipCommand commands[] = { | 320 | static struct VoipCommand commands[] = { |
277 | {"/call ", &do_call, gettext_noop ("Use `/call gns_name'")}, | 321 | {"/call ", &do_call, |
278 | {"/callpeer ", &do_call_peer, | 322 | gettext_noop ("Use `/call USER.gnu'")}, |
279 | gettext_noop ("Use `/call private_key' to call a person")}, | ||
280 | {"/accept", &do_accept, | 323 | {"/accept", &do_accept, |
281 | gettext_noop ("Use `/accept' to accept an incoming call")}, | 324 | gettext_noop ("Use `/accept MESSAGE' to accept an incoming call")}, |
282 | {"/terminate", &do_hang_up, | 325 | {"/cancel", &do_reject, |
283 | gettext_noop ("Use `/terminate' to end a call")}, | 326 | gettext_noop ("Use `/cancel MESSAGE' to reject or terminate a call")}, |
284 | {"/reject", &do_reject, | 327 | {"/quit", &do_quit, |
285 | gettext_noop ("Use `/rejet' to reject an incoming call")}, | 328 | gettext_noop ("Use `/quit' to terminate gnunet-conversation")}, |
286 | {"/quit", &do_quit, gettext_noop ("Use `/quit' to terminate gnunet-conversation")}, | ||
287 | {"/help", &do_help, | 329 | {"/help", &do_help, |
288 | gettext_noop ("Use `/help command' to get help for a specific command")}, | 330 | gettext_noop ("Use `/help command' to get help for a specific command")}, |
289 | {"/", &do_unknown, NULL}, | 331 | {"", &do_unknown, |
290 | {"", &do_unknown, NULL}, | 332 | NULL}, |
291 | {NULL, NULL, NULL}, | 333 | {NULL, NULL, NULL}, |
292 | }; | 334 | }; |
293 | 335 | ||
294 | 336 | ||
295 | /** | 337 | /** |
338 | * Action function to print help for the command shell. | ||
296 | * | 339 | * |
340 | * @param arguments arguments given to the command | ||
297 | */ | 341 | */ |
298 | static int | 342 | static void |
299 | do_help (const char *args, | 343 | do_help (const char *args) |
300 | const void *xtra) | ||
301 | { | 344 | { |
302 | int i; | 345 | unsigned int i; |
303 | 346 | ||
304 | i = 0; | 347 | i = 0; |
305 | while ((NULL != args) && (0 != strlen (args)) && | 348 | while ( (NULL != args) && |
306 | (commands[i].Action != &do_help)) | 349 | (0 != strlen (args)) && |
350 | (commands[i].Action != &do_help)) | ||
307 | { | 351 | { |
308 | if (0 == | 352 | if (0 == |
309 | strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1)) | 353 | strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1)) |
@@ -311,7 +355,7 @@ do_help (const char *args, | |||
311 | FPRINTF (stdout, | 355 | FPRINTF (stdout, |
312 | "%s\n", | 356 | "%s\n", |
313 | gettext (commands[i].helptext)); | 357 | gettext (commands[i].helptext)); |
314 | return GNUNET_OK; | 358 | return; |
315 | } | 359 | } |
316 | i++; | 360 | i++; |
317 | } | 361 | } |
@@ -322,7 +366,7 @@ do_help (const char *args, | |||
322 | while (commands[i].Action != &do_help) | 366 | while (commands[i].Action != &do_help) |
323 | { | 367 | { |
324 | FPRINTF (stdout, | 368 | FPRINTF (stdout, |
325 | " %s", | 369 | "%s", |
326 | gettext (commands[i].command)); | 370 | gettext (commands[i].command)); |
327 | i++; | 371 | i++; |
328 | } | 372 | } |
@@ -332,33 +376,53 @@ do_help (const char *args, | |||
332 | FPRINTF (stdout, | 376 | FPRINTF (stdout, |
333 | "%s\n", | 377 | "%s\n", |
334 | gettext (commands[i].helptext)); | 378 | gettext (commands[i].helptext)); |
335 | return GNUNET_OK; | ||
336 | } | 379 | } |
337 | 380 | ||
338 | 381 | ||
339 | /** | 382 | /** |
383 | * Task run during shutdown. | ||
340 | * | 384 | * |
385 | * @param cls NULL | ||
386 | * @param tc unused | ||
341 | */ | 387 | */ |
342 | static void | 388 | static void |
343 | do_stop_task (void *cls, | 389 | do_stop_task (void *cls, |
344 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 390 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
345 | { | 391 | { |
346 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 392 | if (NULL != call) |
347 | "Running shutdown task\n"); | 393 | { |
348 | GNUNET_CONVERSATION_disconnect (conversation); | 394 | GNUNET_CONVERSATION_call_stop (call, NULL); |
349 | 395 | call = NULL; | |
350 | if (handle_cmd_task != GNUNET_SCHEDULER_NO_TASK) | 396 | } |
397 | if (NULL != phone) | ||
398 | { | ||
399 | GNUNET_CONVERSATION_phone_destroy (phone); | ||
400 | phone = NULL; | ||
401 | } | ||
402 | if (GNUNET_SCHEDULER_NO_TASK != handle_cmd_task) | ||
351 | { | 403 | { |
352 | GNUNET_SCHEDULER_cancel (handle_cmd_task); | 404 | GNUNET_SCHEDULER_cancel (handle_cmd_task); |
353 | handle_cmd_task = GNUNET_SCHEDULER_NO_TASK; | 405 | handle_cmd_task = GNUNET_SCHEDULER_NO_TASK; |
354 | } | 406 | } |
355 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 407 | if (NULL != id) |
356 | "Running shutdown task finished\n"); | 408 | { |
409 | GNUNET_IDENTITY_disconnect (id); | ||
410 | id = NULL; | ||
411 | } | ||
412 | GNUNET_SPEAKER_destroy (speaker); | ||
413 | speaker = NULL; | ||
414 | GNUNET_MICROPHONE_destroy (mic); | ||
415 | mic = NULL; | ||
416 | GNUNET_free (ego_name); | ||
417 | ego_name = NULL; | ||
357 | } | 418 | } |
358 | 419 | ||
359 | 420 | ||
360 | /** | 421 | /** |
422 | * Task to handle commands from the terminal. | ||
361 | * | 423 | * |
424 | * @param cls NULL | ||
425 | * @param tc scheduler context | ||
362 | */ | 426 | */ |
363 | static void | 427 | static void |
364 | handle_command (void *cls, | 428 | handle_command (void *cls, |
@@ -367,38 +431,66 @@ handle_command (void *cls, | |||
367 | char message[MAX_MESSAGE_LENGTH + 1]; | 431 | char message[MAX_MESSAGE_LENGTH + 1]; |
368 | int i; | 432 | int i; |
369 | 433 | ||
434 | handle_cmd_task = | ||
435 | GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, | ||
436 | GNUNET_SCHEDULER_PRIORITY_UI, | ||
437 | &handle_command, NULL); | ||
370 | /* read message from command line and handle it */ | 438 | /* read message from command line and handle it */ |
371 | memset (message, 0, MAX_MESSAGE_LENGTH + 1); | 439 | memset (message, 0, MAX_MESSAGE_LENGTH + 1); |
372 | if (NULL == fgets (message, MAX_MESSAGE_LENGTH, stdin)) | 440 | if (NULL == fgets (message, MAX_MESSAGE_LENGTH, stdin)) |
373 | goto next; | 441 | return; |
374 | if (strlen (message) == 0) | 442 | if (0 == strlen (message)) |
375 | goto next; | 443 | return; |
376 | if (message[strlen (message) - 1] == '\n') | 444 | if (message[strlen (message) - 1] == '\n') |
377 | message[strlen (message) - 1] = '\0'; | 445 | message[strlen (message) - 1] = '\0'; |
378 | if (strlen (message) == 0) | 446 | if (0 == strlen (message)) |
379 | goto next; | 447 | return; |
380 | i = 0; | 448 | i = 0; |
381 | while ((NULL != commands[i].command) && | 449 | while ((NULL != commands[i].command) && |
382 | (0 != | 450 | (0 != strncasecmp (commands[i].command, message, |
383 | strncasecmp (commands[i].command, message, | 451 | strlen (commands[i].command)))) |
384 | strlen (commands[i].command)))) | ||
385 | i++; | 452 | i++; |
386 | if (GNUNET_OK != | 453 | commands[i].Action (&message[strlen (commands[i].command)]); |
387 | commands[i].Action (&message[strlen (commands[i].command)], NULL)) | 454 | } |
388 | goto out; | ||
389 | 455 | ||
390 | next: | ||
391 | handle_cmd_task = | ||
392 | GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_multiply | ||
393 | (GNUNET_TIME_UNIT_MILLISECONDS, | ||
394 | 100), | ||
395 | GNUNET_SCHEDULER_PRIORITY_UI, | ||
396 | &handle_command, NULL); | ||
397 | return; | ||
398 | 456 | ||
399 | out: | 457 | /** |
400 | handle_cmd_task = GNUNET_SCHEDULER_NO_TASK; | 458 | * Function called by identity service with information about egos. |
401 | GNUNET_SCHEDULER_shutdown (); | 459 | * |
460 | * @param cls NULL | ||
461 | * @param ego ego handle | ||
462 | * @param ctx unused | ||
463 | * @param name name of the ego | ||
464 | */ | ||
465 | static void | ||
466 | identity_cb (void *cls, | ||
467 | struct GNUNET_IDENTITY_Ego *ego, | ||
468 | void **ctx, | ||
469 | const char *name) | ||
470 | { | ||
471 | if (NULL == name) | ||
472 | return; | ||
473 | if (ego == caller_id) | ||
474 | { | ||
475 | FPRINTF (stdout, | ||
476 | _("Name of our ego changed to `%s'\n"), | ||
477 | name); | ||
478 | GNUNET_free (ego_name); | ||
479 | ego_name = GNUNET_strdup (name); | ||
480 | return; | ||
481 | } | ||
482 | if (0 != strcmp (name, | ||
483 | ego_name)) | ||
484 | return; | ||
485 | if (NULL == ego) | ||
486 | { | ||
487 | caller_id = NULL; | ||
488 | return; | ||
489 | } | ||
490 | caller_id = ego; | ||
491 | phone = GNUNET_CONVERSATION_phone_create (cfg, | ||
492 | caller_id, | ||
493 | &phone_event_handler, NULL); | ||
402 | } | 494 | } |
403 | 495 | ||
404 | 496 | ||
@@ -416,20 +508,19 @@ run (void *cls, | |||
416 | const char *cfgfile, | 508 | const char *cfgfile, |
417 | const struct GNUNET_CONFIGURATION_Handle *c) | 509 | const struct GNUNET_CONFIGURATION_Handle *c) |
418 | { | 510 | { |
419 | if (NULL == | 511 | cfg = c; |
420 | (conversation = | 512 | speaker = GNUNET_SPEAKER_create_from_hardware (cfg); |
421 | GNUNET_CONVERSATION_connect (c, NULL, | 513 | mic = GNUNET_MICROPHONE_create_from_hardware (cfg); |
422 | &call_handler, | 514 | if (NULL == ego_name) |
423 | &reject_handler, | ||
424 | ¬ification_handler, | ||
425 | &missed_call_handler))) | ||
426 | { | 515 | { |
427 | FPRINTF (stderr, | 516 | FPRINTF (stderr, |
428 | "%s", | 517 | "%s", |
429 | _("Could not access CONVERSATION service. Exiting.\n")); | 518 | _("You must specify the NAME of an ego to use\n")); |
430 | return; | 519 | return; |
431 | } | 520 | } |
432 | 521 | id = GNUNET_IDENTITY_connect (cfg, | |
522 | &identity_cb, | ||
523 | NULL); | ||
433 | handle_cmd_task = | 524 | handle_cmd_task = |
434 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, | 525 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, |
435 | &handle_command, NULL); | 526 | &handle_command, NULL); |
@@ -449,9 +540,14 @@ int | |||
449 | main (int argc, char *const *argv) | 540 | main (int argc, char *const *argv) |
450 | { | 541 | { |
451 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | 542 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { |
543 | {'p', "phone", "LINE", | ||
544 | gettext_noop ("sets the LINE to use for the phone"), | ||
545 | 1, &GNUNET_GETOPT_set_uint, &line}, | ||
546 | {'e', "ego", "NAME", | ||
547 | gettext_noop ("sets the NAME of the ego to use for the phone (and name resolution)"), | ||
548 | 1, &GNUNET_GETOPT_set_string, &ego_name}, | ||
452 | GNUNET_GETOPT_OPTION_END | 549 | GNUNET_GETOPT_OPTION_END |
453 | }; | 550 | }; |
454 | |||
455 | int flags; | 551 | int flags; |
456 | int ret; | 552 | int ret; |
457 | 553 | ||
@@ -461,13 +557,12 @@ main (int argc, char *const *argv) | |||
461 | 557 | ||
462 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 558 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
463 | return 2; | 559 | return 2; |
464 | 560 | ret = GNUNET_PROGRAM_run (argc, argv, | |
465 | ret = GNUNET_PROGRAM_run (argc, argv, "gnunet-conversation", | 561 | "gnunet-conversation", |
466 | gettext_noop ("Print information about conversation."), | 562 | gettext_noop ("Enables having a conversation with other GNUnet users."), |
467 | options, &run, NULL); | 563 | options, &run, NULL); |
468 | GNUNET_free ((void *) argv); | 564 | GNUNET_free ((void *) argv); |
469 | 565 | return (GNUNET_OK == ret) ? 0 : 1; | |
470 | return ret; | ||
471 | } | 566 | } |
472 | 567 | ||
473 | /* end of gnunet-conversation.c */ | 568 | /* end of gnunet-conversation.c */ |