diff options
Diffstat (limited to 'other/apidsl')
-rw-r--r-- | other/apidsl/README.md | 51 | ||||
-rw-r--r-- | other/apidsl/tox.in.h | 2564 | ||||
-rw-r--r-- | other/apidsl/toxav.in.h | 637 |
3 files changed, 0 insertions, 3252 deletions
diff --git a/other/apidsl/README.md b/other/apidsl/README.md deleted file mode 100644 index 00f92c85..00000000 --- a/other/apidsl/README.md +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | This folder contains the input file (``tox.in.h``) that has to be used to generate the ``tox.h`` api with: https://github.com/TokTok/apidsl | ||
2 | |||
3 | # Minimal requirements | ||
4 | |||
5 | There are some minimal requirements to contribute to ``tox.h``: | ||
6 | * unix environment | ||
7 | * ``astyle`` ``>=2.03`` | ||
8 | * [``apidsl``](https://github.com/TokTok/apidsl) (you can use provided service with curl instead) | ||
9 | |||
10 | ## Quick way | ||
11 | |||
12 | If you want to do it quickly and you don't have time for anything other than copypasting commands, you should have ``curl`` installed. | ||
13 | |||
14 | |||
15 | 1. Make sure that you have ``curl`` and ``>=astyle-2.03`` installed | ||
16 | 2. Modify [``tox.in.h``](/other/apidsl/tox.in.h) | ||
17 | 3. Run command below ↓ | ||
18 | |||
19 | Command to run from ``toxcore`` directory (quick way, involves using curl): | ||
20 | ```bash | ||
21 | # For tox.h: | ||
22 | curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ | ||
23 | < other/apidsl/tox.in.h \ | ||
24 | | astyle --options=other/astyle/astylerc \ | ||
25 | > toxcore/tox.h | ||
26 | # For toxav.h: | ||
27 | curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \ | ||
28 | < other/apidsl/toxav.in.h \ | ||
29 | | astyle --options=other/astyle/astylerc \ | ||
30 | > toxav/toxav.h | ||
31 | ``` | ||
32 | |||
33 | You may want to make sure with ``git diff`` that changes made in ``tox.h`` reflect changes in ``tox.in.h``. | ||
34 | |||
35 | And you're done. | ||
36 | |||
37 | |||
38 | ## Manually | ||
39 | |||
40 | If you prefer to have more control over what is happening, there are steps below: | ||
41 | |||
42 | 1. Install [``apidsl``](https://github.com/TokTok/apidsl) | ||
43 | 2. Install ``astyle``, version 2.03 or later. | ||
44 | 3. Modify [``tox.in.h``](/other/apidsl/tox.in.h) | ||
45 | 4. Use ``apidsl`` ``??`` | ||
46 | 5. Parse generated ``tox.h`` with astyle, minimal command for it would be: | ||
47 | ```bash | ||
48 | astyle --options=other/astyle/astylerc toxcore/tox.h | ||
49 | ``` | ||
50 | |||
51 | **Always pass output from ``apidsl`` through astyle.** | ||
diff --git a/other/apidsl/tox.in.h b/other/apidsl/tox.in.h deleted file mode 100644 index 3cad8f4b..00000000 --- a/other/apidsl/tox.in.h +++ /dev/null | |||
@@ -1,2564 +0,0 @@ | |||
1 | %{ | ||
2 | /* tox.h | ||
3 | * | ||
4 | * The Tox public API. | ||
5 | * | ||
6 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
7 | * | ||
8 | * This file is part of Tox. | ||
9 | * | ||
10 | * Tox is free software: you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation, either version 3 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * Tox is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef TOX_H | ||
26 | #define TOX_H | ||
27 | |||
28 | #include <stdbool.h> | ||
29 | #include <stddef.h> | ||
30 | #include <stdint.h> | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "C" { | ||
34 | #endif | ||
35 | %} | ||
36 | |||
37 | |||
38 | /***************************************************************************** | ||
39 | * `tox.h` SHOULD *NOT* BE EDITED MANUALLY – any changes should be made to * | ||
40 | * `tox.in.h`, located in `other/apidsl/`. For instructions on how to * | ||
41 | * generate `tox.h` from `tox.in.h` please refer to `other/apidsl/README.md` * | ||
42 | *****************************************************************************/ | ||
43 | |||
44 | |||
45 | /** \page core Public core API for Tox clients. | ||
46 | * | ||
47 | * Every function that can fail takes a function-specific error code pointer | ||
48 | * that can be used to diagnose problems with the Tox state or the function | ||
49 | * arguments. The error code pointer can be NULL, which does not influence the | ||
50 | * function's behaviour, but can be done if the reason for failure is irrelevant | ||
51 | * to the client. | ||
52 | * | ||
53 | * The exception to this rule are simple allocation functions whose only failure | ||
54 | * mode is allocation failure. They return NULL in that case, and do not set an | ||
55 | * error code. | ||
56 | * | ||
57 | * Every error code type has an OK value to which functions will set their error | ||
58 | * code value on success. Clients can keep their error code uninitialised before | ||
59 | * passing it to a function. The library guarantees that after returning, the | ||
60 | * value pointed to by the error code pointer has been initialised. | ||
61 | * | ||
62 | * Functions with pointer parameters often have a NULL error code, meaning they | ||
63 | * could not perform any operation, because one of the required parameters was | ||
64 | * NULL. Some functions operate correctly or are defined as effectless on NULL. | ||
65 | * | ||
66 | * Some functions additionally return a value outside their | ||
67 | * return type domain, or a bool containing true on success and false on | ||
68 | * failure. | ||
69 | * | ||
70 | * All functions that take a Tox instance pointer will cause undefined behaviour | ||
71 | * when passed a NULL Tox pointer. | ||
72 | * | ||
73 | * All integer values are expected in host byte order. | ||
74 | * | ||
75 | * Functions with parameters with enum types cause unspecified behaviour if the | ||
76 | * enumeration value is outside the valid range of the type. If possible, the | ||
77 | * function will try to use a sane default, but there will be no error code, | ||
78 | * and one possible action for the function to take is to have no effect. | ||
79 | * | ||
80 | * Integer constants and the memory layout of publicly exposed structs are not | ||
81 | * part of the ABI. | ||
82 | */ | ||
83 | |||
84 | /** \subsection events Events and callbacks | ||
85 | * | ||
86 | * Events are handled by callbacks. One callback can be registered per event. | ||
87 | * All events have a callback function type named `tox_{event}_cb` and a | ||
88 | * function to register it named `tox_callback_{event}`. Passing a NULL | ||
89 | * callback will result in no callback being registered for that event. Only | ||
90 | * one callback per event can be registered, so if a client needs multiple | ||
91 | * event listeners, it needs to implement the dispatch functionality itself. | ||
92 | * | ||
93 | * The last argument to a callback is the user data pointer. It is passed from | ||
94 | * ${tox.iterate} to each callback in sequence. | ||
95 | * | ||
96 | * The user data pointer is never stored or dereferenced by any library code, so | ||
97 | * can be any pointer, including NULL. Callbacks must all operate on the same | ||
98 | * object type. In the apidsl code (tox.in.h), this is denoted with `any`. The | ||
99 | * `any` in ${tox.iterate} must be the same `any` as in all callbacks. In C, | ||
100 | * lacking parametric polymorphism, this is a pointer to void. | ||
101 | * | ||
102 | * Old style callbacks that are registered together with a user data pointer | ||
103 | * receive that pointer as argument when they are called. They can each have | ||
104 | * their own user data pointer of their own type. | ||
105 | */ | ||
106 | |||
107 | /** \subsection threading Threading implications | ||
108 | * | ||
109 | * It is possible to run multiple concurrent threads with a Tox instance for | ||
110 | * each thread. It is also possible to run all Tox instances in the same thread. | ||
111 | * A common way to run Tox (multiple or single instance) is to have one thread | ||
112 | * running a simple ${tox.iterate} loop, sleeping for ${tox.iteration_interval} | ||
113 | * milliseconds on each iteration. | ||
114 | * | ||
115 | * If you want to access a single Tox instance from multiple threads, access | ||
116 | * to the instance must be synchronised. While multiple threads can concurrently | ||
117 | * access multiple different Tox instances, no more than one API function can | ||
118 | * operate on a single instance at any given time. | ||
119 | * | ||
120 | * Functions that write to variable length byte arrays will always have a size | ||
121 | * function associated with them. The result of this size function is only valid | ||
122 | * until another mutating function (one that takes a pointer to non-const Tox) | ||
123 | * is called. Thus, clients must ensure that no other thread calls a mutating | ||
124 | * function between the call to the size function and the call to the retrieval | ||
125 | * function. | ||
126 | * | ||
127 | * E.g. to get the current nickname, one would write | ||
128 | * | ||
129 | * \code | ||
130 | * size_t length = ${tox.self.name.size}(tox); | ||
131 | * uint8_t *name = malloc(length); | ||
132 | * if (!name) abort(); | ||
133 | * ${tox.self.name.get}(tox, name); | ||
134 | * \endcode | ||
135 | * | ||
136 | * If any other thread calls ${tox.self.name.set} while this thread is allocating | ||
137 | * memory, the length may have become invalid, and the call to | ||
138 | * ${tox.self.name.get} may cause undefined behaviour. | ||
139 | */ | ||
140 | |||
141 | // The rest of this file is in class tox. | ||
142 | class tox { | ||
143 | |||
144 | /** | ||
145 | * The Tox instance type. All the state associated with a connection is held | ||
146 | * within the instance. Multiple instances can exist and operate concurrently. | ||
147 | * The maximum number of Tox instances that can exist on a single network | ||
148 | * device is limited. Note that this is not just a per-process limit, since the | ||
149 | * limiting factor is the number of usable ports on a device. | ||
150 | */ | ||
151 | struct this; | ||
152 | |||
153 | |||
154 | /******************************************************************************* | ||
155 | * | ||
156 | * :: API version | ||
157 | * | ||
158 | ******************************************************************************/ | ||
159 | |||
160 | |||
161 | /** | ||
162 | * The major version number. Incremented when the API or ABI changes in an | ||
163 | * incompatible way. | ||
164 | * | ||
165 | * The function variants of these constants return the version number of the | ||
166 | * library. They can be used to display the Tox library version or to check | ||
167 | * whether the client is compatible with the dynamically linked version of Tox. | ||
168 | */ | ||
169 | const VERSION_MAJOR = 0; | ||
170 | |||
171 | /** | ||
172 | * The minor version number. Incremented when functionality is added without | ||
173 | * breaking the API or ABI. Set to 0 when the major version number is | ||
174 | * incremented. | ||
175 | */ | ||
176 | const VERSION_MINOR = 0; | ||
177 | |||
178 | /** | ||
179 | * The patch or revision number. Incremented when bugfixes are applied without | ||
180 | * changing any functionality or API or ABI. | ||
181 | */ | ||
182 | const VERSION_PATCH = 1; | ||
183 | |||
184 | /** | ||
185 | * A macro to check at preprocessing time whether the client code is compatible | ||
186 | * with the installed version of Tox. | ||
187 | */ | ||
188 | #define TOX_VERSION_IS_API_COMPATIBLE(MAJOR, MINOR, PATCH) \ | ||
189 | (TOX_VERSION_MAJOR == MAJOR && \ | ||
190 | (TOX_VERSION_MINOR > MINOR || \ | ||
191 | (TOX_VERSION_MINOR == MINOR && \ | ||
192 | TOX_VERSION_PATCH >= PATCH))) | ||
193 | |||
194 | /** | ||
195 | * A macro to make compilation fail if the client code is not compatible with | ||
196 | * the installed version of Tox. | ||
197 | */ | ||
198 | #define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \ | ||
199 | typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1] | ||
200 | |||
201 | static namespace version { | ||
202 | |||
203 | /** | ||
204 | * Return whether the compiled library version is compatible with the passed | ||
205 | * version numbers. | ||
206 | */ | ||
207 | bool is_compatible(uint32_t major, uint32_t minor, uint32_t patch); | ||
208 | |||
209 | } | ||
210 | |||
211 | /** | ||
212 | * A convenience macro to call tox_version_is_compatible with the currently | ||
213 | * compiling API version. | ||
214 | */ | ||
215 | #define TOX_VERSION_IS_ABI_COMPATIBLE() \ | ||
216 | tox_version_is_compatible(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH) | ||
217 | |||
218 | /******************************************************************************* | ||
219 | * | ||
220 | * :: Numeric constants | ||
221 | * | ||
222 | * The values of these are not part of the ABI. Prefer to use the function | ||
223 | * versions of them for code that should remain compatible with future versions | ||
224 | * of toxcore. | ||
225 | * | ||
226 | ******************************************************************************/ | ||
227 | |||
228 | |||
229 | /** | ||
230 | * The size of a Tox Public Key in bytes. | ||
231 | */ | ||
232 | const PUBLIC_KEY_SIZE = 32; | ||
233 | |||
234 | /** | ||
235 | * The size of a Tox Secret Key in bytes. | ||
236 | */ | ||
237 | const SECRET_KEY_SIZE = 32; | ||
238 | |||
239 | /** | ||
240 | * The size of a Tox address in bytes. Tox addresses are in the format | ||
241 | * [Public Key ($PUBLIC_KEY_SIZE bytes)][nospam (4 bytes)][checksum (2 bytes)]. | ||
242 | * | ||
243 | * The checksum is computed over the Public Key and the nospam value. The first | ||
244 | * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an | ||
245 | * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam. | ||
246 | */ | ||
247 | const ADDRESS_SIZE = PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t); | ||
248 | |||
249 | /** | ||
250 | * Maximum length of a nickname in bytes. | ||
251 | */ | ||
252 | const MAX_NAME_LENGTH = 128; | ||
253 | |||
254 | /** | ||
255 | * Maximum length of a status message in bytes. | ||
256 | */ | ||
257 | const MAX_STATUS_MESSAGE_LENGTH = 1007; | ||
258 | |||
259 | /** | ||
260 | * Maximum length of a friend request message in bytes. | ||
261 | */ | ||
262 | const MAX_FRIEND_REQUEST_LENGTH = 1016; | ||
263 | |||
264 | /** | ||
265 | * Maximum length of a single message after which it should be split. | ||
266 | */ | ||
267 | const MAX_MESSAGE_LENGTH = 1372; | ||
268 | |||
269 | /** | ||
270 | * Maximum size of custom packets. TODO(iphydf): should be LENGTH? | ||
271 | */ | ||
272 | const MAX_CUSTOM_PACKET_SIZE = 1373; | ||
273 | |||
274 | /** | ||
275 | * The number of bytes in a hash generated by $hash. | ||
276 | */ | ||
277 | const HASH_LENGTH = 32; | ||
278 | |||
279 | /** | ||
280 | * The number of bytes in a file id. | ||
281 | */ | ||
282 | const FILE_ID_LENGTH = 32; | ||
283 | |||
284 | /** | ||
285 | * Maximum file name length for file transfers. | ||
286 | */ | ||
287 | const MAX_FILENAME_LENGTH = 255; | ||
288 | |||
289 | |||
290 | /******************************************************************************* | ||
291 | * | ||
292 | * :: Global enumerations | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Represents the possible statuses a client can have. | ||
299 | */ | ||
300 | enum class USER_STATUS { | ||
301 | /** | ||
302 | * User is online and available. | ||
303 | */ | ||
304 | NONE, | ||
305 | /** | ||
306 | * User is away. Clients can set this e.g. after a user defined | ||
307 | * inactivity time. | ||
308 | */ | ||
309 | AWAY, | ||
310 | /** | ||
311 | * User is busy. Signals to other clients that this client does not | ||
312 | * currently wish to communicate. | ||
313 | */ | ||
314 | BUSY, | ||
315 | } | ||
316 | |||
317 | |||
318 | /** | ||
319 | * Represents message types for ${tox.friend.send.message} and conference | ||
320 | * messages. | ||
321 | */ | ||
322 | enum class MESSAGE_TYPE { | ||
323 | /** | ||
324 | * Normal text message. Similar to PRIVMSG on IRC. | ||
325 | */ | ||
326 | NORMAL, | ||
327 | /** | ||
328 | * A message describing an user action. This is similar to /me (CTCP ACTION) | ||
329 | * on IRC. | ||
330 | */ | ||
331 | ACTION, | ||
332 | } | ||
333 | |||
334 | |||
335 | /******************************************************************************* | ||
336 | * | ||
337 | * :: Startup options | ||
338 | * | ||
339 | ******************************************************************************/ | ||
340 | |||
341 | |||
342 | /** | ||
343 | * Type of proxy used to connect to TCP relays. | ||
344 | */ | ||
345 | enum class PROXY_TYPE { | ||
346 | /** | ||
347 | * Don't use a proxy. | ||
348 | */ | ||
349 | NONE, | ||
350 | /** | ||
351 | * HTTP proxy using CONNECT. | ||
352 | */ | ||
353 | HTTP, | ||
354 | /** | ||
355 | * SOCKS proxy for simple socket pipes. | ||
356 | */ | ||
357 | SOCKS5, | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * Type of savedata to create the Tox instance from. | ||
362 | */ | ||
363 | enum class SAVEDATA_TYPE { | ||
364 | /** | ||
365 | * No savedata. | ||
366 | */ | ||
367 | NONE, | ||
368 | /** | ||
369 | * Savedata is one that was obtained from ${savedata.get}. | ||
370 | */ | ||
371 | TOX_SAVE, | ||
372 | /** | ||
373 | * Savedata is a secret key of length $SECRET_KEY_SIZE. | ||
374 | */ | ||
375 | SECRET_KEY, | ||
376 | } | ||
377 | |||
378 | |||
379 | static class options { | ||
380 | /** | ||
381 | * This struct contains all the startup options for Tox. You can either | ||
382 | * allocate this object yourself, and pass it to $default, or call $new to get | ||
383 | * a new default options object. | ||
384 | * | ||
385 | * If you allocate it yourself, be aware that your binary will rely on the | ||
386 | * memory layout of this struct. In particular, if additional fields are added | ||
387 | * in future versions of the API, code that allocates it itself will become | ||
388 | * incompatible. | ||
389 | * | ||
390 | * The memory layout of this struct (size, alignment, and field order) is not | ||
391 | * part of the ABI. To remain compatible, prefer to use $new to allocate the | ||
392 | * object and accessor functions to set the members. | ||
393 | */ | ||
394 | struct this [get, set] { | ||
395 | /** | ||
396 | * The type of socket to create. | ||
397 | * | ||
398 | * If this is set to false, an IPv4 socket is created, which subsequently | ||
399 | * only allows IPv4 communication. | ||
400 | * If it is set to true, an IPv6 socket is created, allowing both IPv4 and | ||
401 | * IPv6 communication. | ||
402 | */ | ||
403 | bool ipv6_enabled; | ||
404 | |||
405 | /** | ||
406 | * Enable the use of UDP communication when available. | ||
407 | * | ||
408 | * Setting this to false will force Tox to use TCP only. Communications will | ||
409 | * need to be relayed through a TCP relay node, potentially slowing them down. | ||
410 | * Disabling UDP support is necessary when using anonymous proxies or Tor. | ||
411 | */ | ||
412 | bool udp_enabled; | ||
413 | |||
414 | namespace proxy { | ||
415 | /** | ||
416 | * Pass communications through a proxy. | ||
417 | */ | ||
418 | PROXY_TYPE type; | ||
419 | |||
420 | /** | ||
421 | * The IP address or DNS name of the proxy to be used. | ||
422 | * | ||
423 | * If used, this must be non-NULL and be a valid DNS name. The name must not | ||
424 | * exceed 255 characters, and be in a NUL-terminated C string format | ||
425 | * (255 chars + 1 NUL byte). | ||
426 | * | ||
427 | * This member is ignored (it can be NULL) if proxy_type is ${PROXY_TYPE.NONE}. | ||
428 | * | ||
429 | * The data pointed at by this member is owned by the user, so must | ||
430 | * outlive the options object. | ||
431 | */ | ||
432 | string host; | ||
433 | |||
434 | /** | ||
435 | * The port to use to connect to the proxy server. | ||
436 | * | ||
437 | * Ports must be in the range (1, 65535). The value is ignored if | ||
438 | * proxy_type is ${PROXY_TYPE.NONE}. | ||
439 | */ | ||
440 | uint16_t port; | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * The start port of the inclusive port range to attempt to use. | ||
445 | * | ||
446 | * If both start_port and end_port are 0, the default port range will be | ||
447 | * used: [33445, 33545]. | ||
448 | * | ||
449 | * If either start_port or end_port is 0 while the other is non-zero, the | ||
450 | * non-zero port will be the only port in the range. | ||
451 | * | ||
452 | * Having start_port > end_port will yield the same behavior as if start_port | ||
453 | * and end_port were swapped. | ||
454 | */ | ||
455 | uint16_t start_port; | ||
456 | |||
457 | /** | ||
458 | * The end port of the inclusive port range to attempt to use. | ||
459 | */ | ||
460 | uint16_t end_port; | ||
461 | |||
462 | /** | ||
463 | * The port to use for the TCP server (relay). If 0, the TCP server is | ||
464 | * disabled. | ||
465 | * | ||
466 | * Enabling it is not required for Tox to function properly. | ||
467 | * | ||
468 | * When enabled, your Tox instance can act as a TCP relay for other Tox | ||
469 | * instance. This leads to increased traffic, thus when writing a client | ||
470 | * it is recommended to enable TCP server only if the user has an option | ||
471 | * to disable it. | ||
472 | */ | ||
473 | uint16_t tcp_port; | ||
474 | |||
475 | namespace savedata { | ||
476 | /** | ||
477 | * The type of savedata to load from. | ||
478 | */ | ||
479 | SAVEDATA_TYPE type; | ||
480 | |||
481 | /** | ||
482 | * The savedata. | ||
483 | * | ||
484 | * The data pointed at by this member is owned by the user, so must | ||
485 | * outlive the options object. | ||
486 | */ | ||
487 | const uint8_t[length] data; | ||
488 | |||
489 | /** | ||
490 | * The length of the savedata. | ||
491 | */ | ||
492 | size_t length; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | |||
497 | /** | ||
498 | * Initialises a $this object with the default options. | ||
499 | * | ||
500 | * The result of this function is independent of the original options. All | ||
501 | * values will be overwritten, no values will be read (so it is permissible | ||
502 | * to pass an uninitialised object). | ||
503 | * | ||
504 | * If options is NULL, this function has no effect. | ||
505 | * | ||
506 | * @param options An options object to be filled with default options. | ||
507 | */ | ||
508 | void default(); | ||
509 | |||
510 | |||
511 | /** | ||
512 | * Allocates a new $this object and initialises it with the default | ||
513 | * options. This function can be used to preserve long term ABI compatibility by | ||
514 | * giving the responsibility of allocation and deallocation to the Tox library. | ||
515 | * | ||
516 | * Objects returned from this function must be freed using the $free | ||
517 | * function. | ||
518 | * | ||
519 | * @return A new $this object with default options or NULL on failure. | ||
520 | */ | ||
521 | static this new() { | ||
522 | /** | ||
523 | * The function failed to allocate enough memory for the options struct. | ||
524 | */ | ||
525 | MALLOC, | ||
526 | } | ||
527 | |||
528 | |||
529 | /** | ||
530 | * Releases all resources associated with an options objects. | ||
531 | * | ||
532 | * Passing a pointer that was not returned by $new results in | ||
533 | * undefined behaviour. | ||
534 | */ | ||
535 | void free(); | ||
536 | } | ||
537 | |||
538 | |||
539 | /******************************************************************************* | ||
540 | * | ||
541 | * :: Creation and destruction | ||
542 | * | ||
543 | ******************************************************************************/ | ||
544 | |||
545 | |||
546 | /** | ||
547 | * @brief Creates and initialises a new Tox instance with the options passed. | ||
548 | * | ||
549 | * This function will bring the instance into a valid state. Running the event | ||
550 | * loop with a new instance will operate correctly. | ||
551 | * | ||
552 | * If loading failed or succeeded only partially, the new or partially loaded | ||
553 | * instance is returned and an error code is set. | ||
554 | * | ||
555 | * @param options An options object as described above. If this parameter is | ||
556 | * NULL, the default options are used. | ||
557 | * | ||
558 | * @see $iterate for the event loop. | ||
559 | * | ||
560 | * @return A new Tox instance pointer on success or NULL on failure. | ||
561 | */ | ||
562 | static this new(const options_t *options) { | ||
563 | NULL, | ||
564 | /** | ||
565 | * The function was unable to allocate enough memory to store the internal | ||
566 | * structures for the Tox object. | ||
567 | */ | ||
568 | MALLOC, | ||
569 | /** | ||
570 | * The function was unable to bind to a port. This may mean that all ports | ||
571 | * have already been bound, e.g. by other Tox instances, or it may mean | ||
572 | * a permission error. You may be able to gather more information from errno. | ||
573 | */ | ||
574 | PORT_ALLOC, | ||
575 | |||
576 | namespace PROXY { | ||
577 | /** | ||
578 | * proxy_type was invalid. | ||
579 | */ | ||
580 | BAD_TYPE, | ||
581 | /** | ||
582 | * proxy_type was valid but the proxy_host passed had an invalid format | ||
583 | * or was NULL. | ||
584 | */ | ||
585 | BAD_HOST, | ||
586 | /** | ||
587 | * proxy_type was valid, but the proxy_port was invalid. | ||
588 | */ | ||
589 | BAD_PORT, | ||
590 | /** | ||
591 | * The proxy address passed could not be resolved. | ||
592 | */ | ||
593 | NOT_FOUND, | ||
594 | } | ||
595 | |||
596 | namespace LOAD { | ||
597 | /** | ||
598 | * The byte array to be loaded contained an encrypted save. | ||
599 | */ | ||
600 | ENCRYPTED, | ||
601 | /** | ||
602 | * The data format was invalid. This can happen when loading data that was | ||
603 | * saved by an older version of Tox, or when the data has been corrupted. | ||
604 | * When loading from badly formatted data, some data may have been loaded, | ||
605 | * and the rest is discarded. Passing an invalid length parameter also | ||
606 | * causes this error. | ||
607 | */ | ||
608 | BAD_FORMAT, | ||
609 | } | ||
610 | } | ||
611 | |||
612 | |||
613 | /** | ||
614 | * Releases all resources associated with the Tox instance and disconnects from | ||
615 | * the network. | ||
616 | * | ||
617 | * After calling this function, the Tox pointer becomes invalid. No other | ||
618 | * functions can be called, and the pointer value can no longer be read. | ||
619 | */ | ||
620 | void kill(); | ||
621 | |||
622 | |||
623 | /** | ||
624 | * Severity level of log messages. | ||
625 | */ | ||
626 | enum class LOG_LEVEL { | ||
627 | /** | ||
628 | * Very detailed traces including all network activity. | ||
629 | */ | ||
630 | LOG_TRACE, | ||
631 | /** | ||
632 | * Debug messages such as which port we bind to. | ||
633 | */ | ||
634 | LOG_DEBUG, | ||
635 | /** | ||
636 | * Informational log messages such as video call status changes. | ||
637 | */ | ||
638 | LOG_INFO, | ||
639 | /** | ||
640 | * Warnings about internal inconsistency or logic errors. | ||
641 | */ | ||
642 | LOG_WARNING, | ||
643 | /** | ||
644 | * Severe unexpected errors caused by external or internal inconsistency. | ||
645 | */ | ||
646 | LOG_ERROR, | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * This event is triggered when the toxcore library logs an internal message. | ||
651 | * This is mostly useful for debugging. This callback can be called from any | ||
652 | * function, not just $iterate. This means the user data lifetime must at | ||
653 | * least extend between registering and unregistering it or $kill. | ||
654 | * | ||
655 | * Other toxcore modules such as toxav may concurrently call this callback at | ||
656 | * any time. Thus, user code must make sure it is equipped to handle concurrent | ||
657 | * execution, e.g. by employing appropriate mutex locking. The callback | ||
658 | * registration function must not be called during execution of any other Tox | ||
659 | * library function (toxcore or toxav). | ||
660 | */ | ||
661 | event log { | ||
662 | /** | ||
663 | * @param level The severity of the log message. | ||
664 | * @param file The source file from which the message originated. | ||
665 | * @param line The source line from which the message originated. | ||
666 | * @param func The function from which the message originated. | ||
667 | * @param message The log message. | ||
668 | */ | ||
669 | typedef void(LOG_LEVEL level, string file, uint32_t line, string func, | ||
670 | string message); | ||
671 | } | ||
672 | |||
673 | |||
674 | uint8_t[size] savedata { | ||
675 | /** | ||
676 | * Calculates the number of bytes required to store the tox instance with | ||
677 | * $get. This function cannot fail. The result is always greater than 0. | ||
678 | * | ||
679 | * @see threading for concurrency implications. | ||
680 | */ | ||
681 | size(); | ||
682 | |||
683 | /** | ||
684 | * Store all information associated with the tox instance to a byte array. | ||
685 | * | ||
686 | * @param savedata A memory region large enough to store the tox instance | ||
687 | * data. Call $size to find the number of bytes required. If this parameter | ||
688 | * is NULL, this function has no effect. | ||
689 | */ | ||
690 | get(); | ||
691 | } | ||
692 | |||
693 | |||
694 | /******************************************************************************* | ||
695 | * | ||
696 | * :: Connection lifecycle and event loop | ||
697 | * | ||
698 | ******************************************************************************/ | ||
699 | |||
700 | |||
701 | /** | ||
702 | * Sends a "get nodes" request to the given bootstrap node with IP, port, and | ||
703 | * public key to setup connections. | ||
704 | * | ||
705 | * This function will attempt to connect to the node using UDP. You must use | ||
706 | * this function even if ${options.this.udp_enabled} was set to false. | ||
707 | * | ||
708 | * @param address The hostname or IP address (IPv4 or IPv6) of the node. | ||
709 | * @param port The port on the host on which the bootstrap Tox instance is | ||
710 | * listening. | ||
711 | * @param public_key The long term public key of the bootstrap node | ||
712 | * ($PUBLIC_KEY_SIZE bytes). | ||
713 | * @return true on success. | ||
714 | */ | ||
715 | bool bootstrap(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) { | ||
716 | NULL, | ||
717 | /** | ||
718 | * The address could not be resolved to an IP address, or the IP address | ||
719 | * passed was invalid. | ||
720 | */ | ||
721 | BAD_HOST, | ||
722 | /** | ||
723 | * The port passed was invalid. The valid port range is (1, 65535). | ||
724 | */ | ||
725 | BAD_PORT, | ||
726 | } | ||
727 | |||
728 | |||
729 | /** | ||
730 | * Adds additional host:port pair as TCP relay. | ||
731 | * | ||
732 | * This function can be used to initiate TCP connections to different ports on | ||
733 | * the same bootstrap node, or to add TCP relays without using them as | ||
734 | * bootstrap nodes. | ||
735 | * | ||
736 | * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay. | ||
737 | * @param port The port on the host on which the TCP relay is listening. | ||
738 | * @param public_key The long term public key of the TCP relay | ||
739 | * ($PUBLIC_KEY_SIZE bytes). | ||
740 | * @return true on success. | ||
741 | */ | ||
742 | bool add_tcp_relay(string address, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) | ||
743 | with error for bootstrap; | ||
744 | |||
745 | |||
746 | /** | ||
747 | * Protocols that can be used to connect to the network or friends. | ||
748 | */ | ||
749 | enum class CONNECTION { | ||
750 | /** | ||
751 | * There is no connection. This instance, or the friend the state change is | ||
752 | * about, is now offline. | ||
753 | */ | ||
754 | NONE, | ||
755 | /** | ||
756 | * A TCP connection has been established. For the own instance, this means it | ||
757 | * is connected through a TCP relay, only. For a friend, this means that the | ||
758 | * connection to that particular friend goes through a TCP relay. | ||
759 | */ | ||
760 | TCP, | ||
761 | /** | ||
762 | * A UDP connection has been established. For the own instance, this means it | ||
763 | * is able to send UDP packets to DHT nodes, but may still be connected to | ||
764 | * a TCP relay. For a friend, this means that the connection to that | ||
765 | * particular friend was built using direct UDP packets. | ||
766 | */ | ||
767 | UDP, | ||
768 | } | ||
769 | |||
770 | |||
771 | inline namespace self { | ||
772 | |||
773 | CONNECTION connection_status { | ||
774 | /** | ||
775 | * Return whether we are connected to the DHT. The return value is equal to the | ||
776 | * last value received through the `${event connection_status}` callback. | ||
777 | */ | ||
778 | get(); | ||
779 | } | ||
780 | |||
781 | |||
782 | /** | ||
783 | * This event is triggered whenever there is a change in the DHT connection | ||
784 | * state. When disconnected, a client may choose to call $bootstrap again, to | ||
785 | * reconnect to the DHT. Note that this state may frequently change for short | ||
786 | * amounts of time. Clients should therefore not immediately bootstrap on | ||
787 | * receiving a disconnect. | ||
788 | * | ||
789 | * TODO(iphydf): how long should a client wait before bootstrapping again? | ||
790 | */ | ||
791 | event connection_status const { | ||
792 | /** | ||
793 | * @param connection_status Whether we are connected to the DHT. | ||
794 | */ | ||
795 | typedef void(CONNECTION connection_status); | ||
796 | } | ||
797 | |||
798 | } | ||
799 | |||
800 | |||
801 | /** | ||
802 | * Return the time in milliseconds before $iterate() should be called again | ||
803 | * for optimal performance. | ||
804 | */ | ||
805 | const uint32_t iteration_interval(); | ||
806 | |||
807 | |||
808 | /** | ||
809 | * The main loop that needs to be run in intervals of $iteration_interval() | ||
810 | * milliseconds. | ||
811 | */ | ||
812 | void iterate(any user_data); | ||
813 | |||
814 | |||
815 | /******************************************************************************* | ||
816 | * | ||
817 | * :: Internal client information (Tox address/id) | ||
818 | * | ||
819 | ******************************************************************************/ | ||
820 | |||
821 | |||
822 | inline namespace self { | ||
823 | |||
824 | uint8_t[ADDRESS_SIZE] address { | ||
825 | /** | ||
826 | * Writes the Tox friend address of the client to a byte array. The address is | ||
827 | * not in human-readable format. If a client wants to display the address, | ||
828 | * formatting is required. | ||
829 | * | ||
830 | * @param address A memory region of at least $ADDRESS_SIZE bytes. If this | ||
831 | * parameter is NULL, this function has no effect. | ||
832 | * @see $ADDRESS_SIZE for the address format. | ||
833 | */ | ||
834 | get(); | ||
835 | } | ||
836 | |||
837 | |||
838 | uint32_t nospam { | ||
839 | /** | ||
840 | * Set the 4-byte nospam part of the address. | ||
841 | * | ||
842 | * @param nospam Any 32 bit unsigned integer. | ||
843 | */ | ||
844 | set(); | ||
845 | |||
846 | /** | ||
847 | * Get the 4-byte nospam part of the address. | ||
848 | */ | ||
849 | get(); | ||
850 | } | ||
851 | |||
852 | |||
853 | uint8_t[PUBLIC_KEY_SIZE] public_key { | ||
854 | /** | ||
855 | * Copy the Tox Public Key (long term) from the Tox object. | ||
856 | * | ||
857 | * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If | ||
858 | * this parameter is NULL, this function has no effect. | ||
859 | */ | ||
860 | get(); | ||
861 | } | ||
862 | |||
863 | |||
864 | uint8_t[SECRET_KEY_SIZE] secret_key { | ||
865 | /** | ||
866 | * Copy the Tox Secret Key from the Tox object. | ||
867 | * | ||
868 | * @param secret_key A memory region of at least $SECRET_KEY_SIZE bytes. If | ||
869 | * this parameter is NULL, this function has no effect. | ||
870 | */ | ||
871 | get(); | ||
872 | } | ||
873 | |||
874 | } | ||
875 | |||
876 | |||
877 | /******************************************************************************* | ||
878 | * | ||
879 | * :: User-visible client information (nickname/status) | ||
880 | * | ||
881 | ******************************************************************************/ | ||
882 | |||
883 | |||
884 | /** | ||
885 | * Common error codes for all functions that set a piece of user-visible | ||
886 | * client information. | ||
887 | */ | ||
888 | error for set_info { | ||
889 | NULL, | ||
890 | /** | ||
891 | * Information length exceeded maximum permissible size. | ||
892 | */ | ||
893 | TOO_LONG, | ||
894 | } | ||
895 | |||
896 | |||
897 | inline namespace self { | ||
898 | |||
899 | uint8_t[length <= MAX_NAME_LENGTH] name { | ||
900 | /** | ||
901 | * Set the nickname for the Tox client. | ||
902 | * | ||
903 | * Nickname length cannot exceed $MAX_NAME_LENGTH. If length is 0, the name | ||
904 | * parameter is ignored (it can be NULL), and the nickname is set back to empty. | ||
905 | * | ||
906 | * @param name A byte array containing the new nickname. | ||
907 | * @param length The size of the name byte array. | ||
908 | * | ||
909 | * @return true on success. | ||
910 | */ | ||
911 | set() with error for set_info; | ||
912 | |||
913 | /** | ||
914 | * Return the length of the current nickname as passed to $set. | ||
915 | * | ||
916 | * If no nickname was set before calling this function, the name is empty, | ||
917 | * and this function returns 0. | ||
918 | * | ||
919 | * @see threading for concurrency implications. | ||
920 | */ | ||
921 | size(); | ||
922 | |||
923 | /** | ||
924 | * Write the nickname set by $set to a byte array. | ||
925 | * | ||
926 | * If no nickname was set before calling this function, the name is empty, | ||
927 | * and this function has no effect. | ||
928 | * | ||
929 | * Call $size to find out how much memory to allocate for | ||
930 | * the result. | ||
931 | * | ||
932 | * @param name A valid memory location large enough to hold the nickname. | ||
933 | * If this parameter is NULL, the function has no effect. | ||
934 | */ | ||
935 | get(); | ||
936 | } | ||
937 | |||
938 | |||
939 | uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message { | ||
940 | /** | ||
941 | * Set the client's status message. | ||
942 | * | ||
943 | * Status message length cannot exceed $MAX_STATUS_MESSAGE_LENGTH. If | ||
944 | * length is 0, the status parameter is ignored (it can be NULL), and the | ||
945 | * user status is set back to empty. | ||
946 | */ | ||
947 | set() with error for set_info; | ||
948 | |||
949 | /** | ||
950 | * Return the length of the current status message as passed to $set. | ||
951 | * | ||
952 | * If no status message was set before calling this function, the status | ||
953 | * is empty, and this function returns 0. | ||
954 | * | ||
955 | * @see threading for concurrency implications. | ||
956 | */ | ||
957 | size(); | ||
958 | |||
959 | /** | ||
960 | * Write the status message set by $set to a byte array. | ||
961 | * | ||
962 | * If no status message was set before calling this function, the status is | ||
963 | * empty, and this function has no effect. | ||
964 | * | ||
965 | * Call $size to find out how much memory to allocate for | ||
966 | * the result. | ||
967 | * | ||
968 | * @param status_message A valid memory location large enough to hold the | ||
969 | * status message. If this parameter is NULL, the function has no effect. | ||
970 | */ | ||
971 | get(); | ||
972 | } | ||
973 | |||
974 | |||
975 | USER_STATUS status { | ||
976 | /** | ||
977 | * Set the client's user status. | ||
978 | * | ||
979 | * @param status One of the user statuses listed in the enumeration above. | ||
980 | */ | ||
981 | set(); | ||
982 | |||
983 | /** | ||
984 | * Returns the client's user status. | ||
985 | */ | ||
986 | get(); | ||
987 | } | ||
988 | |||
989 | } | ||
990 | |||
991 | |||
992 | /******************************************************************************* | ||
993 | * | ||
994 | * :: Friend list management | ||
995 | * | ||
996 | ******************************************************************************/ | ||
997 | |||
998 | |||
999 | namespace friend { | ||
1000 | |||
1001 | /** | ||
1002 | * Add a friend to the friend list and send a friend request. | ||
1003 | * | ||
1004 | * A friend request message must be at least 1 byte long and at most | ||
1005 | * $MAX_FRIEND_REQUEST_LENGTH. | ||
1006 | * | ||
1007 | * Friend numbers are unique identifiers used in all functions that operate on | ||
1008 | * friends. Once added, a friend number is stable for the lifetime of the Tox | ||
1009 | * object. After saving the state and reloading it, the friend numbers may not | ||
1010 | * be the same as before. Deleting a friend creates a gap in the friend number | ||
1011 | * set, which is filled by the next adding of a friend. Any pattern in friend | ||
1012 | * numbers should not be relied on. | ||
1013 | * | ||
1014 | * If more than INT32_MAX friends are added, this function causes undefined | ||
1015 | * behaviour. | ||
1016 | * | ||
1017 | * @param address The address of the friend (returned by ${self.address.get} of | ||
1018 | * the friend you wish to add) it must be $ADDRESS_SIZE bytes. | ||
1019 | * @param message The message that will be sent along with the friend request. | ||
1020 | * @param length The length of the data byte array. | ||
1021 | * | ||
1022 | * @return the friend number on success, UINT32_MAX on failure. | ||
1023 | */ | ||
1024 | uint32_t add( | ||
1025 | const uint8_t[ADDRESS_SIZE] address, | ||
1026 | const uint8_t[length <= MAX_FRIEND_REQUEST_LENGTH] message | ||
1027 | ) { | ||
1028 | NULL, | ||
1029 | /** | ||
1030 | * The length of the friend request message exceeded | ||
1031 | * $MAX_FRIEND_REQUEST_LENGTH. | ||
1032 | */ | ||
1033 | TOO_LONG, | ||
1034 | /** | ||
1035 | * The friend request message was empty. This, and the TOO_LONG code will | ||
1036 | * never be returned from $add_norequest. | ||
1037 | */ | ||
1038 | NO_MESSAGE, | ||
1039 | /** | ||
1040 | * The friend address belongs to the sending client. | ||
1041 | */ | ||
1042 | OWN_KEY, | ||
1043 | /** | ||
1044 | * A friend request has already been sent, or the address belongs to a friend | ||
1045 | * that is already on the friend list. | ||
1046 | */ | ||
1047 | ALREADY_SENT, | ||
1048 | /** | ||
1049 | * The friend address checksum failed. | ||
1050 | */ | ||
1051 | BAD_CHECKSUM, | ||
1052 | /** | ||
1053 | * The friend was already there, but the nospam value was different. | ||
1054 | */ | ||
1055 | SET_NEW_NOSPAM, | ||
1056 | /** | ||
1057 | * A memory allocation failed when trying to increase the friend list size. | ||
1058 | */ | ||
1059 | MALLOC, | ||
1060 | } | ||
1061 | |||
1062 | |||
1063 | /** | ||
1064 | * Add a friend without sending a friend request. | ||
1065 | * | ||
1066 | * This function is used to add a friend in response to a friend request. If the | ||
1067 | * client receives a friend request, it can be reasonably sure that the other | ||
1068 | * client added this client as a friend, eliminating the need for a friend | ||
1069 | * request. | ||
1070 | * | ||
1071 | * This function is also useful in a situation where both instances are | ||
1072 | * controlled by the same entity, so that this entity can perform the mutual | ||
1073 | * friend adding. In this case, there is no need for a friend request, either. | ||
1074 | * | ||
1075 | * @param public_key A byte array of length $PUBLIC_KEY_SIZE containing the | ||
1076 | * Public Key (not the Address) of the friend to add. | ||
1077 | * | ||
1078 | * @return the friend number on success, UINT32_MAX on failure. | ||
1079 | * @see $add for a more detailed description of friend numbers. | ||
1080 | */ | ||
1081 | uint32_t add_norequest(const uint8_t[PUBLIC_KEY_SIZE] public_key) | ||
1082 | with error for add; | ||
1083 | |||
1084 | |||
1085 | /** | ||
1086 | * Remove a friend from the friend list. | ||
1087 | * | ||
1088 | * This does not notify the friend of their deletion. After calling this | ||
1089 | * function, this client will appear offline to the friend and no communication | ||
1090 | * can occur between the two. | ||
1091 | * | ||
1092 | * @param friend_number Friend number for the friend to be deleted. | ||
1093 | * | ||
1094 | * @return true on success. | ||
1095 | */ | ||
1096 | bool delete(uint32_t friend_number) { | ||
1097 | /** | ||
1098 | * There was no friend with the given friend number. No friends were deleted. | ||
1099 | */ | ||
1100 | FRIEND_NOT_FOUND, | ||
1101 | } | ||
1102 | |||
1103 | } | ||
1104 | |||
1105 | |||
1106 | /******************************************************************************* | ||
1107 | * | ||
1108 | * :: Friend list queries | ||
1109 | * | ||
1110 | ******************************************************************************/ | ||
1111 | |||
1112 | namespace friend { | ||
1113 | |||
1114 | /** | ||
1115 | * Return the friend number associated with that Public Key. | ||
1116 | * | ||
1117 | * @return the friend number on success, UINT32_MAX on failure. | ||
1118 | * @param public_key A byte array containing the Public Key. | ||
1119 | */ | ||
1120 | const uint32_t by_public_key(const uint8_t[PUBLIC_KEY_SIZE] public_key) { | ||
1121 | NULL, | ||
1122 | /** | ||
1123 | * No friend with the given Public Key exists on the friend list. | ||
1124 | */ | ||
1125 | NOT_FOUND, | ||
1126 | } | ||
1127 | |||
1128 | |||
1129 | /** | ||
1130 | * Checks if a friend with the given friend number exists and returns true if | ||
1131 | * it does. | ||
1132 | */ | ||
1133 | const bool exists(uint32_t friend_number); | ||
1134 | |||
1135 | } | ||
1136 | |||
1137 | inline namespace self { | ||
1138 | |||
1139 | uint32_t[size] friend_list { | ||
1140 | /** | ||
1141 | * Return the number of friends on the friend list. | ||
1142 | * | ||
1143 | * This function can be used to determine how much memory to allocate for | ||
1144 | * $get. | ||
1145 | */ | ||
1146 | size(); | ||
1147 | |||
1148 | |||
1149 | /** | ||
1150 | * Copy a list of valid friend numbers into an array. | ||
1151 | * | ||
1152 | * Call $size to determine the number of elements to allocate. | ||
1153 | * | ||
1154 | * @param friend_list A memory region with enough space to hold the friend | ||
1155 | * list. If this parameter is NULL, this function has no effect. | ||
1156 | */ | ||
1157 | get(); | ||
1158 | } | ||
1159 | |||
1160 | } | ||
1161 | |||
1162 | |||
1163 | |||
1164 | namespace friend { | ||
1165 | |||
1166 | uint8_t[PUBLIC_KEY_SIZE] public_key { | ||
1167 | /** | ||
1168 | * Copies the Public Key associated with a given friend number to a byte array. | ||
1169 | * | ||
1170 | * @param friend_number The friend number you want the Public Key of. | ||
1171 | * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If | ||
1172 | * this parameter is NULL, this function has no effect. | ||
1173 | * | ||
1174 | * @return true on success. | ||
1175 | */ | ||
1176 | get(uint32_t friend_number) { | ||
1177 | /** | ||
1178 | * No friend with the given number exists on the friend list. | ||
1179 | */ | ||
1180 | FRIEND_NOT_FOUND, | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1184 | } | ||
1185 | |||
1186 | namespace friend { | ||
1187 | |||
1188 | uint64_t last_online { | ||
1189 | /** | ||
1190 | * Return a unix-time timestamp of the last time the friend associated with a given | ||
1191 | * friend number was seen online. This function will return UINT64_MAX on error. | ||
1192 | * | ||
1193 | * @param friend_number The friend number you want to query. | ||
1194 | */ | ||
1195 | get(uint32_t friend_number) { | ||
1196 | /** | ||
1197 | * No friend with the given number exists on the friend list. | ||
1198 | */ | ||
1199 | FRIEND_NOT_FOUND, | ||
1200 | } | ||
1201 | } | ||
1202 | |||
1203 | } | ||
1204 | |||
1205 | /******************************************************************************* | ||
1206 | * | ||
1207 | * :: Friend-specific state queries (can also be received through callbacks) | ||
1208 | * | ||
1209 | ******************************************************************************/ | ||
1210 | |||
1211 | |||
1212 | namespace friend { | ||
1213 | |||
1214 | /** | ||
1215 | * Common error codes for friend state query functions. | ||
1216 | */ | ||
1217 | error for query { | ||
1218 | /** | ||
1219 | * The pointer parameter for storing the query result (name, message) was | ||
1220 | * NULL. Unlike the `_self_` variants of these functions, which have no effect | ||
1221 | * when a parameter is NULL, these functions return an error in that case. | ||
1222 | */ | ||
1223 | NULL, | ||
1224 | /** | ||
1225 | * The friend_number did not designate a valid friend. | ||
1226 | */ | ||
1227 | FRIEND_NOT_FOUND, | ||
1228 | } | ||
1229 | |||
1230 | |||
1231 | uint8_t[length <= MAX_NAME_LENGTH] name { | ||
1232 | /** | ||
1233 | * Return the length of the friend's name. If the friend number is invalid, the | ||
1234 | * return value is unspecified. | ||
1235 | * | ||
1236 | * The return value is equal to the `length` argument received by the last | ||
1237 | * `${event name}` callback. | ||
1238 | */ | ||
1239 | size(uint32_t friend_number) | ||
1240 | with error for query; | ||
1241 | |||
1242 | /** | ||
1243 | * Write the name of the friend designated by the given friend number to a byte | ||
1244 | * array. | ||
1245 | * | ||
1246 | * Call $size to determine the allocation size for the `name` | ||
1247 | * parameter. | ||
1248 | * | ||
1249 | * The data written to `name` is equal to the data received by the last | ||
1250 | * `${event name}` callback. | ||
1251 | * | ||
1252 | * @param name A valid memory region large enough to store the friend's name. | ||
1253 | * | ||
1254 | * @return true on success. | ||
1255 | */ | ||
1256 | get(uint32_t friend_number) | ||
1257 | with error for query; | ||
1258 | } | ||
1259 | |||
1260 | |||
1261 | /** | ||
1262 | * This event is triggered when a friend changes their name. | ||
1263 | */ | ||
1264 | event name const { | ||
1265 | /** | ||
1266 | * @param friend_number The friend number of the friend whose name changed. | ||
1267 | * @param name A byte array containing the same data as | ||
1268 | * ${name.get} would write to its `name` parameter. | ||
1269 | * @param length A value equal to the return value of | ||
1270 | * ${name.size}. | ||
1271 | */ | ||
1272 | typedef void(uint32_t friend_number, const uint8_t[length <= MAX_NAME_LENGTH] name); | ||
1273 | } | ||
1274 | |||
1275 | |||
1276 | uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message { | ||
1277 | /** | ||
1278 | * Return the length of the friend's status message. If the friend number is | ||
1279 | * invalid, the return value is SIZE_MAX. | ||
1280 | */ | ||
1281 | size(uint32_t friend_number) | ||
1282 | with error for query; | ||
1283 | |||
1284 | /** | ||
1285 | * Write the status message of the friend designated by the given friend number to a byte | ||
1286 | * array. | ||
1287 | * | ||
1288 | * Call $size to determine the allocation size for the `status_name` | ||
1289 | * parameter. | ||
1290 | * | ||
1291 | * The data written to `status_message` is equal to the data received by the last | ||
1292 | * `${event status_message}` callback. | ||
1293 | * | ||
1294 | * @param status_message A valid memory region large enough to store the friend's status message. | ||
1295 | */ | ||
1296 | get(uint32_t friend_number) | ||
1297 | with error for query; | ||
1298 | } | ||
1299 | |||
1300 | |||
1301 | /** | ||
1302 | * This event is triggered when a friend changes their status message. | ||
1303 | */ | ||
1304 | event status_message const { | ||
1305 | /** | ||
1306 | * @param friend_number The friend number of the friend whose status message | ||
1307 | * changed. | ||
1308 | * @param message A byte array containing the same data as | ||
1309 | * ${status_message.get} would write to its `status_message` parameter. | ||
1310 | * @param length A value equal to the return value of | ||
1311 | * ${status_message.size}. | ||
1312 | */ | ||
1313 | typedef void(uint32_t friend_number, const uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] message); | ||
1314 | } | ||
1315 | |||
1316 | |||
1317 | USER_STATUS status { | ||
1318 | /** | ||
1319 | * Return the friend's user status (away/busy/...). If the friend number is | ||
1320 | * invalid, the return value is unspecified. | ||
1321 | * | ||
1322 | * The status returned is equal to the last status received through the | ||
1323 | * `${event status}` callback. | ||
1324 | */ | ||
1325 | get(uint32_t friend_number) | ||
1326 | with error for query; | ||
1327 | } | ||
1328 | |||
1329 | |||
1330 | /** | ||
1331 | * This event is triggered when a friend changes their user status. | ||
1332 | */ | ||
1333 | event status const { | ||
1334 | /** | ||
1335 | * @param friend_number The friend number of the friend whose user status | ||
1336 | * changed. | ||
1337 | * @param status The new user status. | ||
1338 | */ | ||
1339 | typedef void(uint32_t friend_number, USER_STATUS status); | ||
1340 | } | ||
1341 | |||
1342 | |||
1343 | CONNECTION connection_status { | ||
1344 | /** | ||
1345 | * Check whether a friend is currently connected to this client. | ||
1346 | * | ||
1347 | * The result of this function is equal to the last value received by the | ||
1348 | * `${event connection_status}` callback. | ||
1349 | * | ||
1350 | * @param friend_number The friend number for which to query the connection | ||
1351 | * status. | ||
1352 | * | ||
1353 | * @return the friend's connection status as it was received through the | ||
1354 | * `${event connection_status}` event. | ||
1355 | */ | ||
1356 | get(uint32_t friend_number) | ||
1357 | with error for query; | ||
1358 | } | ||
1359 | |||
1360 | |||
1361 | /** | ||
1362 | * This event is triggered when a friend goes offline after having been online, | ||
1363 | * or when a friend goes online. | ||
1364 | * | ||
1365 | * This callback is not called when adding friends. It is assumed that when | ||
1366 | * adding friends, their connection status is initially offline. | ||
1367 | */ | ||
1368 | event connection_status const { | ||
1369 | /** | ||
1370 | * @param friend_number The friend number of the friend whose connection status | ||
1371 | * changed. | ||
1372 | * @param connection_status The result of calling | ||
1373 | * ${connection_status.get} on the passed friend_number. | ||
1374 | */ | ||
1375 | typedef void(uint32_t friend_number, CONNECTION connection_status); | ||
1376 | } | ||
1377 | |||
1378 | |||
1379 | bool typing { | ||
1380 | /** | ||
1381 | * Check whether a friend is currently typing a message. | ||
1382 | * | ||
1383 | * @param friend_number The friend number for which to query the typing status. | ||
1384 | * | ||
1385 | * @return true if the friend is typing. | ||
1386 | * @return false if the friend is not typing, or the friend number was | ||
1387 | * invalid. Inspect the error code to determine which case it is. | ||
1388 | */ | ||
1389 | get(uint32_t friend_number) | ||
1390 | with error for query; | ||
1391 | } | ||
1392 | |||
1393 | |||
1394 | /** | ||
1395 | * This event is triggered when a friend starts or stops typing. | ||
1396 | */ | ||
1397 | event typing const { | ||
1398 | /** | ||
1399 | * @param friend_number The friend number of the friend who started or stopped | ||
1400 | * typing. | ||
1401 | * @param is_typing The result of calling ${typing.get} on the passed | ||
1402 | * friend_number. | ||
1403 | */ | ||
1404 | typedef void(uint32_t friend_number, bool is_typing); | ||
1405 | } | ||
1406 | |||
1407 | } | ||
1408 | |||
1409 | |||
1410 | /******************************************************************************* | ||
1411 | * | ||
1412 | * :: Sending private messages | ||
1413 | * | ||
1414 | ******************************************************************************/ | ||
1415 | |||
1416 | |||
1417 | inline namespace self { | ||
1418 | |||
1419 | bool typing { | ||
1420 | /** | ||
1421 | * Set the client's typing status for a friend. | ||
1422 | * | ||
1423 | * The client is responsible for turning it on or off. | ||
1424 | * | ||
1425 | * @param friend_number The friend to which the client is typing a message. | ||
1426 | * @param typing The typing status. True means the client is typing. | ||
1427 | * | ||
1428 | * @return true on success. | ||
1429 | */ | ||
1430 | set(uint32_t friend_number) { | ||
1431 | /** | ||
1432 | * The friend number did not designate a valid friend. | ||
1433 | */ | ||
1434 | FRIEND_NOT_FOUND, | ||
1435 | } | ||
1436 | } | ||
1437 | |||
1438 | } | ||
1439 | |||
1440 | |||
1441 | namespace friend { | ||
1442 | |||
1443 | namespace send { | ||
1444 | |||
1445 | /** | ||
1446 | * Send a text chat message to an online friend. | ||
1447 | * | ||
1448 | * This function creates a chat message packet and pushes it into the send | ||
1449 | * queue. | ||
1450 | * | ||
1451 | * The message length may not exceed $MAX_MESSAGE_LENGTH. Larger messages | ||
1452 | * must be split by the client and sent as separate messages. Other clients can | ||
1453 | * then reassemble the fragments. Messages may not be empty. | ||
1454 | * | ||
1455 | * The return value of this function is the message ID. If a read receipt is | ||
1456 | * received, the triggered `${event read_receipt}` event will be passed this message ID. | ||
1457 | * | ||
1458 | * Message IDs are unique per friend. The first message ID is 0. Message IDs are | ||
1459 | * incremented by 1 each time a message is sent. If UINT32_MAX messages were | ||
1460 | * sent, the next message ID is 0. | ||
1461 | * | ||
1462 | * @param type Message type (normal, action, ...). | ||
1463 | * @param friend_number The friend number of the friend to send the message to. | ||
1464 | * @param message A non-NULL pointer to the first element of a byte array | ||
1465 | * containing the message text. | ||
1466 | * @param length Length of the message to be sent. | ||
1467 | */ | ||
1468 | uint32_t message(uint32_t friend_number, MESSAGE_TYPE type, | ||
1469 | const uint8_t[length <= MAX_MESSAGE_LENGTH] message) { | ||
1470 | NULL, | ||
1471 | /** | ||
1472 | * The friend number did not designate a valid friend. | ||
1473 | */ | ||
1474 | FRIEND_NOT_FOUND, | ||
1475 | /** | ||
1476 | * This client is currently not connected to the friend. | ||
1477 | */ | ||
1478 | FRIEND_NOT_CONNECTED, | ||
1479 | /** | ||
1480 | * An allocation error occurred while increasing the send queue size. | ||
1481 | */ | ||
1482 | SENDQ, | ||
1483 | /** | ||
1484 | * Message length exceeded $MAX_MESSAGE_LENGTH. | ||
1485 | */ | ||
1486 | TOO_LONG, | ||
1487 | /** | ||
1488 | * Attempted to send a zero-length message. | ||
1489 | */ | ||
1490 | EMPTY, | ||
1491 | } | ||
1492 | |||
1493 | } | ||
1494 | |||
1495 | |||
1496 | /** | ||
1497 | * This event is triggered when the friend receives the message sent with | ||
1498 | * ${send.message} with the corresponding message ID. | ||
1499 | */ | ||
1500 | event read_receipt const { | ||
1501 | /** | ||
1502 | * @param friend_number The friend number of the friend who received the message. | ||
1503 | * @param message_id The message ID as returned from ${send.message} | ||
1504 | * corresponding to the message sent. | ||
1505 | */ | ||
1506 | typedef void(uint32_t friend_number, uint32_t message_id); | ||
1507 | } | ||
1508 | |||
1509 | } | ||
1510 | |||
1511 | |||
1512 | /******************************************************************************* | ||
1513 | * | ||
1514 | * :: Receiving private messages and friend requests | ||
1515 | * | ||
1516 | ******************************************************************************/ | ||
1517 | |||
1518 | |||
1519 | namespace friend { | ||
1520 | |||
1521 | /** | ||
1522 | * This event is triggered when a friend request is received. | ||
1523 | */ | ||
1524 | event request const { | ||
1525 | /** | ||
1526 | * @param public_key The Public Key of the user who sent the friend request. | ||
1527 | * @param time_delta A delta in seconds between when the message was composed | ||
1528 | * and when it is being transmitted. For messages that are sent immediately, | ||
1529 | * it will be 0. If a message was written and couldn't be sent immediately | ||
1530 | * (due to a connection failure, for example), the time_delta is an | ||
1531 | * approximation of when it was composed. | ||
1532 | * @param message The message they sent along with the request. | ||
1533 | * @param length The size of the message byte array. | ||
1534 | */ | ||
1535 | typedef void(const uint8_t[PUBLIC_KEY_SIZE] public_key, | ||
1536 | // uint32_t time_delta, | ||
1537 | const uint8_t[length <= MAX_MESSAGE_LENGTH] message); | ||
1538 | } | ||
1539 | |||
1540 | |||
1541 | /** | ||
1542 | * This event is triggered when a message from a friend is received. | ||
1543 | */ | ||
1544 | event message const { | ||
1545 | /** | ||
1546 | * @param friend_number The friend number of the friend who sent the message. | ||
1547 | * @param time_delta Time between composition and sending. | ||
1548 | * @param message The message data they sent. | ||
1549 | * @param length The size of the message byte array. | ||
1550 | * | ||
1551 | * @see ${event request} for more information on time_delta. | ||
1552 | */ | ||
1553 | typedef void(uint32_t friend_number, | ||
1554 | // uint32_t time_delta, | ||
1555 | MESSAGE_TYPE type, | ||
1556 | const uint8_t[length <= MAX_MESSAGE_LENGTH] message); | ||
1557 | } | ||
1558 | |||
1559 | } | ||
1560 | |||
1561 | |||
1562 | /******************************************************************************* | ||
1563 | * | ||
1564 | * :: File transmission: common between sending and receiving | ||
1565 | * | ||
1566 | ******************************************************************************/ | ||
1567 | |||
1568 | |||
1569 | /** | ||
1570 | * Generates a cryptographic hash of the given data. | ||
1571 | * | ||
1572 | * This function may be used by clients for any purpose, but is provided | ||
1573 | * primarily for validating cached avatars. This use is highly recommended to | ||
1574 | * avoid unnecessary avatar updates. | ||
1575 | * | ||
1576 | * If hash is NULL or data is NULL while length is not 0 the function returns false, | ||
1577 | * otherwise it returns true. | ||
1578 | * | ||
1579 | * This function is a wrapper to internal message-digest functions. | ||
1580 | * | ||
1581 | * @param hash A valid memory location the hash data. It must be at least | ||
1582 | * $HASH_LENGTH bytes in size. | ||
1583 | * @param data Data to be hashed or NULL. | ||
1584 | * @param length Size of the data array or 0. | ||
1585 | * | ||
1586 | * @return true if hash was not NULL. | ||
1587 | */ | ||
1588 | static bool hash(uint8_t[HASH_LENGTH] hash, const uint8_t[length] data); | ||
1589 | |||
1590 | |||
1591 | namespace file { | ||
1592 | |||
1593 | enum KIND { | ||
1594 | /** | ||
1595 | * Arbitrary file data. Clients can choose to handle it based on the file name | ||
1596 | * or magic or any other way they choose. | ||
1597 | */ | ||
1598 | DATA, | ||
1599 | /** | ||
1600 | * Avatar file_id. This consists of $hash(image). | ||
1601 | * Avatar data. This consists of the image data. | ||
1602 | * | ||
1603 | * Avatars can be sent at any time the client wishes. Generally, a client will | ||
1604 | * send the avatar to a friend when that friend comes online, and to all | ||
1605 | * friends when the avatar changed. A client can save some traffic by | ||
1606 | * remembering which friend received the updated avatar already and only send | ||
1607 | * it if the friend has an out of date avatar. | ||
1608 | * | ||
1609 | * Clients who receive avatar send requests can reject it (by sending | ||
1610 | * ${CONTROL.CANCEL} before any other controls), or accept it (by | ||
1611 | * sending ${CONTROL.RESUME}). The file_id of length $HASH_LENGTH bytes | ||
1612 | * (same length as $FILE_ID_LENGTH) will contain the hash. A client can compare | ||
1613 | * this hash with a saved hash and send ${CONTROL.CANCEL} to terminate the avatar | ||
1614 | * transfer if it matches. | ||
1615 | * | ||
1616 | * When file_size is set to 0 in the transfer request it means that the client | ||
1617 | * has no avatar. | ||
1618 | */ | ||
1619 | AVATAR, | ||
1620 | } | ||
1621 | |||
1622 | |||
1623 | enum class CONTROL { | ||
1624 | /** | ||
1625 | * Sent by the receiving side to accept a file send request. Also sent after a | ||
1626 | * $PAUSE command to continue sending or receiving. | ||
1627 | */ | ||
1628 | RESUME, | ||
1629 | /** | ||
1630 | * Sent by clients to pause the file transfer. The initial state of a file | ||
1631 | * transfer is always paused on the receiving side and running on the sending | ||
1632 | * side. If both the sending and receiving side pause the transfer, then both | ||
1633 | * need to send $RESUME for the transfer to resume. | ||
1634 | */ | ||
1635 | PAUSE, | ||
1636 | /** | ||
1637 | * Sent by the receiving side to reject a file send request before any other | ||
1638 | * commands are sent. Also sent by either side to terminate a file transfer. | ||
1639 | */ | ||
1640 | CANCEL, | ||
1641 | } | ||
1642 | |||
1643 | |||
1644 | /** | ||
1645 | * Sends a file control command to a friend for a given file transfer. | ||
1646 | * | ||
1647 | * @param friend_number The friend number of the friend the file is being | ||
1648 | * transferred to or received from. | ||
1649 | * @param file_number The friend-specific identifier for the file transfer. | ||
1650 | * @param control The control command to send. | ||
1651 | * | ||
1652 | * @return true on success. | ||
1653 | */ | ||
1654 | bool control(uint32_t friend_number, uint32_t file_number, CONTROL control) { | ||
1655 | /** | ||
1656 | * The friend_number passed did not designate a valid friend. | ||
1657 | */ | ||
1658 | FRIEND_NOT_FOUND, | ||
1659 | /** | ||
1660 | * This client is currently not connected to the friend. | ||
1661 | */ | ||
1662 | FRIEND_NOT_CONNECTED, | ||
1663 | /** | ||
1664 | * No file transfer with the given file number was found for the given friend. | ||
1665 | */ | ||
1666 | NOT_FOUND, | ||
1667 | /** | ||
1668 | * A RESUME control was sent, but the file transfer is running normally. | ||
1669 | */ | ||
1670 | NOT_PAUSED, | ||
1671 | /** | ||
1672 | * A RESUME control was sent, but the file transfer was paused by the other | ||
1673 | * party. Only the party that paused the transfer can resume it. | ||
1674 | */ | ||
1675 | DENIED, | ||
1676 | /** | ||
1677 | * A PAUSE control was sent, but the file transfer was already paused. | ||
1678 | */ | ||
1679 | ALREADY_PAUSED, | ||
1680 | /** | ||
1681 | * Packet queue is full. | ||
1682 | */ | ||
1683 | SENDQ, | ||
1684 | } | ||
1685 | |||
1686 | |||
1687 | /** | ||
1688 | * This event is triggered when a file control command is received from a | ||
1689 | * friend. | ||
1690 | */ | ||
1691 | event recv_control const { | ||
1692 | /** | ||
1693 | * When receiving ${CONTROL.CANCEL}, the client should release the | ||
1694 | * resources associated with the file number and consider the transfer failed. | ||
1695 | * | ||
1696 | * @param friend_number The friend number of the friend who is sending the file. | ||
1697 | * @param file_number The friend-specific file number the data received is | ||
1698 | * associated with. | ||
1699 | * @param control The file control command received. | ||
1700 | */ | ||
1701 | typedef void(uint32_t friend_number, uint32_t file_number, CONTROL control); | ||
1702 | } | ||
1703 | |||
1704 | /** | ||
1705 | * Sends a file seek control command to a friend for a given file transfer. | ||
1706 | * | ||
1707 | * This function can only be called to resume a file transfer right before | ||
1708 | * ${CONTROL.RESUME} is sent. | ||
1709 | * | ||
1710 | * @param friend_number The friend number of the friend the file is being | ||
1711 | * received from. | ||
1712 | * @param file_number The friend-specific identifier for the file transfer. | ||
1713 | * @param position The position that the file should be seeked to. | ||
1714 | */ | ||
1715 | bool seek(uint32_t friend_number, uint32_t file_number, uint64_t position) { | ||
1716 | /** | ||
1717 | * The friend_number passed did not designate a valid friend. | ||
1718 | */ | ||
1719 | FRIEND_NOT_FOUND, | ||
1720 | /** | ||
1721 | * This client is currently not connected to the friend. | ||
1722 | */ | ||
1723 | FRIEND_NOT_CONNECTED, | ||
1724 | /** | ||
1725 | * No file transfer with the given file number was found for the given friend. | ||
1726 | */ | ||
1727 | NOT_FOUND, | ||
1728 | /** | ||
1729 | * File was not in a state where it could be seeked. | ||
1730 | */ | ||
1731 | DENIED, | ||
1732 | /** | ||
1733 | * Seek position was invalid | ||
1734 | */ | ||
1735 | INVALID_POSITION, | ||
1736 | /** | ||
1737 | * Packet queue is full. | ||
1738 | */ | ||
1739 | SENDQ, | ||
1740 | } | ||
1741 | |||
1742 | |||
1743 | error for get { | ||
1744 | NULL, | ||
1745 | /** | ||
1746 | * The friend_number passed did not designate a valid friend. | ||
1747 | */ | ||
1748 | FRIEND_NOT_FOUND, | ||
1749 | /** | ||
1750 | * No file transfer with the given file number was found for the given friend. | ||
1751 | */ | ||
1752 | NOT_FOUND, | ||
1753 | } | ||
1754 | |||
1755 | uint8_t[FILE_ID_LENGTH] file_id { | ||
1756 | /** | ||
1757 | * Copy the file id associated to the file transfer to a byte array. | ||
1758 | * | ||
1759 | * @param friend_number The friend number of the friend the file is being | ||
1760 | * transferred to or received from. | ||
1761 | * @param file_number The friend-specific identifier for the file transfer. | ||
1762 | * @param file_id A memory region of at least $FILE_ID_LENGTH bytes. If | ||
1763 | * this parameter is NULL, this function has no effect. | ||
1764 | * | ||
1765 | * @return true on success. | ||
1766 | */ | ||
1767 | get(uint32_t friend_number, uint32_t file_number) | ||
1768 | with error for get; | ||
1769 | } | ||
1770 | |||
1771 | } | ||
1772 | |||
1773 | |||
1774 | /******************************************************************************* | ||
1775 | * | ||
1776 | * :: File transmission: sending | ||
1777 | * | ||
1778 | ******************************************************************************/ | ||
1779 | |||
1780 | |||
1781 | namespace file { | ||
1782 | |||
1783 | /** | ||
1784 | * Send a file transmission request. | ||
1785 | * | ||
1786 | * Maximum filename length is $MAX_FILENAME_LENGTH bytes. The filename | ||
1787 | * should generally just be a file name, not a path with directory names. | ||
1788 | * | ||
1789 | * If a non-UINT64_MAX file size is provided, it can be used by both sides to | ||
1790 | * determine the sending progress. File size can be set to UINT64_MAX for streaming | ||
1791 | * data of unknown size. | ||
1792 | * | ||
1793 | * File transmission occurs in chunks, which are requested through the | ||
1794 | * `${event chunk_request}` event. | ||
1795 | * | ||
1796 | * When a friend goes offline, all file transfers associated with the friend are | ||
1797 | * purged from core. | ||
1798 | * | ||
1799 | * If the file contents change during a transfer, the behaviour is unspecified | ||
1800 | * in general. What will actually happen depends on the mode in which the file | ||
1801 | * was modified and how the client determines the file size. | ||
1802 | * | ||
1803 | * - If the file size was increased | ||
1804 | * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour | ||
1805 | * will be as expected. | ||
1806 | * - and sending mode was file (file_size != UINT64_MAX), the | ||
1807 | * ${event chunk_request} callback will receive length = 0 when Core thinks | ||
1808 | * the file transfer has finished. If the client remembers the file size as | ||
1809 | * it was when sending the request, it will terminate the transfer normally. | ||
1810 | * If the client re-reads the size, it will think the friend cancelled the | ||
1811 | * transfer. | ||
1812 | * - If the file size was decreased | ||
1813 | * - and sending mode was streaming, the behaviour is as expected. | ||
1814 | * - and sending mode was file, the callback will return 0 at the new | ||
1815 | * (earlier) end-of-file, signalling to the friend that the transfer was | ||
1816 | * cancelled. | ||
1817 | * - If the file contents were modified | ||
1818 | * - at a position before the current read, the two files (local and remote) | ||
1819 | * will differ after the transfer terminates. | ||
1820 | * - at a position after the current read, the file transfer will succeed as | ||
1821 | * expected. | ||
1822 | * - In either case, both sides will regard the transfer as complete and | ||
1823 | * successful. | ||
1824 | * | ||
1825 | * @param friend_number The friend number of the friend the file send request | ||
1826 | * should be sent to. | ||
1827 | * @param kind The meaning of the file to be sent. | ||
1828 | * @param file_size Size in bytes of the file the client wants to send, UINT64_MAX if | ||
1829 | * unknown or streaming. | ||
1830 | * @param file_id A file identifier of length $FILE_ID_LENGTH that can be used to | ||
1831 | * uniquely identify file transfers across core restarts. If NULL, a random one will | ||
1832 | * be generated by core. It can then be obtained by using ${file_id.get}(). | ||
1833 | * @param filename Name of the file. Does not need to be the actual name. This | ||
1834 | * name will be sent along with the file send request. | ||
1835 | * @param filename_length Size in bytes of the filename. | ||
1836 | * | ||
1837 | * @return A file number used as an identifier in subsequent callbacks. This | ||
1838 | * number is per friend. File numbers are reused after a transfer terminates. | ||
1839 | * On failure, this function returns UINT32_MAX. Any pattern in file numbers | ||
1840 | * should not be relied on. | ||
1841 | */ | ||
1842 | uint32_t send(uint32_t friend_number, uint32_t kind, uint64_t file_size, | ||
1843 | const uint8_t[FILE_ID_LENGTH] file_id, | ||
1844 | const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename) { | ||
1845 | NULL, | ||
1846 | /** | ||
1847 | * The friend_number passed did not designate a valid friend. | ||
1848 | */ | ||
1849 | FRIEND_NOT_FOUND, | ||
1850 | /** | ||
1851 | * This client is currently not connected to the friend. | ||
1852 | */ | ||
1853 | FRIEND_NOT_CONNECTED, | ||
1854 | /** | ||
1855 | * Filename length exceeded $MAX_FILENAME_LENGTH bytes. | ||
1856 | */ | ||
1857 | NAME_TOO_LONG, | ||
1858 | /** | ||
1859 | * Too many ongoing transfers. The maximum number of concurrent file transfers | ||
1860 | * is 256 per friend per direction (sending and receiving). | ||
1861 | */ | ||
1862 | TOO_MANY, | ||
1863 | } | ||
1864 | |||
1865 | |||
1866 | /** | ||
1867 | * Send a chunk of file data to a friend. | ||
1868 | * | ||
1869 | * This function is called in response to the `${event chunk_request}` callback. The | ||
1870 | * length parameter should be equal to the one received though the callback. | ||
1871 | * If it is zero, the transfer is assumed complete. For files with known size, | ||
1872 | * Core will know that the transfer is complete after the last byte has been | ||
1873 | * received, so it is not necessary (though not harmful) to send a zero-length | ||
1874 | * chunk to terminate. For streams, core will know that the transfer is finished | ||
1875 | * if a chunk with length less than the length requested in the callback is sent. | ||
1876 | * | ||
1877 | * @param friend_number The friend number of the receiving friend for this file. | ||
1878 | * @param file_number The file transfer identifier returned by tox_file_send. | ||
1879 | * @param position The file or stream position from which to continue reading. | ||
1880 | * @return true on success. | ||
1881 | */ | ||
1882 | bool send_chunk(uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t[length] data) { | ||
1883 | /** | ||
1884 | * The length parameter was non-zero, but data was NULL. | ||
1885 | */ | ||
1886 | NULL, | ||
1887 | /** | ||
1888 | * The friend_number passed did not designate a valid friend. | ||
1889 | */ | ||
1890 | FRIEND_NOT_FOUND, | ||
1891 | /** | ||
1892 | * This client is currently not connected to the friend. | ||
1893 | */ | ||
1894 | FRIEND_NOT_CONNECTED, | ||
1895 | /** | ||
1896 | * No file transfer with the given file number was found for the given friend. | ||
1897 | */ | ||
1898 | NOT_FOUND, | ||
1899 | /** | ||
1900 | * File transfer was found but isn't in a transferring state: (paused, done, | ||
1901 | * broken, etc...) (happens only when not called from the request chunk callback). | ||
1902 | */ | ||
1903 | NOT_TRANSFERRING, | ||
1904 | /** | ||
1905 | * Attempted to send more or less data than requested. The requested data size is | ||
1906 | * adjusted according to maximum transmission unit and the expected end of | ||
1907 | * the file. Trying to send less or more than requested will return this error. | ||
1908 | */ | ||
1909 | INVALID_LENGTH, | ||
1910 | /** | ||
1911 | * Packet queue is full. | ||
1912 | */ | ||
1913 | SENDQ, | ||
1914 | /** | ||
1915 | * Position parameter was wrong. | ||
1916 | */ | ||
1917 | WRONG_POSITION, | ||
1918 | } | ||
1919 | |||
1920 | |||
1921 | /** | ||
1922 | * This event is triggered when Core is ready to send more file data. | ||
1923 | */ | ||
1924 | event chunk_request const { | ||
1925 | /** | ||
1926 | * If the length parameter is 0, the file transfer is finished, and the client's | ||
1927 | * resources associated with the file number should be released. After a call | ||
1928 | * with zero length, the file number can be reused for future file transfers. | ||
1929 | * | ||
1930 | * If the requested position is not equal to the client's idea of the current | ||
1931 | * file or stream position, it will need to seek. In case of read-once streams, | ||
1932 | * the client should keep the last read chunk so that a seek back can be | ||
1933 | * supported. A seek-back only ever needs to read from the last requested chunk. | ||
1934 | * This happens when a chunk was requested, but the send failed. A seek-back | ||
1935 | * request can occur an arbitrary number of times for any given chunk. | ||
1936 | * | ||
1937 | * In response to receiving this callback, the client should call the function | ||
1938 | * `$send_chunk` with the requested chunk. If the number of bytes sent | ||
1939 | * through that function is zero, the file transfer is assumed complete. A | ||
1940 | * client must send the full length of data requested with this callback. | ||
1941 | * | ||
1942 | * @param friend_number The friend number of the receiving friend for this file. | ||
1943 | * @param file_number The file transfer identifier returned by $send. | ||
1944 | * @param position The file or stream position from which to continue reading. | ||
1945 | * @param length The number of bytes requested for the current chunk. | ||
1946 | */ | ||
1947 | typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length); | ||
1948 | } | ||
1949 | |||
1950 | } | ||
1951 | |||
1952 | |||
1953 | /******************************************************************************* | ||
1954 | * | ||
1955 | * :: File transmission: receiving | ||
1956 | * | ||
1957 | ******************************************************************************/ | ||
1958 | |||
1959 | |||
1960 | namespace file { | ||
1961 | |||
1962 | /** | ||
1963 | * This event is triggered when a file transfer request is received. | ||
1964 | */ | ||
1965 | event recv const { | ||
1966 | /** | ||
1967 | * The client should acquire resources to be associated with the file transfer. | ||
1968 | * Incoming file transfers start in the PAUSED state. After this callback | ||
1969 | * returns, a transfer can be rejected by sending a ${CONTROL.CANCEL} | ||
1970 | * control command before any other control commands. It can be accepted by | ||
1971 | * sending ${CONTROL.RESUME}. | ||
1972 | * | ||
1973 | * @param friend_number The friend number of the friend who is sending the file | ||
1974 | * transfer request. | ||
1975 | * @param file_number The friend-specific file number the data received is | ||
1976 | * associated with. | ||
1977 | * @param kind The meaning of the file to be sent. | ||
1978 | * @param file_size Size in bytes of the file the client wants to send, | ||
1979 | * UINT64_MAX if unknown or streaming. | ||
1980 | * @param filename Name of the file. Does not need to be the actual name. This | ||
1981 | * name will be sent along with the file send request. | ||
1982 | * @param filename_length Size in bytes of the filename. | ||
1983 | */ | ||
1984 | typedef void(uint32_t friend_number, uint32_t file_number, uint32_t kind, | ||
1985 | uint64_t file_size, const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename); | ||
1986 | } | ||
1987 | |||
1988 | |||
1989 | /** | ||
1990 | * This event is first triggered when a file transfer request is received, and | ||
1991 | * subsequently when a chunk of file data for an accepted request was received. | ||
1992 | */ | ||
1993 | event recv_chunk const { | ||
1994 | /** | ||
1995 | * When length is 0, the transfer is finished and the client should release the | ||
1996 | * resources it acquired for the transfer. After a call with length = 0, the | ||
1997 | * file number can be reused for new file transfers. | ||
1998 | * | ||
1999 | * If position is equal to file_size (received in the file_receive callback) | ||
2000 | * when the transfer finishes, the file was received completely. Otherwise, if | ||
2001 | * file_size was UINT64_MAX, streaming ended successfully when length is 0. | ||
2002 | * | ||
2003 | * @param friend_number The friend number of the friend who is sending the file. | ||
2004 | * @param file_number The friend-specific file number the data received is | ||
2005 | * associated with. | ||
2006 | * @param position The file position of the first byte in data. | ||
2007 | * @param data A byte array containing the received chunk. | ||
2008 | * @param length The length of the received chunk. | ||
2009 | */ | ||
2010 | typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position, | ||
2011 | const uint8_t[length] data); | ||
2012 | } | ||
2013 | |||
2014 | } | ||
2015 | |||
2016 | |||
2017 | /******************************************************************************* | ||
2018 | * | ||
2019 | * :: Conference management | ||
2020 | * | ||
2021 | ******************************************************************************/ | ||
2022 | |||
2023 | namespace conference { | ||
2024 | |||
2025 | /** | ||
2026 | * Conference types for the ${event invite} event. | ||
2027 | */ | ||
2028 | enum class TYPE { | ||
2029 | /** | ||
2030 | * Text-only conferences that must be accepted with the $join function. | ||
2031 | */ | ||
2032 | TEXT, | ||
2033 | /** | ||
2034 | * Video conference. The function to accept these is in toxav. | ||
2035 | */ | ||
2036 | AV, | ||
2037 | } | ||
2038 | |||
2039 | |||
2040 | /** | ||
2041 | * This event is triggered when the client is invited to join a conference. | ||
2042 | */ | ||
2043 | event invite const { | ||
2044 | /** | ||
2045 | * The invitation will remain valid until the inviting friend goes offline | ||
2046 | * or exits the conference. | ||
2047 | * | ||
2048 | * @param friend_number The friend who invited us. | ||
2049 | * @param type The conference type (text only or audio/video). | ||
2050 | * @param cookie A piece of data of variable length required to join the | ||
2051 | * conference. | ||
2052 | * @param length The length of the cookie. | ||
2053 | */ | ||
2054 | typedef void(uint32_t friend_number, TYPE type, const uint8_t[length] cookie); | ||
2055 | } | ||
2056 | |||
2057 | |||
2058 | /** | ||
2059 | * This event is triggered when the client receives a conference message. | ||
2060 | */ | ||
2061 | event message const { | ||
2062 | /** | ||
2063 | * @param conference_number The conference number of the conference the message is intended for. | ||
2064 | * @param peer_number The ID of the peer who sent the message. | ||
2065 | * @param type The type of message (normal, action, ...). | ||
2066 | * @param message The message data. | ||
2067 | * @param length The length of the message. | ||
2068 | */ | ||
2069 | typedef void(uint32_t conference_number, uint32_t peer_number, MESSAGE_TYPE type, | ||
2070 | const uint8_t[length] message); | ||
2071 | } | ||
2072 | |||
2073 | |||
2074 | /** | ||
2075 | * This event is triggered when a peer changes the conference title. | ||
2076 | * | ||
2077 | * If peer_number == UINT32_MAX, then author is unknown (e.g. initial joining the conference). | ||
2078 | */ | ||
2079 | event title const { | ||
2080 | /** | ||
2081 | * @param conference_number The conference number of the conference the title change is intended for. | ||
2082 | * @param peer_number The ID of the peer who changed the title. | ||
2083 | * @param title The title data. | ||
2084 | * @param length The title length. | ||
2085 | */ | ||
2086 | typedef void(uint32_t conference_number, uint32_t peer_number, const uint8_t[length] title); | ||
2087 | } | ||
2088 | |||
2089 | /** | ||
2090 | * Peer list state change types. | ||
2091 | */ | ||
2092 | enum class STATE_CHANGE { | ||
2093 | /** | ||
2094 | * A peer has joined the conference. | ||
2095 | */ | ||
2096 | PEER_JOIN, | ||
2097 | /** | ||
2098 | * A peer has exited the conference. | ||
2099 | */ | ||
2100 | PEER_EXIT, | ||
2101 | /** | ||
2102 | * A peer has changed their name. | ||
2103 | */ | ||
2104 | PEER_NAME_CHANGE, | ||
2105 | } | ||
2106 | |||
2107 | /** | ||
2108 | * This event is triggered when the peer list changes (name change, peer join, peer exit). | ||
2109 | */ | ||
2110 | event namelist_change const { | ||
2111 | /** | ||
2112 | * @param conference_number The conference number of the conference the title change is intended for. | ||
2113 | * @param peer_number The ID of the peer who changed the title. | ||
2114 | * @param change The type of change (one of $STATE_CHANGE). | ||
2115 | */ | ||
2116 | typedef void(uint32_t conference_number, uint32_t peer_number, STATE_CHANGE change); | ||
2117 | } | ||
2118 | |||
2119 | |||
2120 | /** | ||
2121 | * Creates a new conference. | ||
2122 | * | ||
2123 | * This function creates a new text conference. | ||
2124 | * | ||
2125 | * @return conference number on success, or UINT32_MAX on failure. | ||
2126 | */ | ||
2127 | uint32_t new() { | ||
2128 | /** | ||
2129 | * The conference instance failed to initialize. | ||
2130 | */ | ||
2131 | INIT, | ||
2132 | } | ||
2133 | |||
2134 | /** | ||
2135 | * This function deletes a conference. | ||
2136 | * | ||
2137 | * @param conference_number The conference number of the conference to be deleted. | ||
2138 | * | ||
2139 | * @return true on success. | ||
2140 | */ | ||
2141 | bool delete(uint32_t conference_number) { | ||
2142 | /** | ||
2143 | * The conference number passed did not designate a valid conference. | ||
2144 | */ | ||
2145 | CONFERENCE_NOT_FOUND, | ||
2146 | } | ||
2147 | |||
2148 | |||
2149 | namespace peer { | ||
2150 | |||
2151 | /** | ||
2152 | * Error codes for peer info queries. | ||
2153 | */ | ||
2154 | error for query { | ||
2155 | /** | ||
2156 | * The conference number passed did not designate a valid conference. | ||
2157 | */ | ||
2158 | CONFERENCE_NOT_FOUND, | ||
2159 | /** | ||
2160 | * The peer number passed did not designate a valid peer. | ||
2161 | */ | ||
2162 | PEER_NOT_FOUND, | ||
2163 | /** | ||
2164 | * The client is not connected to the conference. | ||
2165 | */ | ||
2166 | NO_CONNECTION, | ||
2167 | } | ||
2168 | |||
2169 | /** | ||
2170 | * Return the number of peers in the conference. Return value is unspecified on failure. | ||
2171 | */ | ||
2172 | const uint32_t count(uint32_t conference_number) | ||
2173 | with error for query; | ||
2174 | |||
2175 | uint8_t[size] name { | ||
2176 | |||
2177 | /** | ||
2178 | * Return the length of the peer's name. Return value is unspecified on failure. | ||
2179 | */ | ||
2180 | size(uint32_t conference_number, uint32_t peer_number) | ||
2181 | with error for query; | ||
2182 | |||
2183 | /** | ||
2184 | * Copy the name of peer_number who is in conference_number to name. | ||
2185 | * name must be at least $MAX_NAME_LENGTH long. | ||
2186 | * | ||
2187 | * @return true on success. | ||
2188 | */ | ||
2189 | get(uint32_t conference_number, uint32_t peer_number) | ||
2190 | with error for query; | ||
2191 | } | ||
2192 | |||
2193 | /** | ||
2194 | * Copy the public key of peer_number who is in conference_number to public_key. | ||
2195 | * public_key must be $PUBLIC_KEY_SIZE long. | ||
2196 | * | ||
2197 | * @return true on success. | ||
2198 | */ | ||
2199 | uint8_t[PUBLIC_KEY_SIZE] public_key { | ||
2200 | get(uint32_t conference_number, uint32_t peer_number) | ||
2201 | with error for query; | ||
2202 | } | ||
2203 | |||
2204 | /** | ||
2205 | * Return true if passed peer_number corresponds to our own. | ||
2206 | */ | ||
2207 | const bool number_is_ours(uint32_t conference_number, uint32_t peer_number) | ||
2208 | with error for query; | ||
2209 | |||
2210 | } | ||
2211 | |||
2212 | |||
2213 | /** | ||
2214 | * Invites a friend to a conference. | ||
2215 | * | ||
2216 | * @param friend_number The friend number of the friend we want to invite. | ||
2217 | * @param conference_number The conference number of the conference we want to invite the friend to. | ||
2218 | * | ||
2219 | * @return true on success. | ||
2220 | */ | ||
2221 | bool invite(uint32_t friend_number, uint32_t conference_number) { | ||
2222 | /** | ||
2223 | * The conference number passed did not designate a valid conference. | ||
2224 | */ | ||
2225 | CONFERENCE_NOT_FOUND, | ||
2226 | /** | ||
2227 | * The invite packet failed to send. | ||
2228 | */ | ||
2229 | FAIL_SEND, | ||
2230 | } | ||
2231 | |||
2232 | |||
2233 | /** | ||
2234 | * Joins a conference that the client has been invited to. | ||
2235 | * | ||
2236 | * @param friend_number The friend number of the friend who sent the invite. | ||
2237 | * @param cookie Received via the `${event invite}` event. | ||
2238 | * @param length The size of cookie. | ||
2239 | * | ||
2240 | * @return conference number on success, UINT32_MAX on failure. | ||
2241 | */ | ||
2242 | uint32_t join(uint32_t friend_number, const uint8_t[length] cookie) { | ||
2243 | /** | ||
2244 | * The cookie passed has an invalid length. | ||
2245 | */ | ||
2246 | INVALID_LENGTH, | ||
2247 | /** | ||
2248 | * The conference is not the expected type. This indicates an invalid cookie. | ||
2249 | */ | ||
2250 | WRONG_TYPE, | ||
2251 | /** | ||
2252 | * The friend number passed does not designate a valid friend. | ||
2253 | */ | ||
2254 | FRIEND_NOT_FOUND, | ||
2255 | /** | ||
2256 | * Client is already in this conference. | ||
2257 | */ | ||
2258 | DUPLICATE, | ||
2259 | /** | ||
2260 | * Conference instance failed to initialize. | ||
2261 | */ | ||
2262 | INIT_FAIL, | ||
2263 | /** | ||
2264 | * The join packet failed to send. | ||
2265 | */ | ||
2266 | FAIL_SEND, | ||
2267 | } | ||
2268 | |||
2269 | |||
2270 | namespace send { | ||
2271 | |||
2272 | /** | ||
2273 | * Send a text chat message to the conference. | ||
2274 | * | ||
2275 | * This function creates a conference message packet and pushes it into the send | ||
2276 | * queue. | ||
2277 | * | ||
2278 | * The message length may not exceed $MAX_MESSAGE_LENGTH. Larger messages | ||
2279 | * must be split by the client and sent as separate messages. Other clients can | ||
2280 | * then reassemble the fragments. | ||
2281 | * | ||
2282 | * @param conference_number The conference number of the conference the message is intended for. | ||
2283 | * @param type Message type (normal, action, ...). | ||
2284 | * @param message A non-NULL pointer to the first element of a byte array | ||
2285 | * containing the message text. | ||
2286 | * @param length Length of the message to be sent. | ||
2287 | * | ||
2288 | * @return true on success. | ||
2289 | */ | ||
2290 | bool message(uint32_t conference_number, MESSAGE_TYPE type, const uint8_t[length] message) { | ||
2291 | /** | ||
2292 | * The conference number passed did not designate a valid conference. | ||
2293 | */ | ||
2294 | CONFERENCE_NOT_FOUND, | ||
2295 | /** | ||
2296 | * The message is too long. | ||
2297 | */ | ||
2298 | TOO_LONG, | ||
2299 | /** | ||
2300 | * The client is not connected to the conference. | ||
2301 | */ | ||
2302 | NO_CONNECTION, | ||
2303 | /** | ||
2304 | * The message packet failed to send. | ||
2305 | */ | ||
2306 | FAIL_SEND, | ||
2307 | } | ||
2308 | } | ||
2309 | |||
2310 | error for title { | ||
2311 | /** | ||
2312 | * The conference number passed did not designate a valid conference. | ||
2313 | */ | ||
2314 | CONFERENCE_NOT_FOUND, | ||
2315 | /** | ||
2316 | * The title is too long or empty. | ||
2317 | */ | ||
2318 | INVALID_LENGTH, | ||
2319 | /** | ||
2320 | * The title packet failed to send. | ||
2321 | */ | ||
2322 | FAIL_SEND, | ||
2323 | } | ||
2324 | |||
2325 | uint8_t[length <= MAX_NAME_LENGTH] title { | ||
2326 | |||
2327 | /** | ||
2328 | * Return the length of the conference title. Return value is unspecified on failure. | ||
2329 | * | ||
2330 | * The return value is equal to the `length` argument received by the last | ||
2331 | * `${event title}` callback. | ||
2332 | */ | ||
2333 | size(uint32_t conference_number) | ||
2334 | with error for title; | ||
2335 | |||
2336 | /** | ||
2337 | * Write the title designated by the given conference number to a byte array. | ||
2338 | * | ||
2339 | * Call $size to determine the allocation size for the `title` parameter. | ||
2340 | * | ||
2341 | * The data written to `title` is equal to the data received by the last | ||
2342 | * `${event title}` callback. | ||
2343 | * | ||
2344 | * @param title A valid memory region large enough to store the title. | ||
2345 | * If this parameter is NULL, this function has no effect. | ||
2346 | * | ||
2347 | * @return true on success. | ||
2348 | */ | ||
2349 | get(uint32_t conference_number) | ||
2350 | with error for title; | ||
2351 | |||
2352 | /** | ||
2353 | * Set the conference title and broadcast it to the rest of the conference. | ||
2354 | * | ||
2355 | * Title length cannot be longer than $MAX_NAME_LENGTH. | ||
2356 | * | ||
2357 | * @return true on success. | ||
2358 | */ | ||
2359 | set(uint32_t conference_number) | ||
2360 | with error for title; | ||
2361 | } | ||
2362 | |||
2363 | |||
2364 | uint32_t[size] chatlist { | ||
2365 | /** | ||
2366 | * Return the number of conferences in the Tox instance. | ||
2367 | * This should be used to determine how much memory to allocate for `$get`. | ||
2368 | */ | ||
2369 | size(); | ||
2370 | |||
2371 | /** | ||
2372 | * Copy a list of valid conference IDs into the array chatlist. Determine how much space | ||
2373 | * to allocate for the array with the `$size` function. | ||
2374 | */ | ||
2375 | get(); | ||
2376 | } | ||
2377 | |||
2378 | |||
2379 | /** | ||
2380 | * Returns the type of conference ($TYPE) that conference_number is. Return value is | ||
2381 | * unspecified on failure. | ||
2382 | */ | ||
2383 | TYPE type { | ||
2384 | get(uint32_t conference_number) { | ||
2385 | /** | ||
2386 | * The conference number passed did not designate a valid conference. | ||
2387 | */ | ||
2388 | CONFERENCE_NOT_FOUND, | ||
2389 | } | ||
2390 | } | ||
2391 | |||
2392 | } | ||
2393 | |||
2394 | |||
2395 | /******************************************************************************* | ||
2396 | * | ||
2397 | * :: Low-level custom packet sending and receiving | ||
2398 | * | ||
2399 | ******************************************************************************/ | ||
2400 | |||
2401 | |||
2402 | namespace friend { | ||
2403 | |||
2404 | inline namespace send { | ||
2405 | |||
2406 | error for custom_packet { | ||
2407 | NULL, | ||
2408 | /** | ||
2409 | * The friend number did not designate a valid friend. | ||
2410 | */ | ||
2411 | FRIEND_NOT_FOUND, | ||
2412 | /** | ||
2413 | * This client is currently not connected to the friend. | ||
2414 | */ | ||
2415 | FRIEND_NOT_CONNECTED, | ||
2416 | /** | ||
2417 | * The first byte of data was not in the specified range for the packet type. | ||
2418 | * This range is 200-254 for lossy, and 160-191 for lossless packets. | ||
2419 | */ | ||
2420 | INVALID, | ||
2421 | /** | ||
2422 | * Attempted to send an empty packet. | ||
2423 | */ | ||
2424 | EMPTY, | ||
2425 | /** | ||
2426 | * Packet data length exceeded $MAX_CUSTOM_PACKET_SIZE. | ||
2427 | */ | ||
2428 | TOO_LONG, | ||
2429 | /** | ||
2430 | * Packet queue is full. | ||
2431 | */ | ||
2432 | SENDQ, | ||
2433 | } | ||
2434 | |||
2435 | /** | ||
2436 | * Send a custom lossy packet to a friend. | ||
2437 | * | ||
2438 | * The first byte of data must be in the range 200-254. Maximum length of a | ||
2439 | * custom packet is $MAX_CUSTOM_PACKET_SIZE. | ||
2440 | * | ||
2441 | * Lossy packets behave like UDP packets, meaning they might never reach the | ||
2442 | * other side or might arrive more than once (if someone is messing with the | ||
2443 | * connection) or might arrive in the wrong order. | ||
2444 | * | ||
2445 | * Unless latency is an issue, it is recommended that you use lossless custom | ||
2446 | * packets instead. | ||
2447 | * | ||
2448 | * @param friend_number The friend number of the friend this lossy packet | ||
2449 | * should be sent to. | ||
2450 | * @param data A byte array containing the packet data. | ||
2451 | * @param length The length of the packet data byte array. | ||
2452 | * | ||
2453 | * @return true on success. | ||
2454 | */ | ||
2455 | bool lossy_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data) | ||
2456 | with error for custom_packet; | ||
2457 | |||
2458 | |||
2459 | /** | ||
2460 | * Send a custom lossless packet to a friend. | ||
2461 | * | ||
2462 | * The first byte of data must be in the range 160-191. Maximum length of a | ||
2463 | * custom packet is $MAX_CUSTOM_PACKET_SIZE. | ||
2464 | * | ||
2465 | * Lossless packet behaviour is comparable to TCP (reliability, arrive in order) | ||
2466 | * but with packets instead of a stream. | ||
2467 | * | ||
2468 | * @param friend_number The friend number of the friend this lossless packet | ||
2469 | * should be sent to. | ||
2470 | * @param data A byte array containing the packet data. | ||
2471 | * @param length The length of the packet data byte array. | ||
2472 | * | ||
2473 | * @return true on success. | ||
2474 | */ | ||
2475 | bool lossless_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data) | ||
2476 | with error for custom_packet; | ||
2477 | |||
2478 | } | ||
2479 | |||
2480 | |||
2481 | event lossy_packet const { | ||
2482 | /** | ||
2483 | * @param friend_number The friend number of the friend who sent a lossy packet. | ||
2484 | * @param data A byte array containing the received packet data. | ||
2485 | * @param length The length of the packet data byte array. | ||
2486 | */ | ||
2487 | typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data); | ||
2488 | } | ||
2489 | |||
2490 | |||
2491 | event lossless_packet const { | ||
2492 | /** | ||
2493 | * @param friend_number The friend number of the friend who sent the packet. | ||
2494 | * @param data A byte array containing the received packet data. | ||
2495 | * @param length The length of the packet data byte array. | ||
2496 | */ | ||
2497 | typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data); | ||
2498 | } | ||
2499 | |||
2500 | } | ||
2501 | |||
2502 | |||
2503 | |||
2504 | /******************************************************************************* | ||
2505 | * | ||
2506 | * :: Low-level network information | ||
2507 | * | ||
2508 | ******************************************************************************/ | ||
2509 | |||
2510 | |||
2511 | inline namespace self { | ||
2512 | |||
2513 | uint8_t[PUBLIC_KEY_SIZE] dht_id { | ||
2514 | /** | ||
2515 | * Writes the temporary DHT public key of this instance to a byte array. | ||
2516 | * | ||
2517 | * This can be used in combination with an externally accessible IP address and | ||
2518 | * the bound port (from ${udp_port.get}) to run a temporary bootstrap node. | ||
2519 | * | ||
2520 | * Be aware that every time a new instance is created, the DHT public key | ||
2521 | * changes, meaning this cannot be used to run a permanent bootstrap node. | ||
2522 | * | ||
2523 | * @param dht_id A memory region of at least $PUBLIC_KEY_SIZE bytes. If this | ||
2524 | * parameter is NULL, this function has no effect. | ||
2525 | */ | ||
2526 | get(); | ||
2527 | } | ||
2528 | |||
2529 | |||
2530 | error for get_port { | ||
2531 | /** | ||
2532 | * The instance was not bound to any port. | ||
2533 | */ | ||
2534 | NOT_BOUND, | ||
2535 | } | ||
2536 | |||
2537 | |||
2538 | uint16_t udp_port { | ||
2539 | /** | ||
2540 | * Return the UDP port this Tox instance is bound to. | ||
2541 | */ | ||
2542 | get() with error for get_port; | ||
2543 | } | ||
2544 | |||
2545 | |||
2546 | uint16_t tcp_port { | ||
2547 | /** | ||
2548 | * Return the TCP port this Tox instance is bound to. This is only relevant if | ||
2549 | * the instance is acting as a TCP relay. | ||
2550 | */ | ||
2551 | get() with error for get_port; | ||
2552 | } | ||
2553 | |||
2554 | } | ||
2555 | |||
2556 | } // class tox | ||
2557 | |||
2558 | %{ | ||
2559 | #ifdef __cplusplus | ||
2560 | } | ||
2561 | #endif | ||
2562 | |||
2563 | #endif | ||
2564 | %} | ||
diff --git a/other/apidsl/toxav.in.h b/other/apidsl/toxav.in.h deleted file mode 100644 index 6e3e9c17..00000000 --- a/other/apidsl/toxav.in.h +++ /dev/null | |||
@@ -1,637 +0,0 @@ | |||
1 | %{ | ||
2 | /* toxav.h | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Tox project All Rights Reserved. | ||
5 | * | ||
6 | * This file is part of Tox. | ||
7 | * | ||
8 | * Tox is free software: you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation, either version 3 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * Tox is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef TOXAV_H | ||
24 | #define TOXAV_H | ||
25 | |||
26 | #include <stdbool.h> | ||
27 | #include <stddef.h> | ||
28 | #include <stdint.h> | ||
29 | |||
30 | #ifdef __cplusplus | ||
31 | extern "C" { | ||
32 | #endif | ||
33 | %} | ||
34 | |||
35 | /** \page av Public audio/video API for Tox clients. | ||
36 | * | ||
37 | * This API can handle multiple calls. Each call has its state, in very rare | ||
38 | * occasions the library can change the state of the call without apps knowledge. | ||
39 | * | ||
40 | */ | ||
41 | |||
42 | /** \subsection events Events and callbacks | ||
43 | * | ||
44 | * As in Core API, events are handled by callbacks. One callback can be | ||
45 | * registered per event. All events have a callback function type named | ||
46 | * `toxav_{event}_cb` and a function to register it named `toxav_callback_{event}`. | ||
47 | * Passing a NULL callback will result in no callback being registered for that | ||
48 | * event. Only one callback per event can be registered, so if a client needs | ||
49 | * multiple event listeners, it needs to implement the dispatch functionality | ||
50 | * itself. Unlike Core API, lack of some event handlers will cause the the | ||
51 | * library to drop calls before they are started. Hanging up call from a | ||
52 | * callback causes undefined behaviour. | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /** \subsection threading Threading implications | ||
57 | * | ||
58 | * Unlike the Core API, this API is fully thread-safe. The library will ensure | ||
59 | * the proper synchronization of parallel calls. | ||
60 | * | ||
61 | * A common way to run ToxAV (multiple or single instance) is to have a thread, | ||
62 | * separate from tox instance thread, running a simple ${toxAV.iterate} loop, | ||
63 | * sleeping for ${toxAV.iteration_interval} * milliseconds on each iteration. | ||
64 | * | ||
65 | * An important thing to note is that events are triggered from both tox and | ||
66 | * toxav thread (see above). Audio and video receive frame events are triggered | ||
67 | * from toxav thread while all the other events are triggered from tox thread. | ||
68 | * | ||
69 | * Tox thread has priority with mutex mechanisms. Any api function can | ||
70 | * fail if mutexes are held by tox thread in which case they will set SYNC | ||
71 | * error code. | ||
72 | */ | ||
73 | |||
74 | /** | ||
75 | * External Tox type. | ||
76 | */ | ||
77 | class tox { | ||
78 | struct this; | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * ToxAV. | ||
83 | */ | ||
84 | class toxAV { | ||
85 | |||
86 | /** | ||
87 | * The ToxAV instance type. Each ToxAV instance can be bound to only one Tox | ||
88 | * instance, and Tox instance can have only one ToxAV instance. One must make | ||
89 | * sure to close ToxAV instance prior closing Tox instance otherwise undefined | ||
90 | * behaviour occurs. Upon closing of ToxAV instance, all active calls will be | ||
91 | * forcibly terminated without notifying peers. | ||
92 | * | ||
93 | */ | ||
94 | struct this; | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * :: Creation and destruction | ||
99 | * | ||
100 | ******************************************************************************/ | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Start new A/V session. There can only be only one session per Tox instance. | ||
105 | */ | ||
106 | static this new(tox::this *tox) { | ||
107 | NULL, | ||
108 | /** | ||
109 | * Memory allocation failure while trying to allocate structures required for | ||
110 | * the A/V session. | ||
111 | */ | ||
112 | MALLOC, | ||
113 | /** | ||
114 | * Attempted to create a second session for the same Tox instance. | ||
115 | */ | ||
116 | MULTIPLE, | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Releases all resources associated with the A/V session. | ||
121 | * | ||
122 | * If any calls were ongoing, these will be forcibly terminated without | ||
123 | * notifying peers. After calling this function, no other functions may be | ||
124 | * called and the av pointer becomes invalid. | ||
125 | */ | ||
126 | void kill(); | ||
127 | |||
128 | /** | ||
129 | * Returns the Tox instance the A/V object was created for. | ||
130 | */ | ||
131 | tox::this *tox { get(); } | ||
132 | |||
133 | |||
134 | /******************************************************************************* | ||
135 | * | ||
136 | * :: A/V event loop | ||
137 | * | ||
138 | ******************************************************************************/ | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Returns the interval in milliseconds when the next toxav_iterate call should | ||
143 | * be. If no call is active at the moment, this function returns 200. | ||
144 | */ | ||
145 | const uint32_t iteration_interval(); | ||
146 | |||
147 | /** | ||
148 | * Main loop for the session. This function needs to be called in intervals of | ||
149 | * toxav_iteration_interval() milliseconds. It is best called in the separate | ||
150 | * thread from tox_iterate. | ||
151 | */ | ||
152 | void iterate(); | ||
153 | |||
154 | |||
155 | /******************************************************************************* | ||
156 | * | ||
157 | * :: Call setup | ||
158 | * | ||
159 | ******************************************************************************/ | ||
160 | |||
161 | |||
162 | /** | ||
163 | * Call a friend. This will start ringing the friend. | ||
164 | * | ||
165 | * It is the client's responsibility to stop ringing after a certain timeout, | ||
166 | * if such behaviour is desired. If the client does not stop ringing, the | ||
167 | * library will not stop until the friend is disconnected. Audio and video | ||
168 | * receiving are both enabled by default. | ||
169 | * | ||
170 | * @param friend_number The friend number of the friend that should be called. | ||
171 | * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable | ||
172 | * audio sending. | ||
173 | * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable | ||
174 | * video sending. | ||
175 | */ | ||
176 | bool call(uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate) { | ||
177 | /** | ||
178 | * A resource allocation error occurred while trying to create the structures | ||
179 | * required for the call. | ||
180 | */ | ||
181 | MALLOC, | ||
182 | /** | ||
183 | * Synchronization error occurred. | ||
184 | */ | ||
185 | SYNC, | ||
186 | /** | ||
187 | * The friend number did not designate a valid friend. | ||
188 | */ | ||
189 | FRIEND_NOT_FOUND, | ||
190 | /** | ||
191 | * The friend was valid, but not currently connected. | ||
192 | */ | ||
193 | FRIEND_NOT_CONNECTED, | ||
194 | /** | ||
195 | * Attempted to call a friend while already in an audio or video call with | ||
196 | * them. | ||
197 | */ | ||
198 | FRIEND_ALREADY_IN_CALL, | ||
199 | /** | ||
200 | * Audio or video bit rate is invalid. | ||
201 | */ | ||
202 | INVALID_BIT_RATE, | ||
203 | } | ||
204 | |||
205 | event call { | ||
206 | /** | ||
207 | * The function type for the ${event call} callback. | ||
208 | * | ||
209 | * @param friend_number The friend number from which the call is incoming. | ||
210 | * @param audio_enabled True if friend is sending audio. | ||
211 | * @param video_enabled True if friend is sending video. | ||
212 | */ | ||
213 | typedef void(uint32_t friend_number, bool audio_enabled, bool video_enabled); | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * Accept an incoming call. | ||
218 | * | ||
219 | * If answering fails for any reason, the call will still be pending and it is | ||
220 | * possible to try and answer it later. Audio and video receiving are both | ||
221 | * enabled by default. | ||
222 | * | ||
223 | * @param friend_number The friend number of the friend that is calling. | ||
224 | * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable | ||
225 | * audio sending. | ||
226 | * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable | ||
227 | * video sending. | ||
228 | */ | ||
229 | bool answer(uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate) { | ||
230 | /** | ||
231 | * Synchronization error occurred. | ||
232 | */ | ||
233 | SYNC, | ||
234 | /** | ||
235 | * Failed to initialize codecs for call session. Note that codec initiation | ||
236 | * will fail if there is no receive callback registered for either audio or | ||
237 | * video. | ||
238 | */ | ||
239 | CODEC_INITIALIZATION, | ||
240 | /** | ||
241 | * The friend number did not designate a valid friend. | ||
242 | */ | ||
243 | FRIEND_NOT_FOUND, | ||
244 | /** | ||
245 | * The friend was valid, but they are not currently trying to initiate a call. | ||
246 | * This is also returned if this client is already in a call with the friend. | ||
247 | */ | ||
248 | FRIEND_NOT_CALLING, | ||
249 | /** | ||
250 | * Audio or video bit rate is invalid. | ||
251 | */ | ||
252 | INVALID_BIT_RATE, | ||
253 | } | ||
254 | |||
255 | |||
256 | /******************************************************************************* | ||
257 | * | ||
258 | * :: Call state graph | ||
259 | * | ||
260 | ******************************************************************************/ | ||
261 | |||
262 | |||
263 | bitmask FRIEND_CALL_STATE { | ||
264 | /** | ||
265 | * Set by the AV core if an error occurred on the remote end or if friend | ||
266 | * timed out. This is the final state after which no more state | ||
267 | * transitions can occur for the call. This call state will never be triggered | ||
268 | * in combination with other call states. | ||
269 | */ | ||
270 | ERROR, | ||
271 | /** | ||
272 | * The call has finished. This is the final state after which no more state | ||
273 | * transitions can occur for the call. This call state will never be | ||
274 | * triggered in combination with other call states. | ||
275 | */ | ||
276 | FINISHED, | ||
277 | /** | ||
278 | * The flag that marks that friend is sending audio. | ||
279 | */ | ||
280 | SENDING_A, | ||
281 | /** | ||
282 | * The flag that marks that friend is sending video. | ||
283 | */ | ||
284 | SENDING_V, | ||
285 | /** | ||
286 | * The flag that marks that friend is receiving audio. | ||
287 | */ | ||
288 | ACCEPTING_A, | ||
289 | /** | ||
290 | * The flag that marks that friend is receiving video. | ||
291 | */ | ||
292 | ACCEPTING_V, | ||
293 | } | ||
294 | |||
295 | event call_state { | ||
296 | /** | ||
297 | * The function type for the ${event call_state} callback. | ||
298 | * | ||
299 | * @param friend_number The friend number for which the call state changed. | ||
300 | * @param state The bitmask of the new call state which is guaranteed to be | ||
301 | * different than the previous state. The state is set to 0 when the call is | ||
302 | * paused. The bitmask represents all the activities currently performed by the | ||
303 | * friend. | ||
304 | */ | ||
305 | typedef void(uint32_t friend_number, uint32_t state); | ||
306 | } | ||
307 | |||
308 | |||
309 | /******************************************************************************* | ||
310 | * | ||
311 | * :: Call control | ||
312 | * | ||
313 | ******************************************************************************/ | ||
314 | |||
315 | |||
316 | enum class CALL_CONTROL { | ||
317 | /** | ||
318 | * Resume a previously paused call. Only valid if the pause was caused by this | ||
319 | * client, if not, this control is ignored. Not valid before the call is accepted. | ||
320 | */ | ||
321 | RESUME, | ||
322 | /** | ||
323 | * Put a call on hold. Not valid before the call is accepted. | ||
324 | */ | ||
325 | PAUSE, | ||
326 | /** | ||
327 | * Reject a call if it was not answered, yet. Cancel a call after it was | ||
328 | * answered. | ||
329 | */ | ||
330 | CANCEL, | ||
331 | /** | ||
332 | * Request that the friend stops sending audio. Regardless of the friend's | ||
333 | * compliance, this will cause the ${event audio.receive_frame} event to stop being | ||
334 | * triggered on receiving an audio frame from the friend. | ||
335 | */ | ||
336 | MUTE_AUDIO, | ||
337 | /** | ||
338 | * Calling this control will notify client to start sending audio again. | ||
339 | */ | ||
340 | UNMUTE_AUDIO, | ||
341 | /** | ||
342 | * Request that the friend stops sending video. Regardless of the friend's | ||
343 | * compliance, this will cause the ${event video.receive_frame} event to stop being | ||
344 | * triggered on receiving a video frame from the friend. | ||
345 | */ | ||
346 | HIDE_VIDEO, | ||
347 | /** | ||
348 | * Calling this control will notify client to start sending video again. | ||
349 | */ | ||
350 | SHOW_VIDEO, | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * Sends a call control command to a friend. | ||
355 | * | ||
356 | * @param friend_number The friend number of the friend this client is in a call | ||
357 | * with. | ||
358 | * @param control The control command to send. | ||
359 | * | ||
360 | * @return true on success. | ||
361 | */ | ||
362 | bool call_control(uint32_t friend_number, CALL_CONTROL control) { | ||
363 | /** | ||
364 | * Synchronization error occurred. | ||
365 | */ | ||
366 | SYNC, | ||
367 | /** | ||
368 | * The friend_number passed did not designate a valid friend. | ||
369 | */ | ||
370 | FRIEND_NOT_FOUND, | ||
371 | /** | ||
372 | * This client is currently not in a call with the friend. Before the call is | ||
373 | * answered, only CANCEL is a valid control. | ||
374 | */ | ||
375 | FRIEND_NOT_IN_CALL, | ||
376 | /** | ||
377 | * Happens if user tried to pause an already paused call or if trying to | ||
378 | * resume a call that is not paused. | ||
379 | */ | ||
380 | INVALID_TRANSITION, | ||
381 | } | ||
382 | |||
383 | |||
384 | /******************************************************************************* | ||
385 | * | ||
386 | * :: Controlling bit rates | ||
387 | * | ||
388 | ******************************************************************************/ | ||
389 | |||
390 | |||
391 | namespace bit_rate { | ||
392 | /** | ||
393 | * Set the bit rate to be used in subsequent audio/video frames. | ||
394 | * | ||
395 | * @param friend_number The friend number of the friend for which to set the | ||
396 | * bit rate. | ||
397 | * @param audio_bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable | ||
398 | * audio sending. Set to -1 to leave unchanged. | ||
399 | * @param video_bit_rate The new video bit rate in Kb/sec. Set to 0 to disable | ||
400 | * video sending. Set to -1 to leave unchanged. | ||
401 | * | ||
402 | */ | ||
403 | bool set(uint32_t friend_number, int32_t audio_bit_rate, int32_t video_bit_rate) { | ||
404 | /** | ||
405 | * Synchronization error occurred. | ||
406 | */ | ||
407 | SYNC, | ||
408 | /** | ||
409 | * The audio bit rate passed was not one of the supported values. | ||
410 | */ | ||
411 | INVALID_AUDIO_BIT_RATE, | ||
412 | /** | ||
413 | * The video bit rate passed was not one of the supported values. | ||
414 | */ | ||
415 | INVALID_VIDEO_BIT_RATE, | ||
416 | /** | ||
417 | * The friend_number passed did not designate a valid friend. | ||
418 | */ | ||
419 | FRIEND_NOT_FOUND, | ||
420 | /** | ||
421 | * This client is currently not in a call with the friend. | ||
422 | */ | ||
423 | FRIEND_NOT_IN_CALL, | ||
424 | } | ||
425 | |||
426 | event status { | ||
427 | /** | ||
428 | * The function type for the ${event status} callback. The event is triggered | ||
429 | * when the network becomes too saturated for current bit rates at which | ||
430 | * point core suggests new bit rates. | ||
431 | * | ||
432 | * @param friend_number The friend number of the friend for which to set the | ||
433 | * bit rate. | ||
434 | * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec. | ||
435 | * @param video_bit_rate Suggested maximum video bit rate in Kb/sec. | ||
436 | */ | ||
437 | typedef void(uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | |||
442 | /******************************************************************************* | ||
443 | * | ||
444 | * :: A/V sending | ||
445 | * | ||
446 | ******************************************************************************/ | ||
447 | |||
448 | |||
449 | error for send_frame { | ||
450 | /** | ||
451 | * In case of video, one of Y, U, or V was NULL. In case of audio, the samples | ||
452 | * data pointer was NULL. | ||
453 | */ | ||
454 | NULL, | ||
455 | /** | ||
456 | * The friend_number passed did not designate a valid friend. | ||
457 | */ | ||
458 | FRIEND_NOT_FOUND, | ||
459 | /** | ||
460 | * This client is currently not in a call with the friend. | ||
461 | */ | ||
462 | FRIEND_NOT_IN_CALL, | ||
463 | /** | ||
464 | * Synchronization error occurred. | ||
465 | */ | ||
466 | SYNC, | ||
467 | /** | ||
468 | * One of the frame parameters was invalid. E.g. the resolution may be too | ||
469 | * small or too large, or the audio sampling rate may be unsupported. | ||
470 | */ | ||
471 | INVALID, | ||
472 | /** | ||
473 | * Either friend turned off audio or video receiving or we turned off sending | ||
474 | * for the said payload. | ||
475 | */ | ||
476 | PAYLOAD_TYPE_DISABLED, | ||
477 | /** | ||
478 | * Failed to push frame through rtp interface. | ||
479 | */ | ||
480 | RTP_FAILED, | ||
481 | } | ||
482 | |||
483 | namespace audio { | ||
484 | /** | ||
485 | * Send an audio frame to a friend. | ||
486 | * | ||
487 | * The expected format of the PCM data is: [s1c1][s1c2][...][s2c1][s2c2][...]... | ||
488 | * Meaning: sample 1 for channel 1, sample 1 for channel 2, ... | ||
489 | * For mono audio, this has no meaning, every sample is subsequent. For stereo, | ||
490 | * this means the expected format is LRLRLR... with samples for left and right | ||
491 | * alternating. | ||
492 | * | ||
493 | * @param friend_number The friend number of the friend to which to send an | ||
494 | * audio frame. | ||
495 | * @param pcm An array of audio samples. The size of this array must be | ||
496 | * sample_count * channels. | ||
497 | * @param sample_count Number of samples in this frame. Valid numbers here are | ||
498 | * ((sample rate) * (audio length) / 1000), where audio length can be | ||
499 | * 2.5, 5, 10, 20, 40 or 60 millseconds. | ||
500 | * @param channels Number of audio channels. Supported values are 1 and 2. | ||
501 | * @param sampling_rate Audio sampling rate used in this frame. Valid sampling | ||
502 | * rates are 8000, 12000, 16000, 24000, or 48000. | ||
503 | */ | ||
504 | bool send_frame(uint32_t friend_number, const int16_t *pcm, size_t sample_count, | ||
505 | uint8_t channels, uint32_t sampling_rate) with error for send_frame; | ||
506 | } | ||
507 | |||
508 | namespace video { | ||
509 | /** | ||
510 | * Send a video frame to a friend. | ||
511 | * | ||
512 | * Y - plane should be of size: height * width | ||
513 | * U - plane should be of size: (height/2) * (width/2) | ||
514 | * V - plane should be of size: (height/2) * (width/2) | ||
515 | * | ||
516 | * @param friend_number The friend number of the friend to which to send a video | ||
517 | * frame. | ||
518 | * @param width Width of the frame in pixels. | ||
519 | * @param height Height of the frame in pixels. | ||
520 | * @param y Y (Luminance) plane data. | ||
521 | * @param u U (Chroma) plane data. | ||
522 | * @param v V (Chroma) plane data. | ||
523 | */ | ||
524 | bool send_frame(uint32_t friend_number, uint16_t width, uint16_t height, | ||
525 | const uint8_t *y, const uint8_t *u, const uint8_t *v) with error for send_frame; | ||
526 | } | ||
527 | |||
528 | |||
529 | /******************************************************************************* | ||
530 | * | ||
531 | * :: A/V receiving | ||
532 | * | ||
533 | ******************************************************************************/ | ||
534 | |||
535 | |||
536 | namespace audio { | ||
537 | event receive_frame { | ||
538 | /** | ||
539 | * The function type for the ${event receive_frame} callback. The callback can be | ||
540 | * called multiple times per single iteration depending on the amount of queued | ||
541 | * frames in the buffer. The received format is the same as in send function. | ||
542 | * | ||
543 | * @param friend_number The friend number of the friend who sent an audio frame. | ||
544 | * @param pcm An array of audio samples (sample_count * channels elements). | ||
545 | * @param sample_count The number of audio samples per channel in the PCM array. | ||
546 | * @param channels Number of audio channels. | ||
547 | * @param sampling_rate Sampling rate used in this frame. | ||
548 | * | ||
549 | */ | ||
550 | typedef void(uint32_t friend_number, const int16_t *pcm, size_t sample_count, | ||
551 | uint8_t channels, uint32_t sampling_rate); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | namespace video { | ||
556 | event receive_frame { | ||
557 | /** | ||
558 | * The function type for the ${event receive_frame} callback. | ||
559 | * | ||
560 | * The size of plane data is derived from width and height as documented | ||
561 | * below. | ||
562 | * | ||
563 | * Strides represent padding for each plane that may or may not be present. | ||
564 | * You must handle strides in your image processing code. Strides are | ||
565 | * negative if the image is bottom-up hence why you MUST abs() it when | ||
566 | * calculating plane buffer size. | ||
567 | * | ||
568 | * @param friend_number The friend number of the friend who sent a video frame. | ||
569 | * @param width Width of the frame in pixels. | ||
570 | * @param height Height of the frame in pixels. | ||
571 | * @param y Luminosity plane. Size = MAX(width, abs(ystride)) * height. | ||
572 | * @param u U chroma plane. Size = MAX(width/2, abs(ustride)) * (height/2). | ||
573 | * @param v V chroma plane. Size = MAX(width/2, abs(vstride)) * (height/2). | ||
574 | * | ||
575 | * @param ystride Luminosity plane stride. | ||
576 | * @param ustride U chroma plane stride. | ||
577 | * @param vstride V chroma plane stride. | ||
578 | */ | ||
579 | typedef void(uint32_t friend_number, uint16_t width, uint16_t height, | ||
580 | const uint8_t *y, const uint8_t *u, const uint8_t *v, | ||
581 | int32_t ystride, int32_t ustride, int32_t vstride); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | } | ||
586 | |||
587 | %{ | ||
588 | /** | ||
589 | * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove | ||
590 | */ | ||
591 | /* Create a new toxav group. | ||
592 | * | ||
593 | * return group number on success. | ||
594 | * return -1 on failure. | ||
595 | * | ||
596 | * Audio data callback format: | ||
597 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
598 | * | ||
599 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
600 | */ | ||
601 | int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(void *, int, int, const int16_t *, unsigned int, uint8_t, | ||
602 | unsigned int, void *), void *userdata); | ||
603 | |||
604 | /* Join a AV group (you need to have been invited first.) | ||
605 | * | ||
606 | * returns group number on success | ||
607 | * returns -1 on failure. | ||
608 | * | ||
609 | * Audio data callback format (same as the one for toxav_add_av_groupchat()): | ||
610 | * audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata) | ||
611 | * | ||
612 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
613 | */ | ||
614 | int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length, | ||
615 | void (*audio_callback)(void *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata); | ||
616 | |||
617 | /* Send audio to the group chat. | ||
618 | * | ||
619 | * return 0 on success. | ||
620 | * return -1 on failure. | ||
621 | * | ||
622 | * Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)). | ||
623 | * | ||
624 | * Valid number of samples are ((sample rate) * (audio length (Valid ones are: 2.5, 5, 10, 20, 40 or 60 ms)) / 1000) | ||
625 | * Valid number of channels are 1 or 2. | ||
626 | * Valid sample rates are 8000, 12000, 16000, 24000, or 48000. | ||
627 | * | ||
628 | * Recommended values are: samples = 960, channels = 1, sample_rate = 48000 | ||
629 | */ | ||
630 | int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, | ||
631 | unsigned int sample_rate); | ||
632 | |||
633 | #ifdef __cplusplus | ||
634 | } | ||
635 | #endif | ||
636 | #endif /* TOXAV_H */ | ||
637 | %} | ||