summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--[-rwxr-xr-x]toxav/event.c247
-rw-r--r--[-rwxr-xr-x]toxav/event.h13
-rw-r--r--toxav/media.c67
-rw-r--r--toxav/media.h14
-rw-r--r--toxav/msi.c583
-rw-r--r--toxav/msi.h82
-rw-r--r--[-rwxr-xr-x]toxav/phone.c966
-rw-r--r--toxav/rtp.c570
-rw-r--r--toxav/rtp.h80
-rw-r--r--toxav/toxav.c262
-rw-r--r--toxav/toxav.h88
11 files changed, 1557 insertions, 1415 deletions
diff --git a/toxav/event.c b/toxav/event.c
index 9efe4be4..f79fd60e 100755..100644
--- a/toxav/event.c
+++ b/toxav/event.c
@@ -1,5 +1,5 @@
1/** event.c 1/** event.c
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -53,31 +53,30 @@ pthread_create(&_tid, NULL, func, args); assert( pthread_detach(_tid) == 0 ); }
53 53
54 54
55typedef struct _EventContainer { 55typedef struct _EventContainer {
56 void* (*func)(void*); 56 void *(*func)(void *);
57 void* func_args; 57 void *func_args;
58 unsigned timeout; 58 unsigned timeout;
59 long long id; 59 long long id;
60 60
61} EventContainer; 61} EventContainer;
62 62
63typedef struct _EventHandler { 63typedef struct _EventHandler {
64 EventContainer* timed_events; 64 EventContainer *timed_events;
65 size_t timed_events_count; 65 size_t timed_events_count;
66 66
67 int running; 67 int running;
68 68
69 pthread_mutex_t mutex; 69 pthread_mutex_t mutex;
70 70
71} EventHandler; 71} EventHandler;
72 72
73int throw_event( void* (func)(void*), void* arg ); 73int throw_event( void * (func)(void *), void *arg );
74int reset_timer_event ( int id, uint32_t timeout ); 74int reset_timer_event ( int id, uint32_t timeout );
75int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout); 75int throw_timer_event ( void * (func)(void *), void *arg, unsigned timeout);
76int cancel_timer_event ( int id ); 76int cancel_timer_event ( int id );
77int execute_timer_event ( int id ); 77int execute_timer_event ( int id );
78 78
79struct _Event event = 79struct _Event event = {
80{
81 throw_event, 80 throw_event,
82 /* reset_timer_event */ NULL, 81 /* reset_timer_event */ NULL,
83 throw_timer_event, 82 throw_timer_event,
@@ -88,62 +87,68 @@ struct _Event event =
88/* 87/*
89 * Random functions used by this file 88 * Random functions used by this file
90 */ 89 */
91void clear_events (EventContainer** event_container, size_t* counter) 90void clear_events (EventContainer **event_container, size_t *counter)
92{ 91{
93 free(*event_container ); 92 free(*event_container );
94 93
95 *event_container = NULL; 94 *event_container = NULL;
96 *counter = 0; 95 *counter = 0;
97} 96}
98 97
99int pop_id ( EventContainer** event_container, size_t* counter, int id ) 98int pop_id ( EventContainer **event_container, size_t *counter, int id )
100{ 99{
101 if ( !*event_container || !*counter || !id ) 100 if ( !*event_container || !*counter || !id )
102 return -1; 101 return -1;
103 102
104 EventContainer* _it = *event_container; 103 EventContainer *_it = *event_container;
105 int i; 104 int i;
106 105
107 for ( i = *counter; i; -- i ){ 106 for ( i = *counter; i; -- i ) {
108 if ( _it->id == id ) { /* Hit! */ 107 if ( _it->id == id ) { /* Hit! */
109 break; 108 break;
110 } 109 }
110
111 ++_it; 111 ++_it;
112 } 112 }
113 113
114 if ( i ) { 114 if ( i ) {
115 for ( ; i; -- i ){ *_it = *(_it + 1); ++_it; } 115 for ( ; i; -- i ) {
116 *_it = *(_it + 1);
117 ++_it;
118 }
119
116 -- (*counter ); 120 -- (*counter );
117 121
118 if ( !(*counter)) { /* Free and set to NULL */ 122 if ( !(*counter)) { /* Free and set to NULL */
119 free(*event_container); 123 free(*event_container);
120 *event_container = NULL; 124 *event_container = NULL;
121 } 125 } else {
122 else { 126 void *_result = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */
123 void* _result = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */ 127
124 128
125 129 if ( _result != NULL ) {
126 if ( _result != NULL ) { *event_container = _result; return 0; } 130 *event_container = _result;
127 else { 131 return 0;
132 } else {
128 /* Not sure what would happen next so abort execution. 133 /* Not sure what would happen next so abort execution.
129 */ 134 */
130 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); 135 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
131 abort(); 136 abort();
132 return -1; 137 return -1;
133 } 138 }
134 } 139 }
135 } 140 }
136 141
137 /* not found here */ 142 /* not found here */
138 143
139 return -1; 144 return -1;
140} 145}
141 146
142void push_event ( EventContainer** container, size_t* counter, void* (func)(void*), void* arg ) 147void push_event ( EventContainer **container, size_t *counter, void * (func)(void *), void *arg )
143{ 148{
144 EventContainer* _new = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1)); 149 EventContainer *_new = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1));
145 150
146 if ( _new == NULL ) { 151 if ( _new == NULL ) {
147 /* Not sure what would happen next so abort execution. 152 /* Not sure what would happen next so abort execution.
148 * TODO: This could notice the calling function 153 * TODO: This could notice the calling function
149 * about realloc failing. 154 * about realloc failing.
@@ -151,188 +156,194 @@ void push_event ( EventContainer** container, size_t* counter, void* (func)(void
151 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); 156 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
152 abort(); 157 abort();
153 } 158 }
154 159
155 _new[*counter].func = func; 160 _new[*counter].func = func;
156 _new[*counter].func_args = arg; 161 _new[*counter].func_args = arg;
157 _new[*counter].timeout = 0; 162 _new[*counter].timeout = 0;
158 _new[*counter].id = 0; 163 _new[*counter].id = 0;
159 164
160 (*container) = _new; 165 (*container) = _new;
161 166
162 (*counter )++; 167 (*counter )++;
163} 168}
164 169
165void reorder_events ( size_t counter, EventContainer* container, unsigned timeout ) 170void reorder_events ( size_t counter, EventContainer *container, unsigned timeout )
166{ 171{
167 if ( counter > 1 ) { 172 if ( counter > 1 ) {
168 173
169 int i = counter - 1; 174 int i = counter - 1;
170 175
171 /* start from behind excluding last added member */ 176 /* start from behind excluding last added member */
172 EventContainer* _it = &container[i - 1]; 177 EventContainer *_it = &container[i - 1];
173 178
174 EventContainer _last_added = container[i]; 179 EventContainer _last_added = container[i];
175 180
176 for ( ; i; --i ) { 181 for ( ; i; --i ) {
177 if ( _it->timeout > timeout ){ 182 if ( _it->timeout > timeout ) {
178 *(_it + 1) = *_it; 183 *(_it + 1) = *_it;
179 *_it = _last_added; -- _it; 184 *_it = _last_added;
185 -- _it;
180 } 186 }
181 } 187 }
182 188
183 } 189 }
184} 190}
185 191
186/* ============================================= */ 192/* ============================================= */
187 193
188/* main poll for event execution */ 194/* main poll for event execution */
189void* event_poll( void* arg ) 195void *event_poll( void *arg )
190{ 196{
191 EventHandler* _event_handler = arg; 197 EventHandler *_event_handler = arg;
192 198
193 while ( _event_handler->running ) 199 while ( _event_handler->running ) {
194 { 200
195
196 LOCK( _event_handler ); 201 LOCK( _event_handler );
197 202
198 if ( _event_handler->timed_events ){ 203 if ( _event_handler->timed_events ) {
199 204
200 uint32_t _time = ((uint32_t)(current_time() / 1000)); 205 uint32_t _time = ((uint32_t)(current_time() / 1000));
201 206
202 if ( _event_handler->timed_events[0].timeout < _time ) { 207 if ( _event_handler->timed_events[0].timeout < _time ) {
203 208
204 RUN_IN_THREAD ( _event_handler->timed_events[0].func, 209 RUN_IN_THREAD ( _event_handler->timed_events[0].func,
205 _event_handler->timed_events[0].func_args ); 210 _event_handler->timed_events[0].func_args );
206 211
207 pop_id(&_event_handler->timed_events, 212 pop_id(&_event_handler->timed_events,
208 &_event_handler->timed_events_count, 213 &_event_handler->timed_events_count,
209 _event_handler->timed_events[0].id); 214 _event_handler->timed_events[0].id);
210 215
211 } 216 }
212 217
213 } 218 }
214 219
215 UNLOCK( _event_handler ); 220 UNLOCK( _event_handler );
216 221
217 usleep(FREQUENCY); 222 usleep(FREQUENCY);
218 } 223 }
219 224
220 LOCK( _event_handler ); 225 LOCK( _event_handler );
221 226
222 clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count); 227 clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count);
223 228
224 UNLOCK( _event_handler ); 229 UNLOCK( _event_handler );
225 230
226 _event_handler->running = -1; 231 _event_handler->running = -1;
227 pthread_exit(NULL); 232 pthread_exit(NULL);
228} 233}
229 234
230int throw_event( void* (func)(void*), void* arg ) 235int throw_event( void * (func)(void *), void *arg )
231{ 236{
232 pthread_t _tid; 237 pthread_t _tid;
233 int _rc = 238 int _rc =
234 pthread_create(&_tid, NULL, func, arg ); 239 pthread_create(&_tid, NULL, func, arg );
235 240
236 return (0 != _rc ) ? _rc : pthread_detach(_tid); 241 return (0 != _rc ) ? _rc : pthread_detach(_tid);
237} 242}
238 243
239EventHandler event_handler; 244EventHandler event_handler;
240 245
241/* Place and order array of timers */ 246/* Place and order array of timers */
242int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout) 247int throw_timer_event ( void * (func)(void *), void *arg, unsigned timeout)
243{ 248{
244 static int _unique_id = 1; 249 static int _unique_id = 1;
245 250
246 push_event(&event_handler.timed_events, &(event_handler.timed_events_count), func, arg ); 251 push_event(&event_handler.timed_events, &(event_handler.timed_events_count), func, arg );
247 252
248 size_t _counter = event_handler.timed_events_count; 253 size_t _counter = event_handler.timed_events_count;
249 254
250 event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)(current_time() / 1000)); 255 event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)(current_time() / 1000));
251 event_handler.timed_events[_counter - 1].id = _unique_id; ++_unique_id; 256 event_handler.timed_events[_counter - 1].id = _unique_id;
252 257 ++_unique_id;
253 258
259
254 /* reorder */ 260 /* reorder */
255 261
256 reorder_events(_counter, event_handler.timed_events, timeout ); 262 reorder_events(_counter, event_handler.timed_events, timeout );
257 263
258 return _unique_id - 1; 264 return _unique_id - 1;
259} 265}
260 266
261int execute_timer_event ( int id ) 267int execute_timer_event ( int id )
262{ 268{
263 int _status; 269 int _status;
264 270
265 LOCK((&event_handler)); 271 LOCK((&event_handler));
266 EventContainer* _it = event_handler.timed_events; 272 EventContainer *_it = event_handler.timed_events;
267 273
268 int _i = event_handler.timed_events_count; 274 int _i = event_handler.timed_events_count;
269 275
270 /* Find it and execute */ 276 /* Find it and execute */
271 for ( ; _i; _i-- ) { 277 for ( ; _i; _i-- ) {
272 if ( _it->id == id ) { 278 if ( _it->id == id ) {
273 RUN_IN_THREAD ( _it->func, _it->func_args ); 279 RUN_IN_THREAD ( _it->func, _it->func_args );
274 break; 280 break;
275 } 281 }
282
276 ++_it; 283 ++_it;
277 } 284 }
278 285
279 /* Now remove it from the queue */ 286 /* Now remove it from the queue */
280 287
281 if ( _i ) { 288 if ( _i ) {
282 for ( ; _i; -- _i ){ *_it = *(_it + 1); ++_it; } 289 for ( ; _i; -- _i ) {
283 290 *_it = *(_it + 1);
291 ++_it;
292 }
293
284 -- event_handler.timed_events_count; 294 -- event_handler.timed_events_count;
285 295
286 if ( !event_handler.timed_events_count ) { /* Free and set to null */ 296 if ( !event_handler.timed_events_count ) { /* Free and set to null */
287 free(event_handler.timed_events); 297 free(event_handler.timed_events);
288 event_handler.timed_events = NULL; 298 event_handler.timed_events = NULL;
289 } 299 } else {
290 else { 300 void *_result = realloc(event_handler.timed_events,
291 void* _result = realloc(event_handler.timed_events, sizeof(EventContainer) * event_handler.timed_events_count); /* resize */ 301 sizeof(EventContainer) * event_handler.timed_events_count); /* resize */
292 302
293 if ( _result != NULL ) { event_handler.timed_events = _result; } 303 if ( _result != NULL ) {
294 else { 304 event_handler.timed_events = _result;
305 } else {
295 /* Not sure what would happen next so abort execution. 306 /* Not sure what would happen next so abort execution.
296 */ 307 */
297 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); 308 fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__);
298 abort(); 309 abort();
299 return -1; 310 return -1;
300 } 311 }
301 } 312 }
302 313
303 _status = 0; 314 _status = 0;
304 315
305 } 316 } else _status = -1;
306 else _status = -1; 317
307
308 UNLOCK((&event_handler)); 318 UNLOCK((&event_handler));
309 319
310 return _status; 320 return _status;
311} 321}
312 322
313int reset_timer_event ( int id, uint32_t timeout ) 323int reset_timer_event ( int id, uint32_t timeout )
314{ 324{
315 int _status; 325 int _status;
316 326
317 LOCK((&event_handler)); 327 LOCK((&event_handler));
318 328
319 EventContainer* _it = event_handler.timed_events; 329 EventContainer *_it = event_handler.timed_events;
320 330
321 int _i = event_handler.timed_events_count; 331 int _i = event_handler.timed_events_count;
322 332
323 /* Find it and change */ 333 /* Find it and change */
324 for ( ; _i; _i-- ) { 334 for ( ; _i; _i-- ) {
325 if ( _it->id == id ) { 335 if ( _it->id == id ) {
326 _it->timeout = timeout + ((uint32_t)(current_time() / 1000)); 336 _it->timeout = timeout + ((uint32_t)(current_time() / 1000));
327 break; 337 break;
328 } 338 }
339
329 ++_it; 340 ++_it;
330 } 341 }
331 342
332 _status = _i ? -1 : 0; 343 _status = _i ? -1 : 0;
333 344
334 UNLOCK((&event_handler)); 345 UNLOCK((&event_handler));
335 346
336 return _status; 347 return _status;
337} 348}
338 349
@@ -352,11 +363,11 @@ void __attribute__((constructor)) init_event_poll ()
352{ 363{
353 event_handler.timed_events = NULL; 364 event_handler.timed_events = NULL;
354 event_handler.timed_events_count = 0; 365 event_handler.timed_events_count = 0;
355 366
356 event_handler.running = 1; 367 event_handler.running = 1;
357 368
358 pthread_mutex_init(&event_handler.mutex, NULL); 369 pthread_mutex_init(&event_handler.mutex, NULL);
359 370
360 RUN_IN_THREAD(event_poll, &event_handler); 371 RUN_IN_THREAD(event_poll, &event_handler);
361} 372}
362 373
@@ -365,9 +376,9 @@ void __attribute__((destructor)) terminate_event_poll()
365{ 376{
366 /* Exit thread */ 377 /* Exit thread */
367 event_handler.running = 0; 378 event_handler.running = 0;
368 379
369 /* Give it enought time to exit */ 380 /* Give it enought time to exit */
370 usleep(FREQUENCY*2); 381 usleep(FREQUENCY * 2);
371 382
372 pthread_mutex_destroy( &event_handler.mutex ); 383 pthread_mutex_destroy( &event_handler.mutex );
373} \ No newline at end of file 384} \ No newline at end of file
diff --git a/toxav/event.h b/toxav/event.h
index 17dadbd5..0fb2d120 100755..100644
--- a/toxav/event.h
+++ b/toxav/event.h
@@ -1,5 +1,5 @@
1/** event.h 1/** event.h
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -36,13 +36,12 @@
36 * - Timeout is measured in milliseconds. 36 * - Timeout is measured in milliseconds.
37 * 37 *
38 * NOTE: timer_reset () and timer_now() are not tested nor usable atm 38 * NOTE: timer_reset () and timer_now() are not tested nor usable atm
39 * 39 *
40 */ 40 */
41extern struct _Event 41extern struct _Event {
42{ 42 int (*rise) (void * ( func ) ( void * ), void *arg);
43 int (*rise) (void* ( func ) ( void* ), void* arg);
44 int (*timer_reset ) ( int id, unsigned timeout ); 43 int (*timer_reset ) ( int id, unsigned timeout );
45 int (*timer_alloc) (void* ( func ) ( void* ), void* arg, unsigned timeout); 44 int (*timer_alloc) (void * ( func ) ( void * ), void *arg, unsigned timeout);
46 int (*timer_release) (int id); 45 int (*timer_release) (int id);
47 int (*timer_now) ( int id ); 46 int (*timer_now) ( int id );
48} event; 47} event;
diff --git a/toxav/media.c b/toxav/media.c
index c4894076..2594f99a 100644
--- a/toxav/media.c
+++ b/toxav/media.c
@@ -1,5 +1,5 @@
1/** media.c 1/** media.c
2 * 2 *
3 * Audio and video codec intitialization, encoding/decoding and playback 3 * Audio and video codec intitialization, encoding/decoding and playback
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -50,8 +50,8 @@ struct jitter_buffer {
50struct jitter_buffer *create_queue(int capacity) 50struct jitter_buffer *create_queue(int capacity)
51{ 51{
52 struct jitter_buffer *q; 52 struct jitter_buffer *q;
53 q = (struct jitter_buffer *)calloc(sizeof(struct jitter_buffer),1); 53 q = (struct jitter_buffer *)calloc(sizeof(struct jitter_buffer), 1);
54 q->queue = (RTPMessage **)calloc(sizeof(RTPMessage*), capacity); 54 q->queue = (RTPMessage **)calloc(sizeof(RTPMessage *), capacity);
55 int i = 0; 55 int i = 0;
56 56
57 for (i = 0; i < capacity; ++i) { 57 for (i = 0; i < capacity; ++i) {
@@ -200,7 +200,8 @@ int queue(struct jitter_buffer *q, RTPMessage *pk)
200 200
201int init_video_decoder(CodecState *cs) 201int init_video_decoder(CodecState *cs)
202{ 202{
203 if (vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0, VPX_DECODER_ABI_VERSION) != VPX_CODEC_OK) { 203 if (vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0,
204 VPX_DECODER_ABI_VERSION) != VPX_CODEC_OK) {
204 fprintf(stderr, "Init video_decoder failed!\n"); 205 fprintf(stderr, "Init video_decoder failed!\n");
205 return -1; 206 return -1;
206 } 207 }
@@ -211,13 +212,13 @@ int init_video_decoder(CodecState *cs)
211int init_audio_decoder(CodecState *cs, uint32_t audio_channels) 212int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
212{ 213{
213 int rc; 214 int rc;
214 cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc ); 215 cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc );
215 216
216 if ( rc != OPUS_OK ){ 217 if ( rc != OPUS_OK ) {
217 fprintf(stderr, "Error while starting audio decoder!\n"); 218 fprintf(stderr, "Error while starting audio decoder!\n");
218 return -1; 219 return -1;
219 } 220 }
220 221
221 return 0; 222 return 0;
222} 223}
223 224
@@ -226,18 +227,22 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t
226{ 227{
227 vpx_codec_enc_cfg_t cfg; 228 vpx_codec_enc_cfg_t cfg;
228 int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); 229 int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);
229 if(res) { 230
231 if (res) {
230 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res)); 232 printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
231 return -1; 233 return -1;
232 } 234 }
233 235
234 cfg.rc_target_bitrate = video_bitrate; 236 cfg.rc_target_bitrate = video_bitrate;
235 cfg.g_w = width; 237 cfg.g_w = width;
236 cfg.g_h = height; 238 cfg.g_h = height;
237 if(vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION) != VPX_CODEC_OK) { 239
240 if (vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0,
241 VPX_ENCODER_ABI_VERSION) != VPX_CODEC_OK) {
238 fprintf(stderr, "Failed to initialize encoder\n"); 242 fprintf(stderr, "Failed to initialize encoder\n");
239 return -1; 243 return -1;
240 } 244 }
245
241 return 0; 246 return 0;
242} 247}
243 248
@@ -247,57 +252,57 @@ int init_audio_encoder(CodecState *cs, uint32_t audio_channels)
247 cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &err); 252 cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &err);
248 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); 253 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate));
249 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); 254 err = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10));
250 255
251 256
252 return err == OPUS_OK ? 0 : -1; 257 return err == OPUS_OK ? 0 : -1;
253} 258}
254 259
255 260
256CodecState* codec_init_session ( uint32_t audio_bitrate, 261CodecState *codec_init_session ( uint32_t audio_bitrate,
257 uint16_t audio_frame_duration, 262 uint16_t audio_frame_duration,
258 uint32_t audio_sample_rate, 263 uint32_t audio_sample_rate,
259 uint32_t audio_channels, 264 uint32_t audio_channels,
260 uint16_t video_width, 265 uint16_t video_width,
261 uint16_t video_height, 266 uint16_t video_height,
262 uint32_t video_bitrate ) 267 uint32_t video_bitrate )
263{ 268{
264 CodecState* _retu = calloc(sizeof(CodecState), 1); 269 CodecState *_retu = calloc(sizeof(CodecState), 1);
265 assert(_retu); 270 assert(_retu);
266 271
267 _retu->audio_bitrate = audio_bitrate; 272 _retu->audio_bitrate = audio_bitrate;
268 _retu->audio_sample_rate = audio_sample_rate; 273 _retu->audio_sample_rate = audio_sample_rate;
269 274
270 /* Encoders */ 275 /* Encoders */
271 if (!video_width || !video_height) { 276 if (!video_width || !video_height) {
272 video_width = 320; 277 video_width = 320;
273 video_height = 240; 278 video_height = 240;
274 } 279 }
275 280
276 if ( 0 == init_video_encoder(_retu, video_width, video_height, video_bitrate) ) 281 if ( 0 == init_video_encoder(_retu, video_width, video_height, video_bitrate) )
277 printf("Video encoder initialized!\n"); 282 printf("Video encoder initialized!\n");
278 283
279 if ( 0 == init_audio_encoder(_retu, audio_channels) ) 284 if ( 0 == init_audio_encoder(_retu, audio_channels) )
280 printf("Audio encoder initialized!\n"); 285 printf("Audio encoder initialized!\n");
281 286
282 287
283 /* Decoders */ 288 /* Decoders */
284 if ( 0 == init_video_decoder(_retu) ) 289 if ( 0 == init_video_decoder(_retu) )
285 printf("Video decoder initialized!\n"); 290 printf("Video decoder initialized!\n");
286 291
287 if ( 0 == init_audio_decoder(_retu, audio_channels) ) 292 if ( 0 == init_audio_decoder(_retu, audio_channels) )
288 printf("Audio decoder initialized!\n"); 293 printf("Audio decoder initialized!\n");
289 294
290 295
291 return _retu; 296 return _retu;
292} 297}
293 298
294void codec_terminate_session ( CodecState* cs ) 299void codec_terminate_session ( CodecState *cs )
295{ 300{
296 if ( cs->audio_encoder ) { 301 if ( cs->audio_encoder ) {
297 opus_encoder_destroy(cs->audio_encoder); 302 opus_encoder_destroy(cs->audio_encoder);
298 printf("Terminated encoder!\n"); 303 printf("Terminated encoder!\n");
299 } 304 }
300 305
301 if ( cs->audio_decoder ) { 306 if ( cs->audio_decoder ) {
302 opus_decoder_destroy(cs->audio_decoder); 307 opus_decoder_destroy(cs->audio_decoder);
303 printf("Terminated decoder!\n"); 308 printf("Terminated decoder!\n");
diff --git a/toxav/media.h b/toxav/media.h
index 030a36ac..aed57ea2 100644
--- a/toxav/media.h
+++ b/toxav/media.h
@@ -1,5 +1,5 @@
1/** media.h 1/** media.h
2 * 2 *
3 * Audio and video codec intitialization, encoding/decoding and playback 3 * Audio and video codec intitialization, encoding/decoding and playback
4 * 4 *
5 * Copyright (C) 2013 Tox project All Rights Reserved. 5 * Copyright (C) 2013 Tox project All Rights Reserved.
@@ -39,7 +39,7 @@
39#include <opus/opus.h> 39#include <opus/opus.h>
40 40
41 41
42typedef struct _CodecState{ 42typedef struct _CodecState {
43 43
44 /* video encoding */ 44 /* video encoding */
45 vpx_codec_ctx_t v_encoder; 45 vpx_codec_ctx_t v_encoder;
@@ -67,14 +67,14 @@ int queue(struct jitter_buffer *q, RTPMessage *pk);
67RTPMessage *dequeue(struct jitter_buffer *q, int *success); 67RTPMessage *dequeue(struct jitter_buffer *q, int *success);
68 68
69 69
70CodecState* codec_init_session ( uint32_t audio_bitrate, 70CodecState *codec_init_session ( uint32_t audio_bitrate,
71 uint16_t audio_frame_duration, 71 uint16_t audio_frame_duration,
72 uint32_t audio_sample_rate, 72 uint32_t audio_sample_rate,
73 uint32_t audio_channels, 73 uint32_t audio_channels,
74 uint16_t video_width, 74 uint16_t video_width,
75 uint16_t video_height, 75 uint16_t video_height,
76 uint32_t video_bitrate ); 76 uint32_t video_bitrate );
77 77
78void codec_terminate_session(CodecState* cs); 78void codec_terminate_session(CodecState *cs);
79 79
80#endif 80#endif
diff --git a/toxav/msi.c b/toxav/msi.c
index 84ab973f..8f69d942 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -1,5 +1,5 @@
1/** toxmsi.c 1/** toxmsi.c
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -46,7 +46,7 @@
46#define TYPE_REQUEST 1 46#define TYPE_REQUEST 1
47#define TYPE_RESPONSE 2 47#define TYPE_RESPONSE 2
48 48
49unsigned char* VERSION_STRING = (unsigned char*)"0.3.1"; 49unsigned char *VERSION_STRING = (unsigned char *)"0.3.1";
50#define VERSION_STRLEN 5 50#define VERSION_STRLEN 5
51 51
52#define CT_AUDIO_HEADER_VALUE "AUDIO" 52#define CT_AUDIO_HEADER_VALUE "AUDIO"
@@ -95,10 +95,10 @@ GENERIC_HEADER ( Nonce )
95/** 95/**
96 * @brief This is the message structure. It contains all of the headers and 96 * @brief This is the message structure. It contains all of the headers and
97 * destination/source of the message stored in friend_id. 97 * destination/source of the message stored in friend_id.
98 * 98 *
99 */ 99 */
100typedef struct _MSIMessage { 100typedef struct _MSIMessage {
101 101
102 MSIHeaderVersion version; 102 MSIHeaderVersion version;
103 MSIHeaderRequest request; 103 MSIHeaderRequest request;
104 MSIHeaderResponse response; 104 MSIHeaderResponse response;
@@ -109,11 +109,11 @@ typedef struct _MSIMessage {
109 MSIHeaderCallId callid; 109 MSIHeaderCallId callid;
110 MSIHeaderCryptoKey cryptokey; 110 MSIHeaderCryptoKey cryptokey;
111 MSIHeaderNonce nonce; 111 MSIHeaderNonce nonce;
112 112
113 struct _MSIMessage* next; 113 struct _MSIMessage *next;
114 114
115 int friend_id; 115 int friend_id;
116 116
117} MSIMessage; 117} MSIMessage;
118 118
119 119
@@ -145,23 +145,24 @@ typedef enum {
145 cancel, 145 cancel,
146 reject, 146 reject,
147 end, 147 end,
148 148
149} MSIRequest; 149} MSIRequest;
150 150
151 151
152/** 152/**
153 * @brief Get string value for request. 153 * @brief Get string value for request.
154 * 154 *
155 * @param request The request. 155 * @param request The request.
156 * @return const uint8_t* The string 156 * @return const uint8_t* The string
157 */ 157 */
158static inline const uint8_t *stringify_request ( MSIRequest request ) { 158static inline const uint8_t *stringify_request ( MSIRequest request )
159 static const uint8_t* strings[] = { 159{
160 ( uint8_t* ) "INVITE", 160 static const uint8_t *strings[] = {
161 ( uint8_t* ) "START", 161 ( uint8_t * ) "INVITE",
162 ( uint8_t* ) "CANCEL", 162 ( uint8_t * ) "START",
163 ( uint8_t* ) "REJECT", 163 ( uint8_t * ) "CANCEL",
164 ( uint8_t* ) "END" 164 ( uint8_t * ) "REJECT",
165 ( uint8_t * ) "END"
165 }; 166 };
166 167
167 return strings[request]; 168 return strings[request];
@@ -179,16 +180,17 @@ typedef enum {
179 180
180/** 181/**
181 * @brief Get string value for response. 182 * @brief Get string value for response.
182 * 183 *
183 * @param response The response. 184 * @param response The response.
184 * @return const uint8_t* The string 185 * @return const uint8_t* The string
185 */ 186 */
186static inline const uint8_t *stringify_response ( MSIResponse response ) { 187static inline const uint8_t *stringify_response ( MSIResponse response )
187 static const uint8_t* strings[] = { 188{
188 ( uint8_t* ) "ringing", 189 static const uint8_t *strings[] = {
189 ( uint8_t* ) "starting", 190 ( uint8_t * ) "ringing",
190 ( uint8_t* ) "ending", 191 ( uint8_t * ) "starting",
191 ( uint8_t* ) "error" 192 ( uint8_t * ) "ending",
193 ( uint8_t * ) "error"
192 }; 194 };
193 195
194 return strings[response]; 196 return strings[response];
@@ -212,78 +214,80 @@ static inline const uint8_t *stringify_response ( MSIResponse response ) {
212 * @brief Parse raw 'data' received from socket into MSIMessage struct. 214 * @brief Parse raw 'data' received from socket into MSIMessage struct.
213 * Every message has to have end value of 'end_byte' or _undefined_ behavior 215 * Every message has to have end value of 'end_byte' or _undefined_ behavior
214 * occures. The best practice is to check the end of the message at the handle_packet. 216 * occures. The best practice is to check the end of the message at the handle_packet.
215 * 217 *
216 * @param msg Container. 218 * @param msg Container.
217 * @param data The data. 219 * @param data The data.
218 * @return int 220 * @return int
219 * @retval -1 Error occured. 221 * @retval -1 Error occured.
220 * @retval 0 Success. 222 * @retval 0 Success.
221 */ 223 */
222int parse_raw_data ( MSIMessage* msg, const uint8_t* data, uint16_t length ) { 224int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
225{
223 assert ( msg ); 226 assert ( msg );
224 227
225 if ( data[length - 1] ) /* End byte must have value 0 */ 228 if ( data[length - 1] ) /* End byte must have value 0 */
226 return -1; 229 return -1;
227 230
228 const uint8_t* _it = data; 231 const uint8_t *_it = data;
229 232
230 while ( *_it ) {/* until end_byte is hit */ 233 while ( *_it ) {/* until end_byte is hit */
231 234
232 uint16_t itedlen = (_it - data) + 2; 235 uint16_t itedlen = (_it - data) + 2;
233 236
234 if ( *_it == field_byte && itedlen < length ) { 237 if ( *_it == field_byte && itedlen < length ) {
235 238
236 uint16_t _size = ( uint16_t ) * ( _it + 1 ) << 8 | 239 uint16_t _size = ( uint16_t ) * ( _it + 1 ) << 8 |
237 ( uint16_t ) * ( _it + 2 ); 240 ( uint16_t ) * ( _it + 2 );
238 241
239 if ( itedlen + _size > length ) return -1; 242 if ( itedlen + _size > length ) return -1;
240 243
241 _it += 3; /* place it at the field value beginning */ 244 _it += 3; /* place it at the field value beginning */
242 245
243 switch ( _size ) { /* Compare the size of the hardcoded values ( vary fast and convenient ) */ 246 switch ( _size ) { /* Compare the size of the hardcoded values ( vary fast and convenient ) */
244 247
245 case 4: { /* INFO header */ 248 case 4: { /* INFO header */
246 if ON_HEADER ( _it, msg->info, INFO_FIELD, 4 ) 249 if ON_HEADER ( _it, msg->info, INFO_FIELD, 4 )
247 } 250 }
248 break; 251 break;
249
250 case 5: { /* NONCE header */
251 if ON_HEADER ( _it, msg->nonce, NONCE_FIELD, 5 )
252 }
253 break;
254 252
255 case 6: { /* Reason header */ 253 case 5: { /* NONCE header */
256 if ON_HEADER ( _it, msg->reason, REASON_FIELD, 6 ) 254 if ON_HEADER ( _it, msg->nonce, NONCE_FIELD, 5 )
257 } 255 }
258 break; 256 break;
259 257
260 case 7: { /* Version, Request, Call-id headers */ 258 case 6: { /* Reason header */
261 if ON_HEADER ( _it, msg->version, VERSION_FIELD, 7 ) 259 if ON_HEADER ( _it, msg->reason, REASON_FIELD, 6 )
262 else if ON_HEADER ( _it, msg->request, REQUEST_FIELD, 7 ) 260 }
263 else if ON_HEADER ( _it, msg->callid, CALLID_FIELD, 7 ) 261 break;
264 }
265 break;
266 262
267 case 8: { /* Response header */ 263 case 7: { /* Version, Request, Call-id headers */
268 if ON_HEADER ( _it, msg->response, RESPONSE_FIELD, 8 ) 264 if ON_HEADER ( _it, msg->version, VERSION_FIELD, 7 )
269 } 265 else if ON_HEADER ( _it, msg->request, REQUEST_FIELD, 7 )
270 break; 266 else if ON_HEADER ( _it, msg->callid, CALLID_FIELD, 7 )
267 }
268 break;
271 269
272 case 9: { /* Call-type header */ 270 case 8: { /* Response header */
273 if ON_HEADER ( _it, msg->calltype, CALLTYPE_FIELD, 9 ) 271 if ON_HEADER ( _it, msg->response, RESPONSE_FIELD, 8 )
274 } 272 }
275 break; 273 break;
276 274
277 case 10: { /* User-agent, Crypto-key headers */ 275 case 9: { /* Call-type header */
278 if ON_HEADER ( _it, msg->useragent, USERAGENT_FIELD, 10 ) 276 if ON_HEADER ( _it, msg->calltype, CALLTYPE_FIELD, 9 )
279 else if ON_HEADER ( _it, msg->cryptokey, CRYPTOKEY_FIELD, 10 )
280 } 277 }
281 break; 278 break;
279
280 case 10: { /* User-agent, Crypto-key headers */
281 if ON_HEADER ( _it, msg->useragent, USERAGENT_FIELD, 10 )
282 else if ON_HEADER ( _it, msg->cryptokey, CRYPTOKEY_FIELD, 10 )
283 }
284 break;
282 285
283 default: 286 default:
284 return -1; 287 return -1;
285 } 288 }
286 } else return -1; 289 } else return -1;
290
287 /* If it's anything else return failure as the message is invalid */ 291 /* If it's anything else return failure as the message is invalid */
288 292
289 } 293 }
@@ -300,11 +304,12 @@ var.size = t_size;
300 304
301/** 305/**
302 * @brief Speaks for it self. 306 * @brief Speaks for it self.
303 * 307 *
304 * @param msg The message. 308 * @param msg The message.
305 * @return void 309 * @return void
306 */ 310 */
307void free_message ( MSIMessage* msg ) { 311void free_message ( MSIMessage *msg )
312{
308 assert ( msg ); 313 assert ( msg );
309 314
310 free ( msg->calltype.header_value ); 315 free ( msg->calltype.header_value );
@@ -323,29 +328,30 @@ void free_message ( MSIMessage* msg ) {
323 328
324 329
325/** 330/**
326 * @brief Create the message. 331 * @brief Create the message.
327 * 332 *
328 * @param type Request or response. 333 * @param type Request or response.
329 * @param type_id Type of request/response. 334 * @param type_id Type of request/response.
330 * @return MSIMessage* Created message. 335 * @return MSIMessage* Created message.
331 * @retval NULL Error occured. 336 * @retval NULL Error occured.
332 */ 337 */
333MSIMessage* msi_new_message ( uint8_t type, const uint8_t* type_id ) { 338MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id )
334 MSIMessage* _retu = calloc ( sizeof ( MSIMessage ), 1 ); 339{
340 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
335 assert ( _retu ); 341 assert ( _retu );
336 342
337 if ( type == TYPE_REQUEST ) { 343 if ( type == TYPE_REQUEST ) {
338 ALLOCATE_HEADER ( _retu->request, type_id, strlen ( (const char*)type_id ) ) 344 ALLOCATE_HEADER ( _retu->request, type_id, strlen ( (const char *)type_id ) )
339 345
340 } else if ( type == TYPE_RESPONSE ) { 346 } else if ( type == TYPE_RESPONSE ) {
341 ALLOCATE_HEADER ( _retu->response, type_id, strlen ( (const char*)type_id ) ) 347 ALLOCATE_HEADER ( _retu->response, type_id, strlen ( (const char *)type_id ) )
342 348
343 } else { 349 } else {
344 free_message ( _retu ); 350 free_message ( _retu );
345 return NULL; 351 return NULL;
346 } 352 }
347 353
348 ALLOCATE_HEADER ( _retu->version, VERSION_STRING, strlen ( (const char*)VERSION_STRING ) ) 354 ALLOCATE_HEADER ( _retu->version, VERSION_STRING, strlen ( (const char *)VERSION_STRING ) )
349 355
350 return _retu; 356 return _retu;
351} 357}
@@ -353,15 +359,16 @@ MSIMessage* msi_new_message ( uint8_t type, const uint8_t* type_id ) {
353 359
354/** 360/**
355 * @brief Parse data from handle_packet. 361 * @brief Parse data from handle_packet.
356 * 362 *
357 * @param data The data. 363 * @param data The data.
358 * @return MSIMessage* Parsed message. 364 * @return MSIMessage* Parsed message.
359 * @retval NULL Error occured. 365 * @retval NULL Error occured.
360 */ 366 */
361MSIMessage* parse_message ( const uint8_t* data, uint16_t length ) { 367MSIMessage *parse_message ( const uint8_t *data, uint16_t length )
368{
362 assert ( data ); 369 assert ( data );
363 370
364 MSIMessage* _retu = calloc ( sizeof ( MSIMessage ), 1 ); 371 MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 );
365 assert ( _retu ); 372 assert ( _retu );
366 373
367 memset ( _retu, 0, sizeof ( MSIMessage ) ); 374 memset ( _retu, 0, sizeof ( MSIMessage ) );
@@ -386,7 +393,7 @@ MSIMessage* parse_message ( const uint8_t* data, uint16_t length ) {
386 393
387/** 394/**
388 * @brief Speaks for it self. 395 * @brief Speaks for it self.
389 * 396 *
390 * @param dest Container. 397 * @param dest Container.
391 * @param header_field Field. 398 * @param header_field Field.
392 * @param header_value Field value. 399 * @param header_value Field value.
@@ -394,45 +401,53 @@ MSIMessage* parse_message ( const uint8_t* data, uint16_t length ) {
394 * @param length Pointer to container length. 401 * @param length Pointer to container length.
395 * @return uint8_t* Iterated container. 402 * @return uint8_t* Iterated container.
396 */ 403 */
397uint8_t* append_header_to_string ( 404uint8_t *append_header_to_string (
398 uint8_t* dest, 405 uint8_t *dest,
399 const uint8_t* header_field, 406 const uint8_t *header_field,
400 const uint8_t* header_value, 407 const uint8_t *header_value,
401 uint16_t value_len, 408 uint16_t value_len,
402 uint16_t* length ) 409 uint16_t *length )
403{ 410{
404 assert ( dest ); 411 assert ( dest );
405 assert ( header_value ); 412 assert ( header_value );
406 assert ( header_field ); 413 assert ( header_field );
407 414
408 const uint8_t* _hvit = header_value; 415 const uint8_t *_hvit = header_value;
409 uint16_t _total = 6 + value_len; /* 6 is known plus header value len + field len*/ 416 uint16_t _total = 6 + value_len; /* 6 is known plus header value len + field len*/
410 417
411 *dest = field_byte; /* Set the first byte */ 418 *dest = field_byte; /* Set the first byte */
412 419
413 uint8_t* _getback_byte = dest + 1; /* remeber the byte we were on */ 420 uint8_t *_getback_byte = dest + 1; /* remeber the byte we were on */
414 dest += 3; /* swith to 4th byte where field value starts */ 421 dest += 3; /* swith to 4th byte where field value starts */
415 422
416 /* Now set the field value and calculate it's length */ 423 /* Now set the field value and calculate it's length */
417 uint16_t _i = 0; 424 uint16_t _i = 0;
425
418 for ( ; header_field[_i]; ++_i ) { 426 for ( ; header_field[_i]; ++_i ) {
419 *dest = header_field[_i]; 427 *dest = header_field[_i];
420 ++dest; 428 ++dest;
421 }; 429 };
430
422 _total += _i; 431 _total += _i;
423 432
424 /* Now set the length of the field byte */ 433 /* Now set the length of the field byte */
425 *_getback_byte = ( uint8_t ) _i >> 8; 434 *_getback_byte = ( uint8_t ) _i >> 8;
435
426 _getback_byte++; 436 _getback_byte++;
437
427 *_getback_byte = ( uint8_t ) _i; 438 *_getback_byte = ( uint8_t ) _i;
428 439
429 /* for value part do it regulary */ 440 /* for value part do it regulary */
430 *dest = value_byte; 441 *dest = value_byte;
442
431 dest++; 443 dest++;
432 444
433 *dest = ( uint8_t ) value_len >> 8; 445 *dest = ( uint8_t ) value_len >> 8;
446
434 dest++; 447 dest++;
448
435 *dest = ( uint8_t ) value_len; 449 *dest = ( uint8_t ) value_len;
450
436 dest++; 451 dest++;
437 452
438 for ( _i = value_len; _i; --_i ) { 453 for ( _i = value_len; _i; --_i ) {
@@ -452,16 +467,17 @@ if ( header.header_value ) { var = append_header_to_string(var, (const uint8_t*)
452 467
453/** 468/**
454 * @brief Convert MSIMessage struct to _sendable_ string. 469 * @brief Convert MSIMessage struct to _sendable_ string.
455 * 470 *
456 * @param msg The message. 471 * @param msg The message.
457 * @param dest Destination. 472 * @param dest Destination.
458 * @return uint16_t It's final size. 473 * @return uint16_t It's final size.
459 */ 474 */
460uint16_t message_to_string ( MSIMessage* msg, uint8_t* dest ) { 475uint16_t message_to_string ( MSIMessage *msg, uint8_t *dest )
476{
461 assert ( msg ); 477 assert ( msg );
462 assert ( dest ); 478 assert ( dest );
463 479
464 uint8_t* _iterated = dest; 480 uint8_t *_iterated = dest;
465 uint16_t _size = 0; 481 uint16_t _size = 0;
466 482
467 CLEAN_ASSIGN ( _size, _iterated, VERSION_FIELD, msg->version ); 483 CLEAN_ASSIGN ( _size, _iterated, VERSION_FIELD, msg->version );
@@ -499,12 +515,13 @@ GENERIC_SETTER_DEFINITION ( nonce )
499 515
500/** 516/**
501 * @brief Generate _random_ alphanumerical string. 517 * @brief Generate _random_ alphanumerical string.
502 * 518 *
503 * @param str Destination. 519 * @param str Destination.
504 * @param size Size of string. 520 * @param size Size of string.
505 * @return void 521 * @return void
506 */ 522 */
507void t_randomstr ( uint8_t* str, size_t size ) { 523void t_randomstr ( uint8_t *str, size_t size )
524{
508 assert ( str ); 525 assert ( str );
509 526
510 static const uint8_t _bytes[] = 527 static const uint8_t _bytes[] =
@@ -535,19 +552,20 @@ typedef enum {
535 552
536/** 553/**
537 * @brief Stringify error code. 554 * @brief Stringify error code.
538 * 555 *
539 * @param error_code The code. 556 * @param error_code The code.
540 * @return const uint8_t* The string. 557 * @return const uint8_t* The string.
541 */ 558 */
542static inline const uint8_t *stringify_error ( MSICallError error_code ) { 559static inline const uint8_t *stringify_error ( MSICallError error_code )
543 static const uint8_t* strings[] = { 560{
544 ( uint8_t* ) "", 561 static const uint8_t *strings[] = {
545 ( uint8_t* ) "Using dead call", 562 ( uint8_t * ) "",
546 ( uint8_t* ) "Call id not set to any call", 563 ( uint8_t * ) "Using dead call",
547 ( uint8_t* ) "Call id not available", 564 ( uint8_t * ) "Call id not set to any call",
548 ( uint8_t* ) "No active call in session", 565 ( uint8_t * ) "Call id not available",
549 ( uint8_t* ) "No Crypto-key set", 566 ( uint8_t * ) "No active call in session",
550 ( uint8_t* ) "Callee busy" 567 ( uint8_t * ) "No Crypto-key set",
568 ( uint8_t * ) "Callee busy"
551 }; 569 };
552 570
553 return strings[error_code]; 571 return strings[error_code];
@@ -556,19 +574,20 @@ static inline const uint8_t *stringify_error ( MSICallError error_code ) {
556 574
557/** 575/**
558 * @brief Convert error_code into string. 576 * @brief Convert error_code into string.
559 * 577 *
560 * @param error_code The code. 578 * @param error_code The code.
561 * @return const uint8_t* The string. 579 * @return const uint8_t* The string.
562 */ 580 */
563static inline const uint8_t *stringify_error_code ( MSICallError error_code ) { 581static inline const uint8_t *stringify_error_code ( MSICallError error_code )
564 static const uint8_t* strings[] = { 582{
565 ( uint8_t* ) "", 583 static const uint8_t *strings[] = {
566 ( uint8_t* ) "1", 584 ( uint8_t * ) "",
567 ( uint8_t* ) "2", 585 ( uint8_t * ) "1",
568 ( uint8_t* ) "3", 586 ( uint8_t * ) "2",
569 ( uint8_t* ) "4", 587 ( uint8_t * ) "3",
570 ( uint8_t* ) "5", 588 ( uint8_t * ) "4",
571 ( uint8_t* ) "6" 589 ( uint8_t * ) "5",
590 ( uint8_t * ) "6"
572 }; 591 };
573 592
574 return strings[error_code]; 593 return strings[error_code];
@@ -577,7 +596,7 @@ static inline const uint8_t *stringify_error_code ( MSICallError error_code ) {
577 596
578/** 597/**
579 * @brief Speaks for it self. 598 * @brief Speaks for it self.
580 * 599 *
581 * @param session Control session. 600 * @param session Control session.
582 * @param msg The message. 601 * @param msg The message.
583 * @param to Where to. 602 * @param to Where to.
@@ -585,73 +604,76 @@ static inline const uint8_t *stringify_error_code ( MSICallError error_code ) {
585 * @retval -1 Error occured. 604 * @retval -1 Error occured.
586 * @retval 0 Success. 605 * @retval 0 Success.
587 */ 606 */
588int send_message ( MSISession* session, MSIMessage* msg, uint32_t to ) 607int send_message ( MSISession *session, MSIMessage *msg, uint32_t to )
589{ 608{
590 msi_msg_set_callid ( msg, session->call->id, CALL_ID_LEN ); 609 msi_msg_set_callid ( msg, session->call->id, CALL_ID_LEN );
591 610
592 uint8_t _msg_string_final [MSI_MAXMSG_SIZE]; 611 uint8_t _msg_string_final [MSI_MAXMSG_SIZE];
593 uint16_t _length = message_to_string ( msg, _msg_string_final ); 612 uint16_t _length = message_to_string ( msg, _msg_string_final );
594 613
595 return m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ? 0 : -1; 614 return m_msi_packet(session->messenger_handle, to, _msg_string_final, _length) ? 0 : -1;
596} 615}
597 616
598 617
599/** 618/**
600 * @brief Speaks for it self. 619 * @brief Speaks for it self.
601 * 620 *
602 * @param session Control session. 621 * @param session Control session.
603 * @param msg The message. 622 * @param msg The message.
604 * @param peer_id The peer. 623 * @param peer_id The peer.
605 * @return void 624 * @return void
606 */ 625 */
607void flush_peer_type ( MSISession* session, MSIMessage* msg, int peer_id ) { 626void flush_peer_type ( MSISession *session, MSIMessage *msg, int peer_id )
627{
608 if ( msg->calltype.header_value ) { 628 if ( msg->calltype.header_value ) {
609 if ( strcmp ( ( const char* ) msg->calltype.header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) { 629 if ( strcmp ( ( const char * ) msg->calltype.header_value, CT_AUDIO_HEADER_VALUE ) == 0 ) {
610 session->call->type_peer[peer_id] = type_audio; 630 session->call->type_peer[peer_id] = type_audio;
611 631
612 } else if ( strcmp ( ( const char* ) msg->calltype.header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) { 632 } else if ( strcmp ( ( const char * ) msg->calltype.header_value, CT_VIDEO_HEADER_VALUE ) == 0 ) {
613 session->call->type_peer[peer_id] = type_video; 633 session->call->type_peer[peer_id] = type_video;
614 } else {} /* Error */ 634 } else {} /* Error */
615 } else {} /* Error */ 635 } else {} /* Error */
616} 636}
617 637
618void handle_remote_connection_change(Messenger* messenger, int friend_num, uint8_t status, void* session_p) 638void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8_t status, void *session_p)
619{ 639{
620 MSISession* session = session_p; 640 MSISession *session = session_p;
621 641
622 switch ( status ) 642 switch ( status ) {
623 { 643 case 0: { /* Went offline */
624 case 0: /* Went offline */
625 {
626 if ( session->call ) { 644 if ( session->call ) {
627 int i = 0; 645 int i = 0;
628 for ( ; i < session->call->peer_count; i ++ ) 646
647 for ( ; i < session->call->peer_count; i ++ )
629 if ( session->call->peers[i] == friend_num ) { 648 if ( session->call->peers[i] == friend_num ) {
630 msi_stopcall(session); /* Stop the call for now */ 649 msi_stopcall(session); /* Stop the call for now */
631 return; 650 return;
632 } 651 }
633 } 652 }
634 } break; 653 }
635 654 break;
636 default: break; 655
656 default:
657 break;
637 } 658 }
638} 659}
639 660
640/** 661/**
641 * @brief Sends error response to peer. 662 * @brief Sends error response to peer.
642 * 663 *
643 * @param session The session. 664 * @param session The session.
644 * @param errid The id. 665 * @param errid The id.
645 * @param to Where to? 666 * @param to Where to?
646 * @return int 667 * @return int
647 * @retval 0 It's always success. 668 * @retval 0 It's always success.
648 */ 669 */
649int handle_error ( MSISession* session, MSICallError errid, uint32_t to ) { 670int handle_error ( MSISession *session, MSICallError errid, uint32_t to )
650 MSIMessage* _msg_error = msi_new_message ( TYPE_RESPONSE, stringify_response ( error ) ); 671{
672 MSIMessage *_msg_error = msi_new_message ( TYPE_RESPONSE, stringify_response ( error ) );
651 673
652 const uint8_t* _error_code_str = stringify_error_code ( errid ); 674 const uint8_t *_error_code_str = stringify_error_code ( errid );
653 675
654 msi_msg_set_reason ( _msg_error, _error_code_str, strlen ( ( const char* ) _error_code_str ) ); 676 msi_msg_set_reason ( _msg_error, _error_code_str, strlen ( ( const char * ) _error_code_str ) );
655 send_message ( session, _msg_error, to ); 677 send_message ( session, _msg_error, to );
656 free_message ( _msg_error ); 678 free_message ( _msg_error );
657 679
@@ -666,14 +688,15 @@ int handle_error ( MSISession* session, MSICallError errid, uint32_t to ) {
666 688
667/** 689/**
668 * @brief Determine the error if any. 690 * @brief Determine the error if any.
669 * 691 *
670 * @param session Control session. 692 * @param session Control session.
671 * @param msg The message. 693 * @param msg The message.
672 * @return int 694 * @return int
673 * @retval -1 No error. 695 * @retval -1 No error.
674 * @retval 0 Error occured and response sent. 696 * @retval 0 Error occured and response sent.
675 */ 697 */
676int has_call_error ( MSISession* session, MSIMessage* msg ) { 698int has_call_error ( MSISession *session, MSIMessage *msg )
699{
677 if ( !msg->callid.header_value ) { 700 if ( !msg->callid.header_value ) {
678 return handle_error ( session, error_no_callid, msg->friend_id ); 701 return handle_error ( session, error_no_callid, msg->friend_id );
679 702
@@ -691,28 +714,29 @@ int has_call_error ( MSISession* session, MSIMessage* msg ) {
691 714
692/** 715/**
693 * @brief Function called at request timeout. 716 * @brief Function called at request timeout.
694 * 717 *
695 * @param arg Control session 718 * @param arg Control session
696 * @return void* 719 * @return void*
697 */ 720 */
698void* handle_timeout ( void* arg ) 721void *handle_timeout ( void *arg )
699{ 722{
700 /* Send hangup either way */ 723 /* Send hangup either way */
701 MSISession* _session = arg; 724 MSISession *_session = arg;
702 725
703 if ( _session && _session->call ) { 726 if ( _session && _session->call ) {
704 727
705 uint32_t* _peers = _session->call->peers; 728 uint32_t *_peers = _session->call->peers;
706 uint16_t _peer_count = _session->call->peer_count; 729 uint16_t _peer_count = _session->call->peer_count;
707 730
708 731
709 /* Cancel all? */ 732 /* Cancel all? */
710 uint16_t _it = 0; 733 uint16_t _it = 0;
734
711 for ( ; _it < _peer_count; _it++ ) 735 for ( ; _it < _peer_count; _it++ )
712 msi_cancel ( arg, _peers[_it], (const uint8_t*)"Timeout" ); 736 msi_cancel ( arg, _peers[_it], (const uint8_t *)"Timeout" );
713 737
714 } 738 }
715 739
716 ( *callbacks[MSI_OnRequestTimeout] ) ( _session->agent_handler ); 740 ( *callbacks[MSI_OnRequestTimeout] ) ( _session->agent_handler );
717 ( *callbacks[MSI_OnEnding ] ) ( _session->agent_handler ); 741 ( *callbacks[MSI_OnEnding ] ) ( _session->agent_handler );
718 742
@@ -722,38 +746,39 @@ void* handle_timeout ( void* arg )
722 746
723/** 747/**
724 * @brief Add peer to peer list. 748 * @brief Add peer to peer list.
725 * 749 *
726 * @param call What call. 750 * @param call What call.
727 * @param peer_id Its id. 751 * @param peer_id Its id.
728 * @return void 752 * @return void
729 */ 753 */
730void add_peer( MSICall* call, int peer_id ) 754void add_peer( MSICall *call, int peer_id )
731{ 755{
732 if ( !call->peers ) { 756 if ( !call->peers ) {
733 call->peers = calloc(sizeof(int), 1); 757 call->peers = calloc(sizeof(int), 1);
734 call->peer_count = 1; 758 call->peer_count = 1;
735 } else{ 759 } else {
736 call->peer_count ++; 760 call->peer_count ++;
737 call->peers = realloc( call->peers, sizeof(int) * call->peer_count); 761 call->peers = realloc( call->peers, sizeof(int) * call->peer_count);
738 } 762 }
739 763
740 call->peers[call->peer_count - 1] = peer_id; 764 call->peers[call->peer_count - 1] = peer_id;
741} 765}
742 766
743 767
744/** 768/**
745 * @brief Speaks for it self. 769 * @brief Speaks for it self.
746 * 770 *
747 * @param session Control session. 771 * @param session Control session.
748 * @param peers Amount of peers. (Currently it only supports 1) 772 * @param peers Amount of peers. (Currently it only supports 1)
749 * @param ringing_timeout Ringing timeout. 773 * @param ringing_timeout Ringing timeout.
750 * @return MSICall* The created call. 774 * @return MSICall* The created call.
751 */ 775 */
752MSICall* init_call ( MSISession* session, int peers, int ringing_timeout ) { 776MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
777{
753 assert ( session ); 778 assert ( session );
754 assert ( peers ); 779 assert ( peers );
755 780
756 MSICall* _call = calloc ( sizeof ( MSICall ), 1 ); 781 MSICall *_call = calloc ( sizeof ( MSICall ), 1 );
757 _call->type_peer = calloc ( sizeof ( MSICallType ), peers ); 782 _call->type_peer = calloc ( sizeof ( MSICallType ), peers );
758 783
759 assert ( _call ); 784 assert ( _call );
@@ -779,13 +804,14 @@ MSICall* init_call ( MSISession* session, int peers, int ringing_timeout ) {
779 804
780/** 805/**
781 * @brief Terminate the call. 806 * @brief Terminate the call.
782 * 807 *
783 * @param session Control session. 808 * @param session Control session.
784 * @return int 809 * @return int
785 * @retval -1 Error occured. 810 * @retval -1 Error occured.
786 * @retval 0 Success. 811 * @retval 0 Success.
787 */ 812 */
788int terminate_call ( MSISession* session ) { 813int terminate_call ( MSISession *session )
814{
789 assert ( session ); 815 assert ( session );
790 816
791 if ( !session->call ) 817 if ( !session->call )
@@ -802,7 +828,7 @@ int terminate_call ( MSISession* session ) {
802 /* Get a handle */ 828 /* Get a handle */
803 pthread_mutex_lock ( &session->call->mutex ); 829 pthread_mutex_lock ( &session->call->mutex );
804 830
805 MSICall* _call = session->call; 831 MSICall *_call = session->call;
806 session->call = NULL; 832 session->call = NULL;
807 833
808 free ( _call->type_peer ); 834 free ( _call->type_peer );
@@ -816,19 +842,21 @@ int terminate_call ( MSISession* session ) {
816 pthread_mutex_destroy ( &_call->mutex ); 842 pthread_mutex_destroy ( &_call->mutex );
817 843
818 free ( _call ); 844 free ( _call );
819 845
820 return 0; 846 return 0;
821} 847}
822 848
823 849
824/********** Request handlers **********/ 850/********** Request handlers **********/
825int handle_recv_invite ( MSISession* session, MSIMessage* msg ) { 851int handle_recv_invite ( MSISession *session, MSIMessage *msg )
852{
826 assert ( session ); 853 assert ( session );
827 854
828 if ( session->call ) { 855 if ( session->call ) {
829 handle_error ( session, error_busy, msg->friend_id ); 856 handle_error ( session, error_busy, msg->friend_id );
830 return 0; 857 return 0;
831 } 858 }
859
832 if ( !msg->callid.header_value ) { 860 if ( !msg->callid.header_value ) {
833 handle_error ( session, error_no_callid, msg->friend_id ); 861 handle_error ( session, error_no_callid, msg->friend_id );
834 return 0; 862 return 0;
@@ -837,12 +865,12 @@ int handle_recv_invite ( MSISession* session, MSIMessage* msg ) {
837 session->call = init_call ( session, 1, 0 ); 865 session->call = init_call ( session, 1, 0 );
838 memcpy ( session->call->id, msg->callid.header_value, CALL_ID_LEN ); 866 memcpy ( session->call->id, msg->callid.header_value, CALL_ID_LEN );
839 session->call->state = call_starting; 867 session->call->state = call_starting;
840 868
841 add_peer( session->call, msg->friend_id); 869 add_peer( session->call, msg->friend_id);
842 870
843 flush_peer_type ( session, msg, 0 ); 871 flush_peer_type ( session, msg, 0 );
844 872
845 MSIMessage* _msg_ringing = msi_new_message ( TYPE_RESPONSE, stringify_response ( ringing ) ); 873 MSIMessage *_msg_ringing = msi_new_message ( TYPE_RESPONSE, stringify_response ( ringing ) );
846 send_message ( session, _msg_ringing, msg->friend_id ); 874 send_message ( session, _msg_ringing, msg->friend_id );
847 free_message ( _msg_ringing ); 875 free_message ( _msg_ringing );
848 876
@@ -850,7 +878,8 @@ int handle_recv_invite ( MSISession* session, MSIMessage* msg ) {
850 878
851 return 1; 879 return 1;
852} 880}
853int handle_recv_start ( MSISession* session, MSIMessage* msg ) { 881int handle_recv_start ( MSISession *session, MSIMessage *msg )
882{
854 assert ( session ); 883 assert ( session );
855 884
856 if ( has_call_error ( session, msg ) == 0 ) 885 if ( has_call_error ( session, msg ) == 0 )
@@ -873,14 +902,15 @@ int handle_recv_start ( MSISession* session, MSIMessage* msg ) {
873 902
874 return 1; 903 return 1;
875} 904}
876int handle_recv_reject ( MSISession* session, MSIMessage* msg ) { 905int handle_recv_reject ( MSISession *session, MSIMessage *msg )
906{
877 assert ( session ); 907 assert ( session );
878 908
879 if ( has_call_error ( session, msg ) == 0 ) 909 if ( has_call_error ( session, msg ) == 0 )
880 return 0; 910 return 0;
881 911
882 912
883 MSIMessage* _msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) ); 913 MSIMessage *_msg_end = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
884 send_message ( session, _msg_end, msg->friend_id ); 914 send_message ( session, _msg_end, msg->friend_id );
885 free_message ( _msg_end ); 915 free_message ( _msg_end );
886 916
@@ -890,7 +920,8 @@ int handle_recv_reject ( MSISession* session, MSIMessage* msg ) {
890 920
891 return 1; 921 return 1;
892} 922}
893int handle_recv_cancel ( MSISession* session, MSIMessage* msg ) { 923int handle_recv_cancel ( MSISession *session, MSIMessage *msg )
924{
894 assert ( session ); 925 assert ( session );
895 926
896 if ( has_call_error ( session, msg ) == 0 ) 927 if ( has_call_error ( session, msg ) == 0 )
@@ -903,14 +934,15 @@ int handle_recv_cancel ( MSISession* session, MSIMessage* msg ) {
903 934
904 return 1; 935 return 1;
905} 936}
906int handle_recv_end ( MSISession* session, MSIMessage* msg ) { 937int handle_recv_end ( MSISession *session, MSIMessage *msg )
938{
907 assert ( session ); 939 assert ( session );
908 940
909 if ( has_call_error ( session, msg ) == 0 ) 941 if ( has_call_error ( session, msg ) == 0 )
910 return 0; 942 return 0;
911 943
912 944
913 MSIMessage* _msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) ); 945 MSIMessage *_msg_ending = msi_new_message ( TYPE_RESPONSE, stringify_response ( ending ) );
914 send_message ( session, _msg_ending, msg->friend_id ); 946 send_message ( session, _msg_ending, msg->friend_id );
915 free_message ( _msg_ending ); 947 free_message ( _msg_ending );
916 948
@@ -922,7 +954,8 @@ int handle_recv_end ( MSISession* session, MSIMessage* msg ) {
922} 954}
923 955
924/********** Response handlers **********/ 956/********** Response handlers **********/
925int handle_recv_ringing ( MSISession* session, MSIMessage* msg ) { 957int handle_recv_ringing ( MSISession *session, MSIMessage *msg )
958{
926 assert ( session ); 959 assert ( session );
927 960
928 if ( has_call_error ( session, msg ) == 0 ) 961 if ( has_call_error ( session, msg ) == 0 )
@@ -933,7 +966,8 @@ int handle_recv_ringing ( MSISession* session, MSIMessage* msg ) {
933 966
934 return 1; 967 return 1;
935} 968}
936int handle_recv_starting ( MSISession* session, MSIMessage* msg ) { 969int handle_recv_starting ( MSISession *session, MSIMessage *msg )
970{
937 assert ( session ); 971 assert ( session );
938 972
939 if ( has_call_error ( session, msg ) == 0 ) 973 if ( has_call_error ( session, msg ) == 0 )
@@ -959,7 +993,7 @@ int handle_recv_starting ( MSISession* session, MSIMessage* msg ) {
959 993
960 session->call->state = call_active; 994 session->call->state = call_active;
961 995
962 MSIMessage* _msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) ); 996 MSIMessage *_msg_start = msi_new_message ( TYPE_REQUEST, stringify_request ( start ) );
963 msi_msg_set_cryptokey ( _msg_start, session->call->key_local, crypto_secretbox_KEYBYTES ); 997 msi_msg_set_cryptokey ( _msg_start, session->call->key_local, crypto_secretbox_KEYBYTES );
964 msi_msg_set_nonce ( _msg_start, session->call->nonce_local, crypto_box_NONCEBYTES ); 998 msi_msg_set_nonce ( _msg_start, session->call->nonce_local, crypto_box_NONCEBYTES );
965 send_message ( session, _msg_start, msg->friend_id ); 999 send_message ( session, _msg_start, msg->friend_id );
@@ -972,7 +1006,8 @@ int handle_recv_starting ( MSISession* session, MSIMessage* msg ) {
972 1006
973 return 1; 1007 return 1;
974} 1008}
975int handle_recv_ending ( MSISession* session, MSIMessage* msg ) { 1009int handle_recv_ending ( MSISession *session, MSIMessage *msg )
1010{
976 assert ( session ); 1011 assert ( session );
977 1012
978 if ( has_call_error ( session, msg ) == 0 ) 1013 if ( has_call_error ( session, msg ) == 0 )
@@ -985,13 +1020,14 @@ int handle_recv_ending ( MSISession* session, MSIMessage* msg ) {
985 1020
986 return 1; 1021 return 1;
987} 1022}
988int handle_recv_error ( MSISession* session, MSIMessage* msg ) { 1023int handle_recv_error ( MSISession *session, MSIMessage *msg )
1024{
989 assert ( session ); 1025 assert ( session );
990 assert ( session->call ); 1026 assert ( session->call );
991 1027
992 /* Handle error accordingly */ 1028 /* Handle error accordingly */
993 if ( msg->reason.header_value ) { 1029 if ( msg->reason.header_value ) {
994 session->last_error_id = atoi ( ( const char* ) msg->reason.header_value ); 1030 session->last_error_id = atoi ( ( const char * ) msg->reason.header_value );
995 session->last_error_str = stringify_error ( session->last_error_id ); 1031 session->last_error_str = stringify_error ( session->last_error_id );
996 } 1032 }
997 1033
@@ -1035,92 +1071,92 @@ int handle_recv_error ( MSISession* session, MSIMessage* msg ) {
1035 * 1071 *
1036 * 1072 *
1037 */ 1073 */
1038void msi_handle_packet ( Messenger* messenger, int source, uint8_t* data, uint16_t length, void* object ) 1074void msi_handle_packet ( Messenger *messenger, int source, uint8_t *data, uint16_t length, void *object )
1039{ 1075{
1040 /* Unused */ 1076 /* Unused */
1041 (void)messenger; 1077 (void)messenger;
1042 1078
1043 MSISession* _session = object; 1079 MSISession *_session = object;
1044 MSIMessage* _msg; 1080 MSIMessage *_msg;
1045 1081
1046 if ( !length ) return; 1082 if ( !length ) return;
1047 1083
1048 _msg = parse_message ( data, length ); 1084 _msg = parse_message ( data, length );
1049 1085
1050 if ( !_msg ) return; 1086 if ( !_msg ) return;
1051 1087
1052 _msg->friend_id = source; 1088 _msg->friend_id = source;
1053 1089
1054 1090
1055 /* Now handle message */ 1091 /* Now handle message */
1056 1092
1057 if ( _msg->request.header_value ) { /* Handle request */ 1093 if ( _msg->request.header_value ) { /* Handle request */
1058 1094
1059 const uint8_t* _request_value = _msg->request.header_value; 1095 const uint8_t *_request_value = _msg->request.header_value;
1060 1096
1061 if ( same ( _request_value, stringify_request ( invite ) ) ) { 1097 if ( same ( _request_value, stringify_request ( invite ) ) ) {
1062 handle_recv_invite ( _session, _msg ); 1098 handle_recv_invite ( _session, _msg );
1063 1099
1064 } else if ( same ( _request_value, stringify_request ( start ) ) ) { 1100 } else if ( same ( _request_value, stringify_request ( start ) ) ) {
1065 handle_recv_start ( _session, _msg ); 1101 handle_recv_start ( _session, _msg );
1066 1102
1067 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) { 1103 } else if ( same ( _request_value, stringify_request ( cancel ) ) ) {
1068 handle_recv_cancel ( _session, _msg ); 1104 handle_recv_cancel ( _session, _msg );
1069 1105
1070 } else if ( same ( _request_value, stringify_request ( reject ) ) ) { 1106 } else if ( same ( _request_value, stringify_request ( reject ) ) ) {
1071 handle_recv_reject ( _session, _msg ); 1107 handle_recv_reject ( _session, _msg );
1072 1108
1073 } else if ( same ( _request_value, stringify_request ( end ) ) ) { 1109 } else if ( same ( _request_value, stringify_request ( end ) ) ) {
1074 handle_recv_end ( _session, _msg ); 1110 handle_recv_end ( _session, _msg );
1075 } 1111 }
1076 1112
1077 else { 1113 else {
1078 free_message ( _msg ); 1114 free_message ( _msg );
1079 return; 1115 return;
1080 } 1116 }
1081 1117
1082 } else if ( _msg->response.header_value ) { /* Handle response */ 1118 } else if ( _msg->response.header_value ) { /* Handle response */
1083 1119
1084 const uint8_t* _response_value = _msg->response.header_value; 1120 const uint8_t *_response_value = _msg->response.header_value;
1085 1121
1086 if ( same ( _response_value, stringify_response ( ringing ) ) ) { 1122 if ( same ( _response_value, stringify_response ( ringing ) ) ) {
1087 handle_recv_ringing ( _session, _msg ); 1123 handle_recv_ringing ( _session, _msg );
1088 1124
1089 } else if ( same ( _response_value, stringify_response ( starting ) ) ) { 1125 } else if ( same ( _response_value, stringify_response ( starting ) ) ) {
1090 handle_recv_starting ( _session, _msg ); 1126 handle_recv_starting ( _session, _msg );
1091 1127
1092 } else if ( same ( _response_value, stringify_response ( ending ) ) ) { 1128 } else if ( same ( _response_value, stringify_response ( ending ) ) ) {
1093 handle_recv_ending ( _session, _msg ); 1129 handle_recv_ending ( _session, _msg );
1094 1130
1095 } else if ( same ( _response_value, stringify_response ( error ) ) ) { 1131 } else if ( same ( _response_value, stringify_response ( error ) ) ) {
1096 handle_recv_error ( _session, _msg ); 1132 handle_recv_error ( _session, _msg );
1097 } else { 1133 } else {
1098 free_message ( _msg ); 1134 free_message ( _msg );
1099 return; 1135 return;
1100 } 1136 }
1101 1137
1102 /* Got response so cancel timer */ 1138 /* Got response so cancel timer */
1103 if ( _session->call ) 1139 if ( _session->call )
1104 event.timer_release ( _session->call->request_timer_id ); 1140 event.timer_release ( _session->call->request_timer_id );
1105 1141
1106 } 1142 }
1107 1143
1108 free_message ( _msg ); 1144 free_message ( _msg );
1109} 1145}
1110 1146
1111 1147
1112/******************************************************************************************************************** 1148/********************************************************************************************************************
1113 * ******************************************************************************************************************* 1149 * *******************************************************************************************************************
1114 ******************************************************************************************************************** 1150 ********************************************************************************************************************
1115 ******************************************************************************************************************** 1151 ********************************************************************************************************************
1116 ******************************************************************************************************************** 1152 ********************************************************************************************************************
1117 * 1153 *
1118 * 1154 *
1119 * 1155 *
1120 * PUBLIC API FUNCTIONS IMPLEMENTATIONS 1156 * PUBLIC API FUNCTIONS IMPLEMENTATIONS
1121 * 1157 *
1122 * 1158 *
1123 * 1159 *
1124 ******************************************************************************************************************** 1160 ********************************************************************************************************************
1125 ******************************************************************************************************************** 1161 ********************************************************************************************************************
1126 ******************************************************************************************************************** 1162 ********************************************************************************************************************
@@ -1136,12 +1172,12 @@ void msi_handle_packet ( Messenger* messenger, int source, uint8_t* data, uint16
1136 1172
1137/** 1173/**
1138 * @brief Callback setter. 1174 * @brief Callback setter.
1139 * 1175 *
1140 * @param callback The callback. 1176 * @param callback The callback.
1141 * @param id The id. 1177 * @param id The id.
1142 * @return void 1178 * @return void
1143 */ 1179 */
1144void msi_register_callback ( MSICallback callback, MSICallbackID id ) 1180void msi_register_callback ( MSICallback callback, MSICallbackID id )
1145{ 1181{
1146 callbacks[id] = callback; 1182 callbacks[id] = callback;
1147} 1183}
@@ -1149,54 +1185,56 @@ void msi_register_callback ( MSICallback callback, MSICallbackID id )
1149 1185
1150/** 1186/**
1151 * @brief Start the control session. 1187 * @brief Start the control session.
1152 * 1188 *
1153 * @param messenger Tox* object. 1189 * @param messenger Tox* object.
1154 * @param user_agent User agent, i.e. 'Venom'; 'QT-gui' 1190 * @param user_agent User agent, i.e. 'Venom'; 'QT-gui'
1155 * @return MSISession* The created session. 1191 * @return MSISession* The created session.
1156 * @retval NULL Error occured. 1192 * @retval NULL Error occured.
1157 */ 1193 */
1158MSISession* msi_init_session ( Messenger* messenger, const uint8_t* ua_name ) { 1194MSISession *msi_init_session ( Messenger *messenger, const uint8_t *ua_name )
1195{
1159 assert ( messenger ); 1196 assert ( messenger );
1160 1197
1161 MSISession* _retu = calloc ( sizeof ( MSISession ), 1 ); 1198 MSISession *_retu = calloc ( sizeof ( MSISession ), 1 );
1162 assert ( _retu ); 1199 assert ( _retu );
1163 1200
1164 _retu->ua_name = ua_name; 1201 _retu->ua_name = ua_name;
1165 _retu->messenger_handle = messenger; 1202 _retu->messenger_handle = messenger;
1166 _retu->agent_handler = NULL; 1203 _retu->agent_handler = NULL;
1167 1204
1168 _retu->call = NULL; 1205 _retu->call = NULL;
1169 1206
1170 _retu->frequ = 10000; /* default value? */ 1207 _retu->frequ = 10000; /* default value? */
1171 _retu->call_timeout = 30000; /* default value? */ 1208 _retu->call_timeout = 30000; /* default value? */
1172 1209
1173 1210
1174 m_callback_msi_packet(messenger, msi_handle_packet, _retu ); 1211 m_callback_msi_packet(messenger, msi_handle_packet, _retu );
1175 1212
1176 /* This is called when remote terminates session */ 1213 /* This is called when remote terminates session */
1177 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu); 1214 m_callback_connectionstatus_internal_av(messenger, handle_remote_connection_change, _retu);
1178 1215
1179 return _retu; 1216 return _retu;
1180} 1217}
1181 1218
1182 1219
1183/** 1220/**
1184 * @brief Terminate control session. 1221 * @brief Terminate control session.
1185 * 1222 *
1186 * @param session The session 1223 * @param session The session
1187 * @return int 1224 * @return int
1188 */ 1225 */
1189int msi_terminate_session ( MSISession* session ) { 1226int msi_terminate_session ( MSISession *session )
1227{
1190 assert ( session ); 1228 assert ( session );
1191 1229
1192 int _status = 0; 1230 int _status = 0;
1193 1231
1194 terminate_call ( session ); 1232 terminate_call ( session );
1195 m_callback_msi_packet((struct Messenger*) session->messenger_handle, NULL, NULL); 1233 m_callback_msi_packet((struct Messenger *) session->messenger_handle, NULL, NULL);
1196 1234
1197 1235
1198 /* TODO: Clean it up more? */ 1236 /* TODO: Clean it up more? */
1199 1237
1200 free ( session ); 1238 free ( session );
1201 return _status; 1239 return _status;
1202} 1240}
@@ -1204,32 +1242,33 @@ int msi_terminate_session ( MSISession* session ) {
1204 1242
1205/** 1243/**
1206 * @brief Send invite request to friend_id. 1244 * @brief Send invite request to friend_id.
1207 * 1245 *
1208 * @param session Control session. 1246 * @param session Control session.
1209 * @param call_type Type of the call. Audio or Video(both audio and video) 1247 * @param call_type Type of the call. Audio or Video(both audio and video)
1210 * @param rngsec Ringing timeout. 1248 * @param rngsec Ringing timeout.
1211 * @param friend_id The friend. 1249 * @param friend_id The friend.
1212 * @return int 1250 * @return int
1213 */ 1251 */
1214int msi_invite ( MSISession* session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ) { 1252int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id )
1253{
1215 assert ( session ); 1254 assert ( session );
1216 1255
1217 MSIMessage* _msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) ); 1256 MSIMessage *_msg_invite = msi_new_message ( TYPE_REQUEST, stringify_request ( invite ) );
1218 1257
1219 session->call = init_call ( session, 1, rngsec ); /* Just one for now */ 1258 session->call = init_call ( session, 1, rngsec ); /* Just one for now */
1220 t_randomstr ( session->call->id, CALL_ID_LEN ); 1259 t_randomstr ( session->call->id, CALL_ID_LEN );
1221 1260
1222 add_peer(session->call, friend_id ); 1261 add_peer(session->call, friend_id );
1223 1262
1224 session->call->type_local = call_type; 1263 session->call->type_local = call_type;
1225 /* Do whatever with message */ 1264 /* Do whatever with message */
1226 1265
1227 if ( call_type == type_audio ) { 1266 if ( call_type == type_audio ) {
1228 msi_msg_set_calltype 1267 msi_msg_set_calltype
1229 ( _msg_invite, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) ); 1268 ( _msg_invite, ( const uint8_t * ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
1230 } else { 1269 } else {
1231 msi_msg_set_calltype 1270 msi_msg_set_calltype
1232 ( _msg_invite, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) ); 1271 ( _msg_invite, ( const uint8_t * ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
1233 } 1272 }
1234 1273
1235 send_message ( session, _msg_invite, friend_id ); 1274 send_message ( session, _msg_invite, friend_id );
@@ -1245,26 +1284,28 @@ int msi_invite ( MSISession* session, MSICallType call_type, uint32_t rngsec, ui
1245 1284
1246/** 1285/**
1247 * @brief Hangup active call. 1286 * @brief Hangup active call.
1248 * 1287 *
1249 * @param session Control session. 1288 * @param session Control session.
1250 * @return int 1289 * @return int
1251 * @retval -1 Error occured. 1290 * @retval -1 Error occured.
1252 * @retval 0 Success. 1291 * @retval 0 Success.
1253 */ 1292 */
1254int msi_hangup ( MSISession* session ) { 1293int msi_hangup ( MSISession *session )
1294{
1255 assert ( session ); 1295 assert ( session );
1256 1296
1257 if ( !session->call || session->call->state != call_active ) 1297 if ( !session->call || session->call->state != call_active )
1258 return -1; 1298 return -1;
1259 1299
1260 MSIMessage* _msg_ending = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) ); 1300 MSIMessage *_msg_ending = msi_new_message ( TYPE_REQUEST, stringify_request ( end ) );
1261 1301
1262 /* hangup for each peer */ 1302 /* hangup for each peer */
1263 int _it = 0; 1303 int _it = 0;
1304
1264 for ( ; _it < session->call->peer_count; _it ++ ) 1305 for ( ; _it < session->call->peer_count; _it ++ )
1265 send_message ( session, _msg_ending, session->call->peers[_it] ); 1306 send_message ( session, _msg_ending, session->call->peers[_it] );
1266 1307
1267 1308
1268 free_message ( _msg_ending ); 1309 free_message ( _msg_ending );
1269 1310
1270 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout ); 1311 session->call->request_timer_id = event.timer_alloc ( handle_timeout, session, m_deftout );
@@ -1275,23 +1316,24 @@ int msi_hangup ( MSISession* session ) {
1275 1316
1276/** 1317/**
1277 * @brief Answer active call request. 1318 * @brief Answer active call request.
1278 * 1319 *
1279 * @param session Control session. 1320 * @param session Control session.
1280 * @param call_type Answer with Audio or Video(both). 1321 * @param call_type Answer with Audio or Video(both).
1281 * @return int 1322 * @return int
1282 */ 1323 */
1283int msi_answer ( MSISession* session, MSICallType call_type ) { 1324int msi_answer ( MSISession *session, MSICallType call_type )
1325{
1284 assert ( session ); 1326 assert ( session );
1285 1327
1286 MSIMessage* _msg_starting = msi_new_message ( TYPE_RESPONSE, stringify_response ( starting ) ); 1328 MSIMessage *_msg_starting = msi_new_message ( TYPE_RESPONSE, stringify_response ( starting ) );
1287 session->call->type_local = call_type; 1329 session->call->type_local = call_type;
1288 1330
1289 if ( call_type == type_audio ) { 1331 if ( call_type == type_audio ) {
1290 msi_msg_set_calltype 1332 msi_msg_set_calltype
1291 ( _msg_starting, ( const uint8_t* ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) ); 1333 ( _msg_starting, ( const uint8_t * ) CT_AUDIO_HEADER_VALUE, strlen ( CT_AUDIO_HEADER_VALUE ) );
1292 } else { 1334 } else {
1293 msi_msg_set_calltype 1335 msi_msg_set_calltype
1294 ( _msg_starting, ( const uint8_t* ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) ); 1336 ( _msg_starting, ( const uint8_t * ) CT_VIDEO_HEADER_VALUE, strlen ( CT_VIDEO_HEADER_VALUE ) );
1295 } 1337 }
1296 1338
1297 /* Now set the local encryption key and pass it with STARTING message */ 1339 /* Now set the local encryption key and pass it with STARTING message */
@@ -1316,18 +1358,19 @@ int msi_answer ( MSISession* session, MSICallType call_type ) {
1316 1358
1317/** 1359/**
1318 * @brief Cancel request. 1360 * @brief Cancel request.
1319 * 1361 *
1320 * @param session Control session. 1362 * @param session Control session.
1321 * @param reason Set optional reason header. Pass NULL if none. 1363 * @param reason Set optional reason header. Pass NULL if none.
1322 * @return int 1364 * @return int
1323 */ 1365 */
1324int msi_cancel ( MSISession* session, uint32_t peer, const uint8_t* reason ) { 1366int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason )
1367{
1325 assert ( session ); 1368 assert ( session );
1326 1369
1327 MSIMessage* _msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) ); 1370 MSIMessage *_msg_cancel = msi_new_message ( TYPE_REQUEST, stringify_request ( cancel ) );
1328 1371
1329 if ( reason ) msi_msg_set_reason(_msg_cancel, reason, strlen((const char*)reason)); 1372 if ( reason ) msi_msg_set_reason(_msg_cancel, reason, strlen((const char *)reason));
1330 1373
1331 send_message ( session, _msg_cancel, peer ); 1374 send_message ( session, _msg_cancel, peer );
1332 free_message ( _msg_cancel ); 1375 free_message ( _msg_cancel );
1333 1376
@@ -1339,17 +1382,18 @@ int msi_cancel ( MSISession* session, uint32_t peer, const uint8_t* reason ) {
1339 1382
1340/** 1383/**
1341 * @brief Reject request. 1384 * @brief Reject request.
1342 * 1385 *
1343 * @param session Control session. 1386 * @param session Control session.
1344 * @return int 1387 * @return int
1345 */ 1388 */
1346int msi_reject ( MSISession* session, const uint8_t* reason ) { 1389int msi_reject ( MSISession *session, const uint8_t *reason )
1390{
1347 assert ( session ); 1391 assert ( session );
1348 1392
1349 MSIMessage* _msg_reject = msi_new_message ( TYPE_REQUEST, stringify_request ( reject ) ); 1393 MSIMessage *_msg_reject = msi_new_message ( TYPE_REQUEST, stringify_request ( reject ) );
1350 1394
1351 if ( reason ) msi_msg_set_reason(_msg_reject, reason, strlen((const char*)reason) + 1); 1395 if ( reason ) msi_msg_set_reason(_msg_reject, reason, strlen((const char *)reason) + 1);
1352 1396
1353 send_message ( session, _msg_reject, session->call->peers[session->call->peer_count - 1] ); 1397 send_message ( session, _msg_reject, session->call->peers[session->call->peer_count - 1] );
1354 free_message ( _msg_reject ); 1398 free_message ( _msg_reject );
1355 1399
@@ -1361,18 +1405,19 @@ int msi_reject ( MSISession* session, const uint8_t* reason ) {
1361 1405
1362/** 1406/**
1363 * @brief Terminate the current call. 1407 * @brief Terminate the current call.
1364 * 1408 *
1365 * @param session Control session. 1409 * @param session Control session.
1366 * @return int 1410 * @return int
1367 */ 1411 */
1368int msi_stopcall ( MSISession* session ) { 1412int msi_stopcall ( MSISession *session )
1413{
1369 assert ( session ); 1414 assert ( session );
1370 1415
1371 if ( !session->call ) 1416 if ( !session->call )
1372 return -1; 1417 return -1;
1373 1418
1374 /* just terminate it */ 1419 /* just terminate it */
1375 1420
1376 terminate_call ( session ); 1421 terminate_call ( session );
1377 1422
1378 return 0; 1423 return 0;
diff --git a/toxav/msi.h b/toxav/msi.h
index 5b693da4..84a30f63 100644
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -1,5 +1,5 @@
1/** toxmsi.h 1/** toxmsi.h
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -33,7 +33,7 @@
33#define CALL_ID_LEN 12 33#define CALL_ID_LEN 12
34 34
35 35
36typedef void* ( *MSICallback ) ( void* arg ); 36typedef void *( *MSICallback ) ( void *arg );
37 37
38 38
39/** 39/**
@@ -60,21 +60,21 @@ typedef enum {
60 60
61/** 61/**
62 * @brief The call struct. 62 * @brief The call struct.
63 * 63 *
64 */ 64 */
65typedef struct _MSICall { /* Call info structure */ 65typedef struct _MSICall { /* Call info structure */
66 MSICallState state; 66 MSICallState state;
67 67
68 MSICallType type_local; /* Type of payload user is ending */ 68 MSICallType type_local; /* Type of payload user is ending */
69 MSICallType* type_peer; /* Type of payload others are sending */ 69 MSICallType *type_peer; /* Type of payload others are sending */
70 70
71 uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */ 71 uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */
72 72
73 uint8_t* key_local; /* The key for encryption */ 73 uint8_t *key_local; /* The key for encryption */
74 uint8_t* key_peer; /* The key for decryption */ 74 uint8_t *key_peer; /* The key for decryption */
75 75
76 uint8_t* nonce_local; /* Local nonce */ 76 uint8_t *nonce_local; /* Local nonce */
77 uint8_t* nonce_peer; /* Peer nonce */ 77 uint8_t *nonce_peer; /* Peer nonce */
78 78
79 int ringing_tout_ms; /* Ringing timeout in ms */ 79 int ringing_tout_ms; /* Ringing timeout in ms */
80 80
@@ -84,39 +84,39 @@ typedef struct _MSICall { /* Call info structure */
84 pthread_mutex_t mutex; /* It's to be assumed that call will have 84 pthread_mutex_t mutex; /* It's to be assumed that call will have
85 * seperate thread so add mutex 85 * seperate thread so add mutex
86 */ 86 */
87 uint32_t* peers; 87 uint32_t *peers;
88 uint16_t peer_count; 88 uint16_t peer_count;
89 89
90 90
91} MSICall; 91} MSICall;
92 92
93 93
94/** 94/**
95 * @brief Control session struct 95 * @brief Control session struct
96 * 96 *
97 */ 97 */
98typedef struct _MSISession { 98typedef struct _MSISession {
99 99
100 /* Call handler */ 100 /* Call handler */
101 struct _MSICall* call; 101 struct _MSICall *call;
102 102
103 int last_error_id; /* Determine the last error */ 103 int last_error_id; /* Determine the last error */
104 const uint8_t* last_error_str; 104 const uint8_t *last_error_str;
105
106 const uint8_t *ua_name;
105 107
106 const uint8_t* ua_name; 108 void *agent_handler; /* Pointer to an object that is handling msi */
109 Messenger *messenger_handle;
107 110
108 void* agent_handler; /* Pointer to an object that is handling msi */
109 Messenger* messenger_handle;
110
111 uint32_t frequ; 111 uint32_t frequ;
112 uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */ 112 uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */
113 113
114 114
115} MSISession; 115} MSISession;
116 116
117 117
118/** 118/**
119 * @brief Callbacks ids that handle the states 119 * @brief Callbacks ids that handle the states
120 */ 120 */
121typedef enum { 121typedef enum {
122 /* Requests */ 122 /* Requests */
@@ -140,7 +140,7 @@ typedef enum {
140 140
141/** 141/**
142 * @brief Callback setter. 142 * @brief Callback setter.
143 * 143 *
144 * @param callback The callback. 144 * @param callback The callback.
145 * @param id The id. 145 * @param id The id.
146 * @return void 146 * @return void
@@ -150,84 +150,84 @@ void msi_register_callback(MSICallback callback, MSICallbackID id);
150 150
151/** 151/**
152 * @brief Start the control session. 152 * @brief Start the control session.
153 * 153 *
154 * @param messenger Tox* object. 154 * @param messenger Tox* object.
155 * @param user_agent User agent, i.e. 'Venom'; 'QT-gui' 155 * @param user_agent User agent, i.e. 'Venom'; 'QT-gui'
156 * @return MSISession* The created session. 156 * @return MSISession* The created session.
157 * @retval NULL Error occured. 157 * @retval NULL Error occured.
158 */ 158 */
159MSISession* msi_init_session ( Messenger* messenger, const uint8_t* ua_name ); 159MSISession *msi_init_session ( Messenger *messenger, const uint8_t *ua_name );
160 160
161 161
162/** 162/**
163 * @brief Terminate control session. 163 * @brief Terminate control session.
164 * 164 *
165 * @param session The session 165 * @param session The session
166 * @return int 166 * @return int
167 */ 167 */
168int msi_terminate_session ( MSISession* session ); 168int msi_terminate_session ( MSISession *session );
169 169
170 170
171/** 171/**
172 * @brief Send invite request to friend_id. 172 * @brief Send invite request to friend_id.
173 * 173 *
174 * @param session Control session. 174 * @param session Control session.
175 * @param call_type Type of the call. Audio or Video(both audio and video) 175 * @param call_type Type of the call. Audio or Video(both audio and video)
176 * @param rngsec Ringing timeout. 176 * @param rngsec Ringing timeout.
177 * @param friend_id The friend. 177 * @param friend_id The friend.
178 * @return int 178 * @return int
179 */ 179 */
180int msi_invite ( MSISession* session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id ); 180int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id );
181 181
182 182
183/** 183/**
184 * @brief Hangup active call. 184 * @brief Hangup active call.
185 * 185 *
186 * @param session Control session. 186 * @param session Control session.
187 * @return int 187 * @return int
188 * @retval -1 Error occured. 188 * @retval -1 Error occured.
189 * @retval 0 Success. 189 * @retval 0 Success.
190 */ 190 */
191int msi_hangup ( MSISession* session ); 191int msi_hangup ( MSISession *session );
192 192
193 193
194/** 194/**
195 * @brief Answer active call request. 195 * @brief Answer active call request.
196 * 196 *
197 * @param session Control session. 197 * @param session Control session.
198 * @param call_type Answer with Audio or Video(both). 198 * @param call_type Answer with Audio or Video(both).
199 * @return int 199 * @return int
200 */ 200 */
201int msi_answer ( MSISession* session, MSICallType call_type ); 201int msi_answer ( MSISession *session, MSICallType call_type );
202 202
203 203
204/** 204/**
205 * @brief Cancel request. 205 * @brief Cancel request.
206 * 206 *
207 * @param session Control session. 207 * @param session Control session.
208 * @param peer To which peer. 208 * @param peer To which peer.
209 * @param reason Set optional reason header. Pass NULL if none. 209 * @param reason Set optional reason header. Pass NULL if none.
210 * @return int 210 * @return int
211 */ 211 */
212int msi_cancel ( MSISession* session, uint32_t peer, const uint8_t* reason ); 212int msi_cancel ( MSISession *session, uint32_t peer, const uint8_t *reason );
213 213
214 214
215/** 215/**
216 * @brief Reject request. 216 * @brief Reject request.
217 * 217 *
218 * @param session Control session. 218 * @param session Control session.
219 * @param reason Set optional reason header. Pass NULL if none. 219 * @param reason Set optional reason header. Pass NULL if none.
220 * @return int 220 * @return int
221 */ 221 */
222int msi_reject ( MSISession* session, const uint8_t* reason ); 222int msi_reject ( MSISession *session, const uint8_t *reason );
223 223
224 224
225/** 225/**
226 * @brief Terminate the current call. 226 * @brief Terminate the current call.
227 * 227 *
228 * @param session Control session. 228 * @param session Control session.
229 * @return int 229 * @return int
230 */ 230 */
231int msi_stopcall ( MSISession* session ); 231int msi_stopcall ( MSISession *session );
232 232
233#endif /* __TOXMSI */ 233#endif /* __TOXMSI */
diff --git a/toxav/phone.c b/toxav/phone.c
index 161275d9..ec7dd143 100755..100644
--- a/toxav/phone.c
+++ b/toxav/phone.c
@@ -1,16 +1,16 @@
1/** phone.c 1/** phone.c
2 * 2 *
3 * NOTE NOTE NOTE NOTE NOTE NOTE 3 * NOTE NOTE NOTE NOTE NOTE NOTE
4 * 4 *
5 * This file is for testing/reference purposes only, hence 5 * This file is for testing/reference purposes only, hence
6 * it is _poorly_ designed and it does not fully reflect the 6 * it is _poorly_ designed and it does not fully reflect the
7 * quaility of msi nor rtp. Although toxmsi* and toxrtp* are tested 7 * quaility of msi nor rtp. Although toxmsi* and toxrtp* are tested
8 * there is always possiblity of crashes. If crash occures, 8 * there is always possiblity of crashes. If crash occures,
9 * contact me ( mannol ) on either irc channel #tox-dev @ freenode.net:6667 9 * contact me ( mannol ) on either irc channel #tox-dev @ freenode.net:6667
10 * or eniz_vukovic@hotmail.com 10 * or eniz_vukovic@hotmail.com
11 * 11 *
12 * NOTE NOTE NOTE NOTE NOTE NOTE 12 * NOTE NOTE NOTE NOTE NOTE NOTE
13 * 13 *
14 * Copyright (C) 2013 Tox project All Rights Reserved. 14 * Copyright (C) 2013 Tox project All Rights Reserved.
15 * 15 *
16 * This file is part of Tox. 16 * This file is part of Tox.
@@ -97,25 +97,25 @@ typedef struct av_friend_s {
97 97
98typedef struct av_session_s { 98typedef struct av_session_s {
99 /* Encoding/decoding/capturing/playing */ 99 /* Encoding/decoding/capturing/playing */
100 ToxAv* av; 100 ToxAv *av;
101 101
102 VideoPicture video_picture; 102 VideoPicture video_picture;
103 struct ALCdevice *audio_capture_device; 103 struct ALCdevice *audio_capture_device;
104 104
105 /* context for converting image format to something SDL can use*/ 105 /* context for converting image format to something SDL can use*/
106 struct SwsContext *sws_SDL_r_ctx; 106 struct SwsContext *sws_SDL_r_ctx;
107 107
108 /* context for converting webcam image format to something the video encoder can use */ 108 /* context for converting webcam image format to something the video encoder can use */
109 struct SwsContext *sws_ctx; 109 struct SwsContext *sws_ctx;
110 110
111 /* Thread running control */ 111 /* Thread running control */
112 int running_decaud, running_encaud, 112 int running_decaud, running_encaud,
113 running_decvid, running_encvid; 113 running_decvid, running_encvid;
114 114
115 pthread_mutex_t _mutex; 115 pthread_mutex_t _mutex;
116 116
117 Tox* _messenger; 117 Tox *_messenger;
118 av_friend_t* _friends; 118 av_friend_t *_friends;
119 int _friend_cout; 119 int _friend_cout;
120 char _my_public_id[200]; 120 char _my_public_id[200];
121#ifdef TOX_FFMPEG 121#ifdef TOX_FFMPEG
@@ -128,43 +128,44 @@ typedef struct av_session_s {
128} av_session_t; 128} av_session_t;
129 129
130 130
131void av_allocate_friend(av_session_t* _phone, int _id, int _active) 131void av_allocate_friend(av_session_t *_phone, int _id, int _active)
132{ 132{
133 static int _new_id = 0; 133 static int _new_id = 0;
134 134
135 if ( !_phone->_friends ) { 135 if ( !_phone->_friends ) {
136 _phone->_friends = calloc(sizeof(av_friend_t), 1); 136 _phone->_friends = calloc(sizeof(av_friend_t), 1);
137 _phone->_friend_cout = 1; 137 _phone->_friend_cout = 1;
138 } else{ 138 } else {
139 _phone->_friend_cout ++; 139 _phone->_friend_cout ++;
140 _phone->_friends = realloc(_phone->_friends, sizeof(av_friend_t) * _phone->_friend_cout); 140 _phone->_friends = realloc(_phone->_friends, sizeof(av_friend_t) * _phone->_friend_cout);
141 } 141 }
142 142
143 if ( _id == -1 ) { 143 if ( _id == -1 ) {
144 _phone->_friends->_id = _new_id; 144 _phone->_friends->_id = _new_id;
145 _new_id ++; 145 _new_id ++;
146 } else _phone->_friends->_id = _id; 146 } else _phone->_friends->_id = _id;
147 147
148 _phone->_friends->_active = _active; 148 _phone->_friends->_active = _active;
149} 149}
150av_friend_t* av_get_friend(av_session_t* _phone, int _id) 150av_friend_t *av_get_friend(av_session_t *_phone, int _id)
151{ 151{
152 av_friend_t* _friends = _phone->_friends; 152 av_friend_t *_friends = _phone->_friends;
153 153
154 if ( !_friends ) return NULL; 154 if ( !_friends ) return NULL;
155 155
156 int _it = 0; 156 int _it = 0;
157
157 for (; _it < _phone->_friend_cout; _it ++) 158 for (; _it < _phone->_friend_cout; _it ++)
158 if ( _friends[_it]._id == _id ) 159 if ( _friends[_it]._id == _id )
159 return _friends + _it; 160 return _friends + _it;
160 161
161 return NULL; 162 return NULL;
162} 163}
163 164
164 165
165/***************** MISC *****************/ 166/***************** MISC *****************/
166 167
167void INFO (const char* _format, ...) 168void INFO (const char *_format, ...)
168{ 169{
169 printf("\r[!] "); 170 printf("\r[!] ");
170 va_list _arg; 171 va_list _arg;
@@ -180,44 +181,44 @@ unsigned char *hex_string_to_bin(char hex_string[])
180 size_t i, len = strlen(hex_string); 181 size_t i, len = strlen(hex_string);
181 unsigned char *val = calloc(sizeof(unsigned char), len); 182 unsigned char *val = calloc(sizeof(unsigned char), len);
182 char *pos = hex_string; 183 char *pos = hex_string;
183 184
184 for (i = 0; i < len; ++i, pos += 2) 185 for (i = 0; i < len; ++i, pos += 2)
185 sscanf(pos, "%2hhx", &val[i]); 186 sscanf(pos, "%2hhx", &val[i]);
186 187
187 return val; 188 return val;
188} 189}
189 190
190int getinput( char* _buff, size_t _limit, int* _len ) 191int getinput( char *_buff, size_t _limit, int *_len )
191{ 192{
192 if ( fgets(_buff, _limit, stdin) == NULL ) 193 if ( fgets(_buff, _limit, stdin) == NULL )
193 return -1; 194 return -1;
194 195
195 *_len = strlen(_buff) - 1; 196 *_len = strlen(_buff) - 1;
196 197
197 /* Get rid of newline */ 198 /* Get rid of newline */
198 _buff[*_len] = '\0'; 199 _buff[*_len] = '\0';
199 200
200 return 0; 201 return 0;
201} 202}
202 203
203char* trim_spaces ( char* buff ) 204char *trim_spaces ( char *buff )
204{ 205{
205 206
206 int _i = 0, _len = strlen(buff); 207 int _i = 0, _len = strlen(buff);
207 208
208 char* container = calloc(sizeof(char), _len); 209 char *container = calloc(sizeof(char), _len);
209 int _ci = 0; 210 int _ci = 0;
210 211
211 for ( ; _i < _len; _i++ ) { 212 for ( ; _i < _len; _i++ ) {
212 while ( _i < _len && buff[_i] == ' ' ) 213 while ( _i < _len && buff[_i] == ' ' )
213 _i++; 214 _i++;
214 215
215 if ( _i < _len ){ 216 if ( _i < _len ) {
216 container[_ci] = buff[_i]; 217 container[_ci] = buff[_i];
217 _ci ++; 218 _ci ++;
218 } 219 }
219 } 220 }
220 221
221 memcpy( buff, container, _ci ); 222 memcpy( buff, container, _ci );
222 buff[_ci] = '\0'; 223 buff[_ci] = '\0';
223 free(container); 224 free(container);
@@ -227,26 +228,26 @@ char* trim_spaces ( char* buff )
227#define FRADDR_TOSTR_CHUNK_LEN 8 228#define FRADDR_TOSTR_CHUNK_LEN 8
228 229
229static void fraddr_to_str(uint8_t *id_bin, char *id_str) 230static void fraddr_to_str(uint8_t *id_bin, char *id_str)
230{ 231{
231 uint i, delta = 0, pos_extra = 0, sum_extra = 0; 232 uint i, delta = 0, pos_extra = 0, sum_extra = 0;
232 233
233 for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) { 234 for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
234 sprintf(&id_str[2 * i + delta], "%02hhX", id_bin[i]); 235 sprintf(&id_str[2 * i + delta], "%02hhX", id_bin[i]);
235 236
236 if ((i + 1) == TOX_CLIENT_ID_SIZE) 237 if ((i + 1) == TOX_CLIENT_ID_SIZE)
237 pos_extra = 2 * (i + 1) + delta; 238 pos_extra = 2 * (i + 1) + delta;
238 239
239 if (i >= TOX_CLIENT_ID_SIZE) 240 if (i >= TOX_CLIENT_ID_SIZE)
240 sum_extra |= id_bin[i]; 241 sum_extra |= id_bin[i];
241 242
242 if (!((i + 1) % FRADDR_TOSTR_CHUNK_LEN)) { 243 if (!((i + 1) % FRADDR_TOSTR_CHUNK_LEN)) {
243 id_str[2 * (i + 1) + delta] = ' '; 244 id_str[2 * (i + 1) + delta] = ' ';
244 delta++; 245 delta++;
245 } 246 }
246 } 247 }
247 248
248 id_str[2 * i + delta] = 0; 249 id_str[2 * i + delta] = 0;
249 250
250 if (!sum_extra) 251 if (!sum_extra)
251 id_str[pos_extra] = 0; 252 id_str[pos_extra] = 0;
252} 253}
@@ -262,8 +263,8 @@ static void fraddr_to_str(uint8_t *id_bin, char *id_str)
262 */ 263 */
263 264
264 265
265/* 266/*
266 * How av stuff _should_ look like 267 * How av stuff _should_ look like
267 */ 268 */
268/* 269/*
269int display_received_frame(av_session_t* _phone, vpx_image_t *image) 270int display_received_frame(av_session_t* _phone, vpx_image_t *image)
@@ -271,7 +272,7 @@ int display_received_frame(av_session_t* _phone, vpx_image_t *image)
271 CodecState* cs = get_cs_temp(_phone->av); 272 CodecState* cs = get_cs_temp(_phone->av);
272 AVPicture pict; 273 AVPicture pict;
273 SDL_LockYUVOverlay(_phone->video_picture.bmp); 274 SDL_LockYUVOverlay(_phone->video_picture.bmp);
274 275
275 pict.data[0] = _phone->video_picture.bmp->pixels[0]; 276 pict.data[0] = _phone->video_picture.bmp->pixels[0];
276 pict.data[1] = _phone->video_picture.bmp->pixels[2]; 277 pict.data[1] = _phone->video_picture.bmp->pixels[2];
277 pict.data[2] = _phone->video_picture.bmp->pixels[1]; 278 pict.data[2] = _phone->video_picture.bmp->pixels[1];
@@ -279,18 +280,18 @@ int display_received_frame(av_session_t* _phone, vpx_image_t *image)
279 pict.linesize[1] = _phone->video_picture.bmp->pitches[2]; 280 pict.linesize[1] = _phone->video_picture.bmp->pitches[2];
280 pict.linesize[2] = _phone->video_picture.bmp->pitches[1]; 281 pict.linesize[2] = _phone->video_picture.bmp->pitches[1];
281 */ 282 */
282 /* Convert the image into YUV format that SDL uses *//* 283/* Convert the image into YUV format that SDL uses *//*
283 sws_scale(_phone->sws_SDL_r_ctx, (uint8_t const * const *)r_video_frame->data, r_video_frame->linesize, 0, 284sws_scale(_phone->sws_SDL_r_ctx, (uint8_t const * const *)r_video_frame->data, r_video_frame->linesize, 0,
284 cs->video_decoder_ctx->height, pict.data, pict.linesize ); 285 cs->video_decoder_ctx->height, pict.data, pict.linesize );
285 286
286 SDL_UnlockYUVOverlay(_phone->video_picture.bmp); 287SDL_UnlockYUVOverlay(_phone->video_picture.bmp);
287 SDL_Rect rect; 288SDL_Rect rect;
288 rect.x = 0; 289rect.x = 0;
289 rect.y = 0; 290rect.y = 0;
290 rect.w = cs->video_decoder_ctx->width; 291rect.w = cs->video_decoder_ctx->width;
291 rect.h = cs->video_decoder_ctx->height; 292rect.h = cs->video_decoder_ctx->height;
292 SDL_DisplayYUVOverlay(_phone->video_picture.bmp, &rect); 293SDL_DisplayYUVOverlay(_phone->video_picture.bmp, &rect);
293 return 1; 294return 1;
294} 295}
295*/ 296*/
296#ifdef TOX_FFMPEG 297#ifdef TOX_FFMPEG
@@ -298,8 +299,8 @@ void *encode_video_thread(void *arg)
298{ 299{
299 INFO("Started encode video thread!"); 300 INFO("Started encode video thread!");
300 301
301 av_session_t* _phone = arg; 302 av_session_t *_phone = arg;
302 303
303 _phone->running_encvid = 1; 304 _phone->running_encvid = 1;
304 //CodecState *cs = get_cs_temp(_phone->av); 305 //CodecState *cs = get_cs_temp(_phone->av);
305 AVPacket pkt1, *packet = &pkt1; 306 AVPacket pkt1, *packet = &pkt1;
@@ -311,40 +312,41 @@ void *encode_video_thread(void *arg)
311 s_video_frame = avcodec_alloc_frame(); 312 s_video_frame = avcodec_alloc_frame();
312 webcam_frame = avcodec_alloc_frame(); 313 webcam_frame = avcodec_alloc_frame();
313 //AVPacket enc_video_packet; 314 //AVPacket enc_video_packet;
314 315
315 uint8_t *buffer; 316 uint8_t *buffer;
316 int numBytes; 317 int numBytes;
317 /* Determine required buffer size and allocate buffer */ 318 /* Determine required buffer size and allocate buffer */
318 numBytes = avpicture_get_size(PIX_FMT_YUV420P, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height); 319 numBytes = avpicture_get_size(PIX_FMT_YUV420P, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height);
319 buffer = (uint8_t *)av_calloc(numBytes * sizeof(uint8_t),1); 320 buffer = (uint8_t *)av_calloc(numBytes * sizeof(uint8_t), 1);
320 avpicture_fill((AVPicture *)s_video_frame, buffer, PIX_FMT_YUV420P, _phone->webcam_decoder_ctx->width, 321 avpicture_fill((AVPicture *)s_video_frame, buffer, PIX_FMT_YUV420P, _phone->webcam_decoder_ctx->width,
321 _phone->webcam_decoder_ctx->height); 322 _phone->webcam_decoder_ctx->height);
322 _phone->sws_ctx = sws_getContext(_phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height, 323 _phone->sws_ctx = sws_getContext(_phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height,
323 _phone->webcam_decoder_ctx->pix_fmt, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height, PIX_FMT_YUV420P, 324 _phone->webcam_decoder_ctx->pix_fmt, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height,
324 SWS_BILINEAR, NULL, NULL, NULL); 325 PIX_FMT_YUV420P,
325 326 SWS_BILINEAR, NULL, NULL, NULL);
326 327
327 vpx_image_t *image = 328
328 vpx_img_alloc(NULL, VPX_IMG_FMT_I420, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height, 1); 329 vpx_image_t *image =
329 330 vpx_img_alloc(NULL, VPX_IMG_FMT_I420, _phone->webcam_decoder_ctx->width, _phone->webcam_decoder_ctx->height, 1);
331
330 //uint32_t frame_counter = 0; 332 //uint32_t frame_counter = 0;
331 while (_phone->running_encvid) { 333 while (_phone->running_encvid) {
332 334
333 if (av_read_frame(_phone->video_format_ctx, packet) < 0) { 335 if (av_read_frame(_phone->video_format_ctx, packet) < 0) {
334 printf("error reading frame\n"); 336 printf("error reading frame\n");
335 337
336 if (_phone->video_format_ctx->pb->error != 0) 338 if (_phone->video_format_ctx->pb->error != 0)
337 break; 339 break;
338 340
339 continue; 341 continue;
340 } 342 }
341 343
342 if (packet->stream_index == _phone->video_stream) { 344 if (packet->stream_index == _phone->video_stream) {
343 if (avcodec_decode_video2(_phone->webcam_decoder_ctx, webcam_frame, &video_frame_finished, packet) < 0) { 345 if (avcodec_decode_video2(_phone->webcam_decoder_ctx, webcam_frame, &video_frame_finished, packet) < 0) {
344 printf("couldn't decode\n"); 346 printf("couldn't decode\n");
345 continue; 347 continue;
346 } 348 }
347 349
348 av_free_packet(packet); 350 av_free_packet(packet);
349 sws_scale(_phone->sws_ctx, (uint8_t const * const *)webcam_frame->data, webcam_frame->linesize, 0, 351 sws_scale(_phone->sws_ctx, (uint8_t const * const *)webcam_frame->data, webcam_frame->linesize, 0,
350 _phone->webcam_decoder_ctx->height, s_video_frame->data, s_video_frame->linesize); 352 _phone->webcam_decoder_ctx->height, s_video_frame->data, s_video_frame->linesize);
@@ -352,7 +354,7 @@ void *encode_video_thread(void *arg)
352 //++p; 354 //++p;
353 /* 355 /*
354 if (p == 60) { 356 if (p == 60) {
355 357
356 s_video_frame->pict_type = AV_PICTURE_TYPE_BI ; 358 s_video_frame->pict_type = AV_PICTURE_TYPE_BI ;
357 } else if (p == 61) { 359 } else if (p == 61) {
358 s_video_frame->pict_type = AV_PICTURE_TYPE_I ; 360 s_video_frame->pict_type = AV_PICTURE_TYPE_I ;
@@ -360,11 +362,14 @@ void *encode_video_thread(void *arg)
360 } else { 362 } else {
361 s_video_frame->pict_type = AV_PICTURE_TYPE_P ; 363 s_video_frame->pict_type = AV_PICTURE_TYPE_P ;
362 }*/ 364 }*/
363 365
364 if (video_frame_finished) { 366 if (video_frame_finished) {
365 memcpy(image->planes[VPX_PLANE_Y], s_video_frame->data[0], s_video_frame->linesize[0] * _phone->webcam_decoder_ctx->height); 367 memcpy(image->planes[VPX_PLANE_Y], s_video_frame->data[0],
366 memcpy(image->planes[VPX_PLANE_U], s_video_frame->data[1], s_video_frame->linesize[1] * _phone->webcam_decoder_ctx->height / 2); 368 s_video_frame->linesize[0] * _phone->webcam_decoder_ctx->height);
367 memcpy(image->planes[VPX_PLANE_V], s_video_frame->data[2], s_video_frame->linesize[2] * _phone->webcam_decoder_ctx->height / 2); 369 memcpy(image->planes[VPX_PLANE_U], s_video_frame->data[1],
370 s_video_frame->linesize[1] * _phone->webcam_decoder_ctx->height / 2);
371 memcpy(image->planes[VPX_PLANE_V], s_video_frame->data[2],
372 s_video_frame->linesize[2] * _phone->webcam_decoder_ctx->height / 2);
368 toxav_send_video (_phone->av, image); 373 toxav_send_video (_phone->av, image);
369 //if (avcodec_encode_video2(cs->video_encoder_ctx, &enc_video_packet, s_video_frame, &got_packet) < 0) { 374 //if (avcodec_encode_video2(cs->video_encoder_ctx, &enc_video_packet, s_video_frame, &got_packet) < 0) {
370 /*if (vpx_codec_encode(&cs->v_encoder, image, frame_counter, 1, 0, 0) != VPX_CODEC_OK) { 375 /*if (vpx_codec_encode(&cs->v_encoder, image, frame_counter, 1, 0, 0) != VPX_CODEC_OK) {
@@ -372,7 +377,7 @@ void *encode_video_thread(void *arg)
372 continue; 377 continue;
373 } 378 }
374 ++frame_counter; 379 ++frame_counter;
375 380
376 vpx_codec_iter_t iter = NULL; 381 vpx_codec_iter_t iter = NULL;
377 vpx_codec_cx_pkt_t *pkt; 382 vpx_codec_cx_pkt_t *pkt;
378 while( (pkt = vpx_codec_get_cx_data(&cs->v_encoder, &iter)) ) { 383 while( (pkt = vpx_codec_get_cx_data(&cs->v_encoder, &iter)) ) {
@@ -382,20 +387,20 @@ void *encode_video_thread(void *arg)
382 //if (!got_packet) { 387 //if (!got_packet) {
383 // continue; 388 // continue;
384 //} 389 //}
385 390
386 //if (!enc_video_packet.data) fprintf(stderr, "video packet data is NULL\n"); 391 //if (!enc_video_packet.data) fprintf(stderr, "video packet data is NULL\n");
387 392
388 //toxav_send_rtp_payload(_phone->av, TypeVideo, enc_video_packet.data, enc_video_packet.size); 393 //toxav_send_rtp_payload(_phone->av, TypeVideo, enc_video_packet.data, enc_video_packet.size);
389 394
390 //av_free_packet(&enc_video_packet); 395 //av_free_packet(&enc_video_packet);
391 } 396 }
392 } else { 397 } else {
393 av_free_packet(packet); 398 av_free_packet(packet);
394 } 399 }
395 } 400 }
396 401
397 vpx_img_free(image); 402 vpx_img_free(image);
398 403
399 /* clean up codecs */ 404 /* clean up codecs */
400 //pthread_mutex_lock(&cs->ctrl_mutex); 405 //pthread_mutex_lock(&cs->ctrl_mutex);
401 av_free(buffer); 406 av_free(buffer);
@@ -405,9 +410,9 @@ void *encode_video_thread(void *arg)
405 //avcodec_close(webcam_decoder_ctx); 410 //avcodec_close(webcam_decoder_ctx);
406 //avcodec_close(cs->video_encoder_ctx); 411 //avcodec_close(cs->video_encoder_ctx);
407 //pthread_mutex_unlock(&cs->ctrl_mutex); 412 //pthread_mutex_unlock(&cs->ctrl_mutex);
408 413
409 _phone->running_encvid = -1; 414 _phone->running_encvid = -1;
410 415
411 pthread_exit ( NULL ); 416 pthread_exit ( NULL );
412} 417}
413#endif 418#endif
@@ -415,23 +420,23 @@ void *encode_video_thread(void *arg)
415void *encode_audio_thread(void *arg) 420void *encode_audio_thread(void *arg)
416{ 421{
417 INFO("Started encode audio thread!"); 422 INFO("Started encode audio thread!");
418 av_session_t* _phone = arg; 423 av_session_t *_phone = arg;
419 _phone->running_encaud = 1; 424 _phone->running_encaud = 1;
420 425
421 int ret = 0; 426 int ret = 0;
422 int16_t frame[4096]; 427 int16_t frame[4096];
423 int frame_size = AUDIO_FRAME_SIZE; 428 int frame_size = AUDIO_FRAME_SIZE;
424 ALint sample = 0; 429 ALint sample = 0;
425 alcCaptureStart((ALCdevice*)_phone->audio_capture_device); 430 alcCaptureStart((ALCdevice *)_phone->audio_capture_device);
426 431
427 while (_phone->running_encaud) { 432 while (_phone->running_encaud) {
428 alcGetIntegerv((ALCdevice*)_phone->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample); 433 alcGetIntegerv((ALCdevice *)_phone->audio_capture_device, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample);
429 434
430 if (sample >= frame_size) { 435 if (sample >= frame_size) {
431 alcCaptureSamples((ALCdevice*)_phone->audio_capture_device, frame, frame_size); 436 alcCaptureSamples((ALCdevice *)_phone->audio_capture_device, frame, frame_size);
432 437
433 ret = toxav_send_audio(_phone->av, frame, frame_size); 438 ret = toxav_send_audio(_phone->av, frame, frame_size);
434 439
435 if (ret < 0) 440 if (ret < 0)
436 printf("Could not encode or send audio packet\n"); 441 printf("Could not encode or send audio packet\n");
437 442
@@ -439,28 +444,29 @@ void *encode_audio_thread(void *arg)
439 usleep(1000); 444 usleep(1000);
440 } 445 }
441 } 446 }
442 447
443 /* clean up codecs * 448 /* clean up codecs *
444 pthread_mutex_lock(&cs->ctrl_mutex);* / 449 pthread_mutex_lock(&cs->ctrl_mutex);* /
445 alcCaptureStop((ALCdevice*)_phone->audio_capture_device); 450 alcCaptureStop((ALCdevice*)_phone->audio_capture_device);
446 alcCaptureCloseDevice((ALCdevice*)_phone->audio_capture_device); 451 alcCaptureCloseDevice((ALCdevice*)_phone->audio_capture_device);
447 / *pthread_mutex_unlock(&cs->ctrl_mutex);*/ 452 / *pthread_mutex_unlock(&cs->ctrl_mutex);*/
448 _phone->running_encaud = -1; 453 _phone->running_encaud = -1;
449 pthread_exit ( NULL ); 454 pthread_exit ( NULL );
450} 455}
451 456
452void convert_to_rgb(vpx_image_t *img, unsigned char *out) 457void convert_to_rgb(vpx_image_t *img, unsigned char *out)
453{ 458{
454 const int w = img->d_w; 459 const int w = img->d_w;
455 const int w2 = w/2; 460 const int w2 = w / 2;
456 const int pstride = w*3; 461 const int pstride = w * 3;
457 const int h = img->d_h; 462 const int h = img->d_h;
458 const int h2 = h/2; 463 const int h2 = h / 2;
459 464
460 const int strideY = img->stride[0]; 465 const int strideY = img->stride[0];
461 const int strideU = img->stride[1]; 466 const int strideU = img->stride[1];
462 const int strideV = img->stride[2]; 467 const int strideV = img->stride[2];
463 int posy, posx; 468 int posy, posx;
469
464 for (posy = 0; posy < h2; posy++) { 470 for (posy = 0; posy < h2; posy++) {
465 unsigned char *dst = out + pstride * (posy * 2); 471 unsigned char *dst = out + pstride * (posy * 2);
466 unsigned char *dst2 = out + pstride * (posy * 2 + 1); 472 unsigned char *dst2 = out + pstride * (posy * 2 + 1);
@@ -468,36 +474,61 @@ void convert_to_rgb(vpx_image_t *img, unsigned char *out)
468 const unsigned char *srcY2 = img->planes[0] + strideY * (posy * 2 + 1); 474 const unsigned char *srcY2 = img->planes[0] + strideY * (posy * 2 + 1);
469 const unsigned char *srcU = img->planes[1] + strideU * posy; 475 const unsigned char *srcU = img->planes[1] + strideU * posy;
470 const unsigned char *srcV = img->planes[2] + strideV * posy; 476 const unsigned char *srcV = img->planes[2] + strideV * posy;
471 477
472 for (posx = 0; posx < w2; posx++) { 478 for (posx = 0; posx < w2; posx++) {
473 unsigned char Y,U,V; 479 unsigned char Y, U, V;
474 short R,G,B; 480 short R, G, B;
475 short iR,iG,iB; 481 short iR, iG, iB;
476 482
477 U = *(srcU++); V = *(srcV++); 483 U = *(srcU++);
478 iR = (351 * (V-128)) / 256; 484 V = *(srcV++);
479 iG = - (179 * (V-128)) / 256 - (86 * (U-128)) / 256; 485 iR = (351 * (V - 128)) / 256;
480 iB = (444 * (U-128)) / 256; 486 iG = - (179 * (V - 128)) / 256 - (86 * (U - 128)) / 256;
481 487 iB = (444 * (U - 128)) / 256;
482 Y = *(srcY++); 488
483 R = Y + iR ; G = Y + iG ; B = Y + iB ; 489 Y = *(srcY++);
484 R = (R<0?0:(R>255?255:R)); G = (G<0?0:(G>255?255:G)); B = (B<0?0:(B>255?255:B)); 490 R = Y + iR ;
485 *(dst++) = R; *(dst++) = G; *(dst++) = B; 491 G = Y + iG ;
486 492 B = Y + iB ;
493 R = (R < 0 ? 0 : (R > 255 ? 255 : R));
494 G = (G < 0 ? 0 : (G > 255 ? 255 : G));
495 B = (B < 0 ? 0 : (B > 255 ? 255 : B));
496 *(dst++) = R;
497 *(dst++) = G;
498 *(dst++) = B;
499
487 Y = *(srcY2++); 500 Y = *(srcY2++);
488 R = Y + iR ; G = Y + iG ; B = Y + iB ; 501 R = Y + iR ;
489 R = (R<0?0:(R>255?255:R)); G = (G<0?0:(G>255?255:G)); B = (B<0?0:(B>255?255:B)); 502 G = Y + iG ;
490 *(dst2++) = R; *(dst2++) = G; *(dst2++) = B; 503 B = Y + iB ;
491 504 R = (R < 0 ? 0 : (R > 255 ? 255 : R));
505 G = (G < 0 ? 0 : (G > 255 ? 255 : G));
506 B = (B < 0 ? 0 : (B > 255 ? 255 : B));
507 *(dst2++) = R;
508 *(dst2++) = G;
509 *(dst2++) = B;
510
492 Y = *(srcY++) ; 511 Y = *(srcY++) ;
493 R = Y + iR ; G = Y + iG ; B = Y + iB ; 512 R = Y + iR ;
494 R = (R<0?0:(R>255?255:R)); G = (G<0?0:(G>255?255:G)); B = (B<0?0:(B>255?255:B)); 513 G = Y + iG ;
495 *(dst++) = R; *(dst++) = G; *(dst++) = B; 514 B = Y + iB ;
496 515 R = (R < 0 ? 0 : (R > 255 ? 255 : R));
516 G = (G < 0 ? 0 : (G > 255 ? 255 : G));
517 B = (B < 0 ? 0 : (B > 255 ? 255 : B));
518 *(dst++) = R;
519 *(dst++) = G;
520 *(dst++) = B;
521
497 Y = *(srcY2++); 522 Y = *(srcY2++);
498 R = Y + iR ; G = Y + iG ; B = Y + iB ; 523 R = Y + iR ;
499 R = (R<0?0:(R>255?255:R)); G = (G<0?0:(G>255?255:G)); B = (B<0?0:(B>255?255:B)); 524 G = Y + iG ;
500 *(dst2++) = R; *(dst2++) = G; *(dst2++) = B; 525 B = Y + iB ;
526 R = (R < 0 ? 0 : (R > 255 ? 255 : R));
527 G = (G < 0 ? 0 : (G > 255 ? 255 : G));
528 B = (B < 0 ? 0 : (B > 255 ? 255 : B));
529 *(dst2++) = R;
530 *(dst2++) = G;
531 *(dst2++) = B;
501 } 532 }
502 } 533 }
503} 534}
@@ -507,15 +538,15 @@ void convert_to_rgb(vpx_image_t *img, unsigned char *out)
507void *decode_video_thread(void *arg) 538void *decode_video_thread(void *arg)
508{ 539{
509 INFO("Started decode video thread!"); 540 INFO("Started decode video thread!");
510 av_session_t* _phone = arg; 541 av_session_t *_phone = arg;
511 _phone->running_decvid = 1; 542 _phone->running_decvid = 1;
512 543
513 //CodecState *cs = get_cs_temp(_phone->av); 544 //CodecState *cs = get_cs_temp(_phone->av);
514 //cs->video_stream = 0; 545 //cs->video_stream = 0;
515 546
516 //int recved_size; 547 //int recved_size;
517 //uint8_t dest[RTP_PAYLOAD_SIZE]; 548 //uint8_t dest[RTP_PAYLOAD_SIZE];
518 549
519 //int dec_frame_finished; 550 //int dec_frame_finished;
520 //AVFrame *r_video_frame; 551 //AVFrame *r_video_frame;
521 //r_video_frame = avcodec_alloc_frame(); 552 //r_video_frame = avcodec_alloc_frame();
@@ -523,89 +554,95 @@ void *decode_video_thread(void *arg)
523 //av_new_packet (&dec_video_packet, 65536); 554 //av_new_packet (&dec_video_packet, 65536);
524 int width = 0; 555 int width = 0;
525 int height = 0; 556 int height = 0;
526 557
527 while (_phone->running_decvid) { 558 while (_phone->running_decvid) {
528 //recved_size = toxav_recv_rtp_payload(_phone->av, TypeVideo, dest); 559 //recved_size = toxav_recv_rtp_payload(_phone->av, TypeVideo, dest);
529 //if (recved_size) { 560 //if (recved_size) {
530 vpx_image_t *image; 561 vpx_image_t *image;
562
531 if (toxav_recv_video(_phone->av, &image) == 0) { 563 if (toxav_recv_video(_phone->av, &image) == 0) {
532 //memcpy(dec_video_packet.data, dest, recved_size); 564 //memcpy(dec_video_packet.data, dest, recved_size);
533 //dec_video_packet.size = recved_size; 565 //dec_video_packet.size = recved_size;
534 566
535 //avcodec_decode_video2(cs->video_decoder_ctx, r_video_frame, &dec_frame_finished, &dec_video_packet); 567 //avcodec_decode_video2(cs->video_decoder_ctx, r_video_frame, &dec_frame_finished, &dec_video_packet);
536 568
537 //if (dec_frame_finished) { 569 //if (dec_frame_finished) {
538 570
539 /* Check if size has changed */ 571 /* Check if size has changed */
540 if (image->d_w != width || image->d_h != height) { 572 if (image->d_w != width || image->d_h != height) {
541 573
542 width = image->d_w; 574 width = image->d_w;
543 height = image->d_h; 575 height = image->d_h;
544 576
545 printf("w: %d h: %d \n", width, height); 577 printf("w: %d h: %d \n", width, height);
546 578
547 screen = SDL_SetVideoMode(width, height, 0, 0); 579 screen = SDL_SetVideoMode(width, height, 0, 0);
548 580
549 //if (_phone->video_picture.bmp) 581 //if (_phone->video_picture.bmp)
550 // SDL_FreeYUVOverlay(_phone->video_picture.bmp); 582 // SDL_FreeYUVOverlay(_phone->video_picture.bmp);
551 583
552 //_phone->video_picture.bmp = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen); 584 //_phone->video_picture.bmp = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen);
553 // _phone->sws_SDL_r_ctx = sws_getContext(width, height, cs->video_decoder_ctx->pix_fmt, width, height, PIX_FMT_YUV420P, 585 // _phone->sws_SDL_r_ctx = sws_getContext(width, height, cs->video_decoder_ctx->pix_fmt, width, height, PIX_FMT_YUV420P,
554 // SWS_BILINEAR, NULL, NULL, NULL); 586 // SWS_BILINEAR, NULL, NULL, NULL);
555 } 587 }
556 uint8_t *rgb_image = malloc(width*height*3); 588
557 convert_to_rgb(image, rgb_image); 589 uint8_t *rgb_image = malloc(width * height * 3);
558 SDL_Surface* img_surface = SDL_CreateRGBSurfaceFrom(rgb_image, width, height, 24, width * 3, mask32(0), mask32(1), mask32(2), 0); 590 convert_to_rgb(image, rgb_image);
559 if(SDL_BlitSurface(img_surface, NULL, screen, NULL) == 0) 591 SDL_Surface *img_surface = SDL_CreateRGBSurfaceFrom(rgb_image, width, height, 24, width * 3, mask32(0), mask32(1),
560 SDL_UpdateRect(screen, 0, 0, 0, 0); 592 mask32(2), 0);
561 /* 593
562 SDL_LockYUVOverlay(_phone->video_picture.bmp); 594 if (SDL_BlitSurface(img_surface, NULL, screen, NULL) == 0)
563 memcpy(_phone->video_picture.bmp->pixels[0], image->planes[VPX_PLANE_Y], _phone->video_picture.bmp->pitches[0] * height); 595 SDL_UpdateRect(screen, 0, 0, 0, 0);
564 memcpy(_phone->video_picture.bmp->pixels[1], image->planes[VPX_PLANE_V], _phone->video_picture.bmp->pitches[1] * height / 2); 596
565 memcpy(_phone->video_picture.bmp->pixels[2], image->planes[VPX_PLANE_U], _phone->video_picture.bmp->pitches[2] * height / 2); 597 /*
566 598 SDL_LockYUVOverlay(_phone->video_picture.bmp);
567 SDL_Rect rect; 599 memcpy(_phone->video_picture.bmp->pixels[0], image->planes[VPX_PLANE_Y], _phone->video_picture.bmp->pitches[0] * height);
568 rect.x = 0; 600 memcpy(_phone->video_picture.bmp->pixels[1], image->planes[VPX_PLANE_V], _phone->video_picture.bmp->pitches[1] * height / 2);
569 rect.y = 0; 601 memcpy(_phone->video_picture.bmp->pixels[2], image->planes[VPX_PLANE_U], _phone->video_picture.bmp->pitches[2] * height / 2);
570 rect.w = width; 602
571 rect.h = height; 603 SDL_Rect rect;
572 SDL_DisplayYUVOverlay(_phone->video_picture.bmp, &rect);*/ 604 rect.x = 0;
573 free(rgb_image); 605 rect.y = 0;
574 //display_received_frame(_phone, image); 606 rect.w = width;
575 607 rect.h = height;
576 } //else { 608 SDL_DisplayYUVOverlay(_phone->video_picture.bmp, &rect);*/
577 /* TODO: request the sender to create a new i-frame immediatly */ 609 free(rgb_image);
578 //printf("Bad video packet\n"); 610 //display_received_frame(_phone, image);
579 //} 611
612 } //else {
613
614 /* TODO: request the sender to create a new i-frame immediatly */
615 //printf("Bad video packet\n");
616 //}
580 //} 617 //}
581 618
582 usleep(1000); 619 usleep(1000);
583 } 620 }
584 621
585 /* clean up codecs */ 622 /* clean up codecs */
586 //av_free(r_video_frame); 623 //av_free(r_video_frame);
587 624
588 //pthread_mutex_lock(&cs->ctrl_mutex); 625 //pthread_mutex_lock(&cs->ctrl_mutex);
589 //avcodec_close(cs->video_decoder_ctx); 626 //avcodec_close(cs->video_decoder_ctx);
590 //pthread_mutex_unlock(&cs->ctrl_mutex); 627 //pthread_mutex_unlock(&cs->ctrl_mutex);
591 628
592 _phone->running_decvid = -1; 629 _phone->running_decvid = -1;
593 630
594 pthread_exit ( NULL ); 631 pthread_exit ( NULL );
595} 632}
596 633
597void *decode_audio_thread(void *arg) 634void *decode_audio_thread(void *arg)
598{ 635{
599 INFO("Started decode audio thread!"); 636 INFO("Started decode audio thread!");
600 av_session_t* _phone = arg; 637 av_session_t *_phone = arg;
601 _phone->running_decaud = 1; 638 _phone->running_decaud = 1;
602 639
603 //int recved_size; 640 //int recved_size;
604 //uint8_t dest [RTP_PAYLOAD_SIZE]; 641 //uint8_t dest [RTP_PAYLOAD_SIZE];
605 642
606 int frame_size = AUDIO_FRAME_SIZE; 643 int frame_size = AUDIO_FRAME_SIZE;
607 //int data_size; 644 //int data_size;
608 645
609 ALCdevice *dev; 646 ALCdevice *dev;
610 ALCcontext *ctx; 647 ALCcontext *ctx;
611 ALuint source, *buffers; 648 ALuint source, *buffers;
@@ -613,72 +650,74 @@ void *decode_audio_thread(void *arg)
613 ctx = alcCreateContext(dev, NULL); 650 ctx = alcCreateContext(dev, NULL);
614 alcMakeContextCurrent(ctx); 651 alcMakeContextCurrent(ctx);
615 int openal_buffers = 5; 652 int openal_buffers = 5;
616 653
617 buffers = calloc(sizeof(ALuint) * openal_buffers,1); 654 buffers = calloc(sizeof(ALuint) * openal_buffers, 1);
618 alGenBuffers(openal_buffers, buffers); 655 alGenBuffers(openal_buffers, buffers);
619 alGenSources((ALuint)1, &source); 656 alGenSources((ALuint)1, &source);
620 alSourcei(source, AL_LOOPING, AL_FALSE); 657 alSourcei(source, AL_LOOPING, AL_FALSE);
621 658
622 ALuint buffer; 659 ALuint buffer;
623 ALint ready; 660 ALint ready;
624 661
625 uint16_t zeros[frame_size]; 662 uint16_t zeros[frame_size];
626 memset(zeros, 0, frame_size); 663 memset(zeros, 0, frame_size);
627 int16_t PCM[frame_size]; 664 int16_t PCM[frame_size];
628 665
629 int i; 666 int i;
667
630 for (i = 0; i < openal_buffers; ++i) { 668 for (i = 0; i < openal_buffers; ++i) {
631 alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000); 669 alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, frame_size, 48000);
632 } 670 }
633 671
634 alSourceQueueBuffers(source, openal_buffers, buffers); 672 alSourceQueueBuffers(source, openal_buffers, buffers);
635 alSourcePlay(source); 673 alSourcePlay(source);
636 674
637 if (alGetError() != AL_NO_ERROR) { 675 if (alGetError() != AL_NO_ERROR) {
638 fprintf(stderr, "Error starting audio\n"); 676 fprintf(stderr, "Error starting audio\n");
639 goto ending; 677 goto ending;
640 } 678 }
641 679
642 int dec_frame_len = 0; 680 int dec_frame_len = 0;
643 681
644 while (_phone->running_decaud) { 682 while (_phone->running_decaud) {
645 683
646 alGetSourcei(source, AL_BUFFERS_PROCESSED, &ready); 684 alGetSourcei(source, AL_BUFFERS_PROCESSED, &ready);
685
647 if (ready <= 0) 686 if (ready <= 0)
648 continue; 687 continue;
649 688
650 dec_frame_len = toxav_recv_audio(_phone->av, frame_size, PCM); 689 dec_frame_len = toxav_recv_audio(_phone->av, frame_size, PCM);
651 690
652 /* Play the packet */ 691 /* Play the packet */
653 if (dec_frame_len > 0) { 692 if (dec_frame_len > 0) {
654 alSourceUnqueueBuffers(source, 1, &buffer); 693 alSourceUnqueueBuffers(source, 1, &buffer);
655 alBufferData(buffer, AL_FORMAT_MONO16, PCM, dec_frame_len * 2 * 1, 48000); 694 alBufferData(buffer, AL_FORMAT_MONO16, PCM, dec_frame_len * 2 * 1, 48000);
656 int error = alGetError(); 695 int error = alGetError();
657 696
658 if (error != AL_NO_ERROR) { 697 if (error != AL_NO_ERROR) {
659 fprintf(stderr, "Error setting buffer %d\n", error); 698 fprintf(stderr, "Error setting buffer %d\n", error);
660 break; 699 break;
661 } 700 }
662 701
663 alSourceQueueBuffers(source, 1, &buffer); 702 alSourceQueueBuffers(source, 1, &buffer);
664 703
665 if (alGetError() != AL_NO_ERROR) { 704 if (alGetError() != AL_NO_ERROR) {
666 fprintf(stderr, "Error: could not buffer audio\n"); 705 fprintf(stderr, "Error: could not buffer audio\n");
667 break; 706 break;
668 } 707 }
669 708
670 alGetSourcei(source, AL_SOURCE_STATE, &ready); 709 alGetSourcei(source, AL_SOURCE_STATE, &ready);
671 710
672 if (ready != AL_PLAYING) alSourcePlay(source); 711 if (ready != AL_PLAYING) alSourcePlay(source);
673 } 712 }
674 713
675 usleep(1000); 714 usleep(1000);
676 } 715 }
677 716
678 717
679ending: 718ending:
680 /* clean up codecs */ 719 /* clean up codecs */
681 //pthread_mutex_lock(&cs->ctrl_mutex); 720 //pthread_mutex_lock(&cs->ctrl_mutex);
682 /* 721 /*
683 alDeleteSources(1, &source); 722 alDeleteSources(1, &source);
684 alDeleteBuffers(openal_buffers, buffers); 723 alDeleteBuffers(openal_buffers, buffers);
@@ -687,9 +726,9 @@ ending:
687 alcCloseDevice(dev); 726 alcCloseDevice(dev);
688 */ 727 */
689 //pthread_mutex_unlock(&cs->ctrl_mutex); 728 //pthread_mutex_unlock(&cs->ctrl_mutex);
690 729
691 _phone->running_decaud = -1; 730 _phone->running_decaud = -1;
692 731
693 pthread_exit ( NULL ); 732 pthread_exit ( NULL );
694} 733}
695 734
@@ -697,48 +736,47 @@ ending:
697 736
698 737
699 738
700int phone_startmedia_loop ( ToxAv* arg ) 739int phone_startmedia_loop ( ToxAv *arg )
701{ 740{
702 if ( !arg ){ 741 if ( !arg ) {
703 return -1; 742 return -1;
704 } 743 }
705 744
706 toxav_prepare_transmission(arg); 745 toxav_prepare_transmission(arg);
707 746
708 /* 747 /*
709 * Rise all threads 748 * Rise all threads
710 */ 749 */
711#ifdef TOX_FFMPEG 750#ifdef TOX_FFMPEG
751
712 /* Only checks for last peer */ 752 /* Only checks for last peer */
713 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo && 753 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo &&
714 0 > event.rise(encode_video_thread, toxav_get_agent_handler(arg)) ) 754 0 > event.rise(encode_video_thread, toxav_get_agent_handler(arg)) ) {
715 {
716 INFO("Error while starting encode_video_thread()"); 755 INFO("Error while starting encode_video_thread()");
717 return -1; 756 return -1;
718 } 757 }
758
719#endif 759#endif
760
720 /* Always send audio */ 761 /* Always send audio */
721 if ( 0 > event.rise(encode_audio_thread, toxav_get_agent_handler(arg)) ) 762 if ( 0 > event.rise(encode_audio_thread, toxav_get_agent_handler(arg)) ) {
722 {
723 INFO("Error while starting encode_audio_thread()"); 763 INFO("Error while starting encode_audio_thread()");
724 return -1; 764 return -1;
725 } 765 }
726 766
727 /* Only checks for last peer */ 767 /* Only checks for last peer */
728 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo && 768 if ( toxav_get_peer_transmission_type(arg, 0) == TypeVideo &&
729 0 > event.rise(decode_video_thread, toxav_get_agent_handler(arg)) ) 769 0 > event.rise(decode_video_thread, toxav_get_agent_handler(arg)) ) {
730 {
731 INFO("Error while starting decode_video_thread()"); 770 INFO("Error while starting decode_video_thread()");
732 return -1; 771 return -1;
733 } 772 }
734 773
735 if ( 0 > event.rise(decode_audio_thread, toxav_get_agent_handler(arg)) ) 774 if ( 0 > event.rise(decode_audio_thread, toxav_get_agent_handler(arg)) ) {
736 {
737 INFO("Error while starting decode_audio_thread()"); 775 INFO("Error while starting decode_audio_thread()");
738 return -1; 776 return -1;
739 } 777 }
740 778
741 779
742 return 0; 780 return 0;
743} 781}
744 782
@@ -760,58 +798,60 @@ int phone_startmedia_loop ( ToxAv* arg )
760 798
761/* Some example callbacks */ 799/* Some example callbacks */
762 800
763void* callback_recv_invite ( void* _arg ) 801void *callback_recv_invite ( void *_arg )
764{ 802{
765 assert(_arg); 803 assert(_arg);
766 804
767 switch ( toxav_get_peer_transmission_type(_arg, 0) ){ 805 switch ( toxav_get_peer_transmission_type(_arg, 0) ) {
768 case TypeAudio: 806 case TypeAudio:
769 INFO( "Incoming audio call!"); 807 INFO( "Incoming audio call!");
770 break; 808 break;
771 case TypeVideo: 809
772 INFO( "Incoming video call!"); 810 case TypeVideo:
773 break; 811 INFO( "Incoming video call!");
812 break;
774 } 813 }
775 814
776 pthread_exit(NULL); 815 pthread_exit(NULL);
777} 816}
778void* callback_recv_ringing ( void* _arg ) 817void *callback_recv_ringing ( void *_arg )
779{ 818{
780 INFO ( "Ringing!" ); 819 INFO ( "Ringing!" );
781 pthread_exit(NULL); 820 pthread_exit(NULL);
782} 821}
783void* callback_recv_starting ( void* _arg ) 822void *callback_recv_starting ( void *_arg )
784{ 823{
785 if ( 0 != phone_startmedia_loop(_arg) ){ 824 if ( 0 != phone_startmedia_loop(_arg) ) {
786 INFO("Starting call failed!"); 825 INFO("Starting call failed!");
787 } else { 826 } else {
788 INFO ("Call started! ( press h to hangup )"); 827 INFO ("Call started! ( press h to hangup )");
789 } 828 }
829
790 pthread_exit(NULL); 830 pthread_exit(NULL);
791} 831}
792void* callback_recv_ending ( void* _arg ) 832void *callback_recv_ending ( void *_arg )
793{ 833{
794 av_session_t* _phone = toxav_get_agent_handler(_arg); 834 av_session_t *_phone = toxav_get_agent_handler(_arg);
795 835
796 _phone->running_encaud = 0; 836 _phone->running_encaud = 0;
797 _phone->running_decaud = 0; 837 _phone->running_decaud = 0;
798 _phone->running_encvid = 0; 838 _phone->running_encvid = 0;
799 _phone->running_decvid = 0; 839 _phone->running_decvid = 0;
800 840
801 /* Wait until all threads are done */ 841 /* Wait until all threads are done */
802 842
803 while ( _phone->running_encaud != -1 || 843 while ( _phone->running_encaud != -1 ||
804 _phone->running_decaud != -1 || 844 _phone->running_decaud != -1 ||
805 _phone->running_encvid != -1 || 845 _phone->running_encvid != -1 ||
806 _phone->running_decvid != -1 ) 846 _phone->running_decvid != -1 )
807 847
808 usleep(10000000); 848 usleep(10000000);
809 849
810 INFO ( "Call ended!" ); 850 INFO ( "Call ended!" );
811 pthread_exit(NULL); 851 pthread_exit(NULL);
812} 852}
813 853
814void* callback_recv_error ( void* _arg ) 854void *callback_recv_error ( void *_arg )
815{ 855{
816 /*MSISession* _session = _arg; 856 /*MSISession* _session = _arg;
817 857
@@ -819,79 +859,79 @@ void* callback_recv_error ( void* _arg )
819 pthread_exit(NULL); 859 pthread_exit(NULL);
820} 860}
821 861
822void* callback_call_started ( void* _arg ) 862void *callback_call_started ( void *_arg )
823{ 863{
824 if ( 0 != phone_startmedia_loop(_arg) ){ 864 if ( 0 != phone_startmedia_loop(_arg) ) {
825 INFO("Starting call failed!"); 865 INFO("Starting call failed!");
826 } else { 866 } else {
827 INFO ("Call started! ( press h to hangup )"); 867 INFO ("Call started! ( press h to hangup )");
828 } 868 }
829 869
830 pthread_exit(NULL); 870 pthread_exit(NULL);
831} 871}
832void* callback_call_canceled ( void* _arg ) 872void *callback_call_canceled ( void *_arg )
833{ 873{
834 INFO ( "Call canceled!" ); 874 INFO ( "Call canceled!" );
835 pthread_exit(NULL); 875 pthread_exit(NULL);
836} 876}
837void* callback_call_rejected ( void* _arg ) 877void *callback_call_rejected ( void *_arg )
838{ 878{
839 INFO ( "Call rejected!" ); 879 INFO ( "Call rejected!" );
840 pthread_exit(NULL); 880 pthread_exit(NULL);
841} 881}
842void* callback_call_ended ( void* _arg ) 882void *callback_call_ended ( void *_arg )
843{ 883{
844 av_session_t* _phone = toxav_get_agent_handler(_arg); 884 av_session_t *_phone = toxav_get_agent_handler(_arg);
845 885
846 _phone->running_encaud = 0; 886 _phone->running_encaud = 0;
847 _phone->running_decaud = 0; 887 _phone->running_decaud = 0;
848 _phone->running_encvid = 0; 888 _phone->running_encvid = 0;
849 _phone->running_decvid = 0; 889 _phone->running_decvid = 0;
850 890
851 /* Wait until all threads are done */ 891 /* Wait until all threads are done */
852 892
853 while ( _phone->running_encaud != -1 || 893 while ( _phone->running_encaud != -1 ||
854 _phone->running_decaud != -1 || 894 _phone->running_decaud != -1 ||
855 _phone->running_encvid != -1 || 895 _phone->running_encvid != -1 ||
856 _phone->running_decvid != -1 ) 896 _phone->running_decvid != -1 )
857 897
858 usleep(10000000); 898 usleep(10000000);
859 899
860 toxav_kill_transmission(_phone->av); 900 toxav_kill_transmission(_phone->av);
861 INFO ( "Call ended!" ); 901 INFO ( "Call ended!" );
862 pthread_exit(NULL); 902 pthread_exit(NULL);
863} 903}
864 904
865void* callback_requ_timeout ( void* _arg ) 905void *callback_requ_timeout ( void *_arg )
866{ 906{
867 INFO( "No answer! " ); 907 INFO( "No answer! " );
868 pthread_exit(NULL); 908 pthread_exit(NULL);
869} 909}
870 910
871av_session_t* av_init_session() 911av_session_t *av_init_session()
872{ 912{
873 av_session_t* _retu = malloc(sizeof(av_session_t)); 913 av_session_t *_retu = malloc(sizeof(av_session_t));
874 914
875 /* Initialize our mutex */ 915 /* Initialize our mutex */
876 pthread_mutex_init ( &_retu->_mutex, NULL ); 916 pthread_mutex_init ( &_retu->_mutex, NULL );
877 917
878 _retu->_messenger = tox_new(1); 918 _retu->_messenger = tox_new(1);
879 919
880 if ( !_retu->_messenger ) { 920 if ( !_retu->_messenger ) {
881 fprintf ( stderr, "tox_new() failed!\n" ); 921 fprintf ( stderr, "tox_new() failed!\n" );
882 return NULL; 922 return NULL;
883 } 923 }
884 924
885 _retu->_friends = NULL; 925 _retu->_friends = NULL;
886 926
887 927
888 const ALchar *_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); 928 const ALchar *_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
889 int i = 0; 929 int i = 0;
890 const ALchar *device_names[20]; 930 const ALchar *device_names[20];
891 931
892 if ( _device_list ) { 932 if ( _device_list ) {
893 INFO("\nAvailable Capture Devices are:"); 933 INFO("\nAvailable Capture Devices are:");
894 934
895 while (*_device_list ) { 935 while (*_device_list ) {
896 device_names[i] = _device_list; 936 device_names[i] = _device_list;
897 INFO("%d) %s", i, device_names[i]); 937 INFO("%d) %s", i, device_names[i]);
@@ -899,32 +939,33 @@ av_session_t* av_init_session()
899 ++i; 939 ++i;
900 } 940 }
901 } 941 }
902 942
903 INFO("Enter capture device number"); 943 INFO("Enter capture device number");
904 944
905 char dev[2]; char* left; 945 char dev[2];
906 char* warned_ = fgets(dev, 2, stdin); 946 char *left;
947 char *warned_ = fgets(dev, 2, stdin);
907 (void)warned_; 948 (void)warned_;
908 long selection = strtol(dev, &left, 10); 949 long selection = strtol(dev, &left, 10);
909 950
910 if ( *left ) { 951 if ( *left ) {
911 printf("'%s' is not a number!", dev); 952 printf("'%s' is not a number!", dev);
912 fflush(stdout); 953 fflush(stdout);
913 exit(EXIT_FAILURE); 954 exit(EXIT_FAILURE);
914 } 955 } else {
915 else {
916 INFO("Selected: %d ( %s )", selection, device_names[selection]); 956 INFO("Selected: %d ( %s )", selection, device_names[selection]);
917 } 957 }
918 958
919 _retu->audio_capture_device = 959 _retu->audio_capture_device =
920 (struct ALCdevice*)alcCaptureOpenDevice( 960 (struct ALCdevice *)alcCaptureOpenDevice(
921 device_names[selection], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, AUDIO_FRAME_SIZE * 4); 961 device_names[selection], AUDIO_SAMPLE_RATE, AL_FORMAT_MONO16, AUDIO_FRAME_SIZE * 4);
922 962
923 963
924 if (alcGetError((ALCdevice*)_retu->audio_capture_device) != AL_NO_ERROR) { 964 if (alcGetError((ALCdevice *)_retu->audio_capture_device) != AL_NO_ERROR) {
925 printf("Could not start capture device! %d\n", alcGetError((ALCdevice*)_retu->audio_capture_device)); 965 printf("Could not start capture device! %d\n", alcGetError((ALCdevice *)_retu->audio_capture_device));
926 return 0; 966 return 0;
927 } 967 }
968
928 uint16_t height = 0, width = 0; 969 uint16_t height = 0, width = 0;
929#ifdef TOX_FFMPEG 970#ifdef TOX_FFMPEG
930 avdevice_register_all(); 971 avdevice_register_all();
@@ -932,6 +973,7 @@ av_session_t* av_init_session()
932 av_register_all(); 973 av_register_all();
933 974
934 _retu->video_input_format = av_find_input_format(VIDEO_DRIVER); 975 _retu->video_input_format = av_find_input_format(VIDEO_DRIVER);
976
935 if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) { 977 if (avformat_open_input(&_retu->video_format_ctx, DEFAULT_WEBCAM, _retu->video_input_format, NULL) != 0) {
936 fprintf(stderr, "Opening video_input_format failed!\n"); 978 fprintf(stderr, "Opening video_input_format failed!\n");
937 //return -1; 979 //return -1;
@@ -968,51 +1010,53 @@ av_session_t* av_init_session()
968 //return -1; 1010 //return -1;
969 return NULL; 1011 return NULL;
970 } 1012 }
1013
971 width = _retu->webcam_decoder_ctx->width; 1014 width = _retu->webcam_decoder_ctx->width;
972 height = _retu->webcam_decoder_ctx->height; 1015 height = _retu->webcam_decoder_ctx->height;
973#endif 1016#endif
974 uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE]; 1017 uint8_t _byte_address[TOX_FRIEND_ADDRESS_SIZE];
975 tox_get_address(_retu->_messenger, _byte_address ); 1018 tox_get_address(_retu->_messenger, _byte_address );
976 fraddr_to_str( _byte_address, _retu->_my_public_id ); 1019 fraddr_to_str( _byte_address, _retu->_my_public_id );
977 1020
978 1021
979 _retu->av = toxav_new(_retu->_messenger, _retu, _USERAGENT, width, height); 1022 _retu->av = toxav_new(_retu->_messenger, _retu, _USERAGENT, width, height);
980 1023
981 /* ------------------ */ 1024 /* ------------------ */
982 1025
983 toxav_register_callstate_callback(callback_call_started, OnStart); 1026 toxav_register_callstate_callback(callback_call_started, OnStart);
984 toxav_register_callstate_callback(callback_call_canceled, OnCancel); 1027 toxav_register_callstate_callback(callback_call_canceled, OnCancel);
985 toxav_register_callstate_callback(callback_call_rejected, OnReject); 1028 toxav_register_callstate_callback(callback_call_rejected, OnReject);
986 toxav_register_callstate_callback(callback_call_ended, OnEnd); 1029 toxav_register_callstate_callback(callback_call_ended, OnEnd);
987 toxav_register_callstate_callback(callback_recv_invite, OnInvite); 1030 toxav_register_callstate_callback(callback_recv_invite, OnInvite);
988 1031
989 toxav_register_callstate_callback(callback_recv_ringing, OnRinging); 1032 toxav_register_callstate_callback(callback_recv_ringing, OnRinging);
990 toxav_register_callstate_callback(callback_recv_starting, OnStarting); 1033 toxav_register_callstate_callback(callback_recv_starting, OnStarting);
991 toxav_register_callstate_callback(callback_recv_ending, OnEnding); 1034 toxav_register_callstate_callback(callback_recv_ending, OnEnding);
992 1035
993 toxav_register_callstate_callback(callback_recv_error, OnError); 1036 toxav_register_callstate_callback(callback_recv_error, OnError);
994 toxav_register_callstate_callback(callback_requ_timeout, OnRequestTimeout); 1037 toxav_register_callstate_callback(callback_requ_timeout, OnRequestTimeout);
995 1038
996 /* ------------------ */ 1039 /* ------------------ */
997 1040
998 return _retu; 1041 return _retu;
999} 1042}
1000 1043
1001int av_terminate_session(av_session_t* _phone) 1044int av_terminate_session(av_session_t *_phone)
1002{ 1045{
1003 toxav_hangup(_phone->av); 1046 toxav_hangup(_phone->av);
1004 1047
1005 free(_phone->_friends); 1048 free(_phone->_friends);
1006 pthread_mutex_destroy ( &_phone->_mutex ); 1049 pthread_mutex_destroy ( &_phone->_mutex );
1007 1050
1008 Tox* _p = _phone->_messenger; 1051 Tox *_p = _phone->_messenger;
1009 _phone->_messenger = NULL; usleep(100000); /* Wait for tox_poll to end */ 1052 _phone->_messenger = NULL;
1010 1053 usleep(100000); /* Wait for tox_poll to end */
1054
1011 tox_kill(_p); 1055 tox_kill(_p);
1012 toxav_kill(_phone->av); 1056 toxav_kill(_phone->av);
1013 1057
1014 free(_phone); 1058 free(_phone);
1015 1059
1016 printf("\r[i] Quit!\n"); 1060 printf("\r[i] Quit!\n");
1017 return 0; 1061 return 0;
1018} 1062}
@@ -1022,65 +1066,65 @@ int av_terminate_session(av_session_t* _phone)
1022/* Auto accept friend request */ 1066/* Auto accept friend request */
1023void av_friend_requ(uint8_t *_public_key, uint8_t *_data, uint16_t _length, void *_userdata) 1067void av_friend_requ(uint8_t *_public_key, uint8_t *_data, uint16_t _length, void *_userdata)
1024{ 1068{
1025 av_session_t* _phone = _userdata; 1069 av_session_t *_phone = _userdata;
1026 av_allocate_friend (_phone, -1, 0); 1070 av_allocate_friend (_phone, -1, 0);
1027 1071
1028 INFO("Got friend request with message: %s", _data); 1072 INFO("Got friend request with message: %s", _data);
1029 1073
1030 tox_add_friend_norequest(_phone->_messenger, _public_key); 1074 tox_add_friend_norequest(_phone->_messenger, _public_key);
1031 1075
1032 INFO("Auto-accepted! Friend id: %d", _phone->_friends->_id ); 1076 INFO("Auto-accepted! Friend id: %d", _phone->_friends->_id );
1033} 1077}
1034 1078
1035void av_friend_active(Tox *_messenger, int _friendnumber, uint8_t *_string, uint16_t _length, void *_userdata) 1079void av_friend_active(Tox *_messenger, int _friendnumber, uint8_t *_string, uint16_t _length, void *_userdata)
1036{ 1080{
1037 av_session_t* _phone = _userdata; 1081 av_session_t *_phone = _userdata;
1038 INFO("Friend no. %d is online", _friendnumber); 1082 INFO("Friend no. %d is online", _friendnumber);
1039 1083
1040 av_friend_t* _this_friend = av_get_friend(_phone, _friendnumber); 1084 av_friend_t *_this_friend = av_get_friend(_phone, _friendnumber);
1041 1085
1042 if ( !_this_friend ) { 1086 if ( !_this_friend ) {
1043 INFO("But it's not registered!"); 1087 INFO("But it's not registered!");
1044 return; 1088 return;
1045 } 1089 }
1046 1090
1047 (*_this_friend)._active = 1; 1091 (*_this_friend)._active = 1;
1048} 1092}
1049 1093
1050int av_add_friend(av_session_t* _phone, char* _friend_hash) 1094int av_add_friend(av_session_t *_phone, char *_friend_hash)
1051{ 1095{
1052 trim_spaces(_friend_hash); 1096 trim_spaces(_friend_hash);
1053 1097
1054 unsigned char *_bin_string = hex_string_to_bin(_friend_hash); 1098 unsigned char *_bin_string = hex_string_to_bin(_friend_hash);
1055 int _number = tox_add_friend(_phone->_messenger, _bin_string, (uint8_t *)"Tox phone "_USERAGENT, sizeof("Tox phone "_USERAGENT)); 1099 int _number = tox_add_friend(_phone->_messenger, _bin_string, (uint8_t *)"Tox phone "_USERAGENT,
1100 sizeof("Tox phone "_USERAGENT));
1056 free(_bin_string); 1101 free(_bin_string);
1057 1102
1058 if ( _number >= 0) { 1103 if ( _number >= 0) {
1059 INFO("Added friend as %d", _number ); 1104 INFO("Added friend as %d", _number );
1060 av_allocate_friend(_phone, _number, 0); 1105 av_allocate_friend(_phone, _number, 0);
1061 } 1106 } else
1062 else
1063 INFO("Unknown error %i", _number ); 1107 INFO("Unknown error %i", _number );
1064 1108
1065 return _number; 1109 return _number;
1066} 1110}
1067 1111
1068int av_connect_to_dht(av_session_t* _phone, char* _dht_key, const char* _dht_addr, unsigned short _dht_port) 1112int av_connect_to_dht(av_session_t *_phone, char *_dht_key, const char *_dht_addr, unsigned short _dht_port)
1069{ 1113{
1070 unsigned char *_binary_string = hex_string_to_bin(_dht_key); 1114 unsigned char *_binary_string = hex_string_to_bin(_dht_key);
1071 1115
1072 uint16_t _port = htons(_dht_port); 1116 uint16_t _port = htons(_dht_port);
1073 1117
1074 int _if = tox_bootstrap_from_address(_phone->_messenger, _dht_addr, 1, _port, _binary_string ); 1118 int _if = tox_bootstrap_from_address(_phone->_messenger, _dht_addr, 1, _port, _binary_string );
1075 1119
1076 free(_binary_string); 1120 free(_binary_string);
1077 1121
1078 return _if ? 0 : -1; 1122 return _if ? 0 : -1;
1079} 1123}
1080 1124
1081/*********************************/ 1125/*********************************/
1082 1126
1083void do_phone ( av_session_t* _phone ) 1127void do_phone ( av_session_t *_phone )
1084{ 1128{
1085 INFO("Welcome to tox_phone version: " _USERAGENT "\n" 1129 INFO("Welcome to tox_phone version: " _USERAGENT "\n"
1086 "Usage: \n" 1130 "Usage: \n"
@@ -1091,218 +1135,218 @@ void do_phone ( av_session_t* _phone )
1091 "r (reject incoming call)\n" 1135 "r (reject incoming call)\n"
1092 "q (quit)\n" 1136 "q (quit)\n"
1093 "================================================================================" 1137 "================================================================================"
1094 ); 1138 );
1095 1139
1096 while ( 1 ) 1140 while ( 1 ) {
1097 {
1098 char _line [ 1500 ]; 1141 char _line [ 1500 ];
1099 int _len; 1142 int _len;
1100 1143
1101 if ( -1 == getinput(_line, 1500, &_len) ){ 1144 if ( -1 == getinput(_line, 1500, &_len) ) {
1102 printf(" >> "); 1145 printf(" >> ");
1103 fflush(stdout); 1146 fflush(stdout);
1104 continue; 1147 continue;
1105 } 1148 }
1106 1149
1107 if ( _len > 1 && _line[1] != ' ' && _line[1] != '\n' ){ 1150 if ( _len > 1 && _line[1] != ' ' && _line[1] != '\n' ) {
1108 INFO("Invalid input!"); 1151 INFO("Invalid input!");
1109 continue; 1152 continue;
1110 } 1153 }
1111 1154
1112 switch (_line[0]){ 1155 switch (_line[0]) {
1113 1156
1114 case 'f': 1157 case 'f': {
1115 { 1158 char _id [128];
1116 char _id [128]; 1159 strncpy(_id, _line + 2, 128);
1117 strncpy(_id, _line + 2, 128); 1160
1118 1161 av_add_friend(_phone, _id);
1119 av_add_friend(_phone, _id); 1162
1120
1121 } break;
1122 case 'c':
1123 {
1124 ToxAvCallType _ctype;
1125
1126 if ( _len < 5 ){
1127 INFO("Invalid input; usage: c a/v [friend]");
1128 break;
1129 } 1163 }
1130 else if ( _line[2] == 'a' || _line[2] != 'v' ){ /* default and audio */ 1164 break;
1131 _ctype = TypeAudio; 1165
1166 case 'c': {
1167 ToxAvCallType _ctype;
1168
1169 if ( _len < 5 ) {
1170 INFO("Invalid input; usage: c a/v [friend]");
1171 break;
1172 } else if ( _line[2] == 'a' || _line[2] != 'v' ) { /* default and audio */
1173 _ctype = TypeAudio;
1174 } else { /* video */
1175 _ctype = TypeVideo;
1176 }
1177
1178 char *_end;
1179 int _friend = strtol(_line + 4, &_end, 10);
1180
1181 if ( *_end ) {
1182 INFO("Friend num has to be numerical value");
1183 break;
1184 }
1185
1186 if ( toxav_call(_phone->av, _friend, _ctype, 30) == ErrorAlreadyInCall ) {
1187 INFO("Already in a call");
1188 break;
1189 } else INFO("Calling friend: %d!", _friend);
1190
1132 } 1191 }
1133 else { /* video */ 1192 break;
1134 _ctype = TypeVideo; 1193
1194 case 'h': {
1195 if ( toxav_hangup(_phone->av) == ErrorNoCall ) {
1196 INFO("No call!");
1197 break;
1198 } else INFO("Hung up...");
1199
1135 } 1200 }
1136 1201 break;
1137 char* _end; 1202
1138 int _friend = strtol(_line + 4, &_end, 10); 1203 case 'a': {
1139 1204 ToxAvError rc;
1140 if ( *_end ){ 1205
1141 INFO("Friend num has to be numerical value"); 1206 if ( _len > 1 && _line[2] == 'v' ) {
1142 break; 1207 rc = toxav_answer(_phone->av, TypeVideo);
1208 } else
1209 rc = toxav_answer(_phone->av, TypeAudio);
1210
1211 if ( rc == ErrorInvalidState ) {
1212 INFO("No call to answer!");
1213 }
1214
1143 } 1215 }
1144 1216 break;
1145 if ( toxav_call(_phone->av, _friend, _ctype, 30) == ErrorAlreadyInCall ){ 1217
1146 INFO("Already in a call"); 1218 case 'r': {
1147 break; 1219 if ( toxav_reject(_phone->av, "User action") == ErrorInvalidState )
1220 INFO("No state to cancel!");
1221 else INFO("Call Rejected...");
1222
1148 } 1223 }
1149 else INFO("Calling friend: %d!", _friend); 1224 break;
1150 1225
1151 } break; 1226 case 'q': {
1152 case 'h': 1227 INFO("Quitting!");
1153 { 1228 return;
1154 if ( toxav_hangup(_phone->av) == ErrorNoCall ) {
1155 INFO("No call!");
1156 break;
1157 } 1229 }
1158 else INFO("Hung up..."); 1230
1159 1231 case '\n': {
1160 } break;
1161 case 'a':
1162 {
1163 ToxAvError rc;
1164
1165 if ( _len > 1 && _line[2] == 'v' ) {
1166 rc = toxav_answer(_phone->av, TypeVideo);
1167 } else
1168 rc = toxav_answer(_phone->av, TypeAudio);
1169
1170 if ( rc == ErrorInvalidState ) {
1171 INFO("No call to answer!");
1172 } 1232 }
1173 1233
1174 } break; 1234 default: {
1175 case 'r': 1235 } break;
1176 {
1177 if ( toxav_reject(_phone->av, "User action") == ErrorInvalidState )
1178 INFO("No state to cancel!");
1179 else INFO("Call Rejected...");
1180
1181 } break;
1182 case 'q':
1183 {
1184 INFO("Quitting!");
1185 return;
1186 }
1187 case '\n':
1188 {
1189 }
1190 default:
1191 {
1192 } break;
1193 1236
1194 } 1237 }
1195 1238
1196 } 1239 }
1197} 1240}
1198 1241
1199void* tox_poll (void* _messenger_p) 1242void *tox_poll (void *_messenger_p)
1200{ 1243{
1201 Tox** _messenger = _messenger_p; 1244 Tox **_messenger = _messenger_p;
1202 while( *_messenger ) { 1245
1203 tox_do(*_messenger); 1246 while ( *_messenger ) {
1247 tox_do(*_messenger);
1204 usleep(10000); 1248 usleep(10000);
1205 } 1249 }
1206 1250
1207 pthread_exit(NULL); 1251 pthread_exit(NULL);
1208} 1252}
1209 1253
1210int av_wait_dht(av_session_t* _phone, int _wait_seconds, const char* _ip, char* _key, unsigned short _port) 1254int av_wait_dht(av_session_t *_phone, int _wait_seconds, const char *_ip, char *_key, unsigned short _port)
1211{ 1255{
1212 if ( !_wait_seconds ) 1256 if ( !_wait_seconds )
1213 return -1; 1257 return -1;
1214 1258
1215 int _waited = 0; 1259 int _waited = 0;
1216 1260
1217 while( !tox_isconnected(_phone->_messenger) ) { 1261 while ( !tox_isconnected(_phone->_messenger) ) {
1218 1262
1219 if ( -1 == av_connect_to_dht(_phone, _key, _ip, _port) ) 1263 if ( -1 == av_connect_to_dht(_phone, _key, _ip, _port) ) {
1220 {
1221 INFO("Could not connect to: %s", _ip); 1264 INFO("Could not connect to: %s", _ip);
1222 av_terminate_session(_phone); 1265 av_terminate_session(_phone);
1223 return -1; 1266 return -1;
1224 } 1267 }
1225 1268
1226 if ( _waited >= _wait_seconds ) return 0; 1269 if ( _waited >= _wait_seconds ) return 0;
1227 1270
1228 printf("."); 1271 printf(".");
1229 fflush(stdout); 1272 fflush(stdout);
1230 1273
1231 _waited ++; 1274 _waited ++;
1232 usleep(1000000); 1275 usleep(1000000);
1233 } 1276 }
1234 1277
1235 int _r = _wait_seconds - _waited; 1278 int _r = _wait_seconds - _waited;
1236 return _r ? _r : 1; 1279 return _r ? _r : 1;
1237} 1280}
1238/* ---------------------- */ 1281/* ---------------------- */
1239 1282
1240int print_help ( const char* _name ) 1283int print_help ( const char *_name )
1241{ 1284{
1242 printf ( "Usage: %s [IP] [PORT] [KEY]\n" 1285 printf ( "Usage: %s [IP] [PORT] [KEY]\n"
1243 "\t[IP] (DHT ip)\n" 1286 "\t[IP] (DHT ip)\n"
1244 "\t[PORT] (DHT port)\n" 1287 "\t[PORT] (DHT port)\n"
1245 "\t[KEY] (DHT public key)\n" 1288 "\t[KEY] (DHT public key)\n"
1246 "P.S. Friends and key are stored in ./tox_phone.conf\n" 1289 "P.S. Friends and key are stored in ./tox_phone.conf\n"
1247 ,_name ); 1290 , _name );
1248 return 1; 1291 return 1;
1249} 1292}
1250 1293
1251int main ( int argc, char* argv [] ) 1294int main ( int argc, char *argv [] )
1252{ 1295{
1253 if ( argc < 1 || argc < 4 ) 1296 if ( argc < 1 || argc < 4 )
1254 return print_help(argv[0]); 1297 return print_help(argv[0]);
1255 1298
1256 char* _convertable; 1299 char *_convertable;
1257 1300
1258 1301
1259 const char* _ip = argv[1]; 1302 const char *_ip = argv[1];
1260 char* _key = argv[3]; 1303 char *_key = argv[3];
1261 unsigned short _port = strtol(argv[2], &_convertable, 10); 1304 unsigned short _port = strtol(argv[2], &_convertable, 10);
1262 1305
1263 if ( *_convertable ) { 1306 if ( *_convertable ) {
1264 printf("Invalid port: cannot convert string to long: %s", _convertable); 1307 printf("Invalid port: cannot convert string to long: %s", _convertable);
1265 return 1; 1308 return 1;
1266 } 1309 }
1267 1310
1268 av_session_t* _phone = av_init_session(); 1311 av_session_t *_phone = av_init_session();
1269 1312
1270 tox_callback_friend_request(_phone->_messenger, av_friend_requ, _phone); 1313 tox_callback_friend_request(_phone->_messenger, av_friend_requ, _phone);
1271 tox_callback_status_message(_phone->_messenger, av_friend_active, _phone); 1314 tox_callback_status_message(_phone->_messenger, av_friend_active, _phone);
1272 1315
1273 1316
1274 INFO("\r================================================================================\n" 1317 INFO("\r================================================================================\n"
1275 "[!] Trying dht@%s:%d" 1318 "[!] Trying dht@%s:%d"
1276 , _ip, _port); 1319 , _ip, _port);
1277 1320
1278 /* Start tox protocol */ 1321 /* Start tox protocol */
1279 event.rise( tox_poll, &_phone->_messenger ); 1322 event.rise( tox_poll, &_phone->_messenger );
1280 1323
1281 /* Just clean one line */ 1324 /* Just clean one line */
1282 printf("\r \r"); 1325 printf("\r \r");
1283 fflush(stdout); 1326 fflush(stdout);
1284 1327
1285 int _r; 1328 int _r;
1286 int _wait_seconds = 5; 1329 int _wait_seconds = 5;
1330
1287 for ( _r = 0; _r == 0; _r = av_wait_dht(_phone, _wait_seconds, _ip, _key, _port) ) _wait_seconds --; 1331 for ( _r = 0; _r == 0; _r = av_wait_dht(_phone, _wait_seconds, _ip, _key, _port) ) _wait_seconds --;
1288 1332
1289 1333
1290 if ( -1 == _r ) { 1334 if ( -1 == _r ) {
1291 INFO("Error while connecting to dht: %s:%d", _ip, _port); 1335 INFO("Error while connecting to dht: %s:%d", _ip, _port);
1292 av_terminate_session(_phone); 1336 av_terminate_session(_phone);
1293 return 1; 1337 return 1;
1294 } 1338 }
1295 1339
1296 INFO("CONNECTED!\n" 1340 INFO("CONNECTED!\n"
1297 "================================================================================\n" 1341 "================================================================================\n"
1298 "%s\n" 1342 "%s\n"
1299 "================================================================================" 1343 "================================================================================"
1300 , _phone->_my_public_id ); 1344 , _phone->_my_public_id );
1301 1345
1302 1346
1303 do_phone (_phone); 1347 do_phone (_phone);
1304 1348
1305 av_terminate_session(_phone); 1349 av_terminate_session(_phone);
1306 1350
1307 return 0; 1351 return 0;
1308} 1352}
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 2543c509..dbaecbb6 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -1,5 +1,5 @@
1/** toxrtp.c 1/** toxrtp.c
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -55,56 +55,56 @@
55 55
56/** 56/**
57 * @brief Converts 4 bytes to uint32_t 57 * @brief Converts 4 bytes to uint32_t
58 * 58 *
59 * @param dest Where to convert 59 * @param dest Where to convert
60 * @param bytes What bytes 60 * @param bytes What bytes
61 * @return void 61 * @return void
62 */ 62 */
63inline__ void bytes_to_U32(uint32_t* dest, const uint8_t* bytes) 63inline__ void bytes_to_U32(uint32_t *dest, const uint8_t *bytes)
64{ 64{
65 *dest = 65 *dest =
66#ifdef WORDS_BIGENDIAN 66#ifdef WORDS_BIGENDIAN
67 ( ( uint32_t ) * bytes ) | 67 ( ( uint32_t ) * bytes ) |
68 ( ( uint32_t ) * ( bytes + 1 ) << 8 ) | 68 ( ( uint32_t ) * ( bytes + 1 ) << 8 ) |
69 ( ( uint32_t ) * ( bytes + 2 ) << 16 ) | 69 ( ( uint32_t ) * ( bytes + 2 ) << 16 ) |
70 ( ( uint32_t ) * ( bytes + 3 ) << 24 ) ; 70 ( ( uint32_t ) * ( bytes + 3 ) << 24 ) ;
71#else 71#else
72 ( ( uint32_t ) * bytes << 24 ) | 72 ( ( uint32_t ) * bytes << 24 ) |
73 ( ( uint32_t ) * ( bytes + 1 ) << 16 ) | 73 ( ( uint32_t ) * ( bytes + 1 ) << 16 ) |
74 ( ( uint32_t ) * ( bytes + 2 ) << 8 ) | 74 ( ( uint32_t ) * ( bytes + 2 ) << 8 ) |
75 ( ( uint32_t ) * ( bytes + 3 ) ) ; 75 ( ( uint32_t ) * ( bytes + 3 ) ) ;
76#endif 76#endif
77} 77}
78 78
79/** 79/**
80 * @brief Converts 2 bytes to uint16_t 80 * @brief Converts 2 bytes to uint16_t
81 * 81 *
82 * @param dest Where to convert 82 * @param dest Where to convert
83 * @param bytes What bytes 83 * @param bytes What bytes
84 * @return void 84 * @return void
85 */ 85 */
86inline__ void bytes_to_U16(uint16_t* dest, const uint8_t* bytes) 86inline__ void bytes_to_U16(uint16_t *dest, const uint8_t *bytes)
87{ 87{
88 *dest = 88 *dest =
89#ifdef WORDS_BIGENDIAN 89#ifdef WORDS_BIGENDIAN
90 ( ( uint16_t ) * bytes ) | 90 ( ( uint16_t ) * bytes ) |
91 ( ( uint16_t ) * ( bytes + 1 ) << 8 ); 91 ( ( uint16_t ) * ( bytes + 1 ) << 8 );
92#else 92#else
93 ( ( uint16_t ) * bytes << 8 ) | 93 ( ( uint16_t ) * bytes << 8 ) |
94 ( ( uint16_t ) * ( bytes + 1 ) ); 94 ( ( uint16_t ) * ( bytes + 1 ) );
95#endif 95#endif
96} 96}
97 97
98/** 98/**
99 * @brief Convert uint32_t to byte string of size 4 99 * @brief Convert uint32_t to byte string of size 4
100 * 100 *
101 * @param dest Where to convert 101 * @param dest Where to convert
102 * @param value The value 102 * @param value The value
103 * @return void 103 * @return void
104 */ 104 */
105inline__ void U32_to_bytes(uint8_t* dest, uint32_t value) 105inline__ void U32_to_bytes(uint8_t *dest, uint32_t value)
106{ 106{
107#ifdef WORDS_BIGENDIAN 107#ifdef WORDS_BIGENDIAN
108 *(dest) = ( value ); 108 *(dest) = ( value );
109 *(dest + 1) = ( value >> 8 ); 109 *(dest + 1) = ( value >> 8 );
110 *(dest + 2) = ( value >> 16 ); 110 *(dest + 2) = ( value >> 16 );
@@ -114,43 +114,43 @@ inline__ void U32_to_bytes(uint8_t* dest, uint32_t value)
114 *(dest + 1) = ( value >> 16 ); 114 *(dest + 1) = ( value >> 16 );
115 *(dest + 2) = ( value >> 8 ); 115 *(dest + 2) = ( value >> 8 );
116 *(dest + 3) = ( value ); 116 *(dest + 3) = ( value );
117#endif 117#endif
118} 118}
119 119
120/** 120/**
121 * @brief Convert uint16_t to byte string of size 2 121 * @brief Convert uint16_t to byte string of size 2
122 * 122 *
123 * @param dest Where to convert 123 * @param dest Where to convert
124 * @param value The value 124 * @param value The value
125 * @return void 125 * @return void
126 */ 126 */
127inline__ void U16_to_bytes(uint8_t* dest, uint16_t value) 127inline__ void U16_to_bytes(uint8_t *dest, uint16_t value)
128{ 128{
129#ifdef WORDS_BIGENDIAN 129#ifdef WORDS_BIGENDIAN
130 *(dest) = ( value ); 130 *(dest) = ( value );
131 *(dest + 1) = ( value >> 8 ); 131 *(dest + 1) = ( value >> 8 );
132#else 132#else
133 *(dest) = ( value >> 8 ); 133 *(dest) = ( value >> 8 );
134 *(dest + 1) = ( value ); 134 *(dest + 1) = ( value );
135#endif 135#endif
136} 136}
137 137
138 138
139/** 139/**
140 * @brief Checks if message came in late. 140 * @brief Checks if message came in late.
141 * 141 *
142 * @param session Control session. 142 * @param session Control session.
143 * @param msg The message. 143 * @param msg The message.
144 * @return int 144 * @return int
145 * @retval -1 The message came in order. 145 * @retval -1 The message came in order.
146 * @retval 0 The message came late. 146 * @retval 0 The message came late.
147 */ 147 */
148inline__ int check_late_message (RTPSession* session, RTPMessage* msg) 148inline__ int check_late_message (RTPSession *session, RTPMessage *msg)
149{ 149{
150 /* 150 /*
151 * Check Sequence number. If this new msg has lesser number then the session->rsequnum 151 * Check Sequence number. If this new msg has lesser number then the session->rsequnum
152 * it shows that the message came in late. Also check timestamp to be 100% certain. 152 * it shows that the message came in late. Also check timestamp to be 100% certain.
153 * 153 *
154 */ 154 */
155 return ( msg->header->sequnum < session->rsequnum && msg->header->timestamp < session->timestamp ) ? 0 : -1; 155 return ( msg->header->sequnum < session->rsequnum && msg->header->timestamp < session->timestamp ) ? 0 : -1;
156} 156}
@@ -158,12 +158,12 @@ inline__ int check_late_message (RTPSession* session, RTPMessage* msg)
158 158
159/** 159/**
160 * @brief Increases nonce value by 'target' 160 * @brief Increases nonce value by 'target'
161 * 161 *
162 * @param nonce The nonce 162 * @param nonce The nonce
163 * @param target The target 163 * @param target The target
164 * @return void 164 * @return void
165 */ 165 */
166inline__ void increase_nonce(uint8_t* nonce, uint16_t target) 166inline__ void increase_nonce(uint8_t *nonce, uint16_t target)
167{ 167{
168 uint16_t _nonce_counter; 168 uint16_t _nonce_counter;
169 169
@@ -176,29 +176,29 @@ inline__ void increase_nonce(uint8_t* nonce, uint16_t target)
176 /* Check overflow */ 176 /* Check overflow */
177 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */ 177 if (_nonce_counter > UINT16_MAX - target ) { /* 2 bytes are not long enough */
178 uint8_t _it = 3; 178 uint8_t _it = 3;
179
179 while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ? crypto_box_NONCEBYTES : 1; 180 while ( _it <= crypto_box_NONCEBYTES ) _it += ++nonce[crypto_box_NONCEBYTES - _it] ? crypto_box_NONCEBYTES : 1;
180 181
181 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */ 182 _nonce_counter = _nonce_counter - (UINT16_MAX - target ); /* Assign the rest of it */
182 } else { /* Increase nonce */ 183 } else { /* Increase nonce */
183 184
184 _nonce_counter+= target; 185 _nonce_counter += target;
185 } 186 }
186 187
187 /* Assign the last bytes */ 188 /* Assign the last bytes */
188 189
189 U16_to_bytes( _reverse_bytes, _nonce_counter); 190 U16_to_bytes( _reverse_bytes, _nonce_counter);
190 nonce [crypto_box_NONCEBYTES - 1] = _reverse_bytes[0]; 191 nonce [crypto_box_NONCEBYTES - 1] = _reverse_bytes[0];
191 nonce [crypto_box_NONCEBYTES - 2] = _reverse_bytes[1]; 192 nonce [crypto_box_NONCEBYTES - 2] = _reverse_bytes[1];
192 193
193} 194}
194 195
195 196
196/** 197/**
197 * @brief Speaks for it self. 198 * @brief Speaks for it self.
198 * 199 *
199 */ 200 */
200static const uint32_t payload_table[] = 201static const uint32_t payload_table[] = {
201{
202 8000, 8000, 8000, 8000, 8000, 8000, 16000, 8000, 8000, 8000, /* 0-9 */ 202 8000, 8000, 8000, 8000, 8000, 8000, 16000, 8000, 8000, 8000, /* 0-9 */
203 44100, 44100, 0, 0, 90000, 8000, 11025, 22050, 0, 0, /* 10-19 */ 203 44100, 44100, 0, 0, 90000, 8000, 11025, 22050, 0, 0, /* 10-19 */
204 0, 0, 0, 0, 0, 90000, 90000, 0, 90000, 0, /* 20-29 */ 204 0, 0, 0, 0, 0, 90000, 90000, 0, 90000, 0, /* 20-29 */
@@ -217,208 +217,227 @@ static const uint32_t payload_table[] =
217 217
218/** 218/**
219 * @brief Extracts header from payload. 219 * @brief Extracts header from payload.
220 * 220 *
221 * @param payload The payload. 221 * @param payload The payload.
222 * @param length The size of payload. 222 * @param length The size of payload.
223 * @return RTPHeader* Extracted header. 223 * @return RTPHeader* Extracted header.
224 * @retval NULL Error occurred while extracting header. 224 * @retval NULL Error occurred while extracting header.
225 */ 225 */
226RTPHeader* extract_header ( const uint8_t* payload, int length ) 226RTPHeader *extract_header ( const uint8_t *payload, int length )
227{ 227{
228 if ( !payload || !length ) { 228 if ( !payload || !length ) {
229 return NULL; 229 return NULL;
230 } 230 }
231 231
232 const uint8_t* _it = payload; 232 const uint8_t *_it = payload;
233 233
234 RTPHeader* _retu = calloc(1, sizeof (RTPHeader)); 234 RTPHeader *_retu = calloc(1, sizeof (RTPHeader));
235 assert(_retu); 235 assert(_retu);
236 236
237 _retu->flags = *_it; ++_it; 237 _retu->flags = *_it;
238 238 ++_it;
239
239 /* This indicates if the first 2 bits are valid. 240 /* This indicates if the first 2 bits are valid.
240 * Now it may happen that this is out of order but 241 * Now it may happen that this is out of order but
241 * it cuts down chances of parsing some invalid value 242 * it cuts down chances of parsing some invalid value
242 */ 243 */
243 244
244 if ( GET_FLAG_VERSION(_retu) != RTP_VERSION ){ 245 if ( GET_FLAG_VERSION(_retu) != RTP_VERSION ) {
245 /* Deallocate */ 246 /* Deallocate */
246 free(_retu); 247 free(_retu);
247 return NULL; 248 return NULL;
248 } 249 }
249 250
250 /* 251 /*
251 * Added a check for the size of the header little sooner so 252 * Added a check for the size of the header little sooner so
252 * I don't need to parse the other stuff if it's bad 253 * I don't need to parse the other stuff if it's bad
253 */ 254 */
254 uint8_t _cc = GET_FLAG_CSRCC ( _retu ); 255 uint8_t _cc = GET_FLAG_CSRCC ( _retu );
255 uint32_t _length = 12 /* Minimum header len */ + ( _cc * 4 ); 256 uint32_t _length = 12 /* Minimum header len */ + ( _cc * 4 );
256 257
257 if ( length < _length ) { 258 if ( length < _length ) {
258 /* Deallocate */ 259 /* Deallocate */
259 free(_retu); 260 free(_retu);
260 return NULL; 261 return NULL;
261 } 262 }
262 263
263 if ( _cc > 0 ) { 264 if ( _cc > 0 ) {
264 _retu->csrc = calloc (_cc, sizeof (uint32_t)); 265 _retu->csrc = calloc (_cc, sizeof (uint32_t));
265 assert(_retu->csrc); 266 assert(_retu->csrc);
266 267
267 } else { /* But this should not happen ever */ 268 } else { /* But this should not happen ever */
268 /* Deallocate */ 269 /* Deallocate */
269 free(_retu); 270 free(_retu);
270 return NULL; 271 return NULL;
271 } 272 }
272 273
273 274
274 _retu->marker_payloadt = *_it; ++_it; 275 _retu->marker_payloadt = *_it;
276 ++_it;
275 _retu->length = _length; 277 _retu->length = _length;
276 278
277 279
278 bytes_to_U32(&_retu->timestamp, _it); _it += 4; 280 bytes_to_U32(&_retu->timestamp, _it);
281 _it += 4;
279 bytes_to_U32(&_retu->ssrc, _it); 282 bytes_to_U32(&_retu->ssrc, _it);
280 283
281 uint8_t _x; 284 uint8_t _x;
285
282 for ( _x = 0; _x < _cc; _x++ ) { 286 for ( _x = 0; _x < _cc; _x++ ) {
283 _it += 4; bytes_to_U32(&(_retu->csrc[_x]), _it); 287 _it += 4;
288 bytes_to_U32(&(_retu->csrc[_x]), _it);
284 } 289 }
285 290
286 return _retu; 291 return _retu;
287} 292}
288 293
289/** 294/**
290 * @brief Extracts external header from payload. Must be called AFTER extract_header()! 295 * @brief Extracts external header from payload. Must be called AFTER extract_header()!
291 * 296 *
292 * @param payload The ITERATED payload. 297 * @param payload The ITERATED payload.
293 * @param length The size of payload. 298 * @param length The size of payload.
294 * @return RTPExtHeader* Extracted extension header. 299 * @return RTPExtHeader* Extracted extension header.
295 * @retval NULL Error occurred while extracting extension header. 300 * @retval NULL Error occurred while extracting extension header.
296 */ 301 */
297RTPExtHeader* extract_ext_header ( const uint8_t* payload, uint16_t length ) 302RTPExtHeader *extract_ext_header ( const uint8_t *payload, uint16_t length )
298{ 303{
299 const uint8_t* _it = payload; 304 const uint8_t *_it = payload;
300 305
301 RTPExtHeader* _retu = calloc(1, sizeof (RTPExtHeader)); 306 RTPExtHeader *_retu = calloc(1, sizeof (RTPExtHeader));
302 assert(_retu); 307 assert(_retu);
303 308
304 uint16_t _ext_length; 309 uint16_t _ext_length;
305 bytes_to_U16(&_ext_length, _it); _it += 2; 310 bytes_to_U16(&_ext_length, _it);
306 311 _it += 2;
307 312
313
308 if ( length < ( _ext_length * sizeof(uint32_t) ) ) { 314 if ( length < ( _ext_length * sizeof(uint32_t) ) ) {
309 free(_retu); 315 free(_retu);
310 return NULL; 316 return NULL;
311 } 317 }
312 318
313 _retu->length = _ext_length; 319 _retu->length = _ext_length;
314 bytes_to_U16(&_retu->type, _it); _it += 2; 320 bytes_to_U16(&_retu->type, _it);
315 321 _it += 2;
322
316 _retu->table = calloc(_ext_length, sizeof (uint32_t)); 323 _retu->table = calloc(_ext_length, sizeof (uint32_t));
317 assert(_retu->table); 324 assert(_retu->table);
318 325
319 uint16_t _x; 326 uint16_t _x;
327
320 for ( _x = 0; _x < _ext_length; _x++ ) { 328 for ( _x = 0; _x < _ext_length; _x++ ) {
321 _it += 4; bytes_to_U32(&(_retu->table[_x]), _it); 329 _it += 4;
330 bytes_to_U32(&(_retu->table[_x]), _it);
322 } 331 }
323 332
324 return _retu; 333 return _retu;
325} 334}
326 335
327/** 336/**
328 * @brief Adds header to payload. Make sure _payload_ has enough space. 337 * @brief Adds header to payload. Make sure _payload_ has enough space.
329 * 338 *
330 * @param header The header. 339 * @param header The header.
331 * @param payload The payload. 340 * @param payload The payload.
332 * @return uint8_t* Iterated position. 341 * @return uint8_t* Iterated position.
333 */ 342 */
334uint8_t* add_header ( RTPHeader* header, uint8_t* payload ) 343uint8_t *add_header ( RTPHeader *header, uint8_t *payload )
335{ 344{
336 uint8_t _cc = GET_FLAG_CSRCC ( header ); 345 uint8_t _cc = GET_FLAG_CSRCC ( header );
337 346
338 uint8_t* _it = payload; 347 uint8_t *_it = payload;
339 348
340 349
341 /* Add sequence number first */ 350 /* Add sequence number first */
342 U16_to_bytes(_it, header->sequnum); _it += 2; 351 U16_to_bytes(_it, header->sequnum);
343 352 _it += 2;
344 *_it = header->flags; ++_it; 353
345 *_it = header->marker_payloadt; ++_it; 354 *_it = header->flags;
346 355 ++_it;
347 356 *_it = header->marker_payloadt;
348 U32_to_bytes( _it, header->timestamp); _it+=4; 357 ++_it;
358
359
360 U32_to_bytes( _it, header->timestamp);
361 _it += 4;
349 U32_to_bytes( _it, header->ssrc); 362 U32_to_bytes( _it, header->ssrc);
350 363
351 if ( header->csrc ) { 364 if ( header->csrc ) {
352 uint8_t _x; 365 uint8_t _x;
366
353 for ( _x = 0; _x < _cc; _x++ ) { 367 for ( _x = 0; _x < _cc; _x++ ) {
354 _it+=4; U32_to_bytes( _it, header->csrc[_x]); 368 _it += 4;
369 U32_to_bytes( _it, header->csrc[_x]);
355 } 370 }
356 } 371 }
357 372
358 return _it + 4; 373 return _it + 4;
359} 374}
360 375
361/** 376/**
362 * @brief Adds extension header to payload. Make sure _payload_ has enough space. 377 * @brief Adds extension header to payload. Make sure _payload_ has enough space.
363 * 378 *
364 * @param header The header. 379 * @param header The header.
365 * @param payload The payload. 380 * @param payload The payload.
366 * @return uint8_t* Iterated position. 381 * @return uint8_t* Iterated position.
367 */ 382 */
368uint8_t* add_ext_header ( RTPExtHeader* header, uint8_t* payload ) 383uint8_t *add_ext_header ( RTPExtHeader *header, uint8_t *payload )
369{ 384{
370 uint8_t* _it = payload; 385 uint8_t *_it = payload;
371 386
372 U16_to_bytes(_it, header->length); _it+=2; 387 U16_to_bytes(_it, header->length);
373 U16_to_bytes(_it, header->type); _it-=2; /* Return to 0 position */ 388 _it += 2;
374 389 U16_to_bytes(_it, header->type);
390 _it -= 2; /* Return to 0 position */
391
375 if ( header->table ) { 392 if ( header->table ) {
376 uint16_t _x; 393 uint16_t _x;
394
377 for ( _x = 0; _x < header->length; _x++ ) { 395 for ( _x = 0; _x < header->length; _x++ ) {
378 _it+=4; U32_to_bytes(_it, header->table[_x]); 396 _it += 4;
397 U32_to_bytes(_it, header->table[_x]);
379 } 398 }
380 } 399 }
381 400
382 return _it + 4; 401 return _it + 4;
383} 402}
384 403
385/** 404/**
386 * @brief Builds header from control session values. 405 * @brief Builds header from control session values.
387 * 406 *
388 * @param session Control session. 407 * @param session Control session.
389 * @return RTPHeader* Created header. 408 * @return RTPHeader* Created header.
390 */ 409 */
391RTPHeader* build_header ( RTPSession* session ) 410RTPHeader *build_header ( RTPSession *session )
392{ 411{
393 RTPHeader* _retu = calloc ( 1, sizeof (RTPHeader) ); 412 RTPHeader *_retu = calloc ( 1, sizeof (RTPHeader) );
394 assert(_retu); 413 assert(_retu);
395 414
396 ADD_FLAG_VERSION ( _retu, session->version ); 415 ADD_FLAG_VERSION ( _retu, session->version );
397 ADD_FLAG_PADDING ( _retu, session->padding ); 416 ADD_FLAG_PADDING ( _retu, session->padding );
398 ADD_FLAG_EXTENSION ( _retu, session->extension ); 417 ADD_FLAG_EXTENSION ( _retu, session->extension );
399 ADD_FLAG_CSRCC ( _retu, session->cc ); 418 ADD_FLAG_CSRCC ( _retu, session->cc );
400 ADD_SETTING_MARKER ( _retu, session->marker ); 419 ADD_SETTING_MARKER ( _retu, session->marker );
401 ADD_SETTING_PAYLOAD ( _retu, session->payload_type ); 420 ADD_SETTING_PAYLOAD ( _retu, session->payload_type );
402 421
403 _retu->sequnum = session->sequnum; 422 _retu->sequnum = session->sequnum;
404 _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */ 423 _retu->timestamp = ((uint32_t)(current_time() / 1000)); /* micro to milli */
405 _retu->ssrc = session->ssrc; 424 _retu->ssrc = session->ssrc;
406 425
407 if ( session->cc > 0 ) { 426 if ( session->cc > 0 ) {
408 _retu->csrc = calloc(session->cc, sizeof (uint32_t)); 427 _retu->csrc = calloc(session->cc, sizeof (uint32_t));
409 assert(_retu->csrc); 428 assert(_retu->csrc);
410 429
411 int i; 430 int i;
412 431
413 for ( i = 0; i < session->cc; i++ ) { 432 for ( i = 0; i < session->cc; i++ ) {
414 _retu->csrc[i] = session->csrc[i]; 433 _retu->csrc[i] = session->csrc[i];
415 } 434 }
416 } else { 435 } else {
417 _retu->csrc = NULL; 436 _retu->csrc = NULL;
418 } 437 }
419 438
420 _retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 ); 439 _retu->length = 12 /* Minimum header len */ + ( session->cc * size_32 );
421 440
422 return _retu; 441 return _retu;
423} 442}
424 443
@@ -427,7 +446,7 @@ RTPHeader* build_header ( RTPSession* session )
427 * @brief Parses data into RTPMessage struct. Stores headers separately from the payload data 446 * @brief Parses data into RTPMessage struct. Stores headers separately from the payload data
428 * and so the length variable is set accordingly. _sequnum_ argument is 447 * and so the length variable is set accordingly. _sequnum_ argument is
429 * passed by the handle_packet() since it's parsed already. 448 * passed by the handle_packet() since it's parsed already.
430 * 449 *
431 * @param session Control session. 450 * @param session Control session.
432 * @param sequnum Sequence number that's parsed from payload in handle_packet() 451 * @param sequnum Sequence number that's parsed from payload in handle_packet()
433 * @param data Payload data. 452 * @param data Payload data.
@@ -435,26 +454,28 @@ RTPHeader* build_header ( RTPSession* session )
435 * @return RTPMessage* 454 * @return RTPMessage*
436 * @retval NULL Error occurred. 455 * @retval NULL Error occurred.
437 */ 456 */
438RTPMessage* msg_parse ( uint16_t sequnum, const uint8_t* data, int length ) 457RTPMessage *msg_parse ( uint16_t sequnum, const uint8_t *data, int length )
439{ 458{
440 RTPMessage* _retu = calloc(1, sizeof (RTPMessage)); 459 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
441 460
442 _retu->header = extract_header ( data, length ); /* It allocates memory and all */ 461 _retu->header = extract_header ( data, length ); /* It allocates memory and all */
443 462
444 if ( !_retu->header ){ 463 if ( !_retu->header ) {
445 free(_retu); 464 free(_retu);
446 return NULL; 465 return NULL;
447 } 466 }
467
448 _retu->header->sequnum = sequnum; 468 _retu->header->sequnum = sequnum;
449 469
450 _retu->length = length - _retu->header->length; 470 _retu->length = length - _retu->header->length;
451 471
452 uint16_t _from_pos = _retu->header->length - 2 /* Since sequ num is excluded */ ; 472 uint16_t _from_pos = _retu->header->length - 2 /* Since sequ num is excluded */ ;
453 473
454 474
455 if ( GET_FLAG_EXTENSION ( _retu->header ) ) { 475 if ( GET_FLAG_EXTENSION ( _retu->header ) ) {
456 _retu->ext_header = extract_ext_header ( data + _from_pos, length ); 476 _retu->ext_header = extract_ext_header ( data + _from_pos, length );
457 if ( _retu->ext_header ){ 477
478 if ( _retu->ext_header ) {
458 _retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 479 _retu->length -= ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
459 _from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 480 _from_pos += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
460 } else { /* Error */ 481 } else { /* Error */
@@ -473,14 +494,15 @@ RTPMessage* msg_parse ( uint16_t sequnum, const uint8_t* data, int length )
473 rtp_free_msg(NULL, _retu); 494 rtp_free_msg(NULL, _retu);
474 return NULL; 495 return NULL;
475 } 496 }
497
476 _retu->next = NULL; 498 _retu->next = NULL;
477 499
478 return _retu; 500 return _retu;
479} 501}
480 502
481/** 503/**
482 * @brief Callback for networking core. 504 * @brief Callback for networking core.
483 * 505 *
484 * @param object RTPSession object. 506 * @param object RTPSession object.
485 * @param ip_port Where the message comes from. 507 * @param ip_port Where the message comes from.
486 * @param data Message data. 508 * @param data Message data.
@@ -489,82 +511,82 @@ RTPMessage* msg_parse ( uint16_t sequnum, const uint8_t* data, int length )
489 * @retval -1 Error occurred. 511 * @retval -1 Error occurred.
490 * @retval 0 Success. 512 * @retval 0 Success.
491 */ 513 */
492int rtp_handle_packet ( void* object, IP_Port ip_port, uint8_t* data, uint32_t length ) 514int rtp_handle_packet ( void *object, IP_Port ip_port, uint8_t *data, uint32_t length )
493{ 515{
494 RTPSession* _session = object; 516 RTPSession *_session = object;
495 RTPMessage* _msg; 517 RTPMessage *_msg;
496 518
497 if ( !_session || length < 13 ) /* 12 is the minimum length for rtp + desc. byte */ 519 if ( !_session || length < 13 ) /* 12 is the minimum length for rtp + desc. byte */
498 return -1; 520 return -1;
499 521
500 uint8_t _plain[MAX_UDP_PACKET_SIZE]; 522 uint8_t _plain[MAX_UDP_PACKET_SIZE];
501 523
502 uint16_t _sequnum; 524 uint16_t _sequnum;
503 bytes_to_U16(&_sequnum, data + 1); 525 bytes_to_U16(&_sequnum, data + 1);
504 526
505 /* Clculate the right nonce */ 527 /* Clculate the right nonce */
506 uint8_t _calculated[crypto_box_NONCEBYTES]; 528 uint8_t _calculated[crypto_box_NONCEBYTES];
507 memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES); 529 memcpy(_calculated, _session->decrypt_nonce, crypto_box_NONCEBYTES);
508 increase_nonce ( _calculated, _sequnum ); 530 increase_nonce ( _calculated, _sequnum );
509 531
510 /* Decrypt message */ 532 /* Decrypt message */
511 int _decrypted_length = decrypt_data_symmetric( 533 int _decrypted_length = decrypt_data_symmetric(
512 (uint8_t*)_session->decrypt_key, _calculated, data + 3, length - 3, _plain ); 534 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
513 535
514 /* This packet is either not encrypted properly or late 536 /* This packet is either not encrypted properly or late
515 */ 537 */
516 if ( -1 == _decrypted_length ){ 538 if ( -1 == _decrypted_length ) {
517 539
518 /* If this is the case, then the packet is most likely late. 540 /* If this is the case, then the packet is most likely late.
519 * Try with old nonce cycle. 541 * Try with old nonce cycle.
520 */ 542 */
521 if ( _session->rsequnum < _sequnum ) { 543 if ( _session->rsequnum < _sequnum ) {
522 _decrypted_length = decrypt_data_symmetric( 544 _decrypted_length = decrypt_data_symmetric(
523 (uint8_t*)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain ); 545 (uint8_t *)_session->decrypt_key, _session->nonce_cycle, data + 3, length - 3, _plain );
524 546
525 if ( !_decrypted_length ) return -1; /* This packet is not encrypted properly */ 547 if ( !_decrypted_length ) return -1; /* This packet is not encrypted properly */
526 548
527 /* Otherwise, if decryption is ok with new cycle, set new cycle 549 /* Otherwise, if decryption is ok with new cycle, set new cycle
528 */ 550 */
529 } else { 551 } else {
530 increase_nonce ( _calculated, MAX_SEQU_NUM ); 552 increase_nonce ( _calculated, MAX_SEQU_NUM );
531 _decrypted_length = decrypt_data_symmetric( 553 _decrypted_length = decrypt_data_symmetric(
532 (uint8_t*)_session->decrypt_key, _calculated, data + 3, length - 3, _plain ); 554 (uint8_t *)_session->decrypt_key, _calculated, data + 3, length - 3, _plain );
533 555
534 if ( !_decrypted_length ) return -1; /* This is just an error */ 556 if ( !_decrypted_length ) return -1; /* This is just an error */
535 557
536 /* A new cycle setting. */ 558 /* A new cycle setting. */
537 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES); 559 memcpy(_session->nonce_cycle, _session->decrypt_nonce, crypto_box_NONCEBYTES);
538 memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES); 560 memcpy(_session->decrypt_nonce, _calculated, crypto_box_NONCEBYTES);
539 } 561 }
540 } 562 }
541 563
542 _msg = msg_parse ( _sequnum, _plain, _decrypted_length ); 564 _msg = msg_parse ( _sequnum, _plain, _decrypted_length );
543 565
544 if ( !_msg ) return -1; 566 if ( !_msg ) return -1;
545 567
546 /* Hopefully this goes well 568 /* Hopefully this goes well
547 * NOTE: Is this even used? 569 * NOTE: Is this even used?
548 */ 570 */
549 memcpy(&_msg->from, &ip_port, sizeof(IP_Port)); 571 memcpy(&_msg->from, &ip_port, sizeof(IP_Port));
550 572
551 /* Check if message came in late */ 573 /* Check if message came in late */
552 if ( check_late_message(_session, _msg) < 0 ) { /* Not late */ 574 if ( check_late_message(_session, _msg) < 0 ) { /* Not late */
553 _session->rsequnum = _msg->header->sequnum; 575 _session->rsequnum = _msg->header->sequnum;
554 _session->timestamp = _msg->header->timestamp; 576 _session->timestamp = _msg->header->timestamp;
555 } 577 }
556 578
557 pthread_mutex_lock(&_session->mutex); 579 pthread_mutex_lock(&_session->mutex);
558 580
559 if ( _session->last_msg ) { 581 if ( _session->last_msg ) {
560 _session->last_msg->next = _msg; 582 _session->last_msg->next = _msg;
561 _session->last_msg = _msg; 583 _session->last_msg = _msg;
562 } else { 584 } else {
563 _session->last_msg = _session->oldest_msg = _msg; 585 _session->last_msg = _session->oldest_msg = _msg;
564 } 586 }
565 587
566 pthread_mutex_unlock(&_session->mutex); 588 pthread_mutex_unlock(&_session->mutex);
567 589
568 return 0; 590 return 0;
569} 591}
570 592
@@ -573,50 +595,50 @@ int rtp_handle_packet ( void* object, IP_Port ip_port, uint8_t* data, uint32_t l
573/** 595/**
574 * @brief Stores headers and payload data in one container ( data ) 596 * @brief Stores headers and payload data in one container ( data )
575 * and the length is set accordingly. Returned message is used for sending _only_. 597 * and the length is set accordingly. Returned message is used for sending _only_.
576 * 598 *
577 * @param session The control session. 599 * @param session The control session.
578 * @param data Payload data to send ( This is what you pass ). 600 * @param data Payload data to send ( This is what you pass ).
579 * @param length Size of the payload data. 601 * @param length Size of the payload data.
580 * @return RTPMessage* Created message. 602 * @return RTPMessage* Created message.
581 * @retval NULL Error occurred. 603 * @retval NULL Error occurred.
582 */ 604 */
583RTPMessage* rtp_new_message ( RTPSession* session, const uint8_t* data, uint32_t length ) 605RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t length )
584{ 606{
585 if ( !session ) 607 if ( !session )
586 return NULL; 608 return NULL;
587 609
588 uint8_t* _from_pos; 610 uint8_t *_from_pos;
589 RTPMessage* _retu = calloc(1, sizeof (RTPMessage)); 611 RTPMessage *_retu = calloc(1, sizeof (RTPMessage));
590 assert(_retu); 612 assert(_retu);
591 613
592 /* Sets header values and copies the extension header in _retu */ 614 /* Sets header values and copies the extension header in _retu */
593 _retu->header = build_header ( session ); /* It allocates memory and all */ 615 _retu->header = build_header ( session ); /* It allocates memory and all */
594 _retu->ext_header = session->ext_header; 616 _retu->ext_header = session->ext_header;
595 617
596 618
597 uint32_t _total_length = length + _retu->header->length; 619 uint32_t _total_length = length + _retu->header->length;
598 620
599 if ( _retu->ext_header ) { 621 if ( _retu->ext_header ) {
600 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 ); 622 _total_length += ( 4 /* Minimum ext header len */ + _retu->ext_header->length * size_32 );
601 623
602 _from_pos = add_header ( _retu->header, _retu->data ); 624 _from_pos = add_header ( _retu->header, _retu->data );
603 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 ); 625 _from_pos = add_ext_header ( _retu->ext_header, _from_pos + 1 );
604 } else { 626 } else {
605 _from_pos = add_header ( _retu->header, _retu->data ); 627 _from_pos = add_header ( _retu->header, _retu->data );
606 } 628 }
607 629
608 /* 630 /*
609 * Parses the extension header into the message 631 * Parses the extension header into the message
610 * Of course if any 632 * Of course if any
611 */ 633 */
612 634
613 /* Appends _data on to _retu->_data */ 635 /* Appends _data on to _retu->_data */
614 memcpy ( _from_pos, data, length ); 636 memcpy ( _from_pos, data, length );
615 637
616 _retu->length = _total_length; 638 _retu->length = _total_length;
617 639
618 _retu->next = NULL; 640 _retu->next = NULL;
619 641
620 return _retu; 642 return _retu;
621} 643}
622 644
@@ -626,18 +648,18 @@ RTPMessage* rtp_new_message ( RTPSession* session, const uint8_t* data, uint32_t
626 648
627 649
628 650
629/******************************************************************************************************************** 651/********************************************************************************************************************
630 ******************************************************************************************************************** 652 ********************************************************************************************************************
631 ******************************************************************************************************************** 653 ********************************************************************************************************************
632 ******************************************************************************************************************** 654 ********************************************************************************************************************
633 ******************************************************************************************************************** 655 ********************************************************************************************************************
634 * 656 *
635 * 657 *
636 * 658 *
637 * PUBLIC API FUNCTIONS IMPLEMENTATIONS 659 * PUBLIC API FUNCTIONS IMPLEMENTATIONS
638 * 660 *
639 * 661 *
640 * 662 *
641 ******************************************************************************************************************** 663 ********************************************************************************************************************
642 ******************************************************************************************************************** 664 ********************************************************************************************************************
643 ******************************************************************************************************************** 665 ********************************************************************************************************************
@@ -654,66 +676,66 @@ RTPMessage* rtp_new_message ( RTPSession* session, const uint8_t* data, uint32_t
654 676
655/** 677/**
656 * @brief Release all messages held by session. 678 * @brief Release all messages held by session.
657 * 679 *
658 * @param session The session. 680 * @param session The session.
659 * @return int 681 * @return int
660 * @retval -1 Error occurred. 682 * @retval -1 Error occurred.
661 * @retval 0 Success. 683 * @retval 0 Success.
662 */ 684 */
663int rtp_release_session_recv ( RTPSession* session ) 685int rtp_release_session_recv ( RTPSession *session )
664{ 686{
665 if ( !session ){ 687 if ( !session ) {
666 return -1; 688 return -1;
667 } 689 }
668 690
669 RTPMessage* _tmp,* _it; 691 RTPMessage *_tmp, * _it;
670 692
671 pthread_mutex_lock(&session->mutex); 693 pthread_mutex_lock(&session->mutex);
672 694
673 for ( _it = session->oldest_msg; _it; _it = _tmp ){ 695 for ( _it = session->oldest_msg; _it; _it = _tmp ) {
674 _tmp = _it->next; 696 _tmp = _it->next;
675 rtp_free_msg( session, _it); 697 rtp_free_msg( session, _it);
676 } 698 }
677 699
678 session->last_msg = session->oldest_msg = NULL; 700 session->last_msg = session->oldest_msg = NULL;
679 701
680 pthread_mutex_unlock(&session->mutex); 702 pthread_mutex_unlock(&session->mutex);
681 703
682 return 0; 704 return 0;
683} 705}
684 706
685 707
686/** 708/**
687 * @brief Gets oldest message in the list. 709 * @brief Gets oldest message in the list.
688 * 710 *
689 * @param session Where the list is. 711 * @param session Where the list is.
690 * @return RTPMessage* The message. You _must_ call rtp_msg_free() to free it. 712 * @return RTPMessage* The message. You _must_ call rtp_msg_free() to free it.
691 * @retval NULL No messages in the list, or no list. 713 * @retval NULL No messages in the list, or no list.
692 */ 714 */
693RTPMessage* rtp_recv_msg ( RTPSession* session ) 715RTPMessage *rtp_recv_msg ( RTPSession *session )
694{ 716{
695 if ( !session ) 717 if ( !session )
696 return NULL; 718 return NULL;
697 719
698 RTPMessage* _retu = session->oldest_msg; 720 RTPMessage *_retu = session->oldest_msg;
699 721
700 pthread_mutex_lock(&session->mutex); 722 pthread_mutex_lock(&session->mutex);
701 723
702 if ( _retu ) 724 if ( _retu )
703 session->oldest_msg = _retu->next; 725 session->oldest_msg = _retu->next;
704 726
705 if ( !session->oldest_msg ) 727 if ( !session->oldest_msg )
706 session->last_msg = NULL; 728 session->last_msg = NULL;
707 729
708 pthread_mutex_unlock(&session->mutex); 730 pthread_mutex_unlock(&session->mutex);
709 731
710 return _retu; 732 return _retu;
711} 733}
712 734
713 735
714/** 736/**
715 * @brief Sends data to _RTPSession::dest 737 * @brief Sends data to _RTPSession::dest
716 * 738 *
717 * @param session The session. 739 * @param session The session.
718 * @param messenger Tox* object. 740 * @param messenger Tox* object.
719 * @param data The payload. 741 * @param data The payload.
@@ -722,38 +744,38 @@ RTPMessage* rtp_recv_msg ( RTPSession* session )
722 * @retval -1 On error. 744 * @retval -1 On error.
723 * @retval 0 On success. 745 * @retval 0 On success.
724 */ 746 */
725int rtp_send_msg ( RTPSession* session, Messenger* messenger, const uint8_t* data, uint16_t length ) 747int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *data, uint16_t length )
726{ 748{
727 RTPMessage* msg = rtp_new_message (session, data, length); 749 RTPMessage *msg = rtp_new_message (session, data, length);
728 750
729 if ( !msg ) return -1; 751 if ( !msg ) return -1;
730 752
731 uint8_t _send_data [ MAX_UDP_PACKET_SIZE ]; 753 uint8_t _send_data [ MAX_UDP_PACKET_SIZE ];
732 754
733 _send_data[0] = session->prefix; 755 _send_data[0] = session->prefix;
734 756
735 /* Generate the right nonce */ 757 /* Generate the right nonce */
736 uint8_t _calculated[crypto_box_NONCEBYTES]; 758 uint8_t _calculated[crypto_box_NONCEBYTES];
737 memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES); 759 memcpy(_calculated, session->encrypt_nonce, crypto_box_NONCEBYTES);
738 increase_nonce ( _calculated, msg->header->sequnum ); 760 increase_nonce ( _calculated, msg->header->sequnum );
739 761
740 /* Need to skip 2 bytes that are for sequnum */ 762 /* Need to skip 2 bytes that are for sequnum */
741 int encrypted_length = encrypt_data_symmetric( /* TODO: msg->length - 2 (fix this properly)*/ 763 int encrypted_length = encrypt_data_symmetric( /* TODO: msg->length - 2 (fix this properly)*/
742 (uint8_t*) session->encrypt_key, _calculated, msg->data + 2, msg->length, _send_data + 3 ); 764 (uint8_t *) session->encrypt_key, _calculated, msg->data + 2, msg->length, _send_data + 3 );
743 765
744 int full_length = encrypted_length + 3; 766 int full_length = encrypted_length + 3;
745 767
746 _send_data[1] = msg->data[0]; 768 _send_data[1] = msg->data[0];
747 _send_data[2] = msg->data[1]; 769 _send_data[2] = msg->data[1];
748 770
749 771
750 /*if ( full_length != sendpacket ( messenger->net, *((IP_Port*) &session->dest), _send_data, full_length) ) {*/ 772 /*if ( full_length != sendpacket ( messenger->net, *((IP_Port*) &session->dest), _send_data, full_length) ) {*/
751 if ( full_length != send_custom_user_packet(messenger, session->dest, _send_data, full_length) ) { 773 if ( full_length != send_custom_user_packet(messenger, session->dest, _send_data, full_length) ) {
752 printf("Rtp error: %s\n", strerror(errno)); 774 printf("Rtp error: %s\n", strerror(errno));
753 return -1; 775 return -1;
754 } 776 }
755 777
756 778
757 /* Set sequ number */ 779 /* Set sequ number */
758 if ( session->sequnum >= MAX_SEQU_NUM ) { 780 if ( session->sequnum >= MAX_SEQU_NUM ) {
759 session->sequnum = 0; 781 session->sequnum = 0;
@@ -761,7 +783,7 @@ int rtp_send_msg ( RTPSession* session, Messenger* messenger, const uint8_t* dat
761 } else { 783 } else {
762 session->sequnum++; 784 session->sequnum++;
763 } 785 }
764 786
765 rtp_free_msg ( session, msg ); 787 rtp_free_msg ( session, msg );
766 return 0; 788 return 0;
767} 789}
@@ -769,29 +791,31 @@ int rtp_send_msg ( RTPSession* session, Messenger* messenger, const uint8_t* dat
769 791
770/** 792/**
771 * @brief Speaks for it self. 793 * @brief Speaks for it self.
772 * 794 *
773 * @param session The control session msg belongs to. You set it as NULL when freeing recved messages. 795 * @param session The control session msg belongs to. You set it as NULL when freeing recved messages.
774 * Otherwise set it to session the message was created from. 796 * Otherwise set it to session the message was created from.
775 * @param msg The message. 797 * @param msg The message.
776 * @return void 798 * @return void
777 */ 799 */
778void rtp_free_msg ( RTPSession* session, RTPMessage* msg ) 800void rtp_free_msg ( RTPSession *session, RTPMessage *msg )
779{ 801{
780 if ( !session ){ 802 if ( !session ) {
781 free ( msg->header->csrc ); 803 free ( msg->header->csrc );
782 if ( msg->ext_header ){ 804
805 if ( msg->ext_header ) {
783 free ( msg->ext_header->table ); 806 free ( msg->ext_header->table );
784 free ( msg->ext_header ); 807 free ( msg->ext_header );
785 } 808 }
786 } else { 809 } else {
787 if ( session->csrc != msg->header->csrc ) 810 if ( session->csrc != msg->header->csrc )
788 free ( msg->header->csrc ); 811 free ( msg->header->csrc );
812
789 if ( msg->ext_header && session->ext_header != msg->ext_header ) { 813 if ( msg->ext_header && session->ext_header != msg->ext_header ) {
790 free ( msg->ext_header->table ); 814 free ( msg->ext_header->table );
791 free ( msg->ext_header ); 815 free ( msg->ext_header );
792 } 816 }
793 } 817 }
794 818
795 free ( msg->header ); 819 free ( msg->header );
796 free ( msg ); 820 free ( msg );
797} 821}
@@ -800,7 +824,7 @@ void rtp_free_msg ( RTPSession* session, RTPMessage* msg )
800/** 824/**
801 * @brief Must be called before calling any other rtp function. It's used 825 * @brief Must be called before calling any other rtp function. It's used
802 * to initialize RTP control session. 826 * to initialize RTP control session.
803 * 827 *
804 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType 828 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
805 * @param messenger Tox* object. 829 * @param messenger Tox* object.
806 * @param friend_num Friend id. 830 * @param friend_num Friend id.
@@ -811,25 +835,24 @@ void rtp_free_msg ( RTPSession* session, RTPMessage* msg )
811 * @return RTPSession* Created control session. 835 * @return RTPSession* Created control session.
812 * @retval NULL Error occurred. 836 * @retval NULL Error occurred.
813 */ 837 */
814RTPSession* rtp_init_session ( int payload_type, 838RTPSession *rtp_init_session ( int payload_type,
815 Messenger* messenger, 839 Messenger *messenger,
816 int friend_num, 840 int friend_num,
817 const uint8_t* encrypt_key, 841 const uint8_t *encrypt_key,
818 const uint8_t* decrypt_key, 842 const uint8_t *decrypt_key,
819 const uint8_t* encrypt_nonce, 843 const uint8_t *encrypt_nonce,
820 const uint8_t* decrypt_nonce ) 844 const uint8_t *decrypt_nonce )
821{ 845{
822 RTPSession* _retu = calloc(1, sizeof(RTPSession)); 846 RTPSession *_retu = calloc(1, sizeof(RTPSession));
823 assert(_retu); 847 assert(_retu);
824 848
825 /*networking_registerhandler(messenger->net, payload_type, rtp_handle_packet, _retu);*/ 849 /*networking_registerhandler(messenger->net, payload_type, rtp_handle_packet, _retu);*/
826 if ( -1 == custom_user_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) ) 850 if ( -1 == custom_user_packet_registerhandler(messenger, friend_num, payload_type, rtp_handle_packet, _retu) ) {
827 {
828 fprintf(stderr, "Error setting custom register handler for rtp session\n"); 851 fprintf(stderr, "Error setting custom register handler for rtp session\n");
829 free(_retu); 852 free(_retu);
830 return NULL; 853 return NULL;
831 } 854 }
832 855
833 _retu->version = RTP_VERSION; /* It's always 2 */ 856 _retu->version = RTP_VERSION; /* It's always 2 */
834 _retu->padding = 0; /* If some additional data is needed about the packet */ 857 _retu->padding = 0; /* If some additional data is needed about the packet */
835 _retu->extension = 0; /* If extension to header is needed */ 858 _retu->extension = 0; /* If extension to header is needed */
@@ -837,41 +860,44 @@ RTPSession* rtp_init_session ( int payload_type,
837 _retu->csrc = NULL; /* Container */ 860 _retu->csrc = NULL; /* Container */
838 _retu->ssrc = random_int(); 861 _retu->ssrc = random_int();
839 _retu->marker = 0; 862 _retu->marker = 0;
840 _retu->payload_type = payload_table[payload_type]; 863 _retu->payload_type = payload_table[payload_type];
841 864
842 _retu->dest = friend_num; 865 _retu->dest = friend_num;
843 866
844 _retu->rsequnum = _retu->sequnum = 1; 867 _retu->rsequnum = _retu->sequnum = 1;
845 868
846 _retu->ext_header = NULL; /* When needed allocate */ 869 _retu->ext_header = NULL; /* When needed allocate */
847 _retu->framerate = -1; 870 _retu->framerate = -1;
848 _retu->resolution = -1; 871 _retu->resolution = -1;
849 872
850 _retu->encrypt_key = encrypt_key; 873 _retu->encrypt_key = encrypt_key;
851 _retu->decrypt_key = decrypt_key; 874 _retu->decrypt_key = decrypt_key;
852 875
853 /* Need to allocate new memory */ 876 /* Need to allocate new memory */
854 _retu->encrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) ); assert(_retu->encrypt_nonce); 877 _retu->encrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
855 _retu->decrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) ); assert(_retu->decrypt_nonce); 878 assert(_retu->encrypt_nonce);
856 _retu->nonce_cycle = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) ); assert(_retu->nonce_cycle); 879 _retu->decrypt_nonce = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
857 880 assert(_retu->decrypt_nonce);
858 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES); 881 _retu->nonce_cycle = calloc ( crypto_box_NONCEBYTES, sizeof (uint8_t) );
882 assert(_retu->nonce_cycle);
883
884 memcpy(_retu->encrypt_nonce, encrypt_nonce, crypto_box_NONCEBYTES);
859 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES); 885 memcpy(_retu->decrypt_nonce, decrypt_nonce, crypto_box_NONCEBYTES);
860 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES); 886 memcpy(_retu->nonce_cycle , decrypt_nonce, crypto_box_NONCEBYTES);
861 887
862 _retu->csrc = calloc(1, sizeof (uint32_t)); 888 _retu->csrc = calloc(1, sizeof (uint32_t));
863 assert(_retu->csrc); 889 assert(_retu->csrc);
864 890
865 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */ 891 _retu->csrc[0] = _retu->ssrc; /* Set my ssrc to the list receive */
866 892
867 /* Also set payload type as prefix */ 893 /* Also set payload type as prefix */
868 _retu->prefix = payload_type; 894 _retu->prefix = payload_type;
869 895
870 _retu->oldest_msg = _retu->last_msg = NULL; 896 _retu->oldest_msg = _retu->last_msg = NULL;
871 897
872 pthread_mutex_init(&_retu->mutex, NULL); 898 pthread_mutex_init(&_retu->mutex, NULL);
873 /* 899 /*
874 * 900 *
875 */ 901 */
876 return _retu; 902 return _retu;
877} 903}
@@ -879,30 +905,30 @@ RTPSession* rtp_init_session ( int payload_type,
879 905
880/** 906/**
881 * @brief Terminate the session. 907 * @brief Terminate the session.
882 * 908 *
883 * @param session The session. 909 * @param session The session.
884 * @param messenger The messenger who owns the session 910 * @param messenger The messenger who owns the session
885 * @return int 911 * @return int
886 * @retval -1 Error occurred. 912 * @retval -1 Error occurred.
887 * @retval 0 Success. 913 * @retval 0 Success.
888 */ 914 */
889int rtp_terminate_session ( RTPSession* session, Messenger* messenger ) 915int rtp_terminate_session ( RTPSession *session, Messenger *messenger )
890{ 916{
891 if ( !session ) 917 if ( !session )
892 return -1; 918 return -1;
893 919
894 custom_user_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); 920 custom_user_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL);
895 921
896 free ( session->ext_header ); 922 free ( session->ext_header );
897 free ( session->csrc ); 923 free ( session->csrc );
898 free ( session->decrypt_nonce ); 924 free ( session->decrypt_nonce );
899 free ( session->encrypt_nonce ); 925 free ( session->encrypt_nonce );
900 free ( session->nonce_cycle ); 926 free ( session->nonce_cycle );
901 927
902 pthread_mutex_destroy(&session->mutex); 928 pthread_mutex_destroy(&session->mutex);
903 929
904 /* And finally free session */ 930 /* And finally free session */
905 free ( session ); 931 free ( session );
906 932
907 return 0; 933 return 0;
908} \ No newline at end of file 934} \ No newline at end of file
diff --git a/toxav/rtp.h b/toxav/rtp.h
index acec8b0a..c2b68b01 100644
--- a/toxav/rtp.h
+++ b/toxav/rtp.h
@@ -1,5 +1,5 @@
1/** toxrtp.h 1/** toxrtp.h
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -38,7 +38,7 @@
38 38
39/** 39/**
40 * @brief Standard rtp header 40 * @brief Standard rtp header
41 * 41 *
42 */ 42 */
43 43
44typedef struct _RTPHeader { 44typedef struct _RTPHeader {
@@ -47,7 +47,7 @@ typedef struct _RTPHeader {
47 uint16_t sequnum; /* Sequence Number */ 47 uint16_t sequnum; /* Sequence Number */
48 uint32_t timestamp; /* Timestamp */ 48 uint32_t timestamp; /* Timestamp */
49 uint32_t ssrc; /* SSRC */ 49 uint32_t ssrc; /* SSRC */
50 uint32_t* csrc; /* CSRC's table */ 50 uint32_t *csrc; /* CSRC's table */
51 uint32_t length; /* Length of the header in payload string. */ 51 uint32_t length; /* Length of the header in payload string. */
52 52
53} RTPHeader; 53} RTPHeader;
@@ -55,29 +55,29 @@ typedef struct _RTPHeader {
55 55
56/** 56/**
57 * @brief Standard rtp extension header. 57 * @brief Standard rtp extension header.
58 * 58 *
59 */ 59 */
60typedef struct _RTPExtHeader { 60typedef struct _RTPExtHeader {
61 uint16_t type; /* Extension profile */ 61 uint16_t type; /* Extension profile */
62 uint16_t length; /* Number of extensions */ 62 uint16_t length; /* Number of extensions */
63 uint32_t* table; /* Extension's table */ 63 uint32_t *table; /* Extension's table */
64 64
65} RTPExtHeader; 65} RTPExtHeader;
66 66
67 67
68/** 68/**
69 * @brief Standard rtp message. 69 * @brief Standard rtp message.
70 * 70 *
71 */ 71 */
72typedef struct _RTPMessage { 72typedef struct _RTPMessage {
73 RTPHeader* header; 73 RTPHeader *header;
74 RTPExtHeader* ext_header; 74 RTPExtHeader *ext_header;
75 75
76 uint8_t data[MAX_RTP_SIZE]; 76 uint8_t data[MAX_RTP_SIZE];
77 uint32_t length; 77 uint32_t length;
78 IP_Port from; 78 IP_Port from;
79 79
80 struct _RTPMessage* next; 80 struct _RTPMessage *next;
81} RTPMessage; 81} RTPMessage;
82 82
83 83
@@ -87,7 +87,7 @@ typedef struct _RTPMessage {
87 * the entire session. There are functions for manipulating 87 * the entire session. There are functions for manipulating
88 * the session so tend to use those instead of directly modifying 88 * the session so tend to use those instead of directly modifying
89 * session parameters. 89 * session parameters.
90 * 90 *
91 */ 91 */
92typedef struct _RTPSession { 92typedef struct _RTPSession {
93 uint8_t version; 93 uint8_t version;
@@ -100,14 +100,14 @@ typedef struct _RTPSession {
100 uint16_t rsequnum; /* Check when recving msg */ 100 uint16_t rsequnum; /* Check when recving msg */
101 uint32_t timestamp; 101 uint32_t timestamp;
102 uint32_t ssrc; 102 uint32_t ssrc;
103 uint32_t* csrc; 103 uint32_t *csrc;
104 104
105 /* If some additional data must be sent via message 105 /* If some additional data must be sent via message
106 * apply it here. Only by allocating this member you will be 106 * apply it here. Only by allocating this member you will be
107 * automatically placing it within a message. 107 * automatically placing it within a message.
108 */ 108 */
109 RTPExtHeader* ext_header; 109 RTPExtHeader *ext_header;
110 110
111 /* External header identifiers */ 111 /* External header identifiers */
112 int resolution; 112 int resolution;
113 int framerate; 113 int framerate;
@@ -117,15 +117,15 @@ typedef struct _RTPSession {
117 * call structure don't allocate or free 117 * call structure don't allocate or free
118 */ 118 */
119 119
120 const uint8_t* encrypt_key; 120 const uint8_t *encrypt_key;
121 const uint8_t* decrypt_key; 121 const uint8_t *decrypt_key;
122 uint8_t* encrypt_nonce; 122 uint8_t *encrypt_nonce;
123 uint8_t* decrypt_nonce; 123 uint8_t *decrypt_nonce;
124 124
125 uint8_t* nonce_cycle; 125 uint8_t *nonce_cycle;
126 126
127 RTPMessage* oldest_msg; 127 RTPMessage *oldest_msg;
128 RTPMessage* last_msg; /* tail */ 128 RTPMessage *last_msg; /* tail */
129 129
130 /* Msg prefix for core to know when recving */ 130 /* Msg prefix for core to know when recving */
131 uint8_t prefix; 131 uint8_t prefix;
@@ -138,28 +138,28 @@ typedef struct _RTPSession {
138 138
139/** 139/**
140 * @brief Release all messages held by session. 140 * @brief Release all messages held by session.
141 * 141 *
142 * @param session The session. 142 * @param session The session.
143 * @return int 143 * @return int
144 * @retval -1 Error occurred. 144 * @retval -1 Error occurred.
145 * @retval 0 Success. 145 * @retval 0 Success.
146 */ 146 */
147int rtp_release_session_recv ( RTPSession* session ); 147int rtp_release_session_recv ( RTPSession *session );
148 148
149 149
150/** 150/**
151 * @brief Get's oldest message in the list. 151 * @brief Get's oldest message in the list.
152 * 152 *
153 * @param session Where the list is. 153 * @param session Where the list is.
154 * @return RTPMessage* The message. You need to call rtp_msg_free() to free it. 154 * @return RTPMessage* The message. You need to call rtp_msg_free() to free it.
155 * @retval NULL No messages in the list, or no list. 155 * @retval NULL No messages in the list, or no list.
156 */ 156 */
157RTPMessage* rtp_recv_msg ( RTPSession* session ); 157RTPMessage *rtp_recv_msg ( RTPSession *session );
158 158
159 159
160/** 160/**
161 * @brief Sends msg to _RTPSession::dest 161 * @brief Sends msg to _RTPSession::dest
162 * 162 *
163 * @param session The session. 163 * @param session The session.
164 * @param msg The message 164 * @param msg The message
165 * @param messenger Tox* object. 165 * @param messenger Tox* object.
@@ -167,23 +167,23 @@ RTPMessage* rtp_recv_msg ( RTPSession* session );
167 * @retval -1 On error. 167 * @retval -1 On error.
168 * @retval 0 On success. 168 * @retval 0 On success.
169 */ 169 */
170int rtp_send_msg ( RTPSession* session, Messenger* messenger, const uint8_t* data, uint16_t length ); 170int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *data, uint16_t length );
171 171
172 172
173/** 173/**
174 * @brief Speaks for it self. 174 * @brief Speaks for it self.
175 * 175 *
176 * @param session The control session msg belongs to. It can be NULL. 176 * @param session The control session msg belongs to. It can be NULL.
177 * @param msg The message. 177 * @param msg The message.
178 * @return void 178 * @return void
179 */ 179 */
180void rtp_free_msg ( RTPSession* session, RTPMessage* msg ); 180void rtp_free_msg ( RTPSession *session, RTPMessage *msg );
181 181
182 182
183/** 183/**
184 * @brief Must be called before calling any other rtp function. It's used 184 * @brief Must be called before calling any other rtp function. It's used
185 * to initialize RTP control session. 185 * to initialize RTP control session.
186 * 186 *
187 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType 187 * @param payload_type Type of payload used to send. You can use values in toxmsi.h::MSICallType
188 * @param messenger Tox* object. 188 * @param messenger Tox* object.
189 * @param friend_num Friend id. 189 * @param friend_num Friend id.
@@ -194,25 +194,25 @@ void rtp_free_msg ( RTPSession* session, RTPMessage* msg );
194 * @return RTPSession* Created control session. 194 * @return RTPSession* Created control session.
195 * @retval NULL Error occurred. 195 * @retval NULL Error occurred.
196 */ 196 */
197RTPSession* rtp_init_session ( int payload_type, 197RTPSession *rtp_init_session ( int payload_type,
198 Messenger* messenger, 198 Messenger *messenger,
199 int friend_num, 199 int friend_num,
200 const uint8_t* encrypt_key, 200 const uint8_t *encrypt_key,
201 const uint8_t* decrypt_key, 201 const uint8_t *decrypt_key,
202 const uint8_t* encrypt_nonce, 202 const uint8_t *encrypt_nonce,
203 const uint8_t* decrypt_nonce ); 203 const uint8_t *decrypt_nonce );
204 204
205 205
206/** 206/**
207 * @brief Terminate the session. 207 * @brief Terminate the session.
208 * 208 *
209 * @param session The session. 209 * @param session The session.
210 * @param messenger The messenger who owns the session 210 * @param messenger The messenger who owns the session
211 * @return int 211 * @return int
212 * @retval -1 Error occurred. 212 * @retval -1 Error occurred.
213 * @retval 0 Success. 213 * @retval 0 Success.
214 */ 214 */
215int rtp_terminate_session ( RTPSession* session, Messenger* messenger ); 215int rtp_terminate_session ( RTPSession *session, Messenger *messenger );
216 216
217 217
218 218
diff --git a/toxav/toxav.c b/toxav/toxav.c
index b40a1c02..f704bc6b 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -1,5 +1,5 @@
1/** toxav.c 1/** toxav.c
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -44,27 +44,26 @@ typedef enum {
44 ts_closing, 44 ts_closing,
45 ts_running, 45 ts_running,
46 ts_closed 46 ts_closed
47 47
48} ThreadState; 48} ThreadState;
49 49
50typedef struct _ToxAv 50typedef struct _ToxAv {
51{ 51 Messenger *messenger;
52 Messenger* messenger; 52
53 53 MSISession *msi_session; /** Main msi session */
54 MSISession* msi_session; /** Main msi session */ 54
55 55 RTPSession *rtp_sessions[2]; /* Audio is first and video is second */
56 RTPSession* rtp_sessions[2]; /* Audio is first and video is second */ 56
57 57 struct jitter_buffer *j_buf;
58 struct jitter_buffer* j_buf; 58 CodecState *cs;
59 CodecState* cs; 59
60 60 void *agent_handler;
61 void* agent_handler;
62} ToxAv; 61} ToxAv;
63 62
64/** 63/**
65 * @brief Start new A/V session. There can only be one session at the time. If you register more 64 * @brief Start new A/V session. There can only be one session at the time. If you register more
66 * it will result in undefined behaviour. 65 * it will result in undefined behaviour.
67 * 66 *
68 * @param messenger The messenger handle. 67 * @param messenger The messenger handle.
69 * @param useragent The agent handling A/V session (i.e. phone). 68 * @param useragent The agent handling A/V session (i.e. phone).
70 * @param ua_name Useragent name. 69 * @param ua_name Useragent name.
@@ -73,67 +72,69 @@ typedef struct _ToxAv
73 * @return ToxAv* 72 * @return ToxAv*
74 * @retval NULL On error. 73 * @retval NULL On error.
75 */ 74 */
76ToxAv* toxav_new( Tox* messenger, void* useragent, const char* ua_name , uint16_t video_width, uint16_t video_height) 75ToxAv *toxav_new( Tox *messenger, void *useragent, const char *ua_name , uint16_t video_width, uint16_t video_height)
77{ 76{
78 ToxAv* av = calloc ( sizeof(ToxAv), 1); 77 ToxAv *av = calloc ( sizeof(ToxAv), 1);
78
79 if (av == NULL) 79 if (av == NULL)
80 return NULL; 80 return NULL;
81 81
82 av->messenger = (Messenger *)messenger; 82 av->messenger = (Messenger *)messenger;
83 83
84 av->msi_session = msi_init_session(av->messenger, (const unsigned char*) ua_name ); 84 av->msi_session = msi_init_session(av->messenger, (const unsigned char *) ua_name );
85 av->msi_session->agent_handler = av; 85 av->msi_session->agent_handler = av;
86 86
87 av->rtp_sessions[0] = av->rtp_sessions [1] = NULL; 87 av->rtp_sessions[0] = av->rtp_sessions [1] = NULL;
88 88
89 /* NOTE: This should be user defined or? */ 89 /* NOTE: This should be user defined or? */
90 av->j_buf = create_queue(20); 90 av->j_buf = create_queue(20);
91 91
92 av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width, video_height, VIDEO_BITRATE); 92 av->cs = codec_init_session(AUDIO_BITRATE, AUDIO_FRAME_DURATION, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, video_width,
93 93 video_height, VIDEO_BITRATE);
94
94 av->agent_handler = useragent; 95 av->agent_handler = useragent;
95 96
96 return av; 97 return av;
97} 98}
98 99
99/** 100/**
100 * @brief Remove A/V session. 101 * @brief Remove A/V session.
101 * 102 *
102 * @param av Handler. 103 * @param av Handler.
103 * @return void 104 * @return void
104 */ 105 */
105void toxav_kill ( ToxAv* av ) 106void toxav_kill ( ToxAv *av )
106{ 107{
107 msi_terminate_session(av->msi_session); 108 msi_terminate_session(av->msi_session);
108 109
109 if ( av->rtp_sessions[audio_index] ) { 110 if ( av->rtp_sessions[audio_index] ) {
110 rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle); 111 rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle);
111 } 112 }
112 113
113 if ( av->rtp_sessions[video_index] ) { 114 if ( av->rtp_sessions[video_index] ) {
114 rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle); 115 rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle);
115 } 116 }
116 117
117 codec_terminate_session(av->cs); 118 codec_terminate_session(av->cs);
118 119
119 free(av); 120 free(av);
120} 121}
121 122
122/** 123/**
123 * @brief Register callback for call state. 124 * @brief Register callback for call state.
124 * 125 *
125 * @param callback The callback 126 * @param callback The callback
126 * @param id One of the ToxAvCallbackID values 127 * @param id One of the ToxAvCallbackID values
127 * @return void 128 * @return void
128 */ 129 */
129void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id ) 130void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id )
130{ 131{
131 msi_register_callback((MSICallback)callback, (MSICallbackID) id); 132 msi_register_callback((MSICallback)callback, (MSICallbackID) id);
132} 133}
133 134
134/** 135/**
135 * @brief Call user. Use its friend_id. 136 * @brief Call user. Use its friend_id.
136 * 137 *
137 * @param av Handler. 138 * @param av Handler.
138 * @param user The user. 139 * @param user The user.
139 * @param call_type Call type. 140 * @param call_type Call type.
@@ -142,68 +143,68 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID
142 * @retval 0 Success. 143 * @retval 0 Success.
143 * @retval ToxAvError On error. 144 * @retval ToxAvError On error.
144 */ 145 */
145int toxav_call (ToxAv* av, int user, ToxAvCallType call_type, int ringing_seconds ) 146int toxav_call (ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds )
146{ 147{
147 if ( av->msi_session->call ) { 148 if ( av->msi_session->call ) {
148 return ErrorAlreadyInCall; 149 return ErrorAlreadyInCall;
149 } 150 }
150 151
151 return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user); 152 return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user);
152} 153}
153 154
154/** 155/**
155 * @brief Hangup active call. 156 * @brief Hangup active call.
156 * 157 *
157 * @param av Handler. 158 * @param av Handler.
158 * @return int 159 * @return int
159 * @retval 0 Success. 160 * @retval 0 Success.
160 * @retval ToxAvError On error. 161 * @retval ToxAvError On error.
161 */ 162 */
162int toxav_hangup ( ToxAv* av ) 163int toxav_hangup ( ToxAv *av )
163{ 164{
164 if ( !av->msi_session->call ) { 165 if ( !av->msi_session->call ) {
165 return ErrorNoCall; 166 return ErrorNoCall;
166 } 167 }
167 168
168 if ( av->msi_session->call->state != call_active ) { 169 if ( av->msi_session->call->state != call_active ) {
169 return ErrorInvalidState; 170 return ErrorInvalidState;
170 } 171 }
171 172
172 return msi_hangup(av->msi_session); 173 return msi_hangup(av->msi_session);
173} 174}
174 175
175/** 176/**
176 * @brief Answer incomming call. 177 * @brief Answer incomming call.
177 * 178 *
178 * @param av Handler. 179 * @param av Handler.
179 * @param call_type Answer with... 180 * @param call_type Answer with...
180 * @return int 181 * @return int
181 * @retval 0 Success. 182 * @retval 0 Success.
182 * @retval ToxAvError On error. 183 * @retval ToxAvError On error.
183 */ 184 */
184int toxav_answer ( ToxAv* av, ToxAvCallType call_type ) 185int toxav_answer ( ToxAv *av, ToxAvCallType call_type )
185{ 186{
186 if ( !av->msi_session->call ) { 187 if ( !av->msi_session->call ) {
187 return ErrorNoCall; 188 return ErrorNoCall;
188 } 189 }
189 190
190 if ( av->msi_session->call->state != call_starting ) { 191 if ( av->msi_session->call->state != call_starting ) {
191 return ErrorInvalidState; 192 return ErrorInvalidState;
192 } 193 }
193 194
194 return msi_answer(av->msi_session, call_type); 195 return msi_answer(av->msi_session, call_type);
195} 196}
196 197
197/** 198/**
198 * @brief Reject incomming call. 199 * @brief Reject incomming call.
199 * 200 *
200 * @param av Handler. 201 * @param av Handler.
201 * @param reason Optional reason. Set NULL if none. 202 * @param reason Optional reason. Set NULL if none.
202 * @return int 203 * @return int
203 * @retval 0 Success. 204 * @retval 0 Success.
204 * @retval ToxAvError On error. 205 * @retval ToxAvError On error.
205 */ 206 */
206int toxav_reject ( ToxAv* av, const char* reason ) 207int toxav_reject ( ToxAv *av, const char *reason )
207{ 208{
208 if ( !av->msi_session->call ) { 209 if ( !av->msi_session->call ) {
209 return ErrorNoCall; 210 return ErrorNoCall;
@@ -213,126 +214,127 @@ int toxav_reject ( ToxAv* av, const char* reason )
213 return ErrorInvalidState; 214 return ErrorInvalidState;
214 } 215 }
215 216
216 return msi_reject(av->msi_session, (const uint8_t*) reason); 217 return msi_reject(av->msi_session, (const uint8_t *) reason);
217} 218}
218 219
219/** 220/**
220 * @brief Cancel outgoing request. 221 * @brief Cancel outgoing request.
221 * 222 *
222 * @param av Handler. 223 * @param av Handler.
223 * @param reason Optional reason. 224 * @param reason Optional reason.
224 * @return int 225 * @return int
225 * @retval 0 Success. 226 * @retval 0 Success.
226 * @retval ToxAvError On error. 227 * @retval ToxAvError On error.
227 */ 228 */
228int toxav_cancel ( ToxAv* av, const char* reason ) 229int toxav_cancel ( ToxAv *av, const char *reason )
229{ 230{
230 if ( !av->msi_session->call ) { 231 if ( !av->msi_session->call ) {
231 return ErrorNoCall; 232 return ErrorNoCall;
232 } 233 }
233 234
234 return msi_cancel(av->msi_session, 0, (const uint8_t*)reason); 235 return msi_cancel(av->msi_session, 0, (const uint8_t *)reason);
235} 236}
236 237
237/** 238/**
238 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. 239 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
239 * 240 *
240 * @param av Handler. 241 * @param av Handler.
241 * @return int 242 * @return int
242 * @retval 0 Success. 243 * @retval 0 Success.
243 * @retval ToxAvError On error. 244 * @retval ToxAvError On error.
244 */ 245 */
245int toxav_stop_call ( ToxAv* av ) 246int toxav_stop_call ( ToxAv *av )
246{ 247{
247 if ( !av->msi_session->call ) { 248 if ( !av->msi_session->call ) {
248 return ErrorNoCall; 249 return ErrorNoCall;
249 } 250 }
250 251
251 return msi_stopcall(av->msi_session); 252 return msi_stopcall(av->msi_session);
252} 253}
253 254
254/** 255/**
255 * @brief Must be call before any RTP transmission occurs. 256 * @brief Must be call before any RTP transmission occurs.
256 * 257 *
257 * @param av Handler. 258 * @param av Handler.
258 * @return int 259 * @return int
259 * @retval 0 Success. 260 * @retval 0 Success.
260 * @retval ToxAvError On error. 261 * @retval ToxAvError On error.
261 */ 262 */
262int toxav_prepare_transmission ( ToxAv* av ) 263int toxav_prepare_transmission ( ToxAv *av )
263{ 264{
264 assert(av->msi_session); 265 assert(av->msi_session);
266
265 if ( !av->msi_session || !av->msi_session->call ) { 267 if ( !av->msi_session || !av->msi_session->call ) {
266 return ErrorNoCall; 268 return ErrorNoCall;
267 } 269 }
268 270
269 av->rtp_sessions[audio_index] = rtp_init_session( 271 av->rtp_sessions[audio_index] = rtp_init_session(
270 type_audio, 272 type_audio,
271 av->messenger, 273 av->messenger,
272 av->msi_session->call->peers[0], 274 av->msi_session->call->peers[0],
273 av->msi_session->call->key_peer, 275 av->msi_session->call->key_peer,
274 av->msi_session->call->key_local, 276 av->msi_session->call->key_local,
275 av->msi_session->call->nonce_peer, 277 av->msi_session->call->nonce_peer,
276 av->msi_session->call->nonce_local 278 av->msi_session->call->nonce_local
277 ); 279 );
278 280
279 281
280 if ( !av->rtp_sessions[audio_index] ) { 282 if ( !av->rtp_sessions[audio_index] ) {
281 fprintf(stderr, "Error while starting audio RTP session!\n"); 283 fprintf(stderr, "Error while starting audio RTP session!\n");
282 return ErrorStartingAudioRtp; 284 return ErrorStartingAudioRtp;
283 } 285 }
284 286
285 av->rtp_sessions[video_index] = rtp_init_session ( 287 av->rtp_sessions[video_index] = rtp_init_session (
286 type_video, 288 type_video,
287 av->messenger, 289 av->messenger,
288 av->msi_session->call->peers[0], 290 av->msi_session->call->peers[0],
289 av->msi_session->call->key_peer, 291 av->msi_session->call->key_peer,
290 av->msi_session->call->key_local, 292 av->msi_session->call->key_local,
291 av->msi_session->call->nonce_peer, 293 av->msi_session->call->nonce_peer,
292 av->msi_session->call->nonce_local 294 av->msi_session->call->nonce_local
293 ); 295 );
294 296
295 297
296 if ( !av->rtp_sessions[video_index] ) { 298 if ( !av->rtp_sessions[video_index] ) {
297 fprintf(stderr, "Error while starting video RTP session!\n"); 299 fprintf(stderr, "Error while starting video RTP session!\n");
298 return ErrorStartingVideoRtp; 300 return ErrorStartingVideoRtp;
299 } 301 }
300 302
301 return ErrorNone; 303 return ErrorNone;
302} 304}
303 305
304/** 306/**
305 * @brief Call this at the end of the transmission. 307 * @brief Call this at the end of the transmission.
306 * 308 *
307 * @param av Handler. 309 * @param av Handler.
308 * @return int 310 * @return int
309 * @retval 0 Success. 311 * @retval 0 Success.
310 * @retval ToxAvError On error. 312 * @retval ToxAvError On error.
311 */ 313 */
312int toxav_kill_transmission ( ToxAv* av ) 314int toxav_kill_transmission ( ToxAv *av )
313{ 315{
314 /* Both sessions should be active at any time */ 316 /* Both sessions should be active at any time */
315 if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] ) 317 if ( !av->rtp_sessions[0] || !av->rtp_sessions[0] )
316 return ErrorNoTransmission; 318 return ErrorNoTransmission;
317 319
318 320
319 if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) { 321 if ( -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
320 fprintf(stderr, "Error while terminating audio RTP session!\n"); 322 fprintf(stderr, "Error while terminating audio RTP session!\n");
321 return ErrorTerminatingAudioRtp; 323 return ErrorTerminatingAudioRtp;
322 } 324 }
323 325
324 if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) { 326 if ( -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) {
325 fprintf(stderr, "Error while terminating video RTP session!\n"); 327 fprintf(stderr, "Error while terminating video RTP session!\n");
326 return ErrorTerminatingVideoRtp; 328 return ErrorTerminatingVideoRtp;
327 } 329 }
328 330
329 return ErrorNone; 331 return ErrorNone;
330} 332}
331 333
332 334
333/** 335/**
334 * @brief Send RTP payload. 336 * @brief Send RTP payload.
335 * 337 *
336 * @param av Handler. 338 * @param av Handler.
337 * @param type Type of payload. 339 * @param type Type of payload.
338 * @param payload The payload. 340 * @param payload The payload.
@@ -341,7 +343,7 @@ int toxav_kill_transmission ( ToxAv* av )
341 * @retval 0 Success. 343 * @retval 0 Success.
342 * @retval -1 Failure. 344 * @retval -1 Failure.
343 */ 345 */
344inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8_t* payload, uint16_t length ) 346inline__ int toxav_send_rtp_payload ( ToxAv *av, ToxAvCallType type, const uint8_t *payload, uint16_t length )
345{ 347{
346 if ( av->rtp_sessions[type - TypeAudio] ) 348 if ( av->rtp_sessions[type - TypeAudio] )
347 return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length ); 349 return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length );
@@ -350,7 +352,7 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8
350 352
351/** 353/**
352 * @brief Receive RTP payload. 354 * @brief Receive RTP payload.
353 * 355 *
354 * @param av Handler. 356 * @param av Handler.
355 * @param type Type of the payload. 357 * @param type Type of the payload.
356 * @param dest Storage. 358 * @param dest Storage.
@@ -358,123 +360,131 @@ inline__ int toxav_send_rtp_payload ( ToxAv* av, ToxAvCallType type, const uint8
358 * @retval ToxAvError On Error. 360 * @retval ToxAvError On Error.
359 * @retval >=0 Size of received payload. 361 * @retval >=0 Size of received payload.
360 */ 362 */
361inline__ int toxav_recv_rtp_payload ( ToxAv* av, ToxAvCallType type, uint8_t* dest ) 363inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *dest )
362{ 364{
363 if ( !dest ) return ErrorInternal; 365 if ( !dest ) return ErrorInternal;
364 366
365 if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession; 367 if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession;
366 368
367 RTPMessage* message; 369 RTPMessage *message;
368 370
369 if ( type == TypeAudio ) { 371 if ( type == TypeAudio ) {
370 372
371 do { 373 do {
372 message = rtp_recv_msg(av->rtp_sessions[audio_index]); 374 message = rtp_recv_msg(av->rtp_sessions[audio_index]);
373 375
374 if (message) { 376 if (message) {
375 /* push the packet into the queue */ 377 /* push the packet into the queue */
376 queue(av->j_buf, message); 378 queue(av->j_buf, message);
377 } 379 }
378 } while(message); 380 } while (message);
379 381
380 int success = 0; 382 int success = 0;
381 message = dequeue(av->j_buf, &success); 383 message = dequeue(av->j_buf, &success);
382 384
383 if ( success == 2) return ErrorAudioPacketLost; 385 if ( success == 2) return ErrorAudioPacketLost;
384 } 386 } else {
385 else {
386 message = rtp_recv_msg(av->rtp_sessions[video_index]); 387 message = rtp_recv_msg(av->rtp_sessions[video_index]);
387 } 388 }
388 389
389 if ( message ) { 390 if ( message ) {
390 memcpy(dest, message->data, message->length); 391 memcpy(dest, message->data, message->length);
391 392
392 int length = message->length; 393 int length = message->length;
393 394
394 rtp_free_msg(NULL, message); 395 rtp_free_msg(NULL, message);
395 396
396 return length; 397 return length;
397 } 398 }
398 399
399 return 0; 400 return 0;
400} 401}
401 402
402/** 403/**
403 * @brief Receive decoded video packet. 404 * @brief Receive decoded video packet.
404 * 405 *
405 * @param av Handler. 406 * @param av Handler.
406 * @param output Storage. 407 * @param output Storage.
407 * @return int 408 * @return int
408 * @retval 0 Success. 409 * @retval 0 Success.
409 * @retval ToxAvError On Error. 410 * @retval ToxAvError On Error.
410 */ 411 */
411inline__ int toxav_recv_video ( ToxAv* av, vpx_image_t **output) 412inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
412{ 413{
413 if ( !output ) return ErrorInternal; 414 if ( !output ) return ErrorInternal;
415
414 uint8_t packet [RTP_PAYLOAD_SIZE]; 416 uint8_t packet [RTP_PAYLOAD_SIZE];
415 int recved_size = 0; 417 int recved_size = 0;
418
416 do { 419 do {
417 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet); 420 recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet);
421
418 if (recved_size > 0) { 422 if (recved_size > 0) {
419 printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0))); 423 printf("decode: %s\n", vpx_codec_err_to_string(vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0)));
420 } 424 }
421 }while (recved_size > 0); 425 } while (recved_size > 0);
426
422 vpx_codec_iter_t iter = NULL; 427 vpx_codec_iter_t iter = NULL;
423 vpx_image_t *img; 428 vpx_image_t *img;
424 img = vpx_codec_get_frame(&av->cs->v_decoder, &iter); 429 img = vpx_codec_get_frame(&av->cs->v_decoder, &iter);
430
425 if (img == NULL) 431 if (img == NULL)
426 return ErrorInternal; 432 return ErrorInternal;
427 433
428 *output = img; 434 *output = img;
429 return 0; 435 return 0;
430} 436}
431 437
432/** 438/**
433 * @brief Encode and send video packet. 439 * @brief Encode and send video packet.
434 * 440 *
435 * @param av Handler. 441 * @param av Handler.
436 * @param input The packet. 442 * @param input The packet.
437 * @return int 443 * @return int
438 * @retval 0 Success. 444 * @retval 0 Success.
439 * @retval ToxAvError On error. 445 * @retval ToxAvError On error.
440 */ 446 */
441inline__ int toxav_send_video ( ToxAv* av, vpx_image_t *input) 447inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
442{ 448{
443 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) { 449 if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) {
444 printf("could not encode video frame\n"); 450 printf("could not encode video frame\n");
445 return ErrorInternal; 451 return ErrorInternal;
446 } 452 }
453
447 ++av->cs->frame_counter; 454 ++av->cs->frame_counter;
448 455
449 vpx_codec_iter_t iter = NULL; 456 vpx_codec_iter_t iter = NULL;
450 const vpx_codec_cx_pkt_t *pkt; 457 const vpx_codec_cx_pkt_t *pkt;
451 int sent = 0; 458 int sent = 0;
452 while( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) { 459
460 while ( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) {
453 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { 461 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
454 if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1) 462 if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1)
455 ++sent; 463 ++sent;
456 } 464 }
457 } 465 }
466
458 if (sent > 0) 467 if (sent > 0)
459 return 0; 468 return 0;
460 469
461 return ErrorInternal; 470 return ErrorInternal;
462} 471}
463 472
464/** 473/**
465 * @brief Receive decoded audio frame. 474 * @brief Receive decoded audio frame.
466 * 475 *
467 * @param av Handler. 476 * @param av Handler.
468 * @param frame_size ... 477 * @param frame_size ...
469 * @param dest Destination of the packet. Make sure it has enough space for 478 * @param dest Destination of the packet. Make sure it has enough space for
470 * RTP_PAYLOAD_SIZE bytes. 479 * RTP_PAYLOAD_SIZE bytes.
471 * @return int 480 * @return int
472 * @retval >=0 Size of received packet. 481 * @retval >=0 Size of received packet.
473 * @retval ToxAvError On error. 482 * @retval ToxAvError On error.
474 */ 483 */
475inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest ) 484inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest )
476{ 485{
477 if ( !dest ) return ErrorInternal; 486 if ( !dest ) return ErrorInternal;
487
478 uint8_t packet [RTP_PAYLOAD_SIZE]; 488 uint8_t packet [RTP_PAYLOAD_SIZE];
479 489
480 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet); 490 int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet);
@@ -482,7 +492,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
482 if ( recved_size == ErrorAudioPacketLost ) { 492 if ( recved_size == ErrorAudioPacketLost ) {
483 printf("Lost packet\n"); 493 printf("Lost packet\n");
484 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1); 494 return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
485 } else if ( recved_size ){ 495 } else if ( recved_size ) {
486 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); 496 return opus_decode(av->cs->audio_decoder, packet, recved_size, dest, frame_size, 0);
487 } else { 497 } else {
488 return 0; /* Nothing received */ 498 return 0; /* Nothing received */
@@ -491,7 +501,7 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
491 501
492/** 502/**
493 * @brief Encode and send audio frame. 503 * @brief Encode and send audio frame.
494 * 504 *
495 * @param av Handler. 505 * @param av Handler.
496 * @param frame The frame. 506 * @param frame The frame.
497 * @param frame_size It's size. 507 * @param frame_size It's size.
@@ -499,10 +509,11 @@ inline__ int toxav_recv_audio ( ToxAv* av, int frame_size, int16_t* dest )
499 * @retval 0 Success. 509 * @retval 0 Success.
500 * @retval ToxAvError On error. 510 * @retval ToxAvError On error.
501 */ 511 */
502inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size) 512inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size)
503{ 513{
504 uint8_t temp_data[RTP_PAYLOAD_SIZE]; 514 uint8_t temp_data[RTP_PAYLOAD_SIZE];
505 int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data)); 515 int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data));
516
506 if (ret <= 0) 517 if (ret <= 0)
507 return ErrorInternal; 518 return ErrorInternal;
508 519
@@ -511,29 +522,30 @@ inline__ int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size)
511 522
512/** 523/**
513 * @brief Get peer transmission type. It can either be audio or video. 524 * @brief Get peer transmission type. It can either be audio or video.
514 * 525 *
515 * @param av Handler. 526 * @param av Handler.
516 * @param peer The peer 527 * @param peer The peer
517 * @return int 528 * @return int
518 * @retval ToxAvCallType On success. 529 * @retval ToxAvCallType On success.
519 * @retval ToxAvError On error. 530 * @retval ToxAvError On error.
520 */ 531 */
521int toxav_get_peer_transmission_type ( ToxAv* av, int peer ) 532int toxav_get_peer_transmission_type ( ToxAv *av, int peer )
522{ 533{
523 assert(av->msi_session); 534 assert(av->msi_session);
535
524 if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer ) 536 if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer )
525 return ErrorInternal; 537 return ErrorInternal;
526 538
527 return av->msi_session->call->type_peer[peer]; 539 return av->msi_session->call->type_peer[peer];
528} 540}
529 541
530/** 542/**
531 * @brief Get reference to an object that is handling av session. 543 * @brief Get reference to an object that is handling av session.
532 * 544 *
533 * @param av Handler. 545 * @param av Handler.
534 * @return void* 546 * @return void*
535 */ 547 */
536void* toxav_get_agent_handler ( ToxAv* av ) 548void *toxav_get_agent_handler ( ToxAv *av )
537{ 549{
538 return av->agent_handler; 550 return av->agent_handler;
539} 551}
diff --git a/toxav/toxav.h b/toxav/toxav.h
index 82334273..be7a2950 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -1,5 +1,5 @@
1/** toxav.h 1/** toxav.h
2 * 2 *
3 * Copyright (C) 2013 Tox project All Rights Reserved. 3 * Copyright (C) 2013 Tox project All Rights Reserved.
4 * 4 *
5 * This file is part of Tox. 5 * This file is part of Tox.
@@ -17,7 +17,7 @@
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 * 19 *
20 * 20 *
21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667 21 * Report bugs/suggestions at #tox-dev @ freenode.net:6667
22 */ 22 */
23 23
@@ -29,7 +29,7 @@
29/* vpx_image_t */ 29/* vpx_image_t */
30#include <vpx/vpx_image.h> 30#include <vpx/vpx_image.h>
31 31
32typedef void* ( *ToxAVCallback ) ( void* arg ); 32typedef void *( *ToxAVCallback ) ( void *arg );
33typedef struct _ToxAv ToxAv; 33typedef struct _ToxAv ToxAv;
34 34
35#ifndef __TOX_DEFINED__ 35#ifndef __TOX_DEFINED__
@@ -61,7 +61,7 @@ typedef struct Tox Tox;
61#define MAX_ENCODE_TIME_US ((1000 / 60) * 1000) 61#define MAX_ENCODE_TIME_US ((1000 / 60) * 1000)
62 62
63 63
64/** 64/**
65 * @brief Callbacks ids that handle the call states. 65 * @brief Callbacks ids that handle the call states.
66 */ 66 */
67typedef enum { 67typedef enum {
@@ -71,16 +71,16 @@ typedef enum {
71 OnCancel, 71 OnCancel,
72 OnReject, 72 OnReject,
73 OnEnd, 73 OnEnd,
74 74
75 /* Responses */ 75 /* Responses */
76 OnRinging, 76 OnRinging,
77 OnStarting, 77 OnStarting,
78 OnEnding, 78 OnEnding,
79 79
80 /* Protocol */ 80 /* Protocol */
81 OnError, 81 OnError,
82 OnRequestTimeout 82 OnRequestTimeout
83 83
84} ToxAvCallbackID; 84} ToxAvCallbackID;
85 85
86 86
@@ -95,7 +95,7 @@ typedef enum {
95 95
96/** 96/**
97 * @brief Error indicators. 97 * @brief Error indicators.
98 * 98 *
99 */ 99 */
100typedef enum { 100typedef enum {
101 ErrorNone = 0, 101 ErrorNone = 0,
@@ -110,14 +110,14 @@ typedef enum {
110 ErrorNoTransmission = -9, /* Returned in toxav_kill_transmission() */ 110 ErrorNoTransmission = -9, /* Returned in toxav_kill_transmission() */
111 ErrorTerminatingAudioRtp = -10, /* Returned in toxav_kill_transmission() */ 111 ErrorTerminatingAudioRtp = -10, /* Returned in toxav_kill_transmission() */
112 ErrorTerminatingVideoRtp = -11, /* Returned in toxav_kill_transmission() */ 112 ErrorTerminatingVideoRtp = -11, /* Returned in toxav_kill_transmission() */
113 113
114} ToxAvError; 114} ToxAvError;
115 115
116 116
117/** 117/**
118 * @brief Start new A/V session. There can only be one session at the time. If you register more 118 * @brief Start new A/V session. There can only be one session at the time. If you register more
119 * it will result in undefined behaviour. 119 * it will result in undefined behaviour.
120 * 120 *
121 * @param messenger The messenger handle. 121 * @param messenger The messenger handle.
122 * @param useragent The agent handling A/V session (i.e. phone). 122 * @param useragent The agent handling A/V session (i.e. phone).
123 * @param ua_name Useragent name. 123 * @param ua_name Useragent name.
@@ -126,19 +126,19 @@ typedef enum {
126 * @return ToxAv* 126 * @return ToxAv*
127 * @retval NULL On error. 127 * @retval NULL On error.
128 */ 128 */
129ToxAv* toxav_new(Tox* messenger, void* useragent, const char* ua_name, uint16_t video_width, uint16_t video_height); 129ToxAv *toxav_new(Tox *messenger, void *useragent, const char *ua_name, uint16_t video_width, uint16_t video_height);
130 130
131/** 131/**
132 * @brief Remove A/V session. 132 * @brief Remove A/V session.
133 * 133 *
134 * @param av Handler. 134 * @param av Handler.
135 * @return void 135 * @return void
136 */ 136 */
137void toxav_kill(ToxAv* av); 137void toxav_kill(ToxAv *av);
138 138
139/** 139/**
140 * @brief Register callback for call state. 140 * @brief Register callback for call state.
141 * 141 *
142 * @param callback The callback 142 * @param callback The callback
143 * @param id One of the ToxAvCallbackID values 143 * @param id One of the ToxAvCallbackID values
144 * @return void 144 * @return void
@@ -147,7 +147,7 @@ void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID
147 147
148/** 148/**
149 * @brief Call user. Use its friend_id. 149 * @brief Call user. Use its friend_id.
150 * 150 *
151 * @param av Handler. 151 * @param av Handler.
152 * @param user The user. 152 * @param user The user.
153 * @param call_type Call type. 153 * @param call_type Call type.
@@ -156,119 +156,119 @@ void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID
156 * @retval 0 Success. 156 * @retval 0 Success.
157 * @retval ToxAvError On error. 157 * @retval ToxAvError On error.
158 */ 158 */
159int toxav_call(ToxAv* av, int user, ToxAvCallType call_type, int ringing_seconds); 159int toxav_call(ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds);
160 160
161/** 161/**
162 * @brief Hangup active call. 162 * @brief Hangup active call.
163 * 163 *
164 * @param av Handler. 164 * @param av Handler.
165 * @return int 165 * @return int
166 * @retval 0 Success. 166 * @retval 0 Success.
167 * @retval ToxAvError On error. 167 * @retval ToxAvError On error.
168 */ 168 */
169int toxav_hangup(ToxAv* av); 169int toxav_hangup(ToxAv *av);
170 170
171/** 171/**
172 * @brief Answer incomming call. 172 * @brief Answer incomming call.
173 * 173 *
174 * @param av Handler. 174 * @param av Handler.
175 * @param call_type Answer with... 175 * @param call_type Answer with...
176 * @return int 176 * @return int
177 * @retval 0 Success. 177 * @retval 0 Success.
178 * @retval ToxAvError On error. 178 * @retval ToxAvError On error.
179 */ 179 */
180int toxav_answer(ToxAv* av, ToxAvCallType call_type ); 180int toxav_answer(ToxAv *av, ToxAvCallType call_type );
181 181
182/** 182/**
183 * @brief Reject incomming call. 183 * @brief Reject incomming call.
184 * 184 *
185 * @param av Handler. 185 * @param av Handler.
186 * @param reason Optional reason. Set NULL if none. 186 * @param reason Optional reason. Set NULL if none.
187 * @return int 187 * @return int
188 * @retval 0 Success. 188 * @retval 0 Success.
189 * @retval ToxAvError On error. 189 * @retval ToxAvError On error.
190 */ 190 */
191int toxav_reject(ToxAv* av, const char* reason); 191int toxav_reject(ToxAv *av, const char *reason);
192 192
193/** 193/**
194 * @brief Cancel outgoing request. 194 * @brief Cancel outgoing request.
195 * 195 *
196 * @param av Handler. 196 * @param av Handler.
197 * @param reason Optional reason. 197 * @param reason Optional reason.
198 * @return int 198 * @return int
199 * @retval 0 Success. 199 * @retval 0 Success.
200 * @retval ToxAvError On error. 200 * @retval ToxAvError On error.
201 */ 201 */
202int toxav_cancel(ToxAv* av, const char* reason); 202int toxav_cancel(ToxAv *av, const char *reason);
203 203
204/** 204/**
205 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. 205 * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
206 * 206 *
207 * @param av Handler. 207 * @param av Handler.
208 * @return int 208 * @return int
209 * @retval 0 Success. 209 * @retval 0 Success.
210 * @retval ToxAvError On error. 210 * @retval ToxAvError On error.
211 */ 211 */
212int toxav_stop_call(ToxAv* av); 212int toxav_stop_call(ToxAv *av);
213 213
214/** 214/**
215 * @brief Must be call before any RTP transmission occurs. 215 * @brief Must be call before any RTP transmission occurs.
216 * 216 *
217 * @param av Handler. 217 * @param av Handler.
218 * @return int 218 * @return int
219 * @retval 0 Success. 219 * @retval 0 Success.
220 * @retval ToxAvError On error. 220 * @retval ToxAvError On error.
221 */ 221 */
222int toxav_prepare_transmission(ToxAv* av); 222int toxav_prepare_transmission(ToxAv *av);
223 223
224/** 224/**
225 * @brief Call this at the end of the transmission. 225 * @brief Call this at the end of the transmission.
226 * 226 *
227 * @param av Handler. 227 * @param av Handler.
228 * @return int 228 * @return int
229 * @retval 0 Success. 229 * @retval 0 Success.
230 * @retval ToxAvError On error. 230 * @retval ToxAvError On error.
231 */ 231 */
232int toxav_kill_transmission(ToxAv* av); 232int toxav_kill_transmission(ToxAv *av);
233 233
234/** 234/**
235 * @brief Receive decoded video packet. 235 * @brief Receive decoded video packet.
236 * 236 *
237 * @param av Handler. 237 * @param av Handler.
238 * @param output Storage. 238 * @param output Storage.
239 * @return int 239 * @return int
240 * @retval 0 Success. 240 * @retval 0 Success.
241 * @retval ToxAvError On Error. 241 * @retval ToxAvError On Error.
242 */ 242 */
243int toxav_recv_video ( ToxAv* av, vpx_image_t **output); 243int toxav_recv_video ( ToxAv *av, vpx_image_t **output);
244 244
245/** 245/**
246 * @brief Receive decoded audio frame. 246 * @brief Receive decoded audio frame.
247 * 247 *
248 * @param av Handler. 248 * @param av Handler.
249 * @param frame_size ... 249 * @param frame_size ...
250 * @param dest Destination of the packet. Make sure it has enough space for 250 * @param dest Destination of the packet. Make sure it has enough space for
251 * RTP_PAYLOAD_SIZE bytes. 251 * RTP_PAYLOAD_SIZE bytes.
252 * @return int 252 * @return int
253 * @retval >=0 Size of received packet. 253 * @retval >=0 Size of received packet.
254 * @retval ToxAvError On error. 254 * @retval ToxAvError On error.
255 */ 255 */
256int toxav_recv_audio( ToxAv* av, int frame_size, int16_t* dest ); 256int toxav_recv_audio( ToxAv *av, int frame_size, int16_t *dest );
257 257
258/** 258/**
259 * @brief Encode and send video packet. 259 * @brief Encode and send video packet.
260 * 260 *
261 * @param av Handler. 261 * @param av Handler.
262 * @param input The packet. 262 * @param input The packet.
263 * @return int 263 * @return int
264 * @retval 0 Success. 264 * @retval 0 Success.
265 * @retval ToxAvError On error. 265 * @retval ToxAvError On error.
266 */ 266 */
267int toxav_send_video ( ToxAv* av, vpx_image_t *input); 267int toxav_send_video ( ToxAv *av, vpx_image_t *input);
268 268
269/** 269/**
270 * @brief Encode and send audio frame. 270 * @brief Encode and send audio frame.
271 * 271 *
272 * @param av Handler. 272 * @param av Handler.
273 * @param frame The frame. 273 * @param frame The frame.
274 * @param frame_size It's size. 274 * @param frame_size It's size.
@@ -276,25 +276,25 @@ int toxav_send_video ( ToxAv* av, vpx_image_t *input);
276 * @retval 0 Success. 276 * @retval 0 Success.
277 * @retval ToxAvError On error. 277 * @retval ToxAvError On error.
278 */ 278 */
279int toxav_send_audio ( ToxAv* av, const int16_t* frame, int frame_size); 279int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size);
280 280
281/** 281/**
282 * @brief Get peer transmission type. It can either be audio or video. 282 * @brief Get peer transmission type. It can either be audio or video.
283 * 283 *
284 * @param av Handler. 284 * @param av Handler.
285 * @param peer The peer 285 * @param peer The peer
286 * @return int 286 * @return int
287 * @retval ToxAvCallType On success. 287 * @retval ToxAvCallType On success.
288 * @retval ToxAvError On error. 288 * @retval ToxAvError On error.
289 */ 289 */
290int toxav_get_peer_transmission_type ( ToxAv* av, int peer ); 290int toxav_get_peer_transmission_type ( ToxAv *av, int peer );
291 291
292/** 292/**
293 * @brief Get reference to an object that is handling av session. 293 * @brief Get reference to an object that is handling av session.
294 * 294 *
295 * @param av Handler. 295 * @param av Handler.
296 * @return void* 296 * @return void*
297 */ 297 */
298void* toxav_get_agent_handler ( ToxAv* av ); 298void *toxav_get_agent_handler ( ToxAv *av );
299 299
300#endif /* __TOXAV */ \ No newline at end of file 300#endif /* __TOXAV */ \ No newline at end of file