Compare commits

..

334 Commits

Author SHA1 Message Date
8d5b619884 full on qoi 2024-03-04 13:38:55 +01:00
2cbda6e7be qoi lib 2024-03-04 12:41:12 +01:00
029df21423 Add 'external/qoi/qoi/' from commit '30d15d79b7726b977cd889151cc5cd6b17742f8f'
git-subtree-dir: external/qoi/qoi
git-subtree-mainline: 28b92b0f4c
git-subtree-split: 30d15d79b7
2024-03-04 12:39:30 +01:00
30d15d79b7 Merge pull request #296 from RomanPro100/master
Add Uiua to "QOI Support in Other Software"
2024-01-18 20:40:14 +01:00
aeb22ad898 Add Uiua to "QOI Support in Other Software" 2024-01-18 22:36:31 +03:00
56ee13c628 Merge pull request #295 from pfusik/imagine
Mention Imagine
2024-01-18 20:01:10 +01:00
e28e20ea83 Mention Imagine 2024-01-17 16:57:07 +01:00
827a7e4418 Merge pull request #292 from finnurthorisson/Add-Lua-LIL
Add Lua LIL
2023-12-11 13:25:07 +01:00
bc8242a28d Add Lua LIL 2023-12-11 10:26:13 +00:00
99159e0bb2 Merge pull request #291 from zertovitch/patch-1
Added implementation of QOI in Ada
2023-12-09 17:05:23 +01:00
35054beeb9 Added implementation of QOI in Ada
The link refers to the Generic Image Decoder (GID) library.
2023-12-09 14:22:00 +01:00
d53fe6c515 Merge pull request #290 from LuisAlfredo92/patch-1
Update README.md
2023-12-02 11:15:02 +01:00
abde91410e Update README.md
Adding SixLabors/ImageSharp
2023-12-01 19:46:19 -06:00
9c487be4fe Merge pull request #288 from phlash/master
Added Swingland implementation
2023-10-20 12:25:07 +02:00
6e949186e6 Added Swingland implemenation 2023-10-19 11:12:49 +01:00
2f9f92f133 Merge pull request #287 from vtorri/vtorri_efl
Mention QOI encoding and decoding support in the EFL
2023-10-17 17:48:32 +02:00
26130106d9 Mention QOI support in the EFL 2023-10-17 17:31:26 +02:00
8d35d93cdc Merge pull request #284 from n00bmind/master
~ Update link to n00bmind/qoi
2023-09-10 22:32:21 +02:00
dcfec1a44d ~ Update link to n00bmind/qoi 2023-09-10 19:19:34 +01:00
4b16be3941 Merge pull request #283 from colemanrgb/master
Add link to decoding and encoding QOI files on RISC OS
2023-09-06 22:22:13 +02:00
e020e4db76 Merge pull request #282 from n00bmind/master
+ Add link to Jai implementation
2023-09-04 14:22:24 +02:00
d23d8f3fea + Add link to Jai implementation 2023-09-03 23:15:36 +01:00
52d9ad5024 Add link to decoding and encoding QOI files on RISC OS 2023-09-02 12:03:35 +01:00
351450e00d Merge pull request #281 from Ernest1338/kde-qoi
Mention KDE's encoding support
2023-08-31 17:46:34 +02:00
dbd68f185f KDE now has encoding support as well 2023-08-31 17:36:53 +02:00
41e8f84bf6 Merge pull request #280 from SpeckyYT/patch-1
Add link to spwn-qoi
2023-08-28 09:09:50 +02:00
855cd4c61e Add link to spwn-qoi 2023-08-27 22:56:32 +02:00
d61e911777 Merge pull request #279 from pfusik/qoi-fu-d
qoi-fu transpiles to D
2023-08-25 10:22:14 +02:00
972a28c955 qoi-fu transpiles to D 2023-08-25 09:27:50 +02:00
7e3b202f9e Merge pull request #278 from Floessie/pam2qoi
Add link to pam2qoi
2023-08-19 20:48:53 +02:00
4231ace045 Add link to pam2qoi 2023-08-19 11:28:21 +02:00
8785fe9f00 Merge pull request #274 from Ernest1338/kde-qoi
Mention QOI support in KDE
2023-08-11 23:38:46 +02:00
a06ba04fa4 Mention QOI support in KDE 2023-08-11 23:33:22 +02:00
19b3b4087b Merge pull request #272 from pfusik/qoi-fu
qoi-ci renamed to qoi-fu
2023-08-10 00:32:16 +02:00
4adab9d4e0 qoi-ci renamed to qoi-fu 2023-08-09 14:28:11 +02:00
9ab99731f8 Merge pull request #271 from victoryforce/QOI-support-in-darktable
Mention QOI support in darktable
2023-07-18 15:05:25 +02:00
1527109c28 Mention QOI support in darktable 2023-07-17 21:33:38 +03:00
f65b365318 Merge pull request #269 from N-R-K/less_hardcode_bench
Less hardcoded benchmarking code
2023-06-16 15:35:38 +02:00
NRK
706ed3eb68 Less hardcoded benchmarking code
this allows people to more easily plugin their implementation for
benchmarking purposes.
2023-06-16 17:31:57 +06:00
c6219a5696 Merge pull request #266 from bpanthi977/master
Add link to Common Lisp implementation
2023-06-15 18:05:29 +02:00
ef61984291 Merge pull request #268 from N-R-K/stdio_errcheck
More strict stdio error checking
2023-06-15 18:03:53 +02:00
NRK
36190eb07d Error check qoi_read() more strictly
fseek is not guaranteed to succeed and can fail, e.g when trying to
seek a pipe. the first fseek() is not error checked since if it failed,
ftell would return 0.

also check for fread errors too before calling qoi_decode().
2023-06-15 16:06:03 +06:00
NRK
00dfdc8b5c Error check qoi_write() more strictly
simply checking the return value of fwrite() wouldn't be enough since
stdio is typically buffered. and so force a flush and check for errors
via ferror().
2023-06-15 14:36:19 +06:00
dfc056e813 Merge pull request #267 from Aftersol/master
Update README.md
2023-05-18 10:23:22 +02:00
76e3789073 Update README.md
small change to my link
2023-05-17 13:32:51 -07:00
1ae0c19492 Add link to Common Lisp implementation 2023-04-30 19:14:36 +05:45
f6dffaf1e8 Merge pull request #263 from sylikc/other-jpegview
add JPEGView to end of Other Software list
2023-03-11 18:44:55 +01:00
040f8a15e5 add JPEGView to end of Other Software list 2023-03-02 00:49:34 -08:00
3dfa66d8fd Merge pull request #262 from LTMX/patch-1
Mention LTMX/Unity.QOI in Tools section
2023-02-24 15:35:45 +01:00
013c745284 Mention LTMX/Unity.QOI in Tools section 2023-02-24 14:20:00 +01:00
0d8d07971b Merge pull request #260 from pfusik/qoi-ci-ts
Mention qoi-ci transpiling to TypeScript
2023-02-09 11:15:34 +01:00
6d5a7ab2fd Mention qoi-ci transpiling to TypeScript 2023-02-09 08:01:07 +01:00
514c259711 Mention ffmpeg support; close #259 2023-02-06 13:35:58 +01:00
c0a27f808f Mention ZTQOI 2023-01-22 20:03:08 +01:00
dc4b97471a Mention tacentview 2023-01-22 20:03:01 +01:00
071f0ce957 Merge pull request #257 from grego/master
Add a link to a Hare implementation to README
2023-01-20 14:44:31 +01:00
d70233b2c6 Add a link to a Hare implementation to README 2023-01-19 21:44:26 +01:00
c3dcfe780b Add LICENSE file; close #250 2022-12-13 21:08:09 +01:00
660839cb2c Merge pull request #247 from lbatalha/master
Add CFLAGS as per GNU Coding Standards
2022-11-16 19:51:04 +01:00
5c787e4173 add CFLAGS as per gnu standards 2022-11-16 15:52:39 +00:00
b8d77df1e8 Merge pull request #245 from rubikscraft/patch-1
Add a singe byte streaming C99 QOI library and NodeJS bindings
2022-09-25 18:32:08 +02:00
3a0560cb77 Add a streaming C qoi library and nodejs bindings 2022-09-24 16:13:23 +02:00
cf90aa165c Merge pull request #244 from LuisAlfredo92/patch-1
Adding Super QOi converter to Tools
2022-09-23 00:16:58 +02:00
07c6d6f7d7 Adding Super QOi converter to Tools
Adding Super QOI converter to Tools section, with links to console and GUI version
2022-09-20 22:22:36 -05:00
b40d1edbae Merge pull request #243 from hzeller/20220920-add-timg-to-tools
Add timg to tool list; provides qoi image viewing in terminal.
2022-09-20 10:16:15 +02:00
63acdd2796 Add timg to tool list; provides qoi image viewing in terminal.
Signed-off-by: Henner Zeller <h.zeller@acm.org>
2022-09-20 00:02:59 -07:00
7039fcd60c Merge pull request #241 from pfusik/qoi-ci-2.0.0
Windows Explorer, Finder, GNOME plugins released in qoi-ci
2022-09-12 12:39:47 +02:00
21c840a2e7 Windows Explorer, Finder, GNOME plugins released in qoi-ci 2022-09-12 12:24:33 +02:00
23c790ce59 Add Racket implementation; close #217 2022-08-06 00:49:35 +02:00
425dfe1221 Add Java SPI implementation; close #210 2022-08-06 00:46:10 +02:00
43240dbc20 Add KDE & Nemo thumbnailers; close #174 2022-08-06 00:38:15 +02:00
aca9552827 Add MacOS QuickLook plugin; close #165 2022-08-06 00:34:50 +02:00
e4892c7aa2 Add delphi implementation; close #144 2022-08-06 00:32:41 +02:00
02a49e5410 Remove outdated implementations 2022-08-06 00:06:55 +02:00
f177c193e0 Attempt to make list of tools and implementation a bit easier to read 2022-08-06 00:05:21 +02:00
76583cc18d Wording 2022-08-06 00:04:49 +02:00
948a53e04c Link QOI plugins to releases overview page 2022-08-06 00:02:20 +02:00
a488d3be0f Mention Debian & Ubuntu packages; add link to Repology 2022-08-05 23:45:59 +02:00
bcb2fb5e48 Add note about MIME type; close #167 2022-08-05 23:44:51 +02:00
a4e7750d68 Add SPDX License Identifier, remove license text; close #168 2022-08-05 23:39:12 +02:00
a2cfc864a2 Merge pull request #237 from pfusik/qoi-ci-1.1.2
New release of qoi-ci
2022-08-03 21:50:35 +02:00
b64209287f New release of qoi-ci 2022-08-03 20:17:24 +02:00
d6e88eb1be Merge pull request #236 from AmCh-Q/patch-1
Fix small typo in qoibench.c
2022-08-02 13:28:08 +02:00
370be5c080 Fix small typo in qoibench.c 2022-08-02 06:36:17 -04:00
b6bf448c41 Merge pull request #235 from ryuukk/patch-1
Add gamut D library
2022-08-01 13:22:40 +02:00
32ac6c3c0f Add gamut D library 2022-07-29 16:23:23 +02:00
3b0a7ebc5f Merge pull request #234 from Aftersol/master
Request for Inclusion into READMD.md
2022-07-28 12:39:03 +02:00
583cdd311e Update README.md 2022-07-28 01:45:28 -07:00
376d39cc67 add my own project link to README.md 2022-07-28 01:28:28 -07:00
edb8d7b114 Merge pull request #226 from Ben1138/unity-qoi
Added unity-qoi to Readme
2022-06-21 08:54:17 +02:00
Ben
948a86f507 Added unity-qoi to Readme 2022-06-20 20:28:55 +02:00
ed5c0287e6 Merge pull request #225 from mzgreen/patch-1
Add Kotlin Multiplatform implementation to the README list
2022-06-20 16:09:32 +02:00
ef929be770 Add Kotlin Multiplatform implementation to the README list 2022-06-20 14:33:20 +02:00
11673fc39c Merge pull request #224 from polluks2/patch-1
Fixed broken makefile
2022-06-18 15:05:09 +02:00
9434e96f9b Fixed broken makefile 2022-06-18 14:39:05 +02:00
1995afbb82 Merge pull request #223 from xiaozhuai/master
Add Jetbrains' plugin url
2022-06-14 20:04:16 +02:00
14c22321ff Add Jetbrains' plugin url 2022-06-14 17:36:49 +08:00
ff148ed284 Merge pull request #222 from dgaw/patch-1
Add AmigaOS support to README
2022-06-13 01:04:20 +02:00
fc4bec9099 Add AmigaOS support to README
Add a link to a datatype plugin that adds QOI support to AmigaOS.
2022-06-12 20:18:57 +02:00
1f4e585898 Merge pull request #221 from Fabien-Chouteau/patch-1
Add link to Ada/SPARK implementation
2022-06-12 09:31:15 +02:00
c1c46c8a76 Add link to Ada/SPARK implementation 2022-06-12 08:35:13 +02:00
b4fab6fbc3 Merge pull request #220 from LuisAlfredo92/patch-1
Adding links to required libreries
2022-06-11 22:10:28 +02:00
553eae423a Adding qoi.h dependency
Adding the text to indicate that "qoi.h" is required to use this file
2022-06-11 13:26:59 -05:00
bce1a069a8 Adding links to required libreries
Adding the URLs to the repo of the required libraries to make even easier to use this program
2022-06-11 12:58:41 -05:00
6005c73e0a Add PureBasic implementation to readme 2022-06-07 09:37:35 +02:00
57628d9d4d Merge pull request #214 from pfusik/xnviewmp
Mention XnView MP
2022-05-24 18:46:00 +02:00
6ba3c1b42e Mention XnView MP 2022-05-24 08:52:18 +02:00
fa70cfc6d2 Merge pull request #213 from 418Coffee/patch-1
Add V implementation
2022-05-22 00:23:40 +02:00
d1875b5ac8 Add V Implementation 2022-05-21 21:16:20 +02:00
911ca7b65f Merge pull request #209 from varuld/simple_makefile
Simple makefile
2022-05-17 15:53:03 +02:00
5204343519 Replaced remaining := with ?= to allow CLI parameters 2022-05-12 14:53:17 +02:00
06d032339b CC:= -> CC?= and removal of dependency cleaning 2022-05-12 14:08:51 +02:00
9374bd61ae feat; working makefile 2022-05-12 10:07:44 +02:00
b9d1e9c3eb feat; init makefile iteration 2022-05-12 09:52:51 +02:00
75e7f308a4 Merge pull request #208 from 0xd34df00d/patch-1
Haskell implementation synced with the spec
2022-05-09 17:40:41 +02:00
a4f498b23c Haskell implementation synced with the spec 2022-05-07 16:22:03 -04:00
805953b1c7 Merge pull request #207 from 10maurycy10/patch-1
Add yet another implementation.
2022-05-04 13:19:37 +02:00
2e58276f20 Add yet another implementaion 2022-05-03 14:26:19 -07:00
6d7eadd28c Merge pull request #205 from JaffaKetchup/added-dart-implementation
Add 'dqoi' to the implementations list on README
2022-04-25 13:50:04 +02:00
70894be9aa Specified framework support
Flutter is the application framework that uses Dart. 'dqoi' provides full support for Flutter apps with custom image painters.
2022-04-25 11:54:00 +01:00
8308c4c107 Add 'dqoi' to the implementations list on README
'dqoi' is my implementation of QOI for Dart and Flutter, based off the C code included here, and @LowLevelJavaScript's implementation.
2022-04-22 20:29:47 +01:00
339e11e2fd Add info about versioning and contributing 2022-04-21 21:25:59 +02:00
3a90672872 Merge pull request #202 from shraiwi/master
Add C streaming decoder to readme.md
2022-04-19 17:03:59 +02:00
477a589907 Merge pull request #201 from HappySeaFox/master
Update link to SAIL library
2022-04-19 17:03:34 +02:00
682273b101 Add C streaming decoder to readme.md 2022-04-16 20:38:36 -05:00
e3612650c0 Update link to SAIL library 2022-04-15 11:18:01 -07:00
028c75fd26 Merge pull request #199 from JohannesFriedrich/master
Add R-package QOI to README.md
2022-04-12 23:51:52 +02:00
J_F
cc97aaed08 Add R-package QOI to README.md 2022-04-12 21:42:58 +02:00
e42b0b3022 Load/store RGBA separately instead of using a typecast; close #197
This should fix problems on big-endian machines and with ILP64
2022-04-11 23:19:04 +02:00
59e0575c49 Remove obsolete, unused vars; close #56 2022-04-11 22:35:39 +02:00
1f8d2b752d Merge pull request #192 from Tiefseetauchner/patch-1
Added lr-paint processing qoi capable drawing program
2022-04-11 22:13:44 +02:00
bf50a4253a Merge branch 'master' into patch-1 2022-04-11 22:13:38 +02:00
d3e2aa8b20 Merge pull request #196 from mathpn/master
include py-qoi in readme
2022-04-11 22:12:37 +02:00
1181570cdf Merge pull request #190 from amstan/upstream
QOI on an FPGA (Verilog)!
2022-04-11 22:09:17 +02:00
4e8e5b6a70 Merge branch 'master' into upstream 2022-04-11 22:09:11 +02:00
c861c4b825 Merge pull request #198 from pfusik/qoi-ci-1.1.1
New release of qoi-ci
2022-04-11 22:08:08 +02:00
1296ad8179 New release of qoi-ci 2022-04-11 21:46:56 +02:00
773915aefd include py-qoi in readme
include a new native python implementation of encoder + decoder following QOI format specifications
2022-04-09 21:56:13 -03:00
a5075d1b6f Merge pull request #195 from musabkilic/musabkilic-patch-1
Add musabkilic/qoi-decoder to implementations
2022-04-09 16:43:42 +02:00
7506300a3e Add musabkilic/qoi-decoder to implementations 2022-04-09 17:17:36 +03:00
fc0eef8e54 Added lr-paint processing qoi capable drawing program
I made LR-Paint in three days to proof (mainly to myself) how simple it is to implement QOI
So I wrote it in Processing
Like any madman would
It's great trust me
And this is totally serious, I want the abomination of Processing code I made to be in the QOI Readme yes yes
2022-04-07 19:10:27 +02:00
56be991260 QOI on an FPGA (Verilog)! 2022-04-05 02:16:00 -07:00
09d144f892 Mention DOjS 2022-03-28 09:28:30 +02:00
009b481b07 Merge pull request #180 from soywiz/patch-1
Added KorGE & KorIM support engine & library to the README
2022-03-25 09:48:00 +01:00
8297ace59d Added KorGE & KorIM support engine & library 2022-03-25 03:09:48 +01:00
375f3f02b4 Merge pull request #175 from DmitriySalnikov/patch-1
Add link to QOI Addon for Godot Engine
2022-03-25 01:02:17 +01:00
9a4a7ce5e8 Merge branch 'master' into patch-1 2022-03-25 01:02:11 +01:00
3d77784bd5 Merge pull request #177 from dan9er/dan9er-readme-tool-farbfeld
Add link to farbfeld-convert-qoi tool in README
2022-03-25 01:00:34 +01:00
777b68ab2f Merge pull request #179 from jmaselbas/patch-2
Update readme with other software with QOI support
2022-03-25 00:59:40 +01:00
6170f9125d Update readme with other software with QOI support 2022-03-25 00:57:01 +01:00
27e433ef92 Merge pull request #178 from pfusik/irfanview
Mention IrfanView
2022-03-23 15:30:29 +01:00
73f04c2ef9 Mention IrfanView 2022-03-23 12:18:38 +01:00
606bf77678 Add link to farbfeld-convert-qoi tool in README 2022-03-02 04:04:04 +00:00
2cfe3f58fa Merge pull request #176 from wx257osn2/patch-1
Add qoixx in implementations list
2022-02-21 11:49:32 +01:00
I
be96074eb0 Add qoixx 2022-02-21 08:56:59 +09:00
6cfd82d35e Add link to QOI Addon for Godot Engine 2022-02-09 02:35:06 +03:00
7094132132 Mention rTexPacker 2022-02-06 12:12:20 +01:00
6c0831f91f Merge pull request #172 from orx/master
Added orx link (other software) to README.md
2022-01-31 18:35:55 +01:00
e6195209d8 Update README.md
Added Orx link to README.md
2022-01-31 10:56:59 -05:00
e8a3f40993 Merge pull request #171 from mhoward540/patch-1
Update README.md to reference Nim version
2022-01-30 12:18:58 +01:00
efd968caba Update README.md to reference Nim version 2022-01-29 20:18:05 +01:00
ee79afbe8b Mention rTexViewer 2022-01-28 01:24:10 +01:00
0db7d65c83 Merge pull request #169 from aquaratixc/patch-1
Update README.md
2022-01-20 20:11:47 +01:00
98d5f5187e Update README.md 2022-01-20 20:13:19 +03:00
e367cb19df Merge pull request #164 from aldanor/feature/add-qoi-rust
Add `qoi` Rust crate reference (aldanor/qoi-rust)
2022-01-06 11:50:43 +01:00
98e8a0237c Add qoi Rust crate reference (aldanor/qoi-rust) 2022-01-06 04:06:21 +03:00
fd6f6463ef Fix documentation for consecutive QOI_OP_INDEX chunks; close #112 2022-01-05 16:57:38 +01:00
07116e8b89 Clarify colorspace & channels header usage; #152 2022-01-05 16:55:27 +01:00
6804a745e4 Fix example in QOI_OP_LUMA documentation; close #161 2022-01-05 16:51:38 +01:00
a27f8ed459 Merge pull request #159 from kaetemi/master
Add link to QOI Bitmap I/O Plugin for 3ds Max
2022-01-04 12:52:08 +01:00
0219479867 Add link to QOI Bitmap I/O Plugin for 3ds Max 2022-01-04 11:34:34 +08:00
ef826267cc Merge pull request #147 from LucasMW/master
Add link to qoiConverter X
2022-01-03 13:52:22 +01:00
2870b54937 Changed Link
Changed to the most stable link
2022-01-03 12:48:27 +00:00
943d2b637b Merge pull request #157 from contriteobserver/gccwarnings
fixed gcc warnings in qoibench.c
2022-01-03 11:51:29 +01:00
a567e5d18e Merge pull request #139 from HappySeaFox/master
Added link to SAIL in README
2022-01-03 11:40:49 +01:00
1a38a0162f Merge pull request #141 from arian/patch-1
Add link to another Go implementation
2022-01-03 11:40:05 +01:00
1f19724a14 Merge branch 'master' into patch-1 2022-01-03 11:39:58 +01:00
82e6cc8ffc Merge pull request #140 from kchapelier/master
Add vanilla JavaScript implementation
2022-01-03 11:39:29 +01:00
501cebce7c Merge branch 'master' into master 2022-01-03 11:39:21 +01:00
f27dbdb94f Merge pull request #148 from KristofferC/patch-1
add a link to the Julia bindings
2022-01-03 11:38:08 +01:00
729c577ca3 Merge branch 'master' into patch-1 2022-01-03 11:38:01 +01:00
7e5ecc8091 Merge pull request #151 from ShadowMitia/patch-1
Add C++ implementation to the README list
2022-01-03 11:32:05 +01:00
a46f5537c8 Merge branch 'master' into patch-1 2022-01-03 11:31:42 +01:00
6a1595aca2 Merge pull request #149 from MKCG/php_library
Add PHP implementation
2022-01-03 11:31:05 +01:00
a4ea2819c4 fixed gcc warnings in qoibench.c
addresses issue #155
2022-01-02 01:26:42 -08:00
cf918138cf Add C++ implementation to the README list 2022-01-01 14:18:54 +01:00
48375ec75a Add PHP implementation 2021-12-31 14:34:55 +01:00
9ad3e1d7b4 add a link to the Julia bindings 2021-12-31 12:35:45 +01:00
05bf89291b Added qoiConverter X 2021-12-30 13:57:58 +00:00
a810fc0762 Add link to another Go implementation 2021-12-28 13:00:39 +01:00
a3d43a850a Add vanilla js implementation 2021-12-27 16:36:37 +01:00
96bfc2dbeb Added link to SAIL in README 2021-12-27 14:44:40 +03:00
00e3421744 Merge pull request #134 from jmaselbas/trailing_spaces
Style: Remove trailing whitespaces
2021-12-26 21:12:47 +01:00
8a27827c71 Merge pull request #133 from jmaselbas/fix_warn
Fix missing prototypes warning
2021-12-26 21:12:22 +01:00
aa1e345cd9 Merge pull request #136 from jsoref/spelling
Spelling
2021-12-26 21:10:05 +01:00
9d7977febf Merge pull request #137 from Tom94/add-tev-tool
Add link to tev image viewer to README
2021-12-26 21:08:26 +01:00
03d6e36d5d Add link to tev image viewer to README 2021-12-26 17:41:44 +01:00
b3f738a204 spelling: mismatch
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2021-12-25 22:49:37 -05:00
446d5e7008 spelling: measure
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2021-12-25 22:49:37 -05:00
2fff023912 spelling: ignore
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2021-12-25 22:49:37 -05:00
c3002a4d70 spelling: head
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2021-12-25 22:49:37 -05:00
da1070a234 Fix missing prototypes warning
Functions qoi_write_32 and qoi_read_32 should either have a prototype
or be declared static. Do the latter, as theses functions are defined
in a header and should only exists in the same compilation unit as the
file including qoi.h and defining QOI_IMPLEMENTATION, ie not exported.

By adding the static keyword in the function declaration the following
command doesn't raise a missing-prototypes warning, anymore:
    cc -Wmissing-prototypes -DQOI_IMPLEMENTATION -c -o qoi.o -xc qoi.h
2021-12-25 16:50:25 +01:00
b060b961e8 Style: Remove trailing whitespaces 2021-12-25 16:44:08 +01:00
c04a975e00 Merge pull request #131 from dbuenzli/ocaml-qoic
Mention qoic, an OCaml implementation.
2021-12-24 01:19:13 +01:00
61306d7ecd Mention qoic, an OCaml implementation. 2021-12-24 00:27:47 +01:00
69b6085d87 Mention xfmoulet/qoi in spec confirming; close #130 2021-12-24 00:12:53 +01:00
fd0d0a33ce Merge pull request #129 from vkoskiv/master
Mention support in the c-ray rendering engine
2021-12-23 22:56:31 +01:00
f9954f5b4b Mention support in the c-ray rendering engine 2021-12-23 23:20:16 +02:00
01af438e9a Merge pull request #128 from pfusik/qoi-ci-1.1.0
Mention Imagine plugin
2021-12-23 22:08:06 +01:00
193862433a Mention Imagine plugin. 2021-12-23 21:24:14 +01:00
c2c01cf5f6 Merge pull request #127 from elihwyma/patch-1
Update Swift-QOI bindings
2021-12-23 19:19:56 +01:00
bdcaaa1fb9 Update Swift-QOI bindings 2021-12-23 16:53:32 +00:00
9f38cffd96 Mention DosWorld/pasqoi; close #92 2021-12-23 12:00:35 +01:00
f0d532c2f1 Mention takeyourhatoff/qoi; close #126 2021-12-23 11:58:21 +01:00
19e118d78e Mention QOI thumbnail provider; #123 2021-12-23 11:52:24 +01:00
56c2272dbe Clarify pixel ordering; close #120 2021-12-23 11:45:19 +01:00
be12bf0b50 Merge pull request #124 from MasterQ32/zig_done
Zig implementation is now spec complete.
2021-12-23 11:43:15 +01:00
c69cc218e5 Merge branch 'master' into zig_done 2021-12-23 11:43:01 +01:00
b53930ad2a Merge pull request #116 from rbino/qoix-1.0-spec
Move Qoix to the implementations section
2021-12-23 11:40:58 +01:00
26365fe23c Merge branch 'master' into qoix-1.0-spec 2021-12-23 11:40:01 +01:00
a8d44375ff Merge pull request #119 from Oldes/master
Mention support in Rebol3; close #58
2021-12-23 11:38:42 +01:00
a53f656538 Merge pull request #121 from NUlliiON/master
Move QoiSharp to the implementations section
2021-12-23 11:38:15 +01:00
51cd6a56f8 Merge branch 'master' into master 2021-12-23 11:37:54 +01:00
82aa277606 Merge pull request #125 from zakarumych/rapid-qoi
rapid-qoi is now spec complete
2021-12-23 11:37:15 +01:00
45bc32524a rapid-qoi is now spec complete 2021-12-23 00:21:46 +03:00
9c720cc682 Zig implementation is now spec complete. 2021-12-22 20:27:53 +01:00
b58a0a28c0 Move QoiSharp to the implementations section 2021-12-22 10:08:40 -06:00
54e77bf164 Mention support in Rebol3; close #58 2021-12-22 11:12:47 +01:00
17dffb408c Move Qoix to the implementations section
Qoix is now aligned with v1.0 spec, see
https://github.com/rbino/qoix/pull/2/files
2021-12-22 02:34:48 +01:00
44fe081388 Merge pull request #113 from GithubPrankster/raylib-mention
Add Raylib as QOI supporting software
2021-12-21 22:49:35 +01:00
0d2e27d3ea Added Raylib under QOI Support in Other Software. 2021-12-21 17:57:07 -03:00
4d20da3282 Add QOI Logo 2021-12-21 19:22:43 +01:00
d006202752 Mention support in SerenityOS; close #109 2021-12-21 19:21:21 +01:00
52051a310f Documentation: clarify alpha handling for certain chunk types; close #105 2021-12-21 18:05:30 +01:00
63f43a9fc1 qoi-java is now spec conforming; close #110 2021-12-21 17:51:08 +01:00
c194b955d8 Split implementations list based on spec conformance; #104 2021-12-21 17:13:11 +01:00
63095126f8 Merge pull request #102 from superzazu/patch-1
Add C bindings (SDL2) link
2021-12-21 13:06:22 +01:00
97e1c1f0e1 Merge pull request #106 from tiagofilipesilva/patch-1
Replace printf() with puts()
2021-12-21 13:02:59 +01:00
e0e21e92fb Replace printf() with puts()
The format strings are absent in these stdout prints.
They can safely be replaced with calls to _puts()_ and shave also the newlines.
2021-12-21 09:41:33 +00:00
3cffa33c45 Add C bindings (SDL2) link 2021-12-20 22:35:13 +01:00
9c77051f83 Merge pull request #99 from iOrange/master
+ added mention of the very first Paint.NET file type plugin
2021-12-20 20:26:51 +01:00
31f6fd3ca5 + added mention of the very first Paint.NET file type plugin that adds the ability to Load/Save QOI images 2021-12-20 13:31:57 -05:00
71ff2ac961 Add plugins for GIMP, Paint.NET and XnView MP 2021-12-20 17:26:18 +01:00
438c1e918f Fix typo in documentation 2021-12-20 16:17:25 +01:00
4192cd1351 Merge pull request #97 from pfusik/cito-transpiled
List languages transpiled from qoi-ci
2021-12-20 11:57:44 +01:00
f752c1a978 Clarify pixel order and image completeness 2021-12-20 11:56:19 +01:00
013cfa1ecd Wording 2021-12-20 11:47:04 +01:00
0f83363f45 List languages transpiled from qoi-ci. 2021-12-20 11:43:04 +01:00
e276f58931 Remove obsolete padding specification; already specified above; #96 2021-12-20 11:38:09 +01:00
b9a9378223 Remove notice about non-final spec 2021-12-20 10:52:19 +01:00
4bc071df78 Fix bias for run-length in the documentation 2021-12-19 23:14:08 +01:00
d8201aa77e Merge pull request #93 from Cr4xy/master
Add Lua implementation
2021-12-19 11:16:10 +01:00
9dee61246f Add Lua implementation 2021-12-19 10:54:49 +01:00
aefa0f7a25 Merge pull request #90 from sezero/sign-compare
minor fix for sign-compare warnings.
2021-12-17 12:23:44 +01:00
4ca3d3ae42 minor fix for sign-compare warnings. 2021-12-17 01:12:20 +03:00
3a62cabad2 Change padding bytes to a unique stream-end marker; #89 2021-12-16 20:50:19 +01:00
bf6951036d Fix check for valid colorspace 2021-12-16 20:13:52 +01:00
2f255c7aff Enforce a limit of 400 million pixels, 2GB file size 2021-12-16 20:12:27 +01:00
11dbe1e6aa Add clang fuzzing harness. Thanks @landaire 2021-12-16 20:02:37 +01:00
ae07396158 Avoid UTF-8 in comments... again. 2021-12-14 21:34:33 +01:00
0112e3d555 Whitespace, cosmetics 2021-12-14 20:54:37 +01:00
296f0ef840 Merge pull request #86 from chocolate42/conv-channels
Force rarer PNG encodings to be read by qoiconv as RGBA
2021-12-14 19:19:41 +01:00
85078d89d6 Merge pull request #85 from chocolate42/bench-channels
Fix qoibench handling of RGB input
2021-12-14 19:19:33 +01:00
91cc726583 Mention Java implementation; close #59 2021-12-13 17:44:24 +01:00
525f32cefe Convert all non-RGB and non-RGBA input to RGBA. 2021-12-13 16:34:39 +00:00
873cba791d Merge branch 'schar' 2021-12-13 17:25:55 +01:00
3973c549dc Remove single line comments to conform to c89 -pedantic 2021-12-13 17:23:04 +01:00
5983658ad4 Whitespace, wording 2021-12-13 17:16:22 +01:00
b743409e06 Fix qoibench to feed RGB input to the encoders when the source image is RGB. Fix rate calculation by having the raw size of RGB input be w x h x 3 instead of w x h x 4. 2021-12-13 15:27:11 +00:00
2aaba8da96 make qoi.h build using c89 compilers.
also add a QOI_ZEROARR macro, wrapping around memset by default.
2021-12-13 15:56:56 +03:00
6a95206e35 Merge pull request #84 from xfmoulet/master
Force a RGB source to have an alpha of 255
2021-12-13 11:24:59 +01:00
99fa97792f Revert "Zero-initialize previous pixel color"
This reverts commit 075ab8fe42.
Closes #30
2021-12-13 11:18:41 +01:00
8c77fad340 change char local vars to signed char
this accomodates toolchains where char type is unsigned by default.
2021-12-11 21:03:37 +03:00
2ee2169e02 Merge pull request #80 from 0xd34df00d/patch-1
Add a Haskell implementation
2021-12-11 17:29:28 +01:00
ba5c1711c7 Add a Haskell implementation 2021-12-11 11:22:41 -05:00
e76f25a606 Ignore stb dependencies and build artifacts 2021-12-11 15:49:14 +01:00
199362ed1d Add note about current specification 2021-12-11 15:48:01 +01:00
6310d49ee8 Merge branch experimental 2021-12-11 15:46:13 +01:00
c2edcd3d7a Cosmetics 2021-12-11 12:54:01 +01:00
0ad304d761 Be more specific with the documentation of the file format 2021-12-10 21:31:28 +01:00
075ab8fe42 Zero-initialize previous pixel color 2021-12-10 20:09:52 +01:00
03c7ab14d4 Merge pull request #66 from NUlliiON/master
Mention QOI implementation written in C#
2021-12-08 22:47:40 +01:00
d9518a9426 Merge branch 'master' into master 2021-12-08 22:47:32 +01:00
8f9c24a5e9 Merge pull request #74 from elihwyma/patch-1
Add Swift Implementation
2021-12-08 22:46:43 +01:00
f49dcc074d Merge branch 'master' into patch-1 2021-12-08 22:46:35 +01:00
a19e0810e6 Merge pull request #68 from rbino/add-qoix
Add Elixir implementation (Qoix) to the implementations section
2021-12-08 22:45:54 +01:00
473e467e7b Add Swift Implementation 2021-12-08 20:22:16 +00:00
2103168519 Minor encoding throughput improvement 2021-12-08 15:45:18 +01:00
6a73cc65c5 Wording, whitespace 2021-12-08 15:45:10 +01:00
92f7ebd3f8 Fix qoi_desc colorspace check 2021-12-08 15:30:56 +01:00
6c83cf2e0c Increase padding to 8 zero-bytes 2021-12-08 15:29:46 +01:00
947941fbd0 Change colorspace header to an enum to avoid confusion 2021-12-08 14:14:51 +01:00
d6b1ec673a Add alpha channel to QOI_HASH 2021-12-08 11:30:58 +01:00
eb29269432 Fix typo in documentation 2021-12-08 11:25:24 +01:00
28954f7a9a Remove QOI_DIFF_16 and QOI_DIFF_24; better tagging of remaining ops; better hash function 2021-12-06 21:23:13 +01:00
66d12eb078 Add option to only print directory totals 2021-12-06 19:55:39 +01:00
f45f47c9f0 Recursive traversal; compression ratio; grand total; options to disable some features 2021-12-06 13:35:54 +01:00
259a3a36a0 Add Elixir implementation (Qoix) to the implementations section 2021-12-06 02:46:44 +01:00
ce32dfed6e Mention QOI implementation written in C# 2021-12-05 14:23:24 -06:00
5039ebd678 Merge pull request #57 from zakarumych/master
Mention rapid-qoi implementation written in Rust
2021-12-05 11:24:12 +01:00
f6f05835c5 Merge pull request #62 from nsauzede/patch-1
Fix typo in DIFF8 documentation
2021-12-05 11:23:42 +01:00
8054316d78 Merge pull request #65 from kodonnell/master
Add link in readme to kodonnell/qoi (Python)
2021-12-05 11:23:20 +01:00
bd7d5c07bb Add link in readme to kodonnell/qoi (Python) 2021-12-05 22:18:49 +13:00
03606a0be7 Fix typo in DIFF8 documentation 2021-12-03 01:24:52 +01:00
2392a3423c Mention rapid-qoi implementation written in Rust 2021-12-01 17:48:53 +03:00
cbb62ea555 Remove QOI_RUN_16, add new QOI_GDIFF_16 op 2021-11-30 22:05:03 +01:00
e9069e11a4 Add notice about the format being not yet finalized 2021-11-30 17:45:48 +01:00
fda5167d76 Add links to Tools and Implementations 2021-11-29 11:23:33 +01:00
a79d03c26b Merge pull request #45 from lbatalha/readme-packages
add AUR package and create packages section
2021-11-29 11:10:28 +01:00
94974653c1 Lock output file before writing; close #18 2021-11-28 17:59:51 +01:00
9dd60534e4 Use local var for channels to speed up encoding 2021-11-28 17:36:47 +01:00
80356a5aaa Improve documentation, whitespace, wording 2021-11-28 17:36:05 +01:00
4f8f59d53e add packages section
includes aur package link
2021-11-28 15:12:08 +00:00
f0a38c19e5 Merge pull request #44 from Samyak2/samyak-typo-fix-1
Fix a typo: "user" -> "use"
2021-11-28 12:32:14 +01:00
bdfda4a5f6 Merge pull request #43 from MasterQ32/improved_docs
Documentation improval
2021-11-28 12:30:51 +01:00
8ebd4e7b6d Fix a typo: "user" -> "use" 2021-11-28 16:18:55 +05:30
ef9ce10bc1 Adds wraparound specification 2021-11-28 01:17:24 +01:00
7053672d3a Starts to improve the documentation. 2021-11-28 01:08:52 +01:00
be8d23c574 Merge pull request #31 from vec4f/bug/qoi_read/fclose
Close file on allocation failure in `qoi_read()`
2021-11-27 21:04:16 +01:00
5506399e0d Fix HEADER_SIZE for the new header 2021-11-27 18:41:02 +01:00
ff542c2ae6 Change the API to supply/return channel count and colorspace info 2021-11-27 18:36:17 +01:00
697abf6696 Align the data format with new spec #37 2021-11-27 17:23:52 +01:00
a902b57ede Announce changes in the file format 2021-11-27 13:21:16 +01:00
ee66591452 Merge pull request #32 from pfusik/utf8
Avoid UTF-8
2021-11-27 00:26:06 +01:00
344ba65a57 Avoid UTF-8 2021-11-26 22:51:22 +01:00
7b1567cc9d Close file on allocation failure 2021-11-26 12:28:49 -08:00
dd0b04b319 Fix #22: avoid UB when reading ints from the stream; 2021-11-26 13:22:00 +01:00
30f8a39ec8 Fix qoibench avg calculation: ignore non-png entries 2021-11-25 15:14:56 +01:00
81b438cb56 Change header to big endian; make it independent from host byte order; close #10 2021-11-25 13:51:05 +01:00
c03edb2f26 Fix naming of chunks in the data format documentation; close #9 2021-11-25 09:43:11 +01:00
324c2243b2 Add warning about untrusted input; #4 2021-11-24 22:28:35 +01:00
e969322d00 Don't run past the padding of the byte stream when decoding; re #4 2021-11-24 22:09:08 +01:00
de17b3c2c1 Fix compile instructions 2021-11-24 11:19:49 +01:00
19dc63cf17 Initial 2021-11-24 11:07:17 +01:00
382 changed files with 5596 additions and 8552 deletions

View File

@ -30,6 +30,9 @@ jobs:
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test
- name: Determine tag name - name: Determine tag name
id: tag id: tag
shell: bash shell: bash
@ -81,6 +84,9 @@ jobs:
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test.exe
- name: Determine tag name - name: Determine tag name
id: tag id: tag
shell: bash shell: bash
@ -132,6 +138,9 @@ jobs:
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test.exe
- name: Determine tag name - name: Determine tag name
id: tag id: tag
shell: bash shell: bash

View File

@ -29,6 +29,9 @@ jobs:
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test
macos: macos:
timeout-minutes: 10 timeout-minutes: 10
@ -72,3 +75,6 @@ jobs:
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
- name: temp test
run: ${{github.workspace}}/build/bin/mono_time_test.exe

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR) cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
add_subdirectory(./tracy)
add_subdirectory(./entt) add_subdirectory(./entt)
add_subdirectory(./solanaceae_util) add_subdirectory(./solanaceae_util)

View File

@ -19,8 +19,6 @@ add_library(toxcore STATIC
${TOX_DIR}toxcore/ccompat.h ${TOX_DIR}toxcore/ccompat.h
${TOX_DIR}toxcore/crypto_core.c ${TOX_DIR}toxcore/crypto_core.c
${TOX_DIR}toxcore/crypto_core.h ${TOX_DIR}toxcore/crypto_core.h
${TOX_DIR}toxcore/crypto_core_pack.c
${TOX_DIR}toxcore/crypto_core_pack.h
${TOX_DIR}toxcore/DHT.c ${TOX_DIR}toxcore/DHT.c
${TOX_DIR}toxcore/DHT.h ${TOX_DIR}toxcore/DHT.h
${TOX_DIR}toxcore/events/conference_connected.c ${TOX_DIR}toxcore/events/conference_connected.c
@ -29,7 +27,6 @@ add_library(toxcore STATIC
${TOX_DIR}toxcore/events/conference_peer_list_changed.c ${TOX_DIR}toxcore/events/conference_peer_list_changed.c
${TOX_DIR}toxcore/events/conference_peer_name.c ${TOX_DIR}toxcore/events/conference_peer_name.c
${TOX_DIR}toxcore/events/conference_title.c ${TOX_DIR}toxcore/events/conference_title.c
${TOX_DIR}toxcore/events/dht_get_nodes_response.c
${TOX_DIR}toxcore/events/events_alloc.c ${TOX_DIR}toxcore/events/events_alloc.c
${TOX_DIR}toxcore/events/events_alloc.h ${TOX_DIR}toxcore/events/events_alloc.h
${TOX_DIR}toxcore/events/file_chunk_request.c ${TOX_DIR}toxcore/events/file_chunk_request.c
@ -171,10 +168,9 @@ configure_file(
target_include_directories(toxcore PRIVATE "${TOX_DIR}toxcore") target_include_directories(toxcore PRIVATE "${TOX_DIR}toxcore")
target_include_directories(toxcore PUBLIC "${TOX_DIR}") target_include_directories(toxcore PUBLIC "${TOX_DIR}")
#target_compile_definitions(toxcore PUBLIC USE_IPV6=1) target_compile_definitions(toxcore PUBLIC USE_IPV6=1)
#target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_DEBUG) #target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_DEBUG)
#target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_INFO) target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_INFO)
target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE)
find_package(unofficial-sodium CONFIG QUIET) find_package(unofficial-sodium CONFIG QUIET)
find_package(sodium QUIET) find_package(sodium QUIET)
@ -213,3 +209,8 @@ add_executable(DHT_Bootstrap EXCLUDE_FROM_ALL
) )
target_link_libraries(DHT_Bootstrap toxcore) target_link_libraries(DHT_Bootstrap toxcore)
add_executable(mono_time_test
./mono_time_test.cc
)
target_link_libraries(mono_time_test toxcore)
target_compile_features(mono_time_test PUBLIC cxx_std_11)

View File

@ -27,7 +27,6 @@ bazel-dbg_task:
- cd /src/workspace && bazel test -k - cd /src/workspace && bazel test -k
--build_tag_filters=-haskell --build_tag_filters=-haskell
--test_tag_filters=-haskell --test_tag_filters=-haskell
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
-- --
//c-toxcore/... //c-toxcore/...
-//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus? -//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus?
@ -48,30 +47,13 @@ cimple_task:
//c-toxcore/... //c-toxcore/...
freebsd_task: freebsd_task:
freebsd_instance: container:
image_family: freebsd-14-0 image: toxchat/freebsd:latest
cpu: 2
memory: 4G
kvm: true
configure_script: configure_script:
- PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
cmake
git
gmake
googletest
libconfig
libsodium
libvpx
opus
pkgconf
- git submodule update --init --recursive - git submodule update --init --recursive
- cd .. && mv cirrus-ci-build /work/c-toxcore && mkdir cirrus-ci-build
test_all_script: test_all_script:
- | - cd /work/c-toxcore && .github/scripts/cmake-freebsd
# TODO(iphydf): Investigate FreeBSD failures on these tests.
sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt
cmake . \
-DMIN_LOGGER_LEVEL=TRACE \
-DMUST_BUILD_TOXAV=ON \
-DNON_HERMETIC_TESTS=ON \
-DTEST_TIMEOUT_SECONDS=50 \
-DUSE_IPV6=OFF \
-DAUTOTEST=ON
cmake --build . --target install
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6

View File

@ -21,7 +21,7 @@ CheckOptions:
- key: readability-identifier-naming.MacroDefinitionCase - key: readability-identifier-naming.MacroDefinitionCase
value: UPPER_CASE value: UPPER_CASE
- key: readability-identifier-naming.MacroDefinitionIgnoredRegexp - key: readability-identifier-naming.MacroDefinitionIgnoredRegexp
value: "^_.*|bitwise|force|nullable|non_null|nullptr|static_assert|ck_.*" value: "^_.*|nullable|non_null|nullptr|static_assert|ck_.*"
- key: readability-identifier-naming.ParameterCase - key: readability-identifier-naming.ParameterCase
value: lower_case value: lower_case
- key: readability-identifier-naming.StructCase - key: readability-identifier-naming.StructCase
@ -36,14 +36,12 @@ CheckOptions:
value: lower_case value: lower_case
- key: llvmlibc-restrict-system-libc-headers.Includes - key: llvmlibc-restrict-system-libc-headers.Includes
value: "alloca.h,arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h" value: "arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h"
- key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals - key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals
value: true value: true
- key: concurrency-mt-unsafe.FunctionSet - key: concurrency-mt-unsafe.FunctionSet
value: posix value: posix
- key: misc-include-cleaner.IgnoreHeaders
value: "pthread.h;stdbool.h;stddef.h;stdint.;stdint.h;stdint...;cstdint;sodium.*;sys/.*;unistd.h;opus.*;vpx.*;attributes.h;tox_struct.h"
- key: readability-function-cognitive-complexity.Threshold - key: readability-function-cognitive-complexity.Threshold
value: 153 # TODO(iphydf): Decrease. tox_new is the highest at the moment. value: 153 # TODO(iphydf): Decrease. tox_new is the highest at the moment.
- key: cppcoreguidelines-avoid-do-while.IgnoreMacros
value: true
- key: readability-simplify-boolean-expr.SimplifyDeMorgan
value: false

View File

@ -18,7 +18,7 @@ docker run \
-e ENABLE_ARCH_i686="$i686" \ -e ENABLE_ARCH_i686="$i686" \
-e ENABLE_ARCH_x86_64="$x86_64" \ -e ENABLE_ARCH_x86_64="$x86_64" \
-e ENABLE_TEST=true \ -e ENABLE_TEST=true \
-e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON -DUSE_IPV6=OFF" \ -e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON" \
-e CMAKE_C_FLAGS="$C_FLAGS" \ -e CMAKE_C_FLAGS="$C_FLAGS" \
-e CMAKE_CXX_FLAGS="$CXX_FLAGS" \ -e CMAKE_CXX_FLAGS="$CXX_FLAGS" \
-e CMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \ -e CMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \
@ -26,6 +26,4 @@ docker run \
-v "$PWD:/toxcore" \ -v "$PWD:/toxcore" \
-v "$PWD/result:/prefix" \ -v "$PWD/result:/prefix" \
--rm \ --rm \
-t \
--pull never \
"toxchat/windows:$WINDOWS_ARCH" "toxchat/windows:$WINDOWS_ARCH"

View File

@ -3,11 +3,10 @@
set -exu -o pipefail set -exu -o pipefail
LOCAL="${1:-}" LOCAL="${1:-}"
CHECK="${2:-}"
readarray -t FILES <<<"$(git ls-files)" readarray -t FILES <<<"$(git ls-files)"
if ! tar c "${FILES[@]}" | docker build --build-arg="CHECK=$CHECK" -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then if ! tar c "${FILES[@]}" | docker build -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then
grep -o "::error.*::[a-f0-9]* /usr/local/bin/tox-bootstrapd" docker-build.log grep -o "::error.*::[a-f0-9]* /usr/local/bin/tox-bootstrapd" docker-build.log
false false
fi fi

View File

@ -15,24 +15,16 @@ jobs:
analysis: analysis:
strategy: strategy:
fail-fast: false
matrix: matrix:
tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle] tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, infer, misra, tcc, tokstyle]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Build toxchat/c-toxcore:sources
uses: docker/build-push-action@v5
with:
file: other/docker/sources/sources.Dockerfile
tags: toxchat/c-toxcore:sources
- name: Docker Build - name: Docker Build
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile file: other/docker/${{ matrix.tool }}/Dockerfile
coverage-linux: coverage-linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -83,7 +75,7 @@ jobs:
- name: Build and test - name: Build and test
run: .github/scripts/cmake-osx run: .github/scripts/cmake-osx
build-windows-msvc: build-msvc:
strategy: strategy:
matrix: matrix:
version: [2019, 2022] version: [2019, 2022]
@ -110,77 +102,17 @@ jobs:
cd _build cd _build
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug
build-netbsd: build-windows:
strategy:
matrix:
bits: [32, 64]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Test in NetBSD - name: Cross compilation
id: test run: .github/scripts/cmake-win${{ matrix.bits }} script
uses: vmactions/netbsd-vm@v1
with:
usesh: true
copyback: false
prepare:
/usr/sbin/pkg_add
cmake
googletest
libconfig
libopus
libsodium
libvpx
pkg-config
run: |
# TODO(iphydf): Investigate NetBSD failures on these tests.
sed -Ei -e '/\((TCP|dht_getnodes_api)\)/s/^/#/' auto_tests/CMakeLists.txt
cmake . \
-DMIN_LOGGER_LEVEL=TRACE \
-DMUST_BUILD_TOXAV=ON \
-DNON_HERMETIC_TESTS=ON \
-DTEST_TIMEOUT_SECONDS=90 \
-DUSE_IPV6=OFF \
-DAUTOTEST=ON
cmake --build . --target install
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
build-freebsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
copyback: false
prepare:
PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
cmake
git
gmake
googletest
libconfig
libsodium
libvpx
opus
pkgconf
run: |
# TODO(iphydf): Investigate FreeBSD failures on these tests.
sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt
cmake . \
-DMIN_LOGGER_LEVEL=TRACE \
-DMUST_BUILD_TOXAV=ON \
-DNON_HERMETIC_TESTS=ON \
-DTEST_TIMEOUT_SECONDS=50 \
-DUSE_IPV6=OFF \
-DAUTOTEST=ON
cmake --build . --target install
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
mypy: mypy:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -8,7 +8,7 @@ jobs:
latest: latest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
with: with:
submodules: recursive submodules: recursive
- name: Install libraries - name: Install libraries

View File

@ -25,9 +25,7 @@ jobs:
with: with:
submodules: recursive submodules: recursive
- name: Docker Build - name: Docker Build
run: .github/scripts/tox-bootstrapd-docker local "$CHECK" run: .github/scripts/tox-bootstrapd-docker local
env:
CHECK: "${{ contains(github.event.pull_request.title, 'chore: Release ') && 'sha256sum' || 'echo' }}"
- name: Push latest image to DockerHub - name: Push latest image to DockerHub
if: ${{ github.event_name == 'push' }} if: ${{ github.event_name == 'push' }}
run: docker push toxchat/bootstrap-node:latest run: docker push toxchat/bootstrap-node:latest
@ -48,7 +46,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
context: "{{defaultContext}}:other/bootstrap_daemon/websocket" context: "{{defaultContext}}:other/bootstrap_daemon/websocket"
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
@ -69,7 +67,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
context: "." context: "."
file: .clusterfuzzlite/Dockerfile file: .clusterfuzzlite/Dockerfile
@ -90,7 +88,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: testing/Dockerfile file: testing/Dockerfile
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
@ -110,7 +108,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/emscripten/Dockerfile file: other/emscripten/Dockerfile
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
@ -123,14 +121,21 @@ jobs:
steps: steps:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Login to DockerHub - name: Login to DockerHub
if: ${{ github.event_name == 'push' }} if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build toxchat/c-toxcore:sources
uses: docker/build-push-action@v4
with:
file: other/docker/sources/Dockerfile
tags: toxchat/c-toxcore:sources
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/docker/esp32/Dockerfile file: other/docker/esp32/Dockerfile
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
@ -138,15 +143,9 @@ jobs:
cache-from: type=registry,ref=toxchat/c-toxcore:esp32 cache-from: type=registry,ref=toxchat/c-toxcore:esp32
cache-to: type=inline cache-to: type=inline
docker-windows-mingw: docker-win32:
strategy:
matrix:
bits: [32, 64]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Login to DockerHub - name: Login to DockerHub
@ -155,27 +154,39 @@ jobs:
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and store to local Docker daemon - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
context: other/docker/windows context: "{{defaultContext}}:other/docker/windows"
load: true
tags: toxchat/windows:win${{ matrix.bits }}
cache-from: type=registry,ref=toxchat/windows:win${{ matrix.bits }}
build-args: |
SUPPORT_ARCH_i686=${{ matrix.bits == '32' }}
SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }}
SUPPORT_TEST=true
- name: Push the stored image to Dockerhub
if: ${{ github.event_name == 'push' }}
uses: docker/build-push-action@v5
with:
context: other/docker/windows
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
tags: toxchat/windows:win${{ matrix.bits }} tags: toxchat/windows:win32
cache-from: type=registry,ref=toxchat/windows:win32
cache-to: type=inline
build-args: | build-args: |
SUPPORT_ARCH_i686=${{ matrix.bits == '32' }} SUPPORT_ARCH_i686=true
SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }} SUPPORT_ARCH_x86_64=false
SUPPORT_TEST=true
docker-win64:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
if: ${{ github.event_name == 'push' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: "{{defaultContext}}:other/docker/windows"
push: ${{ github.event_name == 'push' }}
tags: toxchat/windows:win64
cache-from: type=registry,ref=toxchat/windows:win64
cache-to: type=inline
build-args: |
SUPPORT_ARCH_i686=false
SUPPORT_ARCH_x86_64=true
SUPPORT_TEST=true SUPPORT_TEST=true
- name: Cross-compile
run: .github/scripts/cmake-win${{ matrix.bits }} script

View File

@ -11,7 +11,7 @@ jobs:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Docker Build - name: Docker Build
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/docker/alpine-s390x/Dockerfile file: other/docker/alpine-s390x/Dockerfile
@ -29,14 +29,14 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build toxchat/c-toxcore:sources - name: Build toxchat/c-toxcore:sources
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/docker/sources/sources.Dockerfile file: other/docker/sources/Dockerfile
tags: toxchat/c-toxcore:sources tags: toxchat/c-toxcore:sources
- name: Build and push - name: Build and push
uses: docker/build-push-action@v5 uses: docker/build-push-action@v4
with: with:
file: other/docker/coverage/coverage.Dockerfile file: other/docker/coverage/Dockerfile
push: ${{ github.event_name == 'push' }} push: ${{ github.event_name == 'push' }}
tags: toxchat/c-toxcore:coverage tags: toxchat/c-toxcore:coverage
cache-from: type=registry,ref=toxchat/c-toxcore:coverage cache-from: type=registry,ref=toxchat/c-toxcore:coverage

View File

@ -1,25 +1,20 @@
--- ---
exclude: exclude:
# shfmt doesn't support this file. - "**/*.api.h"
# shfmt doesn't support this file
- "other/analysis/run-clang-tidy" - "other/analysis/run-clang-tidy"
# Generated file.
- "CHANGELOG.md"
restylers: restylers:
- astyle: - astyle:
image: restyled/restyler-astyle:d7967bcb8b622a98524b7df1da1b02652114cf9a
arguments: ["--options=other/astyle/astylerc"] arguments: ["--options=other/astyle/astylerc"]
include: include:
- "**/*.c" - "!**/*.cc"
- "**/*.h"
- autopep8 - autopep8
- black - black
- clang-format: - clang-format:
image: restyled/restyler-clang-format:v16.0.6 image: restyled/restyler-clang-format:13.0.1
include: include:
- "**/*.cc" - "**/*.cc"
- "**/*.hh"
- prettier-markdown
- prettier-yaml - prettier-yaml
- reorder-python-imports - reorder-python-imports
- shellharden - shellharden

View File

@ -136,20 +136,18 @@ if(MIN_LOGGER_LEVEL)
endif() endif()
endif() endif()
option(EXPERIMENTAL_API "Install experimental header file with unstable API" OFF)
option(USE_IPV6 "Use IPv6 in tests" ON) option(USE_IPV6 "Use IPv6 in tests" ON)
if(NOT USE_IPV6) if(NOT USE_IPV6)
add_definitions(-DUSE_IPV6=0) add_definitions(-DUSE_IPV6=0)
endif() endif()
option(BUILD_MISC_TESTS "Build additional tests" OFF) option(BUILD_MISC_TESTS "Build additional tests and utilities" OFF)
option(BUILD_FUN_UTILS "Build additional just for fun utilities" OFF) option(BUILD_FUN_UTILS "Build additional just for fun utilities" OFF)
option(AUTOTEST "Enable autotests (mainly for CI)" OFF) option(AUTOTEST "Enable autotests (mainly for CI)" OFF)
if(AUTOTEST) if(AUTOTEST)
option(NON_HERMETIC_TESTS "Whether to build and run tests that depend on an internet connection" OFF) option(NON_HERMETIC_TESTS "Whether to build and run tests that depend on an internet connection" OFF)
option(PROXY_TEST "Enable proxy test (requires other/proxy/proxy_server.go to be running)" OFF) option(PROXY_TEST "Enable proxy test (needs HTTP/SOCKS5 proxy on port 8080/8081)" OFF)
endif() endif()
option(BUILD_TOXAV "Whether to build the tox AV library" ON) option(BUILD_TOXAV "Whether to build the tox AV library" ON)
@ -225,8 +223,6 @@ set(toxcore_SOURCES
toxcore/ccompat.h toxcore/ccompat.h
toxcore/crypto_core.c toxcore/crypto_core.c
toxcore/crypto_core.h toxcore/crypto_core.h
toxcore/crypto_core_pack.c
toxcore/crypto_core_pack.h
toxcore/DHT.c toxcore/DHT.c
toxcore/DHT.h toxcore/DHT.h
toxcore/events/conference_connected.c toxcore/events/conference_connected.c
@ -235,7 +231,6 @@ set(toxcore_SOURCES
toxcore/events/conference_peer_list_changed.c toxcore/events/conference_peer_list_changed.c
toxcore/events/conference_peer_name.c toxcore/events/conference_peer_name.c
toxcore/events/conference_title.c toxcore/events/conference_title.c
toxcore/events/dht_get_nodes_response.c
toxcore/events/events_alloc.c toxcore/events/events_alloc.c
toxcore/events/events_alloc.h toxcore/events/events_alloc.h
toxcore/events/file_chunk_request.c toxcore/events/file_chunk_request.c
@ -361,11 +356,8 @@ set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium)
set(toxcore_API_HEADERS set(toxcore_API_HEADERS
${toxcore_SOURCE_DIR}/toxcore/tox.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox
${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox
${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox) ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox
if(EXPERIMENTAL_API) ${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox)
set(toxcore_API_HEADERS ${toxcore_API_HEADERS}
${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox)
endif()
################################################################################ ################################################################################
# #
@ -454,7 +446,7 @@ elseif(TARGET Threads::Threads)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads)
endif() endif()
if(WIN32) if(WIN32)
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi ws2_32) set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi wsock32 ws2_32)
endif() endif()
################################################################################ ################################################################################
@ -534,7 +526,7 @@ endfunction()
# The actual unit tests follow. # The actual unit tests follow.
# #
if(TARGET GTest::gtest AND TARGET GTest::gmock) if(GTEST_FOUND)
unit_test(toxav ring_buffer) unit_test(toxav ring_buffer)
unit_test(toxav rtp) unit_test(toxav rtp)
unit_test(toxcore DHT) unit_test(toxcore DHT)

View File

@ -1,8 +1,6 @@
# Installation instructions # Installation instructions
These instructions will guide you through the process of building and installing These instructions will guide you through the process of building and installing the toxcore library and its components, as well as getting already pre-built binaries.
the toxcore library and its components, as well as getting already pre-built
binaries.
## Table of contents ## Table of contents
@ -32,44 +30,37 @@ binaries.
#### Main #### Main
This repository, although called `toxcore`, in fact contains several libraries This repository, although called `toxcore`, in fact contains several libraries besides `toxcore` which complement it, as well as several executables. However, note that although these are separate libraries, at the moment, when building the libraries, they are all merged into a single `toxcore` library. Here is the full list of the main components that can be built using the CMake, their dependencies and descriptions.
besides `toxcore` which complement it, as well as several executables. However,
note that although these are separate libraries, at the moment, when building
the libraries, they are all merged into a single `toxcore` library. Here is the
full list of the main components that can be built using the CMake, their
dependencies and descriptions.
| Name | Type | Dependencies | Platform | Description | | Name | Type | Dependencies | Platform | Description |
| ---------------- | ---------- | ---------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------- | |------------------|------------|------------------------------------|----------------|----------------------------------------------------------------------------|
| `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. | | `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. |
| `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. | | `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. |
| `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. | | `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. |
| `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. | | `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. |
| `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). | | `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). |
| `cmp` | Library | | Cross-platform | C implementation of the MessagePack serialization format. [https://github.com/camgunz/cmp](https://github.com/camgunz/cmp) | | `cmp` | Library | | Cross-platform | C implementation of the MessagePack serialization format. [https://github.com/camgunz/cmp](https://github.com/camgunz/cmp) |
#### Secondary #### Secondary
There are some programs that are not built by default which you might find There are some programs that are not built by default which you might find interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them.
interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them.
##### Vanity key generators ##### Vanity key generators
Can be used to generate vanity Tox Ids or DHT bootstrap node public keys. Can be used to generate vanity Tox Ids or DHT bootstrap node public keys.
| Name | Type | Dependencies | Platform | Description | | Name | Type | Dependencies | Platform | Description |
| ---------------- | ---------- | ----------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. | | `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. |
| `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. | | `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. |
| `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. | | `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. |
##### Key file generators ##### Key file generators
Useful for generating Tox profiles from the output of the vanity key generators, Useful for generating Tox profiles from the output of the vanity key generators, as well as generating random Tox profiles.
as well as generating random Tox profiles.
| Name | Type | Dependencies | Platform | Description | | Name | Type | Dependencies | Platform | Description |
| ------------------------- | ---------- | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `make-funny-savefile` | Script | python | Cross-platform | Generates a Tox profile file (savedata file) with the provided key pair. | | `make-funny-savefile` | Script | python | Cross-platform | Generates a Tox profile file (savedata file) with the provided key pair. |
| `create_bootstrap_keys` | Executable | libsodium | Cross-platform | Generates a keys file for tox-bootstrapd with either the provided or a random key pair. | | `create_bootstrap_keys` | Executable | libsodium | Cross-platform | Generates a keys file for tox-bootstrapd with either the provided or a random key pair. |
| `create_minimal_savedata` | Executable | libsodium | Cross-platform | Generates a minimal Tox profile file (savedata file) with either the provided or a random key pair, printing the generated Tox Id and secret & public key information. | | `create_minimal_savedata` | Executable | libsodium | Cross-platform | Generates a minimal Tox profile file (savedata file) with either the provided or a random key pair, printing the generated Tox Id and secret & public key information. |
@ -78,10 +69,10 @@ as well as generating random Tox profiles.
##### Other ##### Other
| Name | Type | Dependencies | Platform | Description | | Name | Type | Dependencies | Platform | Description |
| --------------------- | ---------- | ------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | |---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. | | `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. |
| `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. | | `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. |
## Building ## Building
@ -89,78 +80,56 @@ as well as generating random Tox profiles.
#### Library dependencies #### Library dependencies
Library dependencies are listed in the [components](#components) table. The Library dependencies are listed in the [components](#components) table. The dependencies need to be satisfied for the components to be built. Note that if you don't have a dependency for some component, e.g. you don't have `libopus` installed required for building `toxav` component, building of that component is silently disabled.
dependencies need to be satisfied for the components to be built. Note that if
you don't have a dependency for some component, e.g. you don't have `libopus`
installed required for building `toxav` component, building of that component is
silently disabled.
Be advised that due to the addition of `cmp` as a submodule, you now also need
to initialize the git submodules required by toxcore. This can be done by Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the addition of `--recurse-submodules` or by running `git submodule update --init` in the root directory of the repo.
cloning the repo with the addition of `--recurse-submodules` or by running
`git submodule update --init` in the root directory of the repo.
#### Compiler requirements #### Compiler requirements
The supported compilers are GCC, Clang and MinGW. The supported compilers are GCC, Clang and MinGW.
In theory, any compiler that fully supports C99 and accepts GCC flags should In theory, any compiler that fully supports C99 and accepts GCC flags should work.
work.
There is a partial and experimental support of Microsoft Visual C++ compiler. We There is a partial and experimental support of Microsoft Visual C++ compiler. We welcome any patches that help improve it.
welcome any patches that help improve it.
You should have a C99 compatible compiler in order to build the main components. You should have a C99 compatible compiler in order to build the main components. The secondary components might require the compiler to support GNU extensions.
The secondary components might require the compiler to support GNU extensions.
#### Build system requirements #### Build system requirements
To build the main components you need to have CMake of at least 2.8.6 version To build the main components you need to have CMake of at least 2.8.6 version installed. You also need to have pkg-config installed, the build system uses it to find dependency libraries.
installed. You also need to have pkg-config installed, the build system uses it
to find dependency libraries.
There is some experimental accommodation for building natively on Windows, i.e. There is some experimental accommodation for building natively on Windows, i.e. without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded paths for finding libraries and supports building only of some of toxcore components, so your mileage might vary.
without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded
paths for finding libraries and supports building only of some of toxcore
components, so your mileage might vary.
### CMake options ### CMake options
There are some options that are available to configure the build. There are some options that are available to configure the build.
| Name | Description | Expected Value | Default Value | | Name | Description | Expected Value | Default Value |
| ----------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------- | |------------------------|-----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------|
| `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF | | `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF |
| `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON | | `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON |
| `BUILD_FUN_UTILS` | Build additional just for fun utilities. | ON or OFF | OFF | | `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF |
| `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF | | `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF |
| `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF | | `BUILD_FUN_UTILS` | Build additional funny utilities. | ON or OFF | OFF |
| `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON | | `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON |
| `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. | | `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. |
| `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. | | `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. |
| `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap`. | ON or OFF | ON | | `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap` | ON or OFF | ON |
| `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON | | `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON |
| `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON | | `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON |
| `EXPERIMENTAL_API` | Install experimental header file with unstable API. | ON or OFF | OFF | | `EXECUTION_TRACE` | Print a function trace during execution (for debugging). | ON or OFF | OFF |
| `FLAT_OUTPUT_STRUCTURE` | Whether to produce output artifacts in {bin,lib}. | ON or OFF | OFF | | `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF |
| `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF | | `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. |
| `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. | | `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF |
| `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF | | `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF |
| `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF | | `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF |
| `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF | | `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF |
| `PROXY_TEST` | Enable proxy test (requires `other/proxy/proxy_server.go` to be running). | ON or OFF | OFF | | `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. |
| `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF | | `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON |
| `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. |
| `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON |
You can get this list of option using the following commands You can get this list of option using the following commands
```sh
cmake -B _build -LAH
```
or
```sh ```sh
grep "option(" CMakeLists.txt cmake/* grep "option(" CMakeLists.txt cmake/*
grep "set(.* CACHE" CMakeLists.txt cmake/* grep "set(.* CACHE" CMakeLists.txt cmake/*
@ -181,12 +150,11 @@ cmake \
``` ```
### Building tests ### Building tests
In addition to the integration tests ("autotests") and miscellaneous tests In addition to the integration tests ("autotests") and miscellaneous tests
enabled by cmake variables described above, there are unit tests which will be enabled by cmake variables described above, there are unit tests which will be
built if the source distribution of gtest (the Google Unit Test framework) is built if the source distribution of gtest (the Google Unit Test framework) is
found by cmake in `c-toxcore/third_party`. This can be achieved by running 'git found by cmake in `c-toxcore/third_party`. This can be achieved by running
clone https://github.com/google/googletest` from that directory. 'git clone https://github.com/google/googletest` from that directory.
### Build process ### Build process
@ -202,33 +170,19 @@ make
make install make install
``` ```
or shorter
```sh
cmake -B _build
cmake -B _build --target install
```
#### Windows #### Windows
##### Building on Windows host ##### Building on Windows host
###### Microsoft Visual Studio's Developer Command Prompt ###### Microsoft Visual Studio's Developer Command Prompt
In addition to meeting the [requirements](#requirements), you need a version of In addition to meeting the [requirements](#requirements), you need a version of Visual Studio (the [community edition](https://www.visualstudio.com/vs/visual-studio-express/) is enough) and a CMake version that's compatible with the Visual Studio version you're using.
Visual Studio (the
[community edition](https://www.visualstudio.com/vs/visual-studio-express/) is
enough) and a CMake version that's compatible with the Visual Studio version
you're using.
You must also ensure that the msvc versions of dependencies you're using are You must also ensure that the msvc versions of dependencies you're using are placed in the correct folders.
placed in the correct folders.
For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32, For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32, it's `c-toxcore/third_party/pthreads-win32`
it's `c-toxcore/third_party/pthreads-win32`
Once all of this is done, from the **Developer Command Prompt for VS**, simply Once all of this is done, from the **Developer Command Prompt for VS**, simply run
run
``` ```
mkdir _build mkdir _build
@ -239,23 +193,22 @@ msbuild ALL_BUILD.vcxproj
###### MSYS/Cygwin ###### MSYS/Cygwin
Download Cygwin Download Cygwin ([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe))
([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe))
Search and select exactly these packages in Devel category: Search and select exactly these packages in Devel category:
- mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit) - mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit)
- mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit) - mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit)
- make - make
- cmake - cmake
- libtool - libtool
- autoconf - autoconf
- automake - automake
- tree - tree
- curl - curl
- perl - perl
- yasm - yasm
- pkg-config - pkg-config
To handle Windows EOL correctly run the following in the Cygwin Terminal: To handle Windows EOL correctly run the following in the Cygwin Terminal:
@ -268,24 +221,18 @@ set -o igncr
Download toxcore source code and extract it to a folder. Download toxcore source code and extract it to a folder.
Open Cygwin Terminal in the toxcore folder and run Open Cygwin Terminal in the toxcore folder and run `./other/windows_build_script_toxcore.sh` to start the build process.
`./other/windows_build_script_toxcore.sh` to start the build process.
Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin folder (default `C:\cygwin64`).
folder (default `C:\cygwin64`).
Dependency versions can be customized in `./other/windows_build_script_toxcore.sh` and described in the section below.
Dependency versions can be customized in
`./other/windows_build_script_toxcore.sh` and described in the section below.
##### Cross-compiling from Linux ##### Cross-compiling from Linux
These cross-compilation instructions were tested on and written for 64-bit These cross-compilation instructions were tested on and written for 64-bit Ubuntu 16.04. You could generalize them for any Linux system, the only requirements are that you have Docker version of >= 1.9.0 and you are running 64-bit system.
Ubuntu 16.04. You could generalize them for any Linux system, the only
requirements are that you have Docker version of >= 1.9.0 and you are running
64-bit system.
The cross-compilation is fully automated by a parameterized The cross-compilation is fully automated by a parameterized [Dockerfile](/other/docker/windows/Dockerfile).
[Dockerfile](/other/docker/windows/Dockerfile).
Install Docker Install Docker
@ -296,18 +243,17 @@ apt-get install docker.io
Get the toxcore source code and navigate to `other/docker/windows`. Get the toxcore source code and navigate to `other/docker/windows`.
Build the container image based on the Dockerfile. The following options are Build the container image based on the Dockerfile. The following options are available to customize the building of the container image.
available to customize the building of the container image.
| Name | Description | Expected Value | Default Value | | Name | Description | Expected Value | Default Value |
| -------------------------- | ----------------------------------------------------- | ----------------------------------- | ------------- | |-----------------------|----------------------------------------------------------------|-------------------------------------|---------------|
| `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true | | `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true |
| `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true | | `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true |
| `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false | | `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false |
| `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.4 | | `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | true |
| `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.19 | | `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.3.1 |
| `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.14.0 | | `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.18 |
| `ENABLE_HASH_VERIFICATION` | Verify the hashes of the default dependency versions. | "true" or "false" (case sensitive). | true | | `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.11.0 |
Example of building a container image with options Example of building a container image with options
@ -319,16 +265,16 @@ docker build \
. .
``` ```
Run the container to build toxcore. The following options are available to Run the container to build toxcore. The following options are available to customize the running of the container image.
customize the running of the container image.
| Name | Description | Expected Value | Default Value | | Name | Description | Expected Value | Default Value |
| -------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------------------------------ | |----------------------|--------------------------------------------------------------------------------------------|-------------------------------------|--------------------------------------------------------------------|
| `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` | | `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` |
| `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` | | `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` |
| `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` | | `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` |
| `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` | | `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` |
| `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90 -DUSE_IPV6=OFF` | | `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90` |
| `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | `true` |
Example of running the container with options Example of running the container with options
@ -338,117 +284,14 @@ docker run \
-e ALLOW_TEST_FAILURE=true \ -e ALLOW_TEST_FAILURE=true \
-v /path/to/toxcore/sourcecode:/toxcore \ -v /path/to/toxcore/sourcecode:/toxcore \
-v /path/to/where/output/build/result:/prefix \ -v /path/to/where/output/build/result:/prefix \
-t \
--rm \ --rm \
toxcore toxcore
``` ```
After the build succeeds, you should see the built toxcore libraries in After the build succeeds, you should see the built toxcore libraries in `/path/to/where/output/build/result`.
`/path/to/where/output/build/result`.
The file structure should look similar to the following
```
result
├── [4.0K] i686
│   ├── [ 36K] bin
│   │   ├── [636K] DHT_bootstrap.exe
│   │   ├── [572K] cracker.exe
│   │   ├── [359K] cracker_simple.exe
│   │   ├── [378K] create_bootstrap_keys.exe
│   │   ├── [378K] create_minimal_savedata.exe
│   │   ├── [958K] create_savedata.exe
│   │   ├── [ 18K] libtoxcore.def
│   │   ├── [2.6M] libtoxcore.dll
│   │   ├── [ 65K] libtoxcore.exp
│   │   ├── [428K] libtoxcore.lib
│   │   ├── [989K] save-generator.exe
│   │   ├── [381K] sign.exe
│   │   └── [408K] strkey.exe
│   ├── [4.0K] include
│   │   └── [4.0K] tox
│   │   ├── [177K] tox.h
│   │   ├── [ 10K] tox_dispatch.h
│   │   ├── [ 26K] tox_events.h
│   │   ├── [6.4K] tox_private.h
│   │   ├── [ 26K] toxav.h
│   │   └── [ 12K] toxencryptsave.h
│   └── [4.0K] lib
│   ├── [577K] libopus.a
│   ├── [660K] libsodium.a
│   ├── [ 10K] libssp.a
│   ├── [1016K] libtoxcore.a
│   ├── [456K] libtoxcore.dll.a
│   ├── [2.7M] libvpx.a
│   ├── [ 72K] libwinpthread.a
│   └── [4.0K] pkgconfig
│   ├── [ 250] libsodium.pc
│   ├── [ 357] opus.pc
│   ├── [ 247] toxcore.pc
│   └── [ 309] vpx.pc
└── [4.0K] x86_64
├── [ 36K] bin
│   ├── [504K] DHT_bootstrap.exe
│   ├── [474K] cracker.exe
│   ├── [277K] cracker_simple.exe
│   ├── [287K] create_bootstrap_keys.exe
│   ├── [288K] create_minimal_savedata.exe
│   ├── [769K] create_savedata.exe
│   ├── [ 18K] libtoxcore.def
│   ├── [2.4M] libtoxcore.dll
│   ├── [ 64K] libtoxcore.exp
│   ├── [420K] libtoxcore.lib
│   ├── [800K] save-generator.exe
│   ├── [289K] sign.exe
│   └── [317K] strkey.exe
├── [4.0K] include
│   └── [4.0K] tox
│   ├── [177K] tox.h
│   ├── [ 10K] tox_dispatch.h
│   ├── [ 26K] tox_events.h
│   ├── [6.4K] tox_private.h
│   ├── [ 26K] toxav.h
│   └── [ 12K] toxencryptsave.h
└── [4.0K] lib
├── [697K] libopus.a
├── [575K] libsodium.a
├── [ 11K] libssp.a
├── [905K] libtoxcore.a
├── [449K] libtoxcore.dll.a
├── [2.9M] libvpx.a
├── [ 68K] libwinpthread.a
└── [4.0K] pkgconfig
├── [ 252] libsodium.pc
├── [ 359] opus.pc
├── [ 249] toxcore.pc
└── [ 311] vpx.pc
12 directories, 60 files
```
- `libtoxcore.dll` is the shared library. It is fully self-contained, with no
additional dependencies aside from the Windows OS dlls, and can be used in
MSVC, MinGW, Clang, etc. projects. Despite its name, it provides toxcore,
toxav, toxencryptsave -- all of Tox.
- `libtoxcore.a` is the static library. In order to use it, it needs to be
linked against the other provided .a libraries (but not the .dll.a!) and
additionally -liphlpapi and -lws2_32 Windows dlls. It similarly provides all
of Tox APIs.
- `libtoxcore.dll.a` is the MinGW import library for `libtoxcore.dll`.
- `libtoxcore.lib` is the MSVC import library for `libtoxcore.dll`.
- `libtoxcore.exp` and `libtoxcore.def` are the exported by `libtoxcore`
symbols.
- `*.exe` are statically compiled executables -- `DHT_bootstrap` and
[the fun utils](#secondary).
## Pre-built binaries ## Pre-built binaries
### Linux ### Linux
Toxcore is packaged by at least by the following distributions: ALT Linux, Toxcore is packaged by at least by the following distributions: ALT Linux, [Arch Linux](https://www.archlinux.org/packages/?q=toxcore), [Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE, PCLinuxOS, ROSA and Slackware, [according to the information from pkgs.org](https://pkgs.org/download/toxcore). Note that this list might be incomplete and some other distributions might package it too.
[Arch Linux](https://www.archlinux.org/packages/?q=toxcore),
[Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE,
PCLinuxOS, ROSA and Slackware,
[according to the information from pkgs.org](https://pkgs.org/download/toxcore).
Note that this list might be incomplete and some other distributions might
package it too.

View File

@ -1,14 +1,8 @@
# ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox") # ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox")
**Current Coverage:** **Current Coverage:** [![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
[![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Blog**](https://blog.tox.chat/) **|** [**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** [**Binaries/Downloads**](https://tox.chat/download.html) **|** [**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** [**Compiling**](/INSTALL.md)
[**Blog**](https://blog.tox.chat/) **|**
[**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|**
[**Binaries/Downloads**](https://tox.chat/download.html) **|**
[**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|**
[**Compiling**](/INSTALL.md)
## What is Tox ## What is Tox
@ -22,33 +16,29 @@ and privacy easy to obtain for regular users. It uses
### ![Danger: Experimental](other/tox-warning.png) ### ![Danger: Experimental](other/tox-warning.png)
This is an **experimental** cryptographic network library. It has not been This is an **experimental** cryptographic network library. It has not been
formally audited by an independent third party that specializes in cryptography formally audited by an independent third party that specializes in
or cryptanalysis. **Use this library at your own risk.** cryptography or cryptanalysis. **Use this library at your own risk.**
The underlying crypto library [libsodium](https://doc.libsodium.org/) provides The underlying crypto library [libsodium](https://doc.libsodium.org/) provides
reliable encryption, but the security model has not yet been fully specified. reliable encryption, but the security model has not yet been fully specified.
See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a discussion See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a
on developing a threat model. See other issues for known weaknesses (e.g. discussion on developing a threat model. See other issues for known weaknesses
[issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes what can (e.g. [issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes
happen if your secret key is stolen). what can happen if your secret key is stolen).
## Toxcore Development Roadmap ## Toxcore Development Roadmap
The roadmap and changelog are generated from GitHub issues. You may view them on The roadmap and changelog are generated from GitHub issues. You may view them
the website, where they are updated at least once every 24 hours: on the website, where they are updated at least once every 24 hours:
- Changelog: https://toktok.ltd/changelog/c-toxcore - Changelog: https://toktok.ltd/changelog/c-toxcore
- Roadmap: https://toktok.ltd/roadmap/c-toxcore - Roadmap: https://toktok.ltd/roadmap/c-toxcore
## Installing toxcore ## Installing toxcore
Detailed installation instructions can be found in [INSTALL.md](INSTALL.md). Detailed installation instructions can be found in [INSTALL.md](INSTALL.md).
Be advised that due to the addition of `cmp` as a submodule, you now also need Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the following command: `git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by running `git submodule update --init` in the root directory of the repo.
to initialize the git submodules required by toxcore. This can be done by
cloning the repo with the following command:
`git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by
running `git submodule update --init` in the root directory of the repo.
In a nutshell, if you have [libsodium](https://github.com/jedisct1/libsodium) In a nutshell, if you have [libsodium](https://github.com/jedisct1/libsodium)
installed, run: installed, run:
@ -84,17 +74,17 @@ if (err_new != TOX_ERR_NEW_OK) {
} }
``` ```
Here, we simply exit the program, but in a real client you will probably want to Here, we simply exit the program, but in a real client you will probably want
do some error handling and proper error reporting to the user. The `NULL` to do some error handling and proper error reporting to the user. The `NULL`
argument given to the first parameter of `tox_new` is the `Tox_Options`. It argument given to the first parameter of `tox_new` is the `Tox_Options`. It
contains various write-once network settings and allows you to load a previously contains various write-once network settings and allows you to load a
serialised instance. See [toxcore/tox.h](tox.h) for details. previously serialised instance. See [toxcore/tox.h](tox.h) for details.
### Setting up callbacks ### Setting up callbacks
Toxcore works with callbacks that you can register to listen for certain events. Toxcore works with callbacks that you can register to listen for certain
Examples of such events are "friend request received" or "friend sent a events. Examples of such events are "friend request received" or "friend sent
message". Search the API for `tox_callback_*` to find all of them. a message". Search the API for `tox_callback_*` to find all of them.
Here, we will set up callbacks for receiving friend requests and receiving Here, we will set up callbacks for receiving friend requests and receiving
messages. We will always accept any friend request (because we're a bot), and messages. We will always accept any friend request (because we're a bot), and
@ -182,24 +172,3 @@ the API documentation in [toxcore/tox.h](toxcore/tox.h) for more information.
- [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot) - [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot)
- [minitox](https://github.com/hqwrong/minitox) (A minimal tox client) - [minitox](https://github.com/hqwrong/minitox) (A minimal tox client)
## SAST Tools
This project uses various tools supporting Static Application Security Testing:
- [clang-tidy](https://clang.llvm.org/extra/clang-tidy/): A clang-based C++
"linter" tool.
- [Coverity](https://scan.coverity.com/): A cloud-based static analyzer service
for Java, C/C++, C#, JavaScript, Ruby, or Python that is free for open source
projects.
- [cppcheck](https://cppcheck.sourceforge.io/): A static analyzer for C/C++
code.
- [cpplint](https://github.com/cpplint/cpplint): Static code checker for C++
- [goblint](https://goblint.in.tum.de/): A static analyzer for multi-threaded C
programs, specializing in finding concurrency bugs.
- [infer](https://github.com/facebook/infer): A static analyzer for Java, C,
C++, and Objective-C.
- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source):
A static analyzer for C, C++, C#, and Java code.
- [tokstyle](https://github.com/TokTok/hs-tokstyle): A style checker for TokTok
C projects.

View File

@ -17,8 +17,6 @@ cc_library(
"//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
], ],
) )

View File

@ -240,7 +240,6 @@ endif
EXTRA_DIST += \ EXTRA_DIST += \
$(top_srcdir)/auto_tests/data/save.tox.big \ $(top_srcdir)/auto_tests/data/save.tox \
$(top_srcdir)/auto_tests/data/save.tox.little \
$(top_srcdir)/auto_tests/check_compat.h \ $(top_srcdir)/auto_tests/check_compat.h \
$(top_srcdir)/auto_tests/auto_test_support.h $(top_srcdir)/auto_tests/auto_test_support.h

View File

@ -45,11 +45,11 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
static void test_basic(void) static void test_basic(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
@ -266,14 +266,13 @@ static void kill_tcp_con(struct sec_TCP_con *con)
static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data,
uint16_t length) uint16_t length)
{ {
const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE; VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
VLA(uint8_t, packet, packet_size);
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet, &c_length, sizeof(uint16_t)); memcpy(packet, &c_length, sizeof(uint16_t));
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
return -1; return -1;
} }
@ -283,7 +282,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
localhost.ip = get_loopback(); localhost.ip = get_loopback();
localhost.port = 0; localhost.port = 0;
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size, ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost) == SIZEOF_VLA(packet),
"Failed to send a packet."); "Failed to send a packet.");
return 0; return 0;
} }
@ -304,11 +303,11 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui
static void test_some(void) static void test_some(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
@ -499,11 +498,11 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
static void test_client(void) static void test_client(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new();
@ -525,9 +524,8 @@ static void test_client(void)
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr);
// TCP sockets might need a moment before they can be written to.
c_sleep(50);
do_tcp_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
c_sleep(50);
// The connection status should be unconfirmed here because we have finished // The connection status should be unconfirmed here because we have finished
// sending our data and are awaiting a response. // sending our data and are awaiting a response.
@ -561,7 +559,6 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
f2_secret_key, nullptr); f2_secret_key, nullptr);
c_sleep(50);
// The client should call this function (defined earlier) during the routing process. // The client should call this function (defined earlier) during the routing process.
routing_response_handler(conn, response_callback, (char *)conn + 2); routing_response_handler(conn, response_callback, (char *)conn + 2);
@ -584,7 +581,7 @@ static void test_client(void)
do_tcp_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
c_sleep(50); c_sleep(50);
const uint8_t data[5] = {1, 2, 3, 4, 5}; uint8_t data[5] = {1, 2, 3, 4, 5};
memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE);
send_oob_packet(logger, conn2, f_public_key, data, 5); send_oob_packet(logger, conn2, f_public_key, data, 5);
send_routing_request(logger, conn, f2_public_key); send_routing_request(logger, conn, f2_public_key);
@ -635,11 +632,11 @@ static void test_client(void)
// Test how the client handles servers that don't respond. // Test how the client handles servers that don't respond.
static void test_client_invalid(void) static void test_client_invalid(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
@ -657,7 +654,7 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
self_public_key, f_public_key, f_secret_key, nullptr); self_public_key, f_public_key, f_secret_key, nullptr);
// Run the client's main loop but not the server. // Run the client's main loop but not the server.
mono_time_update(mono_time); mono_time_update(mono_time);
@ -711,13 +708,14 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t
return 0; return 0;
} }
static void test_tcp_connection(void) static void test_tcp_connection(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
@ -826,11 +824,11 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne
static void test_tcp_connection2(void) static void test_tcp_connection2(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);

View File

@ -13,7 +13,7 @@
static void test_bucketnum(void) static void test_bucketnum(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE];
random_bytes(rng, key1, sizeof(key1)); random_bytes(rng, key1, sizeof(key1));
@ -50,11 +50,11 @@ static void test_announce_data(void *object, const uint8_t *data, uint16_t lengt
static void test_store_data(void) static void test_store_data(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
Logger *log = logger_new(); Logger *log = logger_new();
@ -120,6 +120,7 @@ static void basic_announce_tests(void)
test_store_data(); test_store_data();
} }
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);

View File

@ -5,8 +5,6 @@
#include "../testing/misc_tools.h" #include "../testing/misc_tools.h"
#include "../toxcore/Messenger.h" #include "../toxcore/Messenger.h"
#include "../toxcore/mono_time.h" #include "../toxcore/mono_time.h"
#include "../toxcore/tox_dispatch.h"
#include "../toxcore/tox_events.h"
#include "../toxcore/tox_struct.h" #include "../toxcore/tox_struct.h"
#include "auto_test_support.h" #include "auto_test_support.h"
@ -25,7 +23,6 @@ Run_Auto_Options default_run_auto_options(void)
.graph = GRAPH_COMPLETE, .graph = GRAPH_COMPLETE,
.init_autotox = nullptr, .init_autotox = nullptr,
.tcp_port = 33188, .tcp_port = 33188,
.events = true,
}; };
} }
@ -134,15 +131,7 @@ void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait)
for (uint32_t i = 0; i < tox_count; ++i) { for (uint32_t i = 0; i < tox_count; ++i) {
if (autotoxes[i].alive) { if (autotoxes[i].alive) {
if (autotoxes[i].events) { tox_iterate(autotoxes[i].tox, &autotoxes[i]);
Tox_Err_Events_Iterate err;
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
tox_events_free(events);
} else {
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
}
autotoxes[i].clock += wait; autotoxes[i].clock += wait;
} }
} }
@ -192,7 +181,6 @@ void kill_autotox(AutoTox *autotox)
ck_assert(autotox->alive); ck_assert(autotox->alive);
fprintf(stderr, "Killing #%u\n", autotox->index); fprintf(stderr, "Killing #%u\n", autotox->index);
autotox->alive = false; autotox->alive = false;
tox_dispatch_free(autotox->dispatch);
tox_kill(autotox->tox); tox_kill(autotox->tox);
} }
@ -214,11 +202,6 @@ void reload(AutoTox *autotox)
tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size); tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size);
autotox->tox = tox_new_log(options, nullptr, &autotox->index); autotox->tox = tox_new_log(options, nullptr, &autotox->index);
ck_assert(autotox->tox != nullptr); ck_assert(autotox->tox != nullptr);
autotox->dispatch = tox_dispatch_new(nullptr);
ck_assert(autotox->dispatch != nullptr);
if (autotox->events) {
tox_events_init(autotox->tox);
}
tox_options_free(options); tox_options_free(options);
set_mono_time_callback(autotox); set_mono_time_callback(autotox);
@ -229,7 +212,6 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui
Run_Auto_Options *autotest_opts) Run_Auto_Options *autotest_opts)
{ {
autotox->index = index; autotox->index = index;
autotox->events = autotest_opts->events;
Tox_Err_New err = TOX_ERR_NEW_OK; Tox_Err_New err = TOX_ERR_NEW_OK;
@ -277,12 +259,6 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui
set_mono_time_callback(autotox); set_mono_time_callback(autotox);
autotox->dispatch = tox_dispatch_new(nullptr);
ck_assert(autotox->dispatch != nullptr);
if (autotox->events) {
tox_events_init(autotox->tox);
}
autotox->alive = true; autotox->alive = true;
autotox->save_state = nullptr; autotox->save_state = nullptr;
@ -335,7 +311,7 @@ static void initialise_friend_graph(Graph_Type graph, uint32_t num_toxes, AutoTo
} }
} }
static void bootstrap_autotoxes(const Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts, static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts,
AutoTox *autotoxes) AutoTox *autotoxes)
{ {
const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true; const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true;
@ -363,9 +339,7 @@ static void bootstrap_autotoxes(const Tox_Options *options, uint32_t tox_count,
} }
} }
typedef void autotox_test_cb(AutoTox *autotoxes); void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes),
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test_cb *test,
uint32_t state_size, Run_Auto_Options *autotest_opts) uint32_t state_size, Run_Auto_Options *autotest_opts)
{ {
printf("initialising %u toxes\n", tox_count); printf("initialising %u toxes\n", tox_count);
@ -397,7 +371,6 @@ void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test
test(autotoxes); test(autotoxes);
for (uint32_t i = 0; i < tox_count; ++i) { for (uint32_t i = 0; i < tox_count; ++i) {
tox_dispatch_free(autotoxes[i].dispatch);
tox_kill(autotoxes[i].tox); tox_kill(autotoxes[i].tox);
free(autotoxes[i].state); free(autotoxes[i].state);
free(autotoxes[i].save_state); free(autotoxes[i].save_state);
@ -444,6 +417,7 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin
} }
} }
void print_debug_logger(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata) void print_debug_logger(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata)
{ {
print_debug_log(nullptr, (Tox_Log_Level) level, file, (uint32_t) line, func, message, userdata); print_debug_log(nullptr, (Tox_Log_Level) level, file, (uint32_t) line, func, message, userdata);
@ -481,3 +455,4 @@ Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_d
{ {
return tox_new_log_lan(options, err, log_user_data, false); return tox_new_log_lan(options, err, log_user_data, false);
} }

View File

@ -7,11 +7,9 @@
#include "../testing/misc_tools.h" #include "../testing/misc_tools.h"
#include "../toxcore/Messenger.h" #include "../toxcore/Messenger.h"
#include "../toxcore/mono_time.h" #include "../toxcore/mono_time.h"
#include "../toxcore/tox_dispatch.h"
typedef struct AutoTox { typedef struct AutoTox {
Tox *tox; Tox *tox;
Tox_Dispatch *dispatch;
uint32_t index; uint32_t index;
uint64_t clock; uint64_t clock;
@ -19,7 +17,6 @@ typedef struct AutoTox {
size_t save_size; size_t save_size;
uint8_t *save_state; uint8_t *save_state;
bool alive; bool alive;
bool events;
void *state; void *state;
} AutoTox; } AutoTox;
@ -45,7 +42,6 @@ typedef struct Run_Auto_Options {
Graph_Type graph; Graph_Type graph;
void (*init_autotox)(AutoTox *autotox, uint32_t n); void (*init_autotox)(AutoTox *autotox, uint32_t n);
uint16_t tcp_port; uint16_t tcp_port;
bool events;
} Run_Auto_Options; } Run_Auto_Options;
Run_Auto_Options default_run_auto_options(void); Run_Auto_Options default_run_auto_options(void);
@ -61,7 +57,7 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin
// Use this function when setting the log callback on a Logger object // Use this function when setting the log callback on a Logger object
void print_debug_logger(void *context, Logger_Level level, const char *file, int line, void print_debug_logger(void *context, Logger_Level level, const char *file, int line,
const char *func, const char *message, void *userdata); const char *func, const char *message, void *userdata);
Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data); Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data);
Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery); Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery);

View File

@ -23,11 +23,10 @@ typedef struct State {
} State; } State;
static void handle_self_connection_status( static void handle_self_connection_status(
const Tox_Event_Self_Connection_Status *event, void *user_data) Tox *tox, Tox_Connection connection_status, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
if (connection_status != TOX_CONNECTION_NONE) { if (connection_status != TOX_CONNECTION_NONE) {
printf("tox #%u: is now connected\n", autotox->index); printf("tox #%u: is now connected\n", autotox->index);
} else { } else {
@ -36,13 +35,10 @@ static void handle_self_connection_status(
} }
static void handle_friend_connection_status( static void handle_friend_connection_status(
const Tox_Event_Friend_Connection_Status *event, void *user_data) Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
const uint32_t friendnumber = tox_event_friend_connection_status_get_friend_number(event);
const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event);
if (connection_status != TOX_CONNECTION_NONE) { if (connection_status != TOX_CONNECTION_NONE) {
printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber); printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber);
} else { } else {
@ -74,33 +70,28 @@ static void audio_callback(void *tox, uint32_t groupnumber, uint32_t peernumber,
} }
static void handle_conference_invite( static void handle_conference_invite(
const Tox_Event_Conference_Invite *event, void *user_data) Tox *tox, uint32_t friendnumber, Tox_Conference_Type type,
const uint8_t *data, size_t length, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type); ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type);
ck_assert_msg(toxav_join_av_groupchat(autotox->tox, friend_number, cookie, length, audio_callback, user_data) == 0, ck_assert_msg(toxav_join_av_groupchat(tox, friendnumber, data, length, audio_callback, user_data) == 0,
"tox #%u: failed to join group", autotox->index); "tox #%u: failed to join group", autotox->index);
} }
static void handle_conference_connected( static void handle_conference_connected(
const Tox_Event_Conference_Connected *event, void *user_data) Tox *tox, uint32_t conference_number, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) { if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
return; return;
} }
Tox_Err_Conference_Invite err; Tox_Err_Conference_Invite err;
tox_conference_invite(autotox->tox, 1, 0, &err); tox_conference_invite(tox, 1, 0, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
err); err);
printf("tox #%u: invited next friend\n", autotox->index); printf("tox #%u: invited next friend\n", autotox->index);
@ -108,7 +99,7 @@ static void handle_conference_connected(
} }
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
const bool *disconnected) bool *disconnected)
{ {
uint32_t num_disconnected = 0; uint32_t num_disconnected = 0;
@ -147,10 +138,7 @@ static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes,
do { do {
for (uint32_t i = 0; i < tox_count; ++i) { for (uint32_t i = 0; i < tox_count; ++i) {
if (!disconnect_now[i]) { if (!disconnect_now[i]) {
Tox_Err_Events_Iterate err; tox_iterate(autotoxes[i].tox, &autotoxes[i]);
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
tox_events_free(events);
autotoxes[i].clock += 1000; autotoxes[i].clock += 1000;
} }
} }
@ -177,7 +165,7 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
* returns a random index at which a list of booleans is false * returns a random index at which a list of booleans is false
* (some such index is required to exist) * (some such index is required to exist)
*/ */
static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length) static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
{ {
uint32_t index; uint32_t index;
@ -197,7 +185,7 @@ static bool all_got_audio(AutoTox *autotoxes, const bool *disabled)
} }
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
const State *state = (const State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
if (disabled[i] ^ (state->received_audio_num if (disabled[i] ^ (state->received_audio_num
!= NUM_AV_GROUP_TOX - num_disabled - 1)) { != NUM_AV_GROUP_TOX - num_disabled - 1)) {
@ -303,7 +291,7 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations)
static void run_conference_tests(AutoTox *autotoxes) static void run_conference_tests(AutoTox *autotoxes)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
bool disabled[NUM_AV_GROUP_TOX] = {0}; bool disabled[NUM_AV_GROUP_TOX] = {0};
@ -414,10 +402,10 @@ static void test_groupav(AutoTox *autotoxes)
const time_t test_start_time = time(nullptr); const time_t test_start_time = time(nullptr);
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
tox_events_callback_self_connection_status(autotoxes[i].dispatch, handle_self_connection_status); tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status);
tox_events_callback_friend_connection_status(autotoxes[i].dispatch, handle_friend_connection_status); tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status);
tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
} }
ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX, ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX,
@ -426,6 +414,7 @@ static void test_groupav(AutoTox *autotoxes)
ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend"); ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");
((State *)autotoxes[0].state)->invited_next = true; ((State *)autotoxes[0].state)->invited_next = true;
printf("waiting for invitations to be made\n"); printf("waiting for invitations to be made\n");
uint32_t invited_count = 0; uint32_t invited_count = 0;

View File

@ -12,16 +12,12 @@ typedef struct State {
#include "auto_test_support.h" #include "auto_test_support.h"
static void handle_conference_invite( static void handle_conference_invite(
const Tox_Event_Conference_Invite *event, void *user_data) Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
const uint8_t *cookie, size_t length, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
autotox->index, friend_number, type, (unsigned)length); autotox->index, friend_number, type, (unsigned)length);
fprintf(stderr, "tox%u joining conference\n", autotox->index); fprintf(stderr, "tox%u joining conference\n", autotox->index);
@ -30,7 +26,7 @@ static void handle_conference_invite(
if (friend_number != -1) { if (friend_number != -1) {
Tox_Err_Conference_Join err; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
"attempting to join the conference returned with an error: %d", err); "attempting to join the conference returned with an error: %d", err);
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
@ -41,8 +37,8 @@ static void handle_conference_invite(
static void conference_double_invite_test(AutoTox *autotoxes) static void conference_double_invite_test(AutoTox *autotoxes)
{ {
// Conference callbacks. // Conference callbacks.
tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
State *state[2]; State *state[2];
state[0] = (State *)autotoxes[0].state; state[0] = (State *)autotoxes[0].state;

View File

@ -12,18 +12,15 @@ typedef struct State {
#include "auto_test_support.h" #include "auto_test_support.h"
static void handle_conference_invite( static void handle_conference_invite(
const Tox_Event_Conference_Invite *event, void *user_data) Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
const uint8_t *cookie, size_t length, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
if (friend_number != -1) { if (friend_number != -1) {
Tox_Err_Conference_Join err; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
"attempting to join the conference returned with an error: %d", err); "attempting to join the conference returned with an error: %d", err);
fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference); fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference);
@ -31,7 +28,7 @@ static void handle_conference_invite(
} }
static void handle_conference_connected( static void handle_conference_connected(
const Tox_Event_Conference_Connected *event, void *user_data) Tox *tox, uint32_t conference_number, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
@ -40,7 +37,7 @@ static void handle_conference_connected(
state->connected = true; state->connected = true;
} }
static void wait_connected(AutoTox *autotoxes, const AutoTox *autotox, uint32_t friendnumber) static void wait_connected(AutoTox *autotoxes, AutoTox *autotox, uint32_t friendnumber)
{ {
do { do {
iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
@ -98,8 +95,8 @@ static void conference_invite_merge_test(AutoTox *autotoxes)
// components will cause a split group to merge // components will cause a split group to merge
for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) { for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected); tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
} }
State *state2 = (State *)autotoxes[2].state; State *state2 = (State *)autotoxes[2].state;

View File

@ -13,39 +13,34 @@ typedef struct State {
#include "auto_test_support.h" #include "auto_test_support.h"
static void handle_conference_invite( static void handle_conference_invite(
const Tox_Event_Conference_Invite *event, void *user_data) Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
const uint8_t *cookie, size_t length, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
autotox->index, friend_number, type, (unsigned)length); autotox->index, friend_number, type, (unsigned)length);
fprintf(stderr, "tox%u joining conference\n", autotox->index); fprintf(stderr, "tox%u joining conference\n", autotox->index);
Tox_Err_Conference_Join err; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
"attempting to join the conference returned with an error: %d", err); "attempting to join the conference returned with an error: %d", err);
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference); fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
state->joined = true; state->joined = true;
} }
static void handle_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) static void handle_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event);
fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n", fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n",
autotox->index, conference_number); autotox->index, conference_number);
Tox_Err_Conference_Peer_Query err; Tox_Err_Conference_Peer_Query err;
uint32_t const count = tox_conference_peer_count(autotox->tox, conference_number, &err); uint32_t const count = tox_conference_peer_count(tox, conference_number, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK, ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK,
"failed to get conference peer count: err = %d", err); "failed to get conference peer count: err = %d", err);
printf("tox%u has %u peers\n", autotox->index, count); printf("tox%u has %u peers\n", autotox->index, count);
@ -80,10 +75,10 @@ static void rebuild_peer_list(Tox *tox)
static void conference_peer_nick_test(AutoTox *autotoxes) static void conference_peer_nick_test(AutoTox *autotoxes)
{ {
// Conference callbacks. // Conference callbacks.
tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite); tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
tox_events_callback_conference_peer_list_changed(autotoxes[0].dispatch, handle_peer_list_changed); tox_callback_conference_peer_list_changed(autotoxes[0].tox, handle_peer_list_changed);
tox_events_callback_conference_peer_list_changed(autotoxes[1].dispatch, handle_peer_list_changed); tox_callback_conference_peer_list_changed(autotoxes[1].tox, handle_peer_list_changed);
// Set the names of the toxes. // Set the names of the toxes.
tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr); tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr);

View File

@ -3,14 +3,11 @@
#include "../testing/misc_tools.h" #include "../testing/misc_tools.h"
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
#include "../toxcore/tox_dispatch.h"
#include "../toxcore/tox_events.h"
#include "auto_test_support.h" #include "auto_test_support.h"
#include "check_compat.h" #include "check_compat.h"
typedef struct State { typedef struct State {
uint32_t id; uint32_t id;
Tox *tox;
bool self_online; bool self_online;
bool friend_online; bool friend_online;
bool invited_next; bool invited_next;
@ -23,57 +20,46 @@ typedef struct State {
uint32_t peers; uint32_t peers;
} State; } State;
static void handle_self_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data) static void handle_self_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
fprintf(stderr, "self_connection_status(#%u, %d, _)\n", state->id, connection_status); fprintf(stderr, "self_connection_status(#%u, %d, _)\n", state->id, connection_status);
state->self_online = connection_status != TOX_CONNECTION_NONE; state->self_online = connection_status != TOX_CONNECTION_NONE;
} }
static void handle_friend_connection_status(const Tox_Event_Friend_Connection_Status *event, static void handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status,
void *user_data) void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event);
const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event);
fprintf(stderr, "handle_friend_connection_status(#%u, %u, %d, _)\n", state->id, friend_number, connection_status); fprintf(stderr, "handle_friend_connection_status(#%u, %u, %d, _)\n", state->id, friend_number, connection_status);
state->friend_online = connection_status != TOX_CONNECTION_NONE; state->friend_online = connection_status != TOX_CONNECTION_NONE;
} }
static void handle_conference_invite(const Tox_Event_Conference_Invite *event, void *user_data) static void handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie,
size_t length, void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
const size_t length = tox_event_conference_invite_get_cookie_length(event);
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n", fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
state->id, friend_number, type, (unsigned)length); state->id, friend_number, type, (unsigned)length);
fprintf(stderr, "tox%u joining conference\n", state->id); fprintf(stderr, "tox%u joining conference\n", state->id);
{ {
Tox_Err_Conference_Join err; Tox_Err_Conference_Join err;
state->conference = tox_conference_join(state->tox, friend_number, cookie, length, &err); state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "failed to join a conference: err = %d", err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "failed to join a conference: err = %d", err);
fprintf(stderr, "tox%u Joined conference %u\n", state->id, state->conference); fprintf(stderr, "tox%u Joined conference %u\n", state->id, state->conference);
state->joined = true; state->joined = true;
} }
} }
static void handle_conference_message(const Tox_Event_Conference_Message *event, void *user_data) static void handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number,
Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
const uint32_t conference_number = tox_event_conference_message_get_conference_number(event);
const uint32_t peer_number = tox_event_conference_message_get_peer_number(event);
const Tox_Message_Type type = tox_event_conference_message_get_type(event);
const uint8_t *message = tox_event_conference_message_get_message(event);
const size_t length = tox_event_conference_message_get_message_length(event);
fprintf(stderr, "handle_conference_message(#%u, %u, %u, %d, uint8_t[%u], _)\n", fprintf(stderr, "handle_conference_message(#%u, %u, %u, %d, uint8_t[%u], _)\n",
state->id, conference_number, peer_number, type, (unsigned)length); state->id, conference_number, peer_number, type, (unsigned)length);
@ -81,16 +67,15 @@ static void handle_conference_message(const Tox_Event_Conference_Message *event,
state->received = true; state->received = true;
} }
static void handle_conference_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event);
fprintf(stderr, "handle_conference_peer_list_changed(#%u, %u, _)\n", fprintf(stderr, "handle_conference_peer_list_changed(#%u, %u, _)\n",
state->id, conference_number); state->id, conference_number);
Tox_Err_Conference_Peer_Query err; Tox_Err_Conference_Peer_Query err;
uint32_t count = tox_conference_peer_count(state->tox, conference_number, &err); uint32_t count = tox_conference_peer_count(tox, conference_number, &err);
if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) { if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) {
fprintf(stderr, "ERROR: %d\n", err); fprintf(stderr, "ERROR: %d\n", err);
@ -101,14 +86,14 @@ static void handle_conference_peer_list_changed(const Tox_Event_Conference_Peer_
state->peers = count; state->peers = count;
} }
static void handle_conference_connected(const Tox_Event_Conference_Connected *event, void *user_data) static void handle_conference_connected(Tox *tox, uint32_t conference_number, void *user_data)
{ {
State *state = (State *)user_data; State *state = (State *)user_data;
// We're tox2, so now we invite tox3. // We're tox2, so now we invite tox3.
if (state->id == 2 && !state->invited_next) { if (state->id == 2 && !state->invited_next) {
Tox_Err_Conference_Invite err; Tox_Err_Conference_Invite err;
tox_conference_invite(state->tox, 1, state->conference, &err); tox_conference_invite(tox, 1, state->conference, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox2 failed to invite tox3: err = %d", err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox2 failed to invite tox3: err = %d", err);
state->invited_next = true; state->invited_next = true;
@ -116,27 +101,6 @@ static void handle_conference_connected(const Tox_Event_Conference_Connected *ev
} }
} }
static void iterate_one(
Tox *tox, State *state, const Tox_Dispatch *dispatch)
{
Tox_Err_Events_Iterate err;
Tox_Events *events = tox_events_iterate(tox, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, state);
tox_events_free(events);
}
static void iterate3_wait(
State *state1, State *state2, State *state3,
const Tox_Dispatch *dispatch, int interval)
{
iterate_one(state1->tox, state1, dispatch);
iterate_one(state2->tox, state2, dispatch);
iterate_one(state3->tox, state3, dispatch);
c_sleep(interval);
}
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
@ -146,51 +110,64 @@ int main(void)
State state3 = {3}; State state3 = {3};
// Create toxes. // Create toxes.
state1.tox = tox_new_log(nullptr, nullptr, &state1.id); Tox *tox1 = tox_new_log(nullptr, nullptr, &state1.id);
state2.tox = tox_new_log(nullptr, nullptr, &state2.id); Tox *tox2 = tox_new_log(nullptr, nullptr, &state2.id);
state3.tox = tox_new_log(nullptr, nullptr, &state3.id); Tox *tox3 = tox_new_log(nullptr, nullptr, &state3.id);
tox_events_init(state1.tox);
tox_events_init(state2.tox);
tox_events_init(state3.tox);
// tox1 <-> tox2, tox2 <-> tox3 // tox1 <-> tox2, tox2 <-> tox3
uint8_t key[TOX_PUBLIC_KEY_SIZE]; uint8_t key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_public_key(state2.tox, key); tox_self_get_public_key(tox2, key);
tox_friend_add_norequest(state1.tox, key, nullptr); // tox1 -> tox2 tox_friend_add_norequest(tox1, key, nullptr); // tox1 -> tox2
tox_self_get_public_key(state1.tox, key); tox_self_get_public_key(tox1, key);
tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox1 tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox1
tox_self_get_public_key(state3.tox, key); tox_self_get_public_key(tox3, key);
tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox3 tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox3
tox_self_get_public_key(state2.tox, key); tox_self_get_public_key(tox2, key);
tox_friend_add_norequest(state3.tox, key, nullptr); // tox3 -> tox2 tox_friend_add_norequest(tox3, key, nullptr); // tox3 -> tox2
printf("bootstrapping tox2 and tox3 off tox1\n"); printf("bootstrapping tox2 and tox3 off tox1\n");
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(state1.tox, dht_key); tox_self_get_dht_id(tox1, dht_key);
const uint16_t dht_port = tox_self_get_udp_port(state1.tox, nullptr); const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr);
tox_bootstrap(state2.tox, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr);
tox_bootstrap(state3.tox, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr);
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr);
// Connection callbacks. // Connection callbacks.
tox_events_callback_self_connection_status(dispatch, handle_self_connection_status); tox_callback_self_connection_status(tox1, handle_self_connection_status);
tox_events_callback_friend_connection_status(dispatch, handle_friend_connection_status); tox_callback_self_connection_status(tox2, handle_self_connection_status);
tox_callback_self_connection_status(tox3, handle_self_connection_status);
tox_callback_friend_connection_status(tox1, handle_friend_connection_status);
tox_callback_friend_connection_status(tox2, handle_friend_connection_status);
tox_callback_friend_connection_status(tox3, handle_friend_connection_status);
// Conference callbacks. // Conference callbacks.
tox_events_callback_conference_invite(dispatch, handle_conference_invite); tox_callback_conference_invite(tox1, handle_conference_invite);
tox_events_callback_conference_connected(dispatch, handle_conference_connected); tox_callback_conference_invite(tox2, handle_conference_invite);
tox_events_callback_conference_message(dispatch, handle_conference_message); tox_callback_conference_invite(tox3, handle_conference_invite);
tox_events_callback_conference_peer_list_changed(dispatch, handle_conference_peer_list_changed);
tox_callback_conference_connected(tox1, handle_conference_connected);
tox_callback_conference_connected(tox2, handle_conference_connected);
tox_callback_conference_connected(tox3, handle_conference_connected);
tox_callback_conference_message(tox1, handle_conference_message);
tox_callback_conference_message(tox2, handle_conference_message);
tox_callback_conference_message(tox3, handle_conference_message);
tox_callback_conference_peer_list_changed(tox1, handle_conference_peer_list_changed);
tox_callback_conference_peer_list_changed(tox2, handle_conference_peer_list_changed);
tox_callback_conference_peer_list_changed(tox3, handle_conference_peer_list_changed);
// Wait for self connection. // Wait for self connection.
fprintf(stderr, "Waiting for toxes to come online\n"); fprintf(stderr, "Waiting for toxes to come online\n");
do { do {
iterate3_wait(&state1, &state2, &state3, dispatch, 100); tox_iterate(tox1, &state1);
tox_iterate(tox2, &state2);
tox_iterate(tox3, &state3);
c_sleep(100);
} while (!state1.self_online || !state2.self_online || !state3.self_online); } while (!state1.self_online || !state2.self_online || !state3.self_online);
fprintf(stderr, "Toxes are online\n"); fprintf(stderr, "Toxes are online\n");
@ -199,7 +176,11 @@ int main(void)
fprintf(stderr, "Waiting for friends to connect\n"); fprintf(stderr, "Waiting for friends to connect\n");
do { do {
iterate3_wait(&state1, &state2, &state3, dispatch, 100); tox_iterate(tox1, &state1);
tox_iterate(tox2, &state2);
tox_iterate(tox3, &state3);
c_sleep(100);
} while (!state1.friend_online || !state2.friend_online || !state3.friend_online); } while (!state1.friend_online || !state2.friend_online || !state3.friend_online);
fprintf(stderr, "Friends are connected\n"); fprintf(stderr, "Friends are connected\n");
@ -207,7 +188,7 @@ int main(void)
{ {
// Create new conference, tox1 is the founder. // Create new conference, tox1 is the founder.
Tox_Err_Conference_New err; Tox_Err_Conference_New err;
state1.conference = tox_conference_new(state1.tox, &err); state1.conference = tox_conference_new(tox1, &err);
state1.joined = true; state1.joined = true;
ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err); ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err);
fprintf(stderr, "Created conference: id = %u\n", state1.conference); fprintf(stderr, "Created conference: id = %u\n", state1.conference);
@ -216,7 +197,7 @@ int main(void)
{ {
// Invite friend. // Invite friend.
Tox_Err_Conference_Invite err; Tox_Err_Conference_Invite err;
tox_conference_invite(state1.tox, 0, state1.conference, &err); tox_conference_invite(tox1, 0, state1.conference, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err); ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err);
state1.invited_next = true; state1.invited_next = true;
fprintf(stderr, "tox1 invited tox2\n"); fprintf(stderr, "tox1 invited tox2\n");
@ -225,7 +206,11 @@ int main(void)
fprintf(stderr, "Waiting for invitation to arrive\n"); fprintf(stderr, "Waiting for invitation to arrive\n");
do { do {
iterate3_wait(&state1, &state2, &state3, dispatch, 100); tox_iterate(tox1, &state1);
tox_iterate(tox2, &state2);
tox_iterate(tox3, &state3);
c_sleep(100);
} while (!state1.joined || !state2.joined || !state3.joined); } while (!state1.joined || !state2.joined || !state3.joined);
fprintf(stderr, "Invitations accepted\n"); fprintf(stderr, "Invitations accepted\n");
@ -233,7 +218,11 @@ int main(void)
fprintf(stderr, "Waiting for peers to come online\n"); fprintf(stderr, "Waiting for peers to come online\n");
do { do {
iterate3_wait(&state1, &state2, &state3, dispatch, 100); tox_iterate(tox1, &state1);
tox_iterate(tox2, &state2);
tox_iterate(tox3, &state3);
c_sleep(100);
} while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0); } while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0);
fprintf(stderr, "All peers are online\n"); fprintf(stderr, "All peers are online\n");
@ -241,7 +230,7 @@ int main(void)
{ {
fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n"); fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n");
Tox_Err_Conference_Send_Message err; Tox_Err_Conference_Send_Message err;
tox_conference_send_message(state1.tox, state1.conference, TOX_MESSAGE_TYPE_NORMAL, tox_conference_send_message(tox1, state1.conference, TOX_MESSAGE_TYPE_NORMAL,
(const uint8_t *)"hello!", 7, &err); (const uint8_t *)"hello!", 7, &err);
if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) { if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) {
@ -253,16 +242,18 @@ int main(void)
fprintf(stderr, "Waiting for messages to arrive\n"); fprintf(stderr, "Waiting for messages to arrive\n");
do { do {
iterate3_wait(&state1, &state2, &state3, dispatch, 100); tox_iterate(tox1, &state1);
tox_iterate(tox2, &state2);
tox_iterate(tox3, &state3);
c_sleep(100); c_sleep(100);
} while (!state2.received || !state3.received); } while (!state2.received || !state3.received);
fprintf(stderr, "Messages received. Test complete.\n"); fprintf(stderr, "Messages received. Test complete.\n");
tox_dispatch_free(dispatch); tox_kill(tox3);
tox_kill(state3.tox); tox_kill(tox2);
tox_kill(state2.tox); tox_kill(tox1);
tox_kill(state1.tox);
return 0; return 0;
} }

View File

@ -56,13 +56,13 @@ static void handle_conference_invite(
ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type); ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type);
Tox_Err_Conference_Join err; Tox_Err_Conference_Join err;
uint32_t g_num = tox_conference_join(autotox->tox, friendnumber, data, length, &err); uint32_t g_num = tox_conference_join(tox, friendnumber, data, length, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err); ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err);
ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index); ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index);
// Try joining again. We should only be allowed to join once. // Try joining again. We should only be allowed to join once.
tox_conference_join(autotox->tox, friendnumber, data, length, &err); tox_conference_join(tox, friendnumber, data, length, &err);
ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK, ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK,
"tox #%u: joining groupchat twice should be impossible.", autotox->index); "tox #%u: joining groupchat twice should be impossible.", autotox->index);
} }
@ -73,12 +73,12 @@ static void handle_conference_connected(
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) { if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
return; return;
} }
Tox_Err_Conference_Invite err; Tox_Err_Conference_Invite err;
tox_conference_invite(autotox->tox, 1, 0, &err); tox_conference_invite(tox, 1, 0, &err);
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index, ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
err); err);
printf("tox #%u: invited next friend\n", autotox->index); printf("tox #%u: invited next friend\n", autotox->index);
@ -97,7 +97,7 @@ static void handle_conference_message(
} }
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes, static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
const bool *disconnected) bool *disconnected)
{ {
uint32_t num_disconnected = 0; uint32_t num_disconnected = 0;
@ -174,11 +174,12 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes)
return true; return true;
} }
/** /**
* returns a random index at which a list of booleans is false * returns a random index at which a list of booleans is false
* (some such index is required to exist) * (some such index is required to exist)
*/ */
static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length) static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
{ {
uint32_t index; uint32_t index;
@ -191,7 +192,7 @@ static uint32_t random_false_index(const Random *rng, const bool *list, const ui
static void run_conference_tests(AutoTox *autotoxes) static void run_conference_tests(AutoTox *autotoxes)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
/* disabling name change propagation check for now, as it occasionally /* disabling name change propagation check for now, as it occasionally
* fails due to disconnections too short to trigger freezing */ * fails due to disconnections too short to trigger freezing */
@ -356,6 +357,7 @@ static void test_many_group(AutoTox *autotoxes)
nullptr) != 0, nullptr) != 0,
"failed to set group title"); "failed to set group title");
printf("waiting for invitations to be made\n"); printf("waiting for invitations to be made\n");
uint32_t invited_count = 0; uint32_t invited_count = 0;
@ -433,7 +435,6 @@ int main(void)
Run_Auto_Options options = default_run_auto_options(); Run_Auto_Options options = default_run_auto_options();
options.graph = GRAPH_LINEAR; options.graph = GRAPH_LINEAR;
options.events = false;
run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options); run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options);
return 0; return 0;

View File

@ -125,7 +125,7 @@ static void test_fast_known(void)
static void test_endtoend(void) static void test_endtoend(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
// Test 100 random messages and keypairs // Test 100 random messages and keypairs
@ -192,7 +192,7 @@ static void test_endtoend(void)
static void test_large_data(void) static void test_large_data(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t k[CRYPTO_SHARED_KEY_SIZE];
uint8_t n[CRYPTO_NONCE_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE];
@ -236,7 +236,7 @@ static void test_large_data(void)
static void test_large_data_symmetric(void) static void test_large_data_symmetric(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE];
@ -271,10 +271,10 @@ static void test_large_data_symmetric(void)
static void test_very_large_data(void) static void test_very_large_data(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0}; uint8_t nonce[CRYPTO_NONCE_SIZE] = {0};
uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk[CRYPTO_SECRET_KEY_SIZE]; uint8_t sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, pk, sk); crypto_new_keypair(rng, pk, sk);
@ -316,7 +316,7 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num)
static void test_increment_nonce(void) static void test_increment_nonce(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
uint8_t n[CRYPTO_NONCE_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE];

View File

@ -72,16 +72,12 @@ static bool all_nodes_crawled(const AutoTox *autotoxes, uint32_t num_toxes, uint
return true; return true;
} }
static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data) static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, void *user_data)
{ {
ck_assert(user_data != nullptr); ck_assert(user_data != nullptr);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotoxes = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotoxes->state;
const uint8_t *public_key = tox_event_dht_get_nodes_response_get_public_key(event);
const char *ip = (const char *)tox_event_dht_get_nodes_response_get_ip(event);
const uint16_t port = tox_event_dht_get_nodes_response_get_port(event);
if (node_crawled(state->nodes, state->num_nodes, public_key)) { if (node_crawled(state->nodes, state->num_nodes, public_key)) {
return; return;
@ -101,7 +97,7 @@ static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event,
// ask new node to give us their close nodes to every public key // ask new node to give us their close nodes to every public key
for (size_t i = 0; i < NUM_TOXES; ++i) { for (size_t i = 0; i < NUM_TOXES; ++i) {
tox_dht_get_nodes(autotox->tox, public_key, ip, port, state->public_key_list[i], nullptr); tox_dht_get_nodes(tox, public_key, ip, port, state->public_key_list[i], nullptr);
} }
} }
@ -125,12 +121,13 @@ static void test_dht_getnodes(AutoTox *autotoxes)
ck_assert(public_key_list[i] != nullptr); ck_assert(public_key_list[i] != nullptr);
tox_self_get_dht_id(autotoxes[i].tox, public_key_list[i]); tox_self_get_dht_id(autotoxes[i].tox, public_key_list[i]);
tox_events_callback_dht_get_nodes_response(autotoxes[i].dispatch, getnodes_response_cb); tox_callback_dht_get_nodes_response(autotoxes[i].tox, getnodes_response_cb);
printf("Peer %zu dht closenode count total/announce-capable: %d/%d\n", printf("Peer %zu dht closenode count total/announce-capable: %d/%d\n",
i, i,
tox_dht_get_num_closelist(autotoxes[i].tox), tox_dht_get_num_closelist(autotoxes[i].tox),
tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox)); tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox)
);
} }
while (!all_nodes_crawled(autotoxes, NUM_TOXES, public_key_list)) { while (!all_nodes_crawled(autotoxes, NUM_TOXES, public_key_list)) {

View File

@ -168,7 +168,7 @@ static void test_keys(void)
ck_assert(encrypted2a != nullptr); ck_assert(encrypted2a != nullptr);
uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a); uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a);
ck_assert(in_plaintext2a != nullptr); ck_assert(in_plaintext2a != nullptr);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
random_bytes(rng, in_plaintext2a, plaintext_length2a); random_bytes(rng, in_plaintext2a, plaintext_length2a);
ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr); ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr);
@ -184,6 +184,7 @@ static void test_keys(void)
free(in_plaintext2a); free(in_plaintext2a);
free(out_plaintext2a); free(out_plaintext2a);
uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr); ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr);
ck_assert_msg(ret, "generic failure 3: %d", encerr); ck_assert_msg(ret, "generic failure 3: %d", encerr);

View File

@ -53,7 +53,7 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num
ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id"); ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id");
const uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id"); ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id");
@ -126,6 +126,7 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
Tox_Err_File_Send_Chunk error; Tox_Err_File_Send_Chunk error;
tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error); tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error);
ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK, ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK,
"could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length); "could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length);
@ -133,6 +134,7 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
sending_pos += length; sending_pos += length;
} }
static uint8_t num; static uint8_t num;
static bool file_recv; static bool file_recv;
static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
@ -207,6 +209,7 @@ static void file_transfer_test(void)
file_accepted = file_size = sendf_ok = size_recv = 0; file_accepted = file_size = sendf_ok = size_recv = 0;
file_recv = 0; file_recv = 0;
max_sending = UINT64_MAX; max_sending = UINT64_MAX;
uint64_t totalf_size = 100 * 1024 * 1024;
printf("Starting file streaming transfer test.\n"); printf("Starting file streaming transfer test.\n");
@ -221,10 +224,10 @@ static void file_transfer_test(void)
tox_callback_file_chunk_request(tox2, tox_file_chunk_request); tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
tox_callback_file_recv_control(tox3, file_print_control); tox_callback_file_recv_control(tox3, file_print_control);
tox_callback_file_recv(tox3, tox_file_receive); tox_callback_file_recv(tox3, tox_file_receive);
const uint64_t totalf_size = UINT64_MAX; totalf_size = UINT64_MAX;
Tox_File_Number fnum = tox_file_send( Tox_File_Number fnum = tox_file_send(
tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr,
(const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr);
ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail"); ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail");
Tox_Err_File_Get gfierr; Tox_Err_File_Get gfierr;

View File

@ -26,16 +26,10 @@
#define TOX_LOCALHOST "127.0.0.1" #define TOX_LOCALHOST "127.0.0.1"
#endif #endif
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{ {
Tox *tox = (Tox *)userdata;
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *data = tox_event_friend_request_get_message(event);
const size_t length = tox_event_friend_request_get_message_length(event);
if (length == 7 && memcmp("Gentoo", data, 7) == 0) { if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
tox_friend_add_norequest(tox, public_key, nullptr); tox_friend_add_norequest(m, public_key, nullptr);
} }
} }
@ -45,17 +39,9 @@ static uint64_t sending_pos;
static uint8_t file_cmp_id[TOX_FILE_ID_LENGTH]; static uint8_t file_cmp_id[TOX_FILE_ID_LENGTH];
static uint32_t file_accepted; static uint32_t file_accepted;
static uint64_t file_size; static uint64_t file_size;
static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata) static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t filesize,
const uint8_t *filename, size_t filename_length, void *userdata)
{ {
Tox *state_tox = (Tox *)userdata;
const uint32_t friend_number = tox_event_file_recv_get_friend_number(event);
const uint32_t file_number = tox_event_file_recv_get_file_number(event);
const uint32_t kind = tox_event_file_recv_get_kind(event);
const uint64_t filesize = tox_event_file_recv_get_file_size(event);
const uint8_t *filename = tox_event_file_recv_get_filename(event);
const size_t filename_length = tox_event_file_recv_get_filename_length(event);
ck_assert_msg(kind == TOX_FILE_KIND_DATA, "bad kind"); ck_assert_msg(kind == TOX_FILE_KIND_DATA, "bad kind");
ck_assert_msg(filename_length == sizeof("Gentoo.exe") ck_assert_msg(filename_length == sizeof("Gentoo.exe")
@ -63,11 +49,11 @@ static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata)
uint8_t file_id[TOX_FILE_ID_LENGTH]; uint8_t file_id[TOX_FILE_ID_LENGTH];
ck_assert_msg(tox_file_get_file_id(state_tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error"); ck_assert_msg(tox_file_get_file_id(tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error");
ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id"); ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id");
const uint8_t empty[TOX_FILE_ID_LENGTH] = {0}; uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id"); ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id");
@ -78,7 +64,7 @@ static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata)
Tox_Err_File_Seek err_s; Tox_Err_File_Seek err_s;
ck_assert_msg(tox_file_seek(state_tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error"); ck_assert_msg(tox_file_seek(tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error");
ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_OK, "tox_file_seek wrong error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_OK, "tox_file_seek wrong error");
@ -88,24 +74,21 @@ static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata)
Tox_Err_File_Control error; Tox_Err_File_Control error;
ck_assert_msg(tox_file_control(state_tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error), ck_assert_msg(tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error),
"tox_file_control failed. %i", error); "tox_file_control failed. %i", error);
++file_accepted; ++file_accepted;
Tox_Err_File_Seek err_s; Tox_Err_File_Seek err_s;
ck_assert_msg(!tox_file_seek(state_tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error"); ck_assert_msg(!tox_file_seek(tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error");
ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_DENIED, "tox_file_seek wrong error"); ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_DENIED, "tox_file_seek wrong error");
} }
static uint32_t sendf_ok; static uint32_t sendf_ok;
static void file_print_control(const Tox_Event_File_Recv_Control *event, static void file_print_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
void *userdata) void *userdata)
{ {
const uint32_t file_number = tox_event_file_recv_control_get_file_number(event);
const Tox_File_Control control = tox_event_file_recv_control_get_control(event);
/* First send file num is 0.*/ /* First send file num is 0.*/
if (file_number == 0 && control == TOX_FILE_CONTROL_RESUME) { if (file_number == 0 && control == TOX_FILE_CONTROL_RESUME) {
sendf_ok = 1; sendf_ok = 1;
@ -116,18 +99,12 @@ static uint64_t max_sending;
static bool m_send_reached; static bool m_send_reached;
static uint8_t sending_num; static uint8_t sending_num;
static bool file_sending_done; static bool file_sending_done;
static void tox_file_chunk_request(const Tox_Event_File_Chunk_Request *event, void *user_data) static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
size_t length, void *user_data)
{ {
Tox *state_tox = (Tox *)user_data;
const uint32_t friend_number = tox_event_file_chunk_request_get_friend_number(event);
const uint32_t file_number = tox_event_file_chunk_request_get_file_number(event);
const uint64_t position = tox_event_file_chunk_request_get_position(event);
size_t length = tox_event_file_chunk_request_get_length(event);
ck_assert_msg(sendf_ok, "didn't get resume control"); ck_assert_msg(sendf_ok, "didn't get resume control");
ck_assert_msg(sending_pos == position, "bad position %lu (should be %lu)", (unsigned long)position, (unsigned long)sending_pos); ck_assert_msg(sending_pos == position, "bad position %lu", (unsigned long)position);
if (length == 0) { if (length == 0) {
ck_assert_msg(!file_sending_done, "file sending already done"); ck_assert_msg(!file_sending_done, "file sending already done");
@ -147,7 +124,8 @@ static void tox_file_chunk_request(const Tox_Event_File_Chunk_Request *event, vo
memset(f_data, sending_num, length); memset(f_data, sending_num, length);
Tox_Err_File_Send_Chunk error; Tox_Err_File_Send_Chunk error;
tox_file_send_chunk(state_tox, friend_number, file_number, position, f_data, length, &error); tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error);
ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK, ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK,
"could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length); "could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length);
@ -156,14 +134,12 @@ static void tox_file_chunk_request(const Tox_Event_File_Chunk_Request *event, vo
sending_pos += length; sending_pos += length;
} }
static uint8_t num; static uint8_t num;
static bool file_recv; static bool file_recv;
static void write_file(const Tox_Event_File_Recv_Chunk *event, void *user_data) static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
size_t length, void *user_data)
{ {
const uint64_t position = tox_event_file_recv_chunk_get_position(event);
const uint8_t *data = tox_event_file_recv_chunk_get_data(event);
const size_t length = tox_event_file_recv_chunk_get_data_length(event);
ck_assert_msg(size_recv == position, "bad position"); ck_assert_msg(size_recv == position, "bad position");
if (length == 0) { if (length == 0) {
@ -180,17 +156,6 @@ static void write_file(const Tox_Event_File_Recv_Chunk *event, void *user_data)
size_recv += length; size_recv += length;
} }
static void iterate_and_dispatch(const Tox_Dispatch *dispatch, Tox *tox)
{
Tox_Err_Events_Iterate err;
Tox_Events *events;
events = tox_events_iterate(tox, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, tox);
tox_events_free(events);
}
static void file_transfer_test(void) static void file_transfer_test(void)
{ {
printf("Starting test: few_clients\n"); printf("Starting test: few_clients\n");
@ -206,19 +171,7 @@ static void file_transfer_test(void)
ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances");
tox_events_init(tox1); tox_callback_friend_request(tox2, accept_friend_request);
tox_events_init(tox2);
tox_events_init(tox3);
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
ck_assert(dispatch1 != nullptr);
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
ck_assert(dispatch2 != nullptr);
Tox_Dispatch *dispatch3 = tox_dispatch_new(nullptr);
ck_assert(dispatch3 != nullptr);
tox_events_callback_friend_request(dispatch2, accept_friend_request);
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_self_get_address(tox2, address); tox_self_get_address(tox2, address);
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr); uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
@ -234,9 +187,9 @@ static void file_transfer_test(void)
printf("Waiting for toxes to come online\n"); printf("Waiting for toxes to come online\n");
do { do {
iterate_and_dispatch(dispatch1, tox1); tox_iterate(tox1, nullptr);
iterate_and_dispatch(dispatch2, tox2); tox_iterate(tox2, nullptr);
iterate_and_dispatch(dispatch3, tox3); tox_iterate(tox3, nullptr);
printf("Connections: self (%d, %d, %d), friends (%d, %d)\n", printf("Connections: self (%d, %d, %d), friends (%d, %d)\n",
tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox1),
@ -257,11 +210,11 @@ static void file_transfer_test(void)
file_recv = 0; file_recv = 0;
max_sending = UINT64_MAX; max_sending = UINT64_MAX;
uint64_t f_time = time(nullptr); uint64_t f_time = time(nullptr);
tox_events_callback_file_recv_chunk(dispatch3, write_file); tox_callback_file_recv_chunk(tox3, write_file);
tox_events_callback_file_recv_control(dispatch2, file_print_control); tox_callback_file_recv_control(tox2, file_print_control);
tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request); tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
tox_events_callback_file_recv_control(dispatch3, file_print_control); tox_callback_file_recv_control(tox3, file_print_control);
tox_events_callback_file_recv(dispatch3, tox_file_receive); tox_callback_file_recv(tox3, tox_file_receive);
uint64_t totalf_size = 100 * 1024 * 1024; uint64_t totalf_size = 100 * 1024 * 1024;
uint32_t fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe", uint32_t fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe",
sizeof("Gentoo.exe"), nullptr); sizeof("Gentoo.exe"), nullptr);
@ -278,9 +231,9 @@ static void file_transfer_test(void)
const size_t max_iterations = INT16_MAX; const size_t max_iterations = INT16_MAX;
for (size_t i = 0; i < max_iterations; i++) { for (size_t i = 0; i < max_iterations; i++) {
iterate_and_dispatch(dispatch1, tox1); tox_iterate(tox1, nullptr);
iterate_and_dispatch(dispatch2, tox2); tox_iterate(tox2, nullptr);
iterate_and_dispatch(dispatch3, tox3); tox_iterate(tox3, nullptr);
if (file_sending_done) { if (file_sending_done) {
ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv
@ -321,11 +274,11 @@ static void file_transfer_test(void)
sendf_ok = 0; sendf_ok = 0;
size_recv = 0; size_recv = 0;
file_recv = 0; file_recv = 0;
tox_events_callback_file_recv_chunk(dispatch3, write_file); tox_callback_file_recv_chunk(tox3, write_file);
tox_events_callback_file_recv_control(dispatch2, file_print_control); tox_callback_file_recv_control(tox2, file_print_control);
tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request); tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
tox_events_callback_file_recv_control(dispatch3, file_print_control); tox_callback_file_recv_control(tox3, file_print_control);
tox_events_callback_file_recv(dispatch3, tox_file_receive); tox_callback_file_recv(tox3, tox_file_receive);
totalf_size = 0; totalf_size = 0;
fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr,
(const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr); (const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr);
@ -345,9 +298,9 @@ static void file_transfer_test(void)
c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval))); c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval)));
iterate_and_dispatch(dispatch1, tox1); tox_iterate(tox1, nullptr);
iterate_and_dispatch(dispatch2, tox2); tox_iterate(tox2, nullptr);
iterate_and_dispatch(dispatch3, tox3); tox_iterate(tox3, nullptr);
} while (!file_sending_done); } while (!file_sending_done);
ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size
@ -359,12 +312,9 @@ static void file_transfer_test(void)
printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time); printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time);
tox_dispatch_free(dispatch3);
tox_dispatch_free(dispatch2);
tox_dispatch_free(dispatch1);
tox_kill(tox3);
tox_kill(tox2);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2);
tox_kill(tox3);
} }
int main(void) int main(void)

View File

@ -47,8 +47,8 @@ static void test_forwarded_request_cb(void *object, const IP_Port *forwarder,
const uint8_t *sendback, uint16_t sendback_length, const uint8_t *sendback, uint16_t sendback_length,
const uint8_t *data, uint16_t length, void *userdata) const uint8_t *data, uint16_t length, void *userdata)
{ {
const Test_Data *test_data = (const Test_Data *)object; Test_Data *test_data = (Test_Data *)object;
const uint8_t *index = (const uint8_t *)userdata; uint8_t *index = (uint8_t *)userdata;
if (length != 12 || memcmp("hello: ", data, 8) != 0) { if (length != 12 || memcmp("hello: ", data, 8) != 0) {
printf("[%u] got unexpected data of length %d\n", *index, length); printf("[%u] got unexpected data of length %d\n", *index, length);
@ -66,7 +66,7 @@ static void test_forwarded_response_cb(void *object,
const uint8_t *data, uint16_t length, void *userdata) const uint8_t *data, uint16_t length, void *userdata)
{ {
Test_Data *test_data = (Test_Data *)object; Test_Data *test_data = (Test_Data *)object;
const uint8_t *index = (const uint8_t *)userdata; uint8_t *index = (uint8_t *)userdata;
if (length != 12 || memcmp("reply: ", data, 8) != 0) { if (length != 12 || memcmp("reply: ", data, 8) != 0) {
printf("[%u] got unexpected data of length %d\n", *index, length); printf("[%u] got unexpected data of length %d\n", *index, length);
@ -104,9 +104,9 @@ typedef struct Forwarding_Subtox {
static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port) static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox));
@ -152,11 +152,11 @@ static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox)
static void test_forwarding(void) static void test_forwarding(void)
{ {
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
uint32_t index[NUM_FORWARDER]; uint32_t index[NUM_FORWARDER];
@ -317,6 +317,7 @@ static void test_forwarding(void)
} }
} }
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
kill_forwarding_subtox(mem, subtoxes[i]); kill_forwarding_subtox(mem, subtoxes[i]);
} }
@ -324,6 +325,7 @@ static void test_forwarding(void)
tox_kill(relay); tox_kill(relay);
} }
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);

View File

@ -22,18 +22,12 @@ typedef struct State {
bool unused; bool unused;
} State; } State;
static void accept_friend_request(const Tox_Event_Friend_Request *event, static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length,
void *userdata) void *userdata)
{ {
AutoTox *autotox = (AutoTox *)userdata;
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *data = tox_event_friend_request_get_message(event);
const size_t length = tox_event_friend_request_get_message_length(event);
ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0,
"unexpected friend request message"); "unexpected friend request message");
tox_friend_add_norequest(autotox->tox, public_key, nullptr); tox_friend_add_norequest(tox, public_key, nullptr);
} }
static void test_friend_request(AutoTox *autotoxes) static void test_friend_request(AutoTox *autotoxes)
@ -41,7 +35,7 @@ static void test_friend_request(AutoTox *autotoxes)
const time_t con_time = time(nullptr); const time_t con_time = time(nullptr);
printf("All toxes add tox1 as friend.\n"); printf("All toxes add tox1 as friend.\n");
tox_events_callback_friend_request(autotoxes[0].dispatch, accept_friend_request); tox_callback_friend_request(autotoxes[0].tox, accept_friend_request);
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_self_get_address(autotoxes[0].tox, address); tox_self_get_address(autotoxes[0].tox, address);

View File

@ -15,36 +15,12 @@
#define FR_MESSAGE "Gentoo" #define FR_MESSAGE "Gentoo"
static void accept_friend_request(const Tox_Event_Friend_Request *event, static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length,
void *userdata) void *userdata)
{ {
Tox *state_tox = (Tox *)userdata;
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *data = tox_event_friend_request_get_message(event);
const size_t length = tox_event_friend_request_get_message_length(event);
ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0, ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0,
"unexpected friend request message"); "unexpected friend request message");
tox_friend_add_norequest(state_tox, public_key, nullptr); tox_friend_add_norequest(tox, public_key, nullptr);
}
static void iterate2_wait(const Tox_Dispatch *dispatch, Tox *tox1, Tox *tox2)
{
Tox_Err_Events_Iterate err;
Tox_Events *events;
events = tox_events_iterate(tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, tox1);
tox_events_free(events);
events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, tox2);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL);
} }
static void test_friend_request(void) static void test_friend_request(void)
@ -57,9 +33,6 @@ static void test_friend_request(void)
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
tox_events_init(tox1);
tox_events_init(tox2);
printf("Bootstrapping tox2 off tox1.\n"); printf("Bootstrapping tox2 off tox1.\n");
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(tox1, dht_key); tox_self_get_dht_id(tox1, dht_key);
@ -67,11 +40,11 @@ static void test_friend_request(void)
tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr);
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr);
do { do {
iterate2_wait(dispatch, tox1, tox2); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
c_sleep(ITERATION_INTERVAL);
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE);
@ -79,7 +52,7 @@ static void test_friend_request(void)
const time_t con_time = time(nullptr); const time_t con_time = time(nullptr);
printf("Tox1 adds tox2 as friend, tox2 accepts.\n"); printf("Tox1 adds tox2 as friend, tox2 accepts.\n");
tox_events_callback_friend_request(dispatch, accept_friend_request); tox_callback_friend_request(tox2, accept_friend_request);
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_self_get_address(tox2, address); tox_self_get_address(tox2, address);
@ -88,14 +61,16 @@ static void test_friend_request(void)
ck_assert_msg(test == 0, "failed to add friend error code: %u", test); ck_assert_msg(test == 0, "failed to add friend error code: %u", test);
do { do {
iterate2_wait(dispatch, tox1, tox2); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
c_sleep(ITERATION_INTERVAL);
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP);
printf("Tox clients connected took %lu seconds.\n", (unsigned long)(time(nullptr) - con_time)); printf("Tox clients connected took %lu seconds.\n", (unsigned long)(time(nullptr) - con_time));
printf("friend_request_test succeeded, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time)); printf("friend_request_test succeeded, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time));
tox_dispatch_free(dispatch);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2); tox_kill(tox2);
} }

View File

@ -43,7 +43,7 @@ typedef struct State {
#define PEER_LIMIT 20 #define PEER_LIMIT 20
static void print_ip(const Tox *tox, uint32_t groupnumber, uint32_t peer_id) static void print_ip(Tox *tox, uint32_t groupnumber, uint32_t peer_id)
{ {
Tox_Err_Group_Peer_Query err; Tox_Err_Group_Peer_Query err;
size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err); size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err);
@ -81,35 +81,32 @@ static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, ui
return true; return true;
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t groupnumber = tox_event_group_peer_join_get_group_number(event);
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
// we do a connection test here for fun // we do a connection test here for fun
Tox_Err_Group_Peer_Query pq_err; Tox_Err_Group_Peer_Query pq_err;
Tox_Connection connection_status = tox_group_peer_get_connection_status(autotox->tox, groupnumber, peer_id, &pq_err); TOX_CONNECTION connection_status = tox_group_peer_get_connection_status(tox, groupnumber, peer_id, &pq_err);
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(connection_status != TOX_CONNECTION_NONE); ck_assert(connection_status != TOX_CONNECTION_NONE);
Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, groupnumber, peer_id, &pq_err); Tox_Group_Role role = tox_group_peer_get_role(tox, groupnumber, peer_id, &pq_err);
ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err); ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err);
Tox_User_Status status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &pq_err); Tox_User_Status status = tox_group_peer_get_status(tox, groupnumber, peer_id, &pq_err);
ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err); ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err);
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &pq_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &pq_err);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &pq_err); tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &pq_err);
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
@ -140,37 +137,35 @@ static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void
} }
fprintf(stderr, "%s joined with IP: ", peer_name); fprintf(stderr, "%s joined with IP: ", peer_name);
print_ip(autotox->tox, groupnumber, peer_id); print_ip(tox, groupnumber, peer_id);
state->peer_id = peer_id; state->peer_id = peer_id;
++state->peer_joined_count; ++state->peer_joined_count;
} }
static void group_peer_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data) static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t groupnumber = tox_event_group_self_join_get_group_number(event);
// make sure we see our own correct peer state on join callback // make sure we see our own correct peer state on join callback
Tox_Err_Group_Self_Query sq_err; Tox_Err_Group_Self_Query sq_err;
size_t self_length = tox_group_self_get_name_size(autotox->tox, groupnumber, &sq_err); size_t self_length = tox_group_self_get_name_size(tox, groupnumber, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
uint8_t self_name[TOX_MAX_NAME_LENGTH]; uint8_t self_name[TOX_MAX_NAME_LENGTH];
tox_group_self_get_name(autotox->tox, groupnumber, self_name, &sq_err); tox_group_self_get_name(tox, groupnumber, self_name, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
Tox_User_Status self_status = tox_group_self_get_status(autotox->tox, groupnumber, &sq_err); TOX_USER_STATUS self_status = tox_group_self_get_status(tox, groupnumber, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
Tox_Group_Role self_role = tox_group_self_get_role(autotox->tox, groupnumber, &sq_err); Tox_Group_Role self_role = tox_group_self_get_role(tox, groupnumber, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
if (state->is_founder) { if (state->is_founder) {
@ -190,37 +185,36 @@ static void group_peer_self_join_handler(const Tox_Event_Group_Self_Join *event,
uint8_t group_name[GROUP_NAME_LEN]; uint8_t group_name[GROUP_NAME_LEN];
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
ck_assert(tox_group_get_peer_limit(autotox->tox, groupnumber, nullptr) == PEER_LIMIT); ck_assert(tox_group_get_peer_limit(tox, groupnumber, nullptr) == PEER_LIMIT);
ck_assert(tox_group_get_name_size(autotox->tox, groupnumber, nullptr) == GROUP_NAME_LEN); ck_assert(tox_group_get_name_size(tox, groupnumber, nullptr) == GROUP_NAME_LEN);
ck_assert(tox_group_get_topic_size(autotox->tox, groupnumber, nullptr) == TOPIC_LEN); ck_assert(tox_group_get_topic_size(tox, groupnumber, nullptr) == TOPIC_LEN);
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
tox_group_get_name(autotox->tox, groupnumber, group_name, &query_err); tox_group_get_name(tox, groupnumber, group_name, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
ck_assert(memcmp(group_name, GROUP_NAME, GROUP_NAME_LEN) == 0); ck_assert(memcmp(group_name, GROUP_NAME, GROUP_NAME_LEN) == 0);
tox_group_get_topic(autotox->tox, groupnumber, topic, &query_err); tox_group_get_topic(tox, groupnumber, topic, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0); ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0);
uint32_t peer_id = tox_group_self_get_peer_id(autotox->tox, groupnumber, nullptr); uint32_t peer_id = tox_group_self_get_peer_id(tox, groupnumber, nullptr);
fprintf(stderr, "self joined with IP: "); fprintf(stderr, "self joined with IP: ");
print_ip(autotox->tox, groupnumber, peer_id); print_ip(tox, groupnumber, peer_id);
++state->self_joined_count; ++state->self_joined_count;
} }
static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data) static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
const uint8_t *name, size_t name_length, const uint8_t *part_message,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint8_t *part_message = tox_event_group_peer_exit_get_part_message(event);
const size_t length = tox_event_group_peer_exit_get_part_message_length(event);
++state->peer_exit_count; ++state->peer_exit_count;
// first exit is a disconnect. second is a real exit with a part message // first exit is a disconnect. second is a real exit with a part message
@ -230,16 +224,14 @@ static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void
} }
} }
static void group_peer_name_handler(const Tox_Event_Group_Peer_Name *event, void *user_data) static void group_peer_name_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *name,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint8_t *name = tox_event_group_peer_name_get_name(event);
const size_t length = tox_event_group_peer_name_get_name_length(event);
// note: we already test the name_get api call elsewhere // note: we already test the name_get api call elsewhere
ck_assert(length == PEER0_NICK2_LEN); ck_assert(length == PEER0_NICK2_LEN);
@ -248,7 +240,7 @@ static void group_peer_name_handler(const Tox_Event_Group_Peer_Name *event, void
state->peer_nick = true; state->peer_nick = true;
} }
static void group_peer_status_handler(const Tox_Event_Group_Peer_Status *event, static void group_peer_status_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_USER_STATUS status,
void *user_data) void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
@ -256,12 +248,8 @@ static void group_peer_status_handler(const Tox_Event_Group_Peer_Status *event,
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t groupnumber = tox_event_group_peer_status_get_group_number(event);
const uint32_t peer_id = tox_event_group_peer_status_get_peer_id(event);
const Tox_User_Status status = tox_event_group_peer_status_get_status(event);
Tox_Err_Group_Peer_Query err; Tox_Err_Group_Peer_Query err;
Tox_User_Status cur_status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &err); TOX_USER_STATUS cur_status = tox_group_peer_get_status(tox, groupnumber, peer_id, &err);
ck_assert_msg(cur_status == status, "%d, %d", cur_status, status); ck_assert_msg(cur_status == status, "%d, %d", cur_status, status);
ck_assert(status == TOX_USER_STATUS_BUSY); ck_assert(status == TOX_USER_STATUS_BUSY);
@ -276,15 +264,15 @@ static void group_announce_test(AutoTox *autotoxes)
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
Tox *tox1 = autotoxes[1].tox; Tox *tox1 = autotoxes[1].tox;
State *state0 = (State *)autotoxes[0].state; State *state0 = (State *)autotoxes[0].state;
const State *state1 = (const State *)autotoxes[1].state; State *state1 = (State *)autotoxes[1].state;
tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler); tox_callback_group_peer_join(tox0, group_peer_join_handler);
tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler); tox_callback_group_peer_join(tox1, group_peer_join_handler);
tox_events_callback_group_self_join(autotoxes[0].dispatch, group_peer_self_join_handler); tox_callback_group_self_join(tox0, group_peer_self_join_handler);
tox_events_callback_group_self_join(autotoxes[1].dispatch, group_peer_self_join_handler); tox_callback_group_self_join(tox1, group_peer_self_join_handler);
tox_events_callback_group_peer_name(autotoxes[1].dispatch, group_peer_name_handler); tox_callback_group_peer_name(tox1, group_peer_name_handler);
tox_events_callback_group_peer_status(autotoxes[1].dispatch, group_peer_status_handler); tox_callback_group_peer_status(tox1, group_peer_status_handler);
tox_events_callback_group_peer_exit(autotoxes[1].dispatch, group_peer_exit_handler); tox_callback_group_peer_exit(tox1, group_peer_exit_handler);
// tox0 makes new group. // tox0 makes new group.
Tox_Err_Group_New err_new; Tox_Err_Group_New err_new;
@ -298,19 +286,19 @@ static void group_announce_test(AutoTox *autotoxes)
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
// changes the state (for sync check purposes) // changes the state (for sync check purposes)
Tox_Err_Group_Set_Peer_Limit limit_set_err; Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
tox_group_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err); tox_group_founder_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err);
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
Tox_Err_Group_Topic_Set tp_err; Tox_Err_Group_Topic_Set tp_err;
tox_group_set_topic(tox0, groupnumber, (const uint8_t *)TOPIC, TOPIC_LEN, &tp_err); tox_group_set_topic(tox0, groupnumber, (const uint8_t *)TOPIC, TOPIC_LEN, &tp_err);
ck_assert(tp_err == TOX_ERR_GROUP_TOPIC_SET_OK); ck_assert(tp_err == TOX_ERR_GROUP_TOPIC_SET_OK);
// get the chat id of the new group. // get the chat id of the new group.
Tox_Err_Group_State_Query err_id; Tox_Err_Group_State_Queries err_id;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, groupnumber, chat_id, &err_id); tox_group_get_chat_id(tox0, groupnumber, chat_id, &err_id);
ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERIES_OK);
// tox1 joins it. // tox1 joins it.
Tox_Err_Group_Join err_join; Tox_Err_Group_Join err_join;
@ -355,7 +343,7 @@ static void group_announce_test(AutoTox *autotoxes)
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
Tox_User_Status self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err); TOX_USER_STATUS self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_status == TOX_USER_STATUS_BUSY); ck_assert(self_status == TOX_USER_STATUS_BUSY);
@ -441,12 +429,10 @@ static void group_announce_test(AutoTox *autotoxes)
tox_group_leave(tox1, groupnumber, nullptr, 0, &err_exit); tox_group_leave(tox1, groupnumber, nullptr, 0, &err_exit);
ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK); ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK);
while (num_groups1 != 0 || num_groups2 != 0) { num_groups1 = tox_group_get_number_groups(tox0);
num_groups1 = tox_group_get_number_groups(tox0); num_groups2 = tox_group_get_number_groups(tox1);
num_groups2 = tox_group_get_number_groups(tox1);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); ck_assert(num_groups1 == num_groups2 && num_groups2 == 0);
}
printf("All tests passed!\n"); printf("All tests passed!\n");
} }

View File

@ -51,15 +51,13 @@ static bool group_has_full_graph(const AutoTox *autotoxes, uint32_t group_number
return true; return true;
} }
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
switch (fail_type) { switch (fail_type) {
case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: { case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: {
state->peer_limit_fail = true; state->peer_limit_fail = true;
@ -81,7 +79,7 @@ static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void
} }
} }
static void group_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data) static void group_self_join_handler(Tox *tox, uint32_t group_number, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -91,7 +89,7 @@ static void group_self_join_handler(const Tox_Event_Group_Self_Join *event, void
state->connected = true; state->connected = true;
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -107,9 +105,9 @@ static void group_invite_test(AutoTox *autotoxes)
ck_assert_msg(NUM_GROUP_TOXES > 7, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); ck_assert_msg(NUM_GROUP_TOXES > 7, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler); tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler);
tox_events_callback_group_self_join(autotoxes[i].dispatch, group_self_join_handler); tox_callback_group_self_join(autotoxes[i].tox, group_self_join_handler);
} }
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
@ -120,12 +118,12 @@ static void group_invite_test(AutoTox *autotoxes)
Tox *tox5 = autotoxes[5].tox; Tox *tox5 = autotoxes[5].tox;
Tox *tox6 = autotoxes[6].tox; Tox *tox6 = autotoxes[6].tox;
const State *state0 = (const State *)autotoxes[0].state; State *state0 = (State *)autotoxes[0].state;
const State *state2 = (const State *)autotoxes[2].state; State *state2 = (State *)autotoxes[2].state;
const State *state3 = (const State *)autotoxes[3].state; State *state3 = (State *)autotoxes[3].state;
const State *state4 = (const State *)autotoxes[4].state; State *state4 = (State *)autotoxes[4].state;
const State *state5 = (const State *)autotoxes[5].state; State *state5 = (State *)autotoxes[5].state;
const State *state6 = (const State *)autotoxes[6].state; State *state6 = (State *)autotoxes[6].state;
Tox_Err_Group_New new_err; Tox_Err_Group_New new_err;
uint32_t groupnumber = tox_group_new(tox0, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4, uint32_t groupnumber = tox_group_new(tox0, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4,
@ -134,11 +132,11 @@ static void group_invite_test(AutoTox *autotoxes)
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
// peer 1 joins public group with no password // peer 1 joins public group with no password
Tox_Err_Group_Join join_err; Tox_Err_Group_Join join_err;
@ -152,9 +150,9 @@ static void group_invite_test(AutoTox *autotoxes)
printf("Peer 1 joined group\n"); printf("Peer 1 joined group\n");
// founder sets a password // founder sets a password
Tox_Err_Group_Set_Password pass_set_err; Tox_Err_Group_Founder_Set_Password pass_set_err;
tox_group_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); tox_group_founder_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err); ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
@ -179,9 +177,9 @@ static void group_invite_test(AutoTox *autotoxes)
printf("Peer 3 successfully blocked with invalid password\n"); printf("Peer 3 successfully blocked with invalid password\n");
// founder sets peer limit to 1 // founder sets peer limit to 1
Tox_Err_Group_Set_Peer_Limit limit_set_err; Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
tox_group_set_peer_limit(tox0, groupnumber, 1, &limit_set_err); tox_group_founder_set_peer_limit(tox0, groupnumber, 1, &limit_set_err);
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err); ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
@ -196,11 +194,11 @@ static void group_invite_test(AutoTox *autotoxes)
printf("Peer 4 successfully blocked from joining full group\n"); printf("Peer 4 successfully blocked from joining full group\n");
// founder removes password and increases peer limit to 100 // founder removes password and increases peer limit to 100
tox_group_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err); tox_group_founder_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err);
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err); ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err);
tox_group_set_peer_limit(tox0, groupnumber, 100, &limit_set_err); tox_group_founder_set_peer_limit(tox0, groupnumber, 100, &limit_set_err);
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err); ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
@ -215,9 +213,9 @@ static void group_invite_test(AutoTox *autotoxes)
printf("Peer 5 successfully joined the group\n"); printf("Peer 5 successfully joined the group\n");
// founder makes group private // founder makes group private
Tox_Err_Group_Set_Privacy_State priv_err; Tox_Err_Group_Founder_Set_Privacy_State priv_err;
tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err); tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err);
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err); ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
@ -233,8 +231,8 @@ static void group_invite_test(AutoTox *autotoxes)
printf("Peer 6 failed to join private group via chat ID\n"); printf("Peer 6 failed to join private group via chat ID\n");
// founder makes group public again // founder makes group public again
tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err); tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err);
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err); ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);

View File

@ -19,7 +19,7 @@ typedef struct State {
bool peer_joined; bool peer_joined;
bool message_sent; bool message_sent;
bool message_received; bool message_received;
Tox_Group_Message_Id pseudo_msg_id; uint32_t pseudo_msg_id;
bool private_message_received; bool private_message_received;
size_t custom_packets_received; size_t custom_packets_received;
size_t custom_private_packets_received; size_t custom_private_packets_received;
@ -71,37 +71,28 @@ static uint16_t get_message_checksum(const uint8_t *message, uint16_t length)
return sum; return sum;
} }
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length,
const uint8_t *group_name, size_t group_name_length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
const size_t length = tox_event_group_invite_get_invite_data_length(event);
printf("invite arrived; accepting\n"); printf("invite arrived; accepting\n");
Tox_Err_Group_Invite_Accept err_accept; Tox_Err_Group_Invite_Accept err_accept;
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN, tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN,
nullptr, 0, &err_accept); nullptr, 0, &err_accept);
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
} }
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) static void group_join_fail_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Join_Fail fail_type, void *user_data)
{ {
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
printf("join failed: %d\n", fail_type); printf("join failed: %d\n", fail_type);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
ck_assert_msg(state->peer_joined == false, "Peer timedout"); ck_assert_msg(state->peer_joined == false, "Peer timedout");
printf("peer %u joined, sending message\n", peer_id); printf("peer %u joined, sending message\n", peer_id);
@ -109,16 +100,9 @@ static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void
state->peer_id = peer_id; state->peer_id = peer_id;
} }
static void group_custom_private_packet_handler(const Tox_Event_Group_Custom_Private_Packet *event, void *user_data) static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t groupnumber = tox_event_group_custom_private_packet_get_group_number(event);
const uint32_t peer_id = tox_event_group_custom_private_packet_get_peer_id(event);
const uint8_t *data = tox_event_group_custom_private_packet_get_data(event);
const size_t length = tox_event_group_custom_private_packet_get_data_length(event);
ck_assert_msg(length == TEST_CUSTOM_PRIVATE_PACKET_LEN, ck_assert_msg(length == TEST_CUSTOM_PRIVATE_PACKET_LEN,
"Failed to receive custom private packet. Invalid length: %zu\n", length); "Failed to receive custom private packet. Invalid length: %zu\n", length);
@ -127,25 +111,25 @@ static void group_custom_private_packet_handler(const Tox_Event_Group_Custom_Pri
message_buf[length] = 0; message_buf[length] = 0;
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err); tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
Tox_Err_Group_Self_Query s_err; Tox_Err_Group_Self_Query s_err;
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
char self_name[TOX_MAX_NAME_LENGTH + 1]; char self_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
self_name[self_name_len] = 0; self_name[self_name_len] = 0;
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
@ -154,21 +138,17 @@ static void group_custom_private_packet_handler(const Tox_Event_Group_Custom_Pri
printf("%s sent custom private packet to %s: %s\n", peer_name, self_name, message_buf); printf("%s sent custom private packet to %s: %s\n", peer_name, self_name, message_buf);
ck_assert(memcmp(message_buf, TEST_CUSTOM_PRIVATE_PACKET, length) == 0); ck_assert(memcmp(message_buf, TEST_CUSTOM_PRIVATE_PACKET, length) == 0);
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
++state->custom_private_packets_received; ++state->custom_private_packets_received;
} }
static void group_custom_packet_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data) static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t groupnumber = tox_event_group_custom_packet_get_group_number(event);
const uint32_t peer_id = tox_event_group_custom_packet_get_peer_id(event);
const uint8_t *data = tox_event_group_custom_packet_get_data(event);
const size_t length = tox_event_group_custom_packet_get_data_length(event);
ck_assert_msg(length == TEST_CUSTOM_PACKET_LEN, "Failed to receive custom packet. Invalid length: %zu\n", length); ck_assert_msg(length == TEST_CUSTOM_PACKET_LEN, "Failed to receive custom packet. Invalid length: %zu\n", length);
char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1]; char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
@ -176,25 +156,25 @@ static void group_custom_packet_handler(const Tox_Event_Group_Custom_Packet *eve
message_buf[length] = 0; message_buf[length] = 0;
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
Tox_Err_Group_Self_Query s_err; Tox_Err_Group_Self_Query s_err;
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
char self_name[TOX_MAX_NAME_LENGTH + 1]; char self_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
self_name[self_name_len] = 0; self_name[self_name_len] = 0;
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
@ -203,39 +183,32 @@ static void group_custom_packet_handler(const Tox_Event_Group_Custom_Packet *eve
printf("%s sent custom packet to %s: %s\n", peer_name, self_name, message_buf); printf("%s sent custom packet to %s: %s\n", peer_name, self_name, message_buf);
ck_assert(memcmp(message_buf, TEST_CUSTOM_PACKET, length) == 0); ck_assert(memcmp(message_buf, TEST_CUSTOM_PACKET, length) == 0);
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
++state->custom_packets_received; ++state->custom_packets_received;
} }
static void group_custom_packet_large_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data) static void group_custom_packet_large_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint8_t *data = tox_event_group_custom_packet_get_data(event);
const size_t length = tox_event_group_custom_packet_get_data_length(event);
ck_assert_msg(length == TEST_CUSTOM_PACKET_LARGE_LEN, "Failed to receive large custom packet. Invalid length: %zu\n", length); ck_assert_msg(length == TEST_CUSTOM_PACKET_LARGE_LEN, "Failed to receive large custom packet. Invalid length: %zu\n", length);
ck_assert(memcmp(data, TEST_CUSTOM_PACKET_LARGE, length) == 0); ck_assert(memcmp(data, TEST_CUSTOM_PACKET_LARGE, length) == 0);
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
++state->custom_packets_received; ++state->custom_packets_received;
} }
static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data) static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t groupnumber = tox_event_group_message_get_group_number(event);
const uint32_t peer_id = tox_event_group_message_get_peer_id(event);
const uint8_t *message = tox_event_group_message_get_message(event);
const size_t length = tox_event_group_message_get_message_length(event);
const uint32_t pseudo_msg_id = tox_event_group_message_get_message_id(event);
ck_assert(!(length == IGNORE_MESSAGE_LEN && memcmp(message, IGNORE_MESSAGE, length) == 0)); ck_assert(!(length == IGNORE_MESSAGE_LEN && memcmp(message, IGNORE_MESSAGE, length) == 0));
ck_assert_msg(length == TEST_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length); ck_assert_msg(length == TEST_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
@ -244,25 +217,25 @@ static void group_message_handler(const Tox_Event_Group_Message *event, void *us
message_buf[length] = 0; message_buf[length] = 0;
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
Tox_Err_Group_Self_Query s_err; Tox_Err_Group_Self_Query s_err;
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
char self_name[TOX_MAX_NAME_LENGTH + 1]; char self_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
self_name[self_name_len] = 0; self_name[self_name_len] = 0;
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
@ -271,24 +244,19 @@ static void group_message_handler(const Tox_Event_Group_Message *event, void *us
printf("%s sent message to %s:(id:%u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf); printf("%s sent message to %s:(id:%u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf);
ck_assert(memcmp(message_buf, TEST_MESSAGE, length) == 0); ck_assert(memcmp(message_buf, TEST_MESSAGE, length) == 0);
State *state = (State *)autotox->state;
state->message_received = true;
state->pseudo_msg_id = pseudo_msg_id;
}
static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data)
{
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
const uint32_t groupnumber = tox_event_group_private_message_get_group_number(event); State *state = (State *)autotox->state;
const uint32_t peer_id = tox_event_group_private_message_get_peer_id(event);
const Tox_Message_Type type = tox_event_group_private_message_get_message_type(event);
const uint8_t *message = tox_event_group_private_message_get_message(event);
const size_t length = tox_event_group_private_message_get_message_length(event);
const Tox_Group_Message_Id pseudo_msg_id = tox_event_group_private_message_get_message_id(event);
state->message_received = true;
state->pseudo_msg_id = pseudo_msg_id;
}
static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, void *user_data)
{
ck_assert_msg(length == TEST_PRIVATE_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length); ck_assert_msg(length == TEST_PRIVATE_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1]; char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1];
@ -296,46 +264,46 @@ static void group_private_message_handler(const Tox_Event_Group_Private_Message
message_buf[length] = 0; message_buf[length] = 0;
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err); tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0); ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
Tox_Err_Group_Self_Query s_err; Tox_Err_Group_Self_Query s_err;
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err); size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
char self_name[TOX_MAX_NAME_LENGTH + 1]; char self_name[TOX_MAX_NAME_LENGTH + 1];
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err); tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
self_name[self_name_len] = 0; self_name[self_name_len] = 0;
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0); ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
printf("%s sent private action to %s:(id: %u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf); printf("%s sent private action to %s: %s\n", peer_name, self_name, message_buf);
ck_assert(memcmp(message_buf, TEST_PRIVATE_MESSAGE, length) == 0); ck_assert(memcmp(message_buf, TEST_PRIVATE_MESSAGE, length) == 0);
ck_assert(type == TOX_MESSAGE_TYPE_ACTION); ck_assert(type == TOX_MESSAGE_TYPE_ACTION);
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
state->private_message_received = true; state->private_message_received = true;
state->pseudo_msg_id = pseudo_msg_id;
} }
static void group_message_handler_lossless_test(const Tox_Event_Group_Message *event, void *user_data) static void group_message_handler_lossless_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
{ {
const uint8_t *message = tox_event_group_message_get_message(event);
const size_t length = tox_event_group_message_get_message_length(event);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -357,11 +325,10 @@ static void group_message_handler_lossless_test(const Tox_Event_Group_Message *e
state->lossless_check = true; state->lossless_check = true;
} }
} }
static void group_message_handler_wraparound_test(const Tox_Event_Group_Message *event, void *user_data) static void group_message_handler_wraparound_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id,
TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
{ {
const uint8_t *message = tox_event_group_message_get_message(event);
const size_t length = tox_event_group_message_get_message_length(event);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -385,11 +352,11 @@ static void group_message_test(AutoTox *autotoxes)
{ {
ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
const Tox *tox1 = autotoxes[1].tox; Tox *tox1 = autotoxes[1].tox;
State *state0 = (State *)autotoxes[0].state; State *state0 = (State *)autotoxes[0].state;
State *state1 = (State *)autotoxes[1].state; State *state1 = (State *)autotoxes[1].state;
@ -398,15 +365,15 @@ static void group_message_test(AutoTox *autotoxes)
state0->pseudo_msg_id = 0; state0->pseudo_msg_id = 0;
state1->pseudo_msg_id = 1; state1->pseudo_msg_id = 1;
tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler); tox_callback_group_invite(tox1, group_invite_handler);
tox_events_callback_group_join_fail(autotoxes[1].dispatch, group_join_fail_handler); tox_callback_group_join_fail(tox1, group_join_fail_handler);
tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler); tox_callback_group_peer_join(tox1, group_peer_join_handler);
tox_events_callback_group_join_fail(autotoxes[0].dispatch, group_join_fail_handler); tox_callback_group_join_fail(tox0, group_join_fail_handler);
tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler); tox_callback_group_peer_join(tox0, group_peer_join_handler);
tox_events_callback_group_message(autotoxes[0].dispatch, group_message_handler); tox_callback_group_message(tox0, group_message_handler);
tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_handler); tox_callback_group_custom_packet(tox0, group_custom_packet_handler);
tox_events_callback_group_custom_private_packet(autotoxes[0].dispatch, group_custom_private_packet_handler); tox_callback_group_custom_private_packet(tox0, group_custom_private_packet_handler);
tox_events_callback_group_private_message(autotoxes[0].dispatch, group_private_message_handler); tox_callback_group_private_message(tox0, group_private_message_handler);
Tox_Err_Group_Send_Message err_send; Tox_Err_Group_Send_Message err_send;
@ -429,15 +396,14 @@ static void group_message_test(AutoTox *autotoxes)
if (state1->peer_joined && !state1->message_sent) { if (state1->peer_joined && !state1->message_sent) {
state1->pseudo_msg_id = tox_group_send_message( state1->pseudo_msg_id = tox_group_send_message(
tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE, tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE,
TEST_MESSAGE_LEN, &err_send); TEST_MESSAGE_LEN, &err_send);
ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK); ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK);
state1->message_sent = true; state1->message_sent = true;
} }
} }
ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", state0->pseudo_msg_id, state1->pseudo_msg_id);
state0->pseudo_msg_id, state1->pseudo_msg_id);
// Make sure we're still connected to each friend // Make sure we're still connected to each friend
Tox_Connection conn_1 = tox_friend_get_connection_status(tox0, 0, nullptr); Tox_Connection conn_1 = tox_friend_get_connection_status(tox0, 0, nullptr);
@ -462,23 +428,14 @@ static void group_message_test(AutoTox *autotoxes)
tox_group_set_ignore(tox0, group_number, state0->peer_id, false, &ig_err); tox_group_set_ignore(tox0, group_number, state0->peer_id, false, &ig_err);
ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err); ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err);
fprintf(stderr, "Sending private action...\n"); fprintf(stderr, "Sending private message...\n");
// tox1 sends a private action to tox0 // tox0 sends a private action to tox1
Tox_Err_Group_Send_Private_Message m_err; Tox_Err_Group_Send_Private_Message m_err;
state1->pseudo_msg_id = tox_group_send_private_message(tox1, group_number, state1->peer_id, tox_group_send_private_message(tox1, group_number, state1->peer_id, TOX_MESSAGE_TYPE_ACTION,
TOX_MESSAGE_TYPE_ACTION, (const uint8_t *)TEST_PRIVATE_MESSAGE, (const uint8_t *)TEST_PRIVATE_MESSAGE, TEST_PRIVATE_MESSAGE_LEN, &m_err);
TEST_PRIVATE_MESSAGE_LEN, &m_err);
ck_assert_msg(m_err == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", m_err); ck_assert_msg(m_err == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", m_err);
while (!state0->private_message_received) {
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
}
ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u",
state0->pseudo_msg_id, state1->pseudo_msg_id);
fprintf(stderr, "Sending custom packets...\n"); fprintf(stderr, "Sending custom packets...\n");
// tox0 sends a lossless and lossy custom packet to tox1 // tox0 sends a lossless and lossy custom packet to tox1
@ -507,14 +464,15 @@ static void group_message_test(AutoTox *autotoxes)
ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr); ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr);
while (state0->custom_packets_received < 2 || state0->custom_private_packets_received < 2) { while (!state0->private_message_received || state0->custom_packets_received < 2
|| state0->custom_private_packets_received < 2) {
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
} }
// tox0 sends a large max sized lossy custom packet // tox0 sends a large max sized lossy custom packet
// overwrite callback for larger packet // overwrite callback for larger packet
tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_large_handler); tox_callback_group_custom_packet(tox0, group_custom_packet_large_handler);
tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET_LARGE, TEST_CUSTOM_PACKET_LARGE_LEN, tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET_LARGE, TEST_CUSTOM_PACKET_LARGE_LEN,
&c_err); &c_err);
@ -528,7 +486,7 @@ static void group_message_test(AutoTox *autotoxes)
fprintf(stderr, "Doing lossless packet test...\n"); fprintf(stderr, "Doing lossless packet test...\n");
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_lossless_test); tox_callback_group_message(tox1, group_message_handler_lossless_test);
state1->last_msg_recv = -1; state1->last_msg_recv = -1;
// lossless and packet splitting/reassembly test // lossless and packet splitting/reassembly test
@ -559,7 +517,7 @@ static void group_message_test(AutoTox *autotoxes)
} }
state1->last_msg_recv = -1; state1->last_msg_recv = -1;
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_wraparound_test); tox_callback_group_message(tox1, group_message_handler_wraparound_test);
fprintf(stderr, "Doing wraparound test...\n"); fprintf(stderr, "Doing wraparound test...\n");

View File

@ -19,13 +19,13 @@
#define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1) #define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1)
typedef struct Peer { typedef struct Peer {
char name[TOX_MAX_NAME_LENGTH + 1]; char name[TOX_MAX_NAME_LENGTH];
size_t name_length; size_t name_length;
uint32_t peer_id; uint32_t peer_id;
} Peer; } Peer;
typedef struct State { typedef struct State {
char self_name[TOX_MAX_NAME_LENGTH + 1]; char self_name[TOX_MAX_NAME_LENGTH];
size_t self_name_length; size_t self_name_length;
uint32_t group_number; uint32_t group_number;
@ -38,6 +38,7 @@ typedef struct State {
char mod_name1[TOX_MAX_NAME_LENGTH]; char mod_name1[TOX_MAX_NAME_LENGTH];
char mod_name2[TOX_MAX_NAME_LENGTH]; char mod_name2[TOX_MAX_NAME_LENGTH];
bool observer_check; bool observer_check;
size_t observer_event_count; size_t observer_event_count;
char observer_name1[TOX_MAX_NAME_LENGTH]; char observer_name1[TOX_MAX_NAME_LENGTH];
@ -52,7 +53,7 @@ typedef struct State {
static bool all_peers_connected(AutoTox *autotoxes) static bool all_peers_connected(AutoTox *autotoxes)
{ {
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
const State *state = (const State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
if (state->num_peers != NUM_GROUP_TOXES - 1) { if (state->num_peers != NUM_GROUP_TOXES - 1) {
return false; return false;
@ -145,7 +146,7 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers
ck_assert(name != nullptr && name_length <= TOX_MAX_NAME_LENGTH); ck_assert(name != nullptr && name_length <= TOX_MAX_NAME_LENGTH);
for (size_t i = 0; i < num_peers; ++i) { for (size_t i = 0; i < num_peers; ++i) {
const State *state = (const State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
if (memcmp(state->self_name, name, name_length) == 0) { if (memcmp(state->self_name, name, name_length) == 0) {
return i; return i;
@ -155,33 +156,29 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers
ck_assert_msg(0, "Failed to find index"); ck_assert_msg(0, "Failed to find index");
} }
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data) static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data)
{ {
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
fprintf(stderr, "Failed to join group: %d", fail_type); fprintf(stderr, "Failed to join group: %d", fail_type);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t group_number = tox_event_group_peer_join_get_group_number(event);
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
ck_assert(state->group_number == group_number); ck_assert(state->group_number == group_number);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
tox_group_peer_get_name(autotox->tox, group_number, peer_id, (uint8_t *) peer_name, &q_err); tox_group_peer_get_name(tox, group_number, peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
@ -196,7 +193,7 @@ static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void
ck_assert(state->num_peers < NUM_GROUP_TOXES); ck_assert(state->num_peers < NUM_GROUP_TOXES);
} }
static void handle_mod(State *state, const char *peer_name, size_t peer_name_len) static void handle_mod(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
{ {
if (state->mod_event_count == 0) { if (state->mod_event_count == 0) {
ck_assert(memcmp(peer_name, state->mod_name1, peer_name_len) == 0); ck_assert(memcmp(peer_name, state->mod_name1, peer_name_len) == 0);
@ -208,9 +205,10 @@ static void handle_mod(State *state, const char *peer_name, size_t peer_name_len
++state->mod_event_count; ++state->mod_event_count;
state->mod_check = true; state->mod_check = true;
ck_assert(role == TOX_GROUP_ROLE_MODERATOR);
} }
static void handle_observer(State *state, const char *peer_name, size_t peer_name_len) static void handle_observer(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
{ {
if (state->observer_event_count == 0) { if (state->observer_event_count == 0) {
ck_assert(memcmp(peer_name, state->observer_name1, peer_name_len) == 0); ck_assert(memcmp(peer_name, state->observer_name1, peer_name_len) == 0);
@ -222,9 +220,10 @@ static void handle_observer(State *state, const char *peer_name, size_t peer_nam
++state->observer_event_count; ++state->observer_event_count;
state->observer_check = true; state->observer_check = true;
ck_assert(role == TOX_GROUP_ROLE_OBSERVER);
} }
static void handle_user(State *state, const char *peer_name, size_t peer_name_len) static void handle_user(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
{ {
// event 1: observer1 gets promoted back to user // event 1: observer1 gets promoted back to user
// event 2: observer2 gets promoted to moderator // event 2: observer2 gets promoted to moderator
@ -244,25 +243,23 @@ static void handle_user(State *state, const char *peer_name, size_t peer_name_le
++state->user_event_count; ++state->user_event_count;
state->user_check = true; state->user_check = true;
ck_assert(role == TOX_GROUP_ROLE_USER);
} }
static void group_mod_event_handler(const Tox_Event_Group_Moderation *event, void *user_data) static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id,
Tox_Group_Mod_Event mod_type, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t group_number = tox_event_group_moderation_get_group_number(event);
const uint32_t target_peer_id = tox_event_group_moderation_get_target_peer_id(event);
const Tox_Group_Mod_Event mod_type = tox_event_group_moderation_get_mod_type(event);
ck_assert(state->group_number == group_number); ck_assert(state->group_number == group_number);
char peer_name[TOX_MAX_NAME_LENGTH + 1]; char peer_name[TOX_MAX_NAME_LENGTH + 1];
Tox_Err_Group_Peer_Query q_err; Tox_Err_Group_Peer_Query q_err;
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, target_peer_id, &q_err); size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, target_peer_id, &q_err);
if (q_err == TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND) { // may occurr on sync attempts if (q_err == TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND) { // may occurr on sync attempts
return; return;
@ -271,13 +268,12 @@ static void group_mod_event_handler(const Tox_Event_Group_Moderation *event, voi
ck_assert_msg(q_err == TOX_ERR_GROUP_PEER_QUERY_OK, "error %d", q_err); ck_assert_msg(q_err == TOX_ERR_GROUP_PEER_QUERY_OK, "error %d", q_err);
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH); ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
tox_group_peer_get_name(autotox->tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err); tox_group_peer_get_name(tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err);
peer_name[peer_name_len] = 0; peer_name[peer_name_len] = 0;
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, group_number, target_peer_id, &q_err); Tox_Group_Role role = tox_group_peer_get_role(tox, group_number, target_peer_id, &q_err);
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK); ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
ck_assert(role <= TOX_GROUP_ROLE_OBSERVER);
fprintf(stderr, "tox%u: got moderator event %d (%s), role = %s\n", fprintf(stderr, "tox%u: got moderator event %d (%s), role = %s\n",
autotox->index, mod_type, tox_group_mod_event_to_string(mod_type), autotox->index, mod_type, tox_group_mod_event_to_string(mod_type),
@ -285,17 +281,17 @@ static void group_mod_event_handler(const Tox_Event_Group_Moderation *event, voi
switch (mod_type) { switch (mod_type) {
case TOX_GROUP_MOD_EVENT_MODERATOR: { case TOX_GROUP_MOD_EVENT_MODERATOR: {
handle_mod(state, peer_name, peer_name_len); handle_mod(state, peer_name, peer_name_len, role);
break; break;
} }
case TOX_GROUP_MOD_EVENT_OBSERVER: { case TOX_GROUP_MOD_EVENT_OBSERVER: {
handle_observer(state, peer_name, peer_name_len); handle_observer(state, peer_name, peer_name_len, role);
break; break;
} }
case TOX_GROUP_MOD_EVENT_USER: { case TOX_GROUP_MOD_EVENT_USER: {
handle_user(state, peer_name, peer_name_len); handle_user(state, peer_name, peer_name_len, role);
break; break;
} }
@ -318,7 +314,7 @@ static void check_self_role(AutoTox *autotoxes, uint32_t peer_id, Tox_Group_Role
Tox_Err_Group_Self_Query sq_err; Tox_Err_Group_Self_Query sq_err;
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
const State *state = (const State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
uint32_t self_peer_id = tox_group_self_get_peer_id(autotoxes[i].tox, state->group_number, &sq_err); uint32_t self_peer_id = tox_group_self_get_peer_id(autotoxes[i].tox, state->group_number, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
@ -382,13 +378,13 @@ static void voice_state_message_test(AutoTox *autotox, Tox_Group_Voice_State voi
static bool all_peers_got_voice_state_change(AutoTox *autotoxes, uint32_t num_toxes, static bool all_peers_got_voice_state_change(AutoTox *autotoxes, uint32_t num_toxes,
Tox_Group_Voice_State expected_voice_state) Tox_Group_Voice_State expected_voice_state)
{ {
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t i = 0; i < num_toxes; ++i) {
const State *state = (State *)autotoxes[i].state; const State *state = (State *)autotoxes[i].state;
Tox_Group_Voice_State voice_state = tox_group_get_voice_state(autotoxes[i].tox, state->group_number, &query_err); Tox_Group_Voice_State voice_state = tox_group_get_voice_state(autotoxes[i].tox, state->group_number, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (voice_state != expected_voice_state) { if (voice_state != expected_voice_state) {
return false; return false;
@ -402,10 +398,10 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
{ {
// founder sets voice state to Moderator // founder sets voice state to Moderator
const State *state = (State *)autotoxes[0].state; const State *state = (State *)autotoxes[0].state;
Tox_Err_Group_Set_Voice_State voice_set_err; Tox_Err_Group_Founder_Set_Voice_State voice_set_err;
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR, tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR,
&voice_set_err); &voice_set_err);
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t i = 0; i < num_toxes; ++i) {
do { do {
@ -415,8 +411,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_MODERATOR); voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_MODERATOR);
} }
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err); tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err);
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t i = 0; i < num_toxes; ++i) {
do { do {
@ -426,8 +422,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_FOUNDER); voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_FOUNDER);
} }
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err); tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err);
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK); ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
for (uint32_t i = 0; i < num_toxes; ++i) { for (uint32_t i = 0; i < num_toxes; ++i) {
do { do {
@ -451,9 +447,9 @@ static void group_moderation_test(AutoTox *autotoxes)
snprintf(state->self_name, sizeof(state->self_name), "peer_%zu", i); snprintf(state->self_name, sizeof(state->self_name), "peer_%zu", i);
state->self_name[name_length] = 0; state->self_name[name_length] = 0;
tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler); tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler);
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
tox_events_callback_group_moderation(autotoxes[i].dispatch, group_mod_event_handler); tox_callback_group_moderation(autotoxes[i].tox, group_mod_event_handler);
} }
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
@ -472,11 +468,11 @@ static void group_moderation_test(AutoTox *autotoxes)
ck_assert_msg(err_new == TOX_ERR_GROUP_NEW_OK, "Failed to create group. error: %d\n", err_new); ck_assert_msg(err_new == TOX_ERR_GROUP_NEW_OK, "Failed to create group. error: %d\n", err_new);
/* Founder gets chat ID */ /* Founder gets chat ID */
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, state0->group_number, chat_id, &id_err); tox_group_get_chat_id(tox0, state0->group_number, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get chat ID. error: %d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get chat ID. error: %d", id_err);
fprintf(stderr, "Peers attemping to join DHT group via the chat ID\n"); fprintf(stderr, "Peers attemping to join DHT group via the chat ID\n");
@ -516,7 +512,7 @@ static void group_moderation_test(AutoTox *autotoxes)
/* all peers should be user role except founder */ /* all peers should be user role except founder */
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
const State *state = (const State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
self_role = tox_group_self_get_role(autotoxes[i].tox, state->group_number, &sq_err); self_role = tox_group_self_get_role(autotoxes[i].tox, state->group_number, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
ck_assert(self_role == TOX_GROUP_ROLE_USER); ck_assert(self_role == TOX_GROUP_ROLE_USER);
@ -525,9 +521,9 @@ static void group_moderation_test(AutoTox *autotoxes)
/* founder sets first peer to moderator */ /* founder sets first peer to moderator */
fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[0].name); fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[0].name);
Tox_Err_Group_Set_Role role_err; Tox_Err_Group_Mod_Set_Role role_err;
tox_group_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); tox_group_mod_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
// manually flag the role setter because they don't get a callback // manually flag the role setter because they don't get a callback
state0->mod_check = true; state0->mod_check = true;
@ -541,8 +537,8 @@ static void group_moderation_test(AutoTox *autotoxes)
/* founder sets second and third peer to observer */ /* founder sets second and third peer to observer */
fprintf(stderr, "Founder setting %s to observer\n", state0->peers[1].name); fprintf(stderr, "Founder setting %s to observer\n", state0->peers[1].name);
tox_group_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); tox_group_mod_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
state0->observer_check = true; state0->observer_check = true;
++state0->observer_event_count; ++state0->observer_event_count;
@ -552,8 +548,8 @@ static void group_moderation_test(AutoTox *autotoxes)
fprintf(stderr, "Founder setting %s to observer\n", state0->peers[2].name); fprintf(stderr, "Founder setting %s to observer\n", state0->peers[2].name);
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
state0->observer_check = true; state0->observer_check = true;
++state0->observer_event_count; ++state0->observer_event_count;
@ -578,8 +574,8 @@ static void group_moderation_test(AutoTox *autotoxes)
fprintf(stderr, "%s is promoting %s back to user\n", state1->self_name, state0->peers[1].name); fprintf(stderr, "%s is promoting %s back to user\n", state1->self_name, state0->peers[1].name);
tox_group_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err); tox_group_mod_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to promote observer back to user. error: %d", ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to promote observer back to user. error: %d",
role_err); role_err);
state1->user_check = true; state1->user_check = true;
@ -591,8 +587,8 @@ static void group_moderation_test(AutoTox *autotoxes)
/* founder assigns third peer to moderator (this triggers two events: user and moderator) */ /* founder assigns third peer to moderator (this triggers two events: user and moderator) */
fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[2].name); fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[2].name);
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err); tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
state0->mod_check = true; state0->mod_check = true;
++state0->mod_event_count; ++state0->mod_event_count;
@ -604,27 +600,18 @@ static void group_moderation_test(AutoTox *autotoxes)
/* moderator attempts to demote and kick founder */ /* moderator attempts to demote and kick founder */
uint32_t founder_peer_id = get_peer_id_by_nick(state1->peers, NUM_GROUP_TOXES - 1, state0->self_name); uint32_t founder_peer_id = get_peer_id_by_nick(state1->peers, NUM_GROUP_TOXES - 1, state0->self_name);
tox_group_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err); tox_group_mod_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
ck_assert_msg(role_err != TOX_ERR_GROUP_SET_ROLE_OK, "Mod set founder to observer"); ck_assert_msg(role_err != TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Mod set founder to observer");
Tox_Err_Group_Kick_Peer k_err; Tox_Err_Group_Mod_Kick_Peer k_err;
tox_group_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err); tox_group_mod_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err);
ck_assert_msg(k_err != TOX_ERR_GROUP_KICK_PEER_OK, "Mod kicked founder"); ck_assert_msg(k_err != TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Mod kicked founder");
/* the moderator about to be kicked changes the topic to trigger the founder to
* re-sign and redistribute it after the kick.
*/
const State *state_x = (const State *)autotoxes[idx].state;
Tox *tox_x = autotoxes[idx].tox;
Tox_Err_Group_Topic_Set topic_err;
tox_group_set_topic(tox_x, state_x->group_number, nullptr, 0, &topic_err);
ck_assert(topic_err == TOX_ERR_GROUP_TOPIC_SET_OK);
/* founder kicks moderator (this triggers two events: user and kick) */ /* founder kicks moderator (this triggers two events: user and kick) */
fprintf(stderr, "Founder is kicking %s\n", state0->peers[0].name); fprintf(stderr, "Founder is kicking %s\n", state0->peers[0].name);
tox_group_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err); tox_group_mod_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err);
ck_assert_msg(k_err == TOX_ERR_GROUP_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err); ck_assert_msg(k_err == TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err);
state0->kick_check = true; state0->kick_check = true;
check_mod_event(autotoxes, NUM_GROUP_TOXES, TOX_GROUP_MOD_EVENT_KICK); check_mod_event(autotoxes, NUM_GROUP_TOXES, TOX_GROUP_MOD_EVENT_KICK);
@ -632,8 +619,9 @@ static void group_moderation_test(AutoTox *autotoxes)
fprintf(stderr, "All peers successfully received kick event\n"); fprintf(stderr, "All peers successfully received kick event\n");
fprintf(stderr, "Founder is demoting moderator to user\n"); fprintf(stderr, "Founder is demoting moderator to user\n");
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err); tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err);
state0->user_check = true; state0->user_check = true;
++state0->user_event_count; ++state0->user_event_count;

View File

@ -26,23 +26,17 @@ typedef struct State {
#define PEER0_NICK_LEN (sizeof(PEER0_NICK) -1) #define PEER0_NICK_LEN (sizeof(PEER0_NICK) -1)
#define NEW_USER_STATUS TOX_USER_STATUS_BUSY #define NEW_USER_STATUS TOX_USER_STATUS_BUSY
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length,
const uint8_t *group_name, size_t group_name_length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
const size_t length = tox_event_group_invite_get_invite_data_length(event);
Tox_Err_Group_Invite_Accept err_accept; Tox_Err_Group_Invite_Accept err_accept;
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5, tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5,
nullptr, 0, &err_accept); nullptr, 0, &err_accept);
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -58,28 +52,28 @@ static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void
*/ */
static int has_correct_group_state(const Tox *tox, uint32_t group_number, const uint8_t *expected_chat_id) static int has_correct_group_state(const Tox *tox, uint32_t group_number, const uint8_t *expected_chat_id)
{ {
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
Tox_Group_Privacy_State priv_state = tox_group_get_privacy_state(tox, group_number, &query_err); Tox_Group_Privacy_State priv_state = tox_group_get_privacy_state(tox, group_number, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (priv_state != NEW_PRIV_STATE) { if (priv_state != NEW_PRIV_STATE) {
return -1; return -1;
} }
size_t pass_len = tox_group_get_password_size(tox, group_number, &query_err); size_t pass_len = tox_group_get_password_size(tox, group_number, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
uint8_t password[TOX_GROUP_MAX_PASSWORD_SIZE]; uint8_t password[TOX_GROUP_MAX_PASSWORD_SIZE];
tox_group_get_password(tox, group_number, password, &query_err); tox_group_get_password(tox, group_number, password, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (pass_len != PASS_LEN || memcmp(password, PASSWORD, pass_len) != 0) { if (pass_len != PASS_LEN || memcmp(password, PASSWORD, pass_len) != 0) {
return -2; return -2;
} }
size_t gname_len = tox_group_get_name_size(tox, group_number, &query_err); size_t gname_len = tox_group_get_name_size(tox, group_number, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
uint8_t group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH]; uint8_t group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
tox_group_get_name(tox, group_number, group_name, &query_err); tox_group_get_name(tox, group_number, group_name, &query_err);
@ -93,17 +87,17 @@ static int has_correct_group_state(const Tox *tox, uint32_t group_number, const
} }
Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(tox, group_number, &query_err); Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(tox, group_number, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (topic_lock != TOX_GROUP_TOPIC_LOCK_DISABLED) { if (topic_lock != TOX_GROUP_TOPIC_LOCK_DISABLED) {
return -5; return -5;
} }
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox, group_number, chat_id, &id_err); tox_group_get_chat_id(tox, group_number, chat_id, &id_err);
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (memcmp(chat_id, expected_chat_id, TOX_GROUP_CHAT_ID_SIZE) != 0) { if (memcmp(chat_id, expected_chat_id, TOX_GROUP_CHAT_ID_SIZE) != 0) {
return -6; return -6;
@ -126,7 +120,7 @@ static int has_correct_self_state(const Tox *tox, uint32_t group_number, const u
return -1; return -1;
} }
Tox_User_Status self_status = tox_group_self_get_status(tox, group_number, &sq_err); TOX_USER_STATUS self_status = tox_group_self_get_status(tox, group_number, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
if (self_status != NEW_USER_STATUS) { if (self_status != NEW_USER_STATUS) {
@ -157,8 +151,8 @@ static void group_save_test(AutoTox *autotoxes)
ck_assert_msg(NUM_GROUP_TOXES > 1, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); ck_assert_msg(NUM_GROUP_TOXES > 1, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_invite(autotoxes[i].dispatch, group_invite_handler); tox_callback_group_invite(autotoxes[i].tox, group_invite_handler);
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
} }
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
@ -174,9 +168,9 @@ static void group_save_test(AutoTox *autotoxes)
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
tox_group_get_chat_id(tox0, group_number, chat_id, &id_err); tox_group_get_chat_id(tox0, group_number, chat_id, &id_err);
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
uint8_t founder_pk[TOX_GROUP_PEER_PUBLIC_KEY_SIZE]; uint8_t founder_pk[TOX_GROUP_PEER_PUBLIC_KEY_SIZE];
@ -184,6 +178,7 @@ static void group_save_test(AutoTox *autotoxes)
tox_group_self_get_public_key(tox0, group_number, founder_pk, &sq_err); tox_group_self_get_public_key(tox0, group_number, founder_pk, &sq_err);
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK); ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
Tox_Err_Group_Invite_Friend err_invite; Tox_Err_Group_Invite_Friend err_invite;
tox_group_invite_friend(tox0, group_number, 0, &err_invite); tox_group_invite_friend(tox0, group_number, 0, &err_invite);
@ -200,21 +195,21 @@ static void group_save_test(AutoTox *autotoxes)
tox_group_set_topic(tox0, group_number, (const uint8_t *)TOPIC, TOPIC_LEN, &top_err); tox_group_set_topic(tox0, group_number, (const uint8_t *)TOPIC, TOPIC_LEN, &top_err);
ck_assert(top_err == TOX_ERR_GROUP_TOPIC_SET_OK); ck_assert(top_err == TOX_ERR_GROUP_TOPIC_SET_OK);
Tox_Err_Group_Set_Topic_Lock lock_set_err; Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
tox_group_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); tox_group_founder_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
ck_assert(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK); ck_assert(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK);
Tox_Err_Group_Set_Privacy_State priv_err; Tox_Err_Group_Founder_Set_Privacy_State priv_err;
tox_group_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err); tox_group_founder_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err);
ck_assert(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK); ck_assert(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK);
Tox_Err_Group_Set_Password pass_set_err; Tox_Err_Group_Founder_Set_Password pass_set_err;
tox_group_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err); tox_group_founder_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
ck_assert(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK); ck_assert(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK);
Tox_Err_Group_Set_Peer_Limit limit_set_err; Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
tox_group_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err); tox_group_founder_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err);
ck_assert(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK); ck_assert(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK);
// change self state // change self state
Tox_Err_Group_Self_Name_Set n_err; Tox_Err_Group_Self_Name_Set n_err;
@ -246,8 +241,8 @@ static void group_save_test(AutoTox *autotoxes)
ck_assert(options != nullptr); ck_assert(options != nullptr);
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE); tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
tox_options_set_savedata_data(options, save, save_length); tox_options_set_savedata_data(options, save, save_length);
tox_options_set_experimental_groups_persistence(options, true);
Tox *new_tox = tox_new_log(options, nullptr, nullptr); Tox *new_tox = tox_new_log(options, nullptr, nullptr);
@ -283,11 +278,7 @@ int main(void)
Run_Auto_Options autotest_opts = default_run_auto_options(); Run_Auto_Options autotest_opts = default_run_auto_options();
autotest_opts.graph = GRAPH_COMPLETE; autotest_opts.graph = GRAPH_COMPLETE;
Tox_Options *opts = tox_options_new(nullptr); run_auto_test(nullptr, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts);
ck_assert(opts != nullptr);
tox_options_set_experimental_groups_persistence(opts, true);
run_auto_test(opts, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts);
tox_options_free(opts);
return 0; return 0;
} }

View File

@ -60,97 +60,66 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou
return true; return true;
} }
static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event, static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock,
void *user_data) void *user_data)
{ {
const AutoTox *autotox = (const AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &err);
const uint32_t groupnumber = tox_event_group_topic_lock_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event);
Tox_Err_Group_State_Query err;
Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(autotox->tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert_msg(current_topic_lock == topic_lock, "topic locks don't match in callback: %d %d", ck_assert_msg(current_topic_lock == topic_lock, "topic locks don't match in callback: %d %d",
topic_lock, current_topic_lock); topic_lock, current_topic_lock);
} }
static void group_voice_state_handler(const Tox_Event_Group_Voice_State *event, static void group_voice_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Voice_State voice_state,
void *user_data) void *user_data)
{ {
const AutoTox *autotox = (const AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &err);
const uint32_t groupnumber = tox_event_group_voice_state_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const Tox_Group_Voice_State voice_state = tox_event_group_voice_state_get_voice_state(event);
Tox_Err_Group_State_Query err;
Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(autotox->tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert_msg(current_voice_state == voice_state, "voice states don't match in callback: %d %d", ck_assert_msg(current_voice_state == voice_state, "voice states don't match in callback: %d %d",
voice_state, current_voice_state); voice_state, current_voice_state);
} }
static void group_privacy_state_handler(const Tox_Event_Group_Privacy_State *event, static void group_privacy_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state,
void *user_data) void *user_data)
{ {
const AutoTox *autotox = (const AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(tox, groupnumber, &err);
const uint32_t groupnumber = tox_event_group_privacy_state_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const Tox_Group_Privacy_State privacy_state = tox_event_group_privacy_state_get_privacy_state(event);
Tox_Err_Group_State_Query err;
Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(autotox->tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert_msg(current_pstate == privacy_state, "privacy states don't match in callback"); ck_assert_msg(current_pstate == privacy_state, "privacy states don't match in callback");
} }
static void group_peer_limit_handler(const Tox_Event_Group_Peer_Limit *event, void *user_data) static void group_peer_limit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_limit, void *user_data)
{ {
const AutoTox *autotox = (const AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); uint32_t current_plimit = tox_group_get_peer_limit(tox, groupnumber, &err);
const uint32_t groupnumber = tox_event_group_peer_limit_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const uint32_t peer_limit = tox_event_group_peer_limit_get_peer_limit(event);
Tox_Err_Group_State_Query err;
uint32_t current_plimit = tox_group_get_peer_limit(autotox->tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert_msg(peer_limit == current_plimit, ck_assert_msg(peer_limit == current_plimit,
"Peer limits don't match in callback: %u, %u\n", peer_limit, current_plimit); "Peer limits don't match in callback: %u, %u\n", peer_limit, current_plimit);
} }
static void group_password_handler(const Tox_Event_Group_Password *event, static void group_password_handler(Tox *tox, uint32_t groupnumber, const uint8_t *password, size_t length,
void *user_data) void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); size_t curr_pwlength = tox_group_get_password_size(tox, groupnumber, &err);
const uint32_t groupnumber = tox_event_group_password_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const uint8_t *password = tox_event_group_password_get_password(event);
const size_t length = tox_event_group_password_get_password_length(event);
Tox_Err_Group_State_Query err;
size_t curr_pwlength = tox_group_get_password_size(autotox->tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert(length == curr_pwlength); ck_assert(length == curr_pwlength);
uint8_t current_password[TOX_GROUP_MAX_PASSWORD_SIZE]; uint8_t current_password[TOX_GROUP_MAX_PASSWORD_SIZE];
tox_group_get_password(autotox->tox, groupnumber, current_password, &err); tox_group_get_password(tox, groupnumber, current_password, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
ck_assert_msg(memcmp(current_password, password, length) == 0, ck_assert_msg(memcmp(current_password, password, length) == 0,
"Passwords don't match: %s, %s", password, current_password); "Passwords don't match: %s, %s", password, current_password);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -168,24 +137,24 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
Tox_Group_Privacy_State priv_state, Tox_Group_Voice_State voice_state, Tox_Group_Privacy_State priv_state, Tox_Group_Voice_State voice_state,
const uint8_t *password, size_t pass_len, Tox_Group_Topic_Lock topic_lock) const uint8_t *password, size_t pass_len, Tox_Group_Topic_Lock topic_lock)
{ {
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
Tox_Group_Privacy_State my_priv_state = tox_group_get_privacy_state(tox, groupnumber, &query_err); Tox_Group_Privacy_State my_priv_state = tox_group_get_privacy_state(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get privacy state: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get privacy state: %d", query_err);
if (my_priv_state != priv_state) { if (my_priv_state != priv_state) {
return -1; return -1;
} }
uint32_t my_peer_limit = tox_group_get_peer_limit(tox, groupnumber, &query_err); uint32_t my_peer_limit = tox_group_get_peer_limit(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get peer limit: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get peer limit: %d", query_err);
if (my_peer_limit != peer_limit) { if (my_peer_limit != peer_limit) {
return -2; return -2;
} }
size_t my_pass_len = tox_group_get_password_size(tox, groupnumber, &query_err); size_t my_pass_len = tox_group_get_password_size(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password size: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password size: %d", query_err);
if (my_pass_len != pass_len) { if (my_pass_len != pass_len) {
return -5; return -5;
@ -194,10 +163,10 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
if (password != nullptr && my_pass_len > 0) { if (password != nullptr && my_pass_len > 0) {
ck_assert(my_pass_len <= TOX_GROUP_MAX_PASSWORD_SIZE); ck_assert(my_pass_len <= TOX_GROUP_MAX_PASSWORD_SIZE);
uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE + 1]; uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE];
tox_group_get_password(tox, groupnumber, my_pass, &query_err); tox_group_get_password(tox, groupnumber, my_pass, &query_err);
my_pass[my_pass_len] = 0; my_pass[my_pass_len] = 0;
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password: %d", query_err);
if (memcmp(my_pass, password, my_pass_len) != 0) { if (memcmp(my_pass, password, my_pass_len) != 0) {
return -6; return -6;
@ -206,7 +175,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
/* Group name should never change */ /* Group name should never change */
size_t my_gname_len = tox_group_get_name_size(tox, groupnumber, &query_err); size_t my_gname_len = tox_group_get_name_size(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get group name size: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get group name size: %d", query_err);
if (my_gname_len != GROUP_NAME_LEN) { if (my_gname_len != GROUP_NAME_LEN) {
return -7; return -7;
@ -214,7 +183,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
ck_assert(my_gname_len <= TOX_GROUP_MAX_GROUP_NAME_LENGTH); ck_assert(my_gname_len <= TOX_GROUP_MAX_GROUP_NAME_LENGTH);
uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1]; uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
tox_group_get_name(tox, groupnumber, my_gname, &query_err); tox_group_get_name(tox, groupnumber, my_gname, &query_err);
my_gname[my_gname_len] = 0; my_gname[my_gname_len] = 0;
@ -223,14 +192,14 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
} }
Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &query_err); Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get topic lock: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get topic lock: %d", query_err);
if (current_topic_lock != topic_lock) { if (current_topic_lock != topic_lock) {
return -9; return -9;
} }
Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &query_err); Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &query_err);
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get voice state: %d", query_err); ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get voice state: %d", query_err);
if (current_voice_state != voice_state) { if (current_voice_state != voice_state) {
return -10; return -10;
@ -244,26 +213,26 @@ static void set_group_state(Tox *tox, uint32_t groupnumber, uint32_t peer_limit,
Tox_Group_Topic_Lock topic_lock) Tox_Group_Topic_Lock topic_lock)
{ {
Tox_Err_Group_Set_Peer_Limit limit_set_err; Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
tox_group_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err); tox_group_founder_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err);
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err); ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
Tox_Err_Group_Set_Privacy_State priv_err; Tox_Err_Group_Founder_Set_Privacy_State priv_err;
tox_group_set_privacy_state(tox, groupnumber, priv_state, &priv_err); tox_group_founder_set_privacy_state(tox, groupnumber, priv_state, &priv_err);
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err); ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err);
Tox_Err_Group_Set_Password pass_set_err; Tox_Err_Group_Founder_Set_Password pass_set_err;
tox_group_set_password(tox, groupnumber, password, pass_len, &pass_set_err); tox_group_founder_set_password(tox, groupnumber, password, pass_len, &pass_set_err);
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err); ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err);
Tox_Err_Group_Set_Topic_Lock lock_set_err; Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
tox_group_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err); tox_group_founder_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err);
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d", ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d",
lock_set_err); lock_set_err);
Tox_Err_Group_Set_Voice_State voice_set_err; Tox_Err_Group_Founder_Set_Voice_State voice_set_err;
tox_group_set_voice_state(tox, groupnumber, voice_state, &voice_set_err); tox_group_founder_set_voice_state(tox, groupnumber, voice_state, &voice_set_err);
ck_assert_msg(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK, "failed to set voice state: %d", ck_assert_msg(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK, "failed to set voice state: %d",
voice_set_err); voice_set_err);
} }
@ -272,12 +241,12 @@ static void group_state_test(AutoTox *autotoxes)
ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_privacy_state(autotoxes[i].dispatch, group_privacy_state_handler); tox_callback_group_privacy_state(autotoxes[i].tox, group_privacy_state_handler);
tox_events_callback_group_peer_limit(autotoxes[i].dispatch, group_peer_limit_handler); tox_callback_group_peer_limit(autotoxes[i].tox, group_peer_limit_handler);
tox_events_callback_group_password(autotoxes[i].dispatch, group_password_handler); tox_callback_group_password(autotoxes[i].tox, group_password_handler);
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
tox_events_callback_group_voice_state(autotoxes[i].dispatch, group_voice_state_handler); tox_callback_group_voice_state(autotoxes[i].tox, group_voice_state_handler);
tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler); tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler);
} }
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
@ -294,11 +263,11 @@ static void group_state_test(AutoTox *autotoxes)
(const uint8_t *)PASSWORD, PASS_LEN, TOX_GROUP_TOPIC_LOCK_ENABLED); (const uint8_t *)PASSWORD, PASS_LEN, TOX_GROUP_TOPIC_LOCK_ENABLED);
/* Founder gets the Chat ID and implicitly shares it publicly */ /* Founder gets the Chat ID and implicitly shares it publicly */
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, groupnum, chat_id, &id_err); tox_group_get_chat_id(tox0, groupnum, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err);
/* All other peers join the group using the Chat ID and password */ /* All other peers join the group using the Chat ID and password */
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {

View File

@ -96,42 +96,38 @@ static void peers_cleanup(Peers *peers)
free(peers); free(peers);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
ck_assert(add_peer(state->peers, peer_id) == 0); ck_assert(add_peer(state->peers, peer_id) == 0);
} }
static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data) static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
const uint8_t *name, size_t name_length, const uint8_t *part_message,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t peer_id = tox_event_group_peer_exit_get_peer_id(event);
ck_assert(del_peer(state->peers, peer_id) == 0); ck_assert(del_peer(state->peers, peer_id) == 0);
} }
static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data) static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint8_t *topic = tox_event_group_topic_get_topic(event);
const size_t length = tox_event_group_topic_get_topic_length(event);
ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH); ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH);
memcpy(state->callback_topic, (const char *)topic, length); memcpy(state->callback_topic, (const char *)topic, length);
@ -205,7 +201,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers,
int64_t peer_id = state0->peers->peer_ids[idx]; int64_t peer_id = state0->peers->peer_ids[idx];
if (peer_id >= 0) { if (peer_id >= 0) {
tox_group_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr); tox_group_mod_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr);
} }
// mods randomly promote or demote one of the non-mods // mods randomly promote or demote one of the non-mods
@ -222,7 +218,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers,
peer_id = state_j->peers->peer_ids[i]; peer_id = state_j->peers->peer_ids[i];
if (peer_id >= 0) { if (peer_id >= 0) {
tox_group_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr); tox_group_mod_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr);
} }
} }
} }
@ -264,14 +260,14 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
{ {
uint8_t expected_topic[TOX_GROUP_MAX_TOPIC_LENGTH]; uint8_t expected_topic[TOX_GROUP_MAX_TOPIC_LENGTH];
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
size_t expected_topic_length = tox_group_get_topic_size(autotoxes[0].tox, groupnumber, &query_err); size_t expected_topic_length = tox_group_get_topic_size(autotoxes[0].tox, groupnumber, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
tox_group_get_topic(autotoxes[0].tox, groupnumber, expected_topic, &query_err); tox_group_get_topic(autotoxes[0].tox, groupnumber, expected_topic, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const State *state0 = (const State *)autotoxes[0].state; const State *state0 = (const State *)autotoxes[0].state;
@ -286,7 +282,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
for (size_t i = 1; i < num_peers; ++i) { for (size_t i = 1; i < num_peers; ++i) {
size_t topic_length = tox_group_get_topic_size(autotoxes[i].tox, groupnumber, &query_err); size_t topic_length = tox_group_get_topic_size(autotoxes[i].tox, groupnumber, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (topic_length != expected_topic_length) { if (topic_length != expected_topic_length) {
return false; return false;
@ -295,7 +291,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
tox_group_get_topic(autotoxes[i].tox, groupnumber, topic, &query_err); tox_group_get_topic(autotoxes[i].tox, groupnumber, topic, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (memcmp(expected_topic, (const char *)topic, topic_length) != 0) { if (memcmp(expected_topic, (const char *)topic, topic_length) != 0) {
return false; return false;
@ -335,13 +331,13 @@ static void topic_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers
static void group_sync_test(AutoTox *autotoxes) static void group_sync_test(AutoTox *autotoxes)
{ {
ck_assert(NUM_GROUP_TOXES >= 5); ck_assert(NUM_GROUP_TOXES >= 5);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler); tox_callback_group_topic(autotoxes[i].tox, group_topic_handler);
tox_events_callback_group_peer_exit(autotoxes[i].dispatch, group_peer_exit_handler); tox_callback_group_peer_exit(autotoxes[i].tox, group_peer_exit_handler);
State *state = (State *)autotoxes[i].state; State *state = (State *)autotoxes[i].state;
state->peers = (Peers *)calloc(1, sizeof(Peers)); state->peers = (Peers *)calloc(1, sizeof(Peers));
@ -360,11 +356,11 @@ static void group_sync_test(AutoTox *autotoxes)
fprintf(stderr, "tox0 creats new group and invites all his friends"); fprintf(stderr, "tox0 creats new group and invites all his friends");
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
Tox_Err_Group_Join join_err; Tox_Err_Group_Join join_err;
@ -379,9 +375,9 @@ static void group_sync_test(AutoTox *autotoxes)
fprintf(stderr, "%d peers joined the group\n", NUM_GROUP_TOXES); fprintf(stderr, "%d peers joined the group\n", NUM_GROUP_TOXES);
Tox_Err_Group_Set_Topic_Lock lock_set_err; Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
lock_set_err); lock_set_err);
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
@ -392,8 +388,8 @@ static void group_sync_test(AutoTox *autotoxes)
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
lock_set_err); lock_set_err);
do { do {
@ -402,12 +398,12 @@ static void group_sync_test(AutoTox *autotoxes)
&& !all_peers_see_same_roles(autotoxes, NUM_GROUP_TOXES, groupnumber) && !all_peers_see_same_roles(autotoxes, NUM_GROUP_TOXES, groupnumber)
&& state0->peers->num_peers != NUM_GROUP_TOXES - 1); && state0->peers->num_peers != NUM_GROUP_TOXES - 1);
Tox_Err_Group_Set_Role role_err; Tox_Err_Group_Mod_Set_Role role_err;
for (size_t i = 0; i < state0->peers->num_peers; ++i) { for (size_t i = 0; i < state0->peers->num_peers; ++i) {
tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR, tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR,
&role_err); &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
} }
fprintf(stderr, "founder enabled topic lock and set all peers to moderator role\n"); fprintf(stderr, "founder enabled topic lock and set all peers to moderator role\n");
@ -423,9 +419,9 @@ static void group_sync_test(AutoTox *autotoxes)
fprintf(stderr, "founder demoting %u moderators to user\n", num_demoted); fprintf(stderr, "founder demoting %u moderators to user\n", num_demoted);
for (size_t i = 0; i < num_demoted; ++i) { for (size_t i = 0; i < num_demoted; ++i) {
tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER, tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER,
&role_err); &role_err);
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set user. error: %d", role_err); ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set user. error: %d", role_err);
} }
do { do {

View File

@ -19,43 +19,32 @@ typedef struct State {
uint32_t peer_id[NUM_GROUP_TOXES - 1]; uint32_t peer_id[NUM_GROUP_TOXES - 1];
} State; } State;
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data) static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length,
const uint8_t *group_name, size_t group_name_length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr);
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
const size_t length = tox_event_group_invite_get_invite_data_length(event);
printf("Accepting friend invite\n"); printf("Accepting friend invite\n");
Tox_Err_Group_Invite_Accept err_accept; Tox_Err_Group_Invite_Accept err_accept;
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test", 4, tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test", 4,
nullptr, 0, &err_accept); nullptr, 0, &err_accept);
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK); ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
fprintf(stderr, "joined: %zu, %u\n", state->num_peers, peer_id); fprintf(stderr, "joined: %zu, %u\n", state->num_peers, peer_id);
ck_assert_msg(state->num_peers < NUM_GROUP_TOXES - 1, "%zu", state->num_peers); ck_assert_msg(state->num_peers < NUM_GROUP_TOXES - 1, "%zu", state->num_peers);
state->peer_id[state->num_peers++] = peer_id; state->peer_id[state->num_peers++] = peer_id;
} }
static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data) static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, void *user_data)
{ {
const uint8_t *message = tox_event_group_private_message_get_message(event);
const size_t length = tox_event_group_private_message_get_message_length(event);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -69,11 +58,9 @@ static void group_private_message_handler(const Tox_Event_Group_Private_Message
state->got_code = true; state->got_code = true;
} }
static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data) static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t message_id, void *user_data)
{ {
const uint8_t *message = tox_event_group_message_get_message(event);
const size_t length = tox_event_group_message_get_message_length(event);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -146,12 +133,12 @@ static void group_tcp_test(AutoTox *autotoxes)
State *state1 = (State *)autotoxes[1].state; State *state1 = (State *)autotoxes[1].state;
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler); tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
tox_events_callback_group_private_message(autotoxes[i].dispatch, group_private_message_handler); tox_callback_group_private_message(autotoxes[i].tox, group_private_message_handler);
} }
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler); tox_callback_group_message(autotoxes[1].tox, group_message_handler);
tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler); tox_callback_group_invite(autotoxes[1].tox, group_invite_handler);
Tox_Err_Group_New new_err; Tox_Err_Group_New new_err;
uint32_t groupnumber = tox_group_new(autotoxes[0].tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4, uint32_t groupnumber = tox_group_new(autotoxes[0].tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4,
@ -160,11 +147,11 @@ static void group_tcp_test(AutoTox *autotoxes)
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL); iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(autotoxes[0].tox, groupnumber, chat_id, &id_err); tox_group_get_chat_id(autotoxes[0].tox, groupnumber, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
printf("Tox 0 created new group...\n"); printf("Tox 0 created new group...\n");
@ -181,6 +168,7 @@ static void group_tcp_test(AutoTox *autotoxes)
printf("%d peers successfully joined. Waiting for code...\n", NUM_GROUP_TOXES); printf("%d peers successfully joined. Waiting for code...\n", NUM_GROUP_TOXES);
printf("Tox 0 sending secret code to all peers\n"); printf("Tox 0 sending secret code to all peers\n");
for (size_t i = 0; i < NUM_GROUP_TOXES - 1; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES - 1; ++i) {
Tox_Err_Group_Send_Private_Message perr; Tox_Err_Group_Send_Private_Message perr;

View File

@ -55,11 +55,8 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou
return true; return true;
} }
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data) static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
{ {
//const uint32_t group_number = tox_event_group_peer_join_get_group_number(event);
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
AutoTox *autotox = (AutoTox *)user_data; AutoTox *autotox = (AutoTox *)user_data;
ck_assert(autotox != nullptr); ck_assert(autotox != nullptr);
@ -68,41 +65,28 @@ static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void
state->peer_id = peer_id; state->peer_id = peer_id;
} }
static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data) static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic,
size_t length, void *user_data)
{ {
AutoTox *autotox = (AutoTox *)user_data; ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH);
ck_assert(autotox != nullptr);
const uint32_t group_number = tox_event_group_topic_get_group_number(event); Tox_Err_Group_State_Queries query_err;
//const uint32_t peer_id = tox_event_group_topic_get_peer_id(event);
const uint8_t *topic = tox_event_group_topic_get_topic(event);
const uint32_t topic_length = tox_event_group_topic_get_topic_length(event);
ck_assert(topic_length <= TOX_GROUP_MAX_TOPIC_LENGTH);
Tox_Err_Group_State_Query query_err;
uint8_t topic2[TOX_GROUP_MAX_TOPIC_LENGTH]; uint8_t topic2[TOX_GROUP_MAX_TOPIC_LENGTH];
tox_group_get_topic(autotox->tox, group_number, topic2, &query_err); tox_group_get_topic(tox, groupnumber, topic2, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
size_t topic_length_getter = tox_group_get_topic_size(autotox->tox, group_number, &query_err); size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err);
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
ck_assert_msg(topic_length_getter == topic_length && memcmp(topic, topic2, topic_length) == 0, ck_assert_msg(topic_length == length && memcmp(topic, topic2, length) == 0,
"topic differs in callback: %s, %s", topic, topic2); "topic differs in callback: %s, %s", topic, topic2);
} }
static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event, void *user_data) static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *user_data)
{ {
const AutoTox *autotox = (const AutoTox *)user_data; Tox_Err_Group_State_Queries err;
ck_assert(autotox != nullptr); Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(tox, groupnumber, &err);
const uint32_t group_number = tox_event_group_topic_lock_get_group_number(event); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event);
Tox_Err_Group_State_Query err;
Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(autotox->tox, group_number, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
ck_assert_msg(topic_lock == current_lock, "topic locks differ in callback"); ck_assert_msg(topic_lock == current_lock, "topic locks differ in callback");
} }
@ -123,10 +107,10 @@ static bool set_topic(Tox *tox, uint32_t groupnumber, const char *topic, size_t
*/ */
static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expected_topic, size_t expected_length) static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expected_topic, size_t expected_length)
{ {
Tox_Err_Group_State_Query query_err; Tox_Err_Group_State_Queries query_err;
size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err); size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err);
if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) { if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
return -1; return -1;
} }
@ -137,7 +121,7 @@ static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expecte
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH]; uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
tox_group_get_topic(tox, groupnumber, topic, &query_err); tox_group_get_topic(tox, groupnumber, topic, &query_err);
if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) { if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
return -3; return -3;
} }
@ -156,9 +140,9 @@ static void wait_topic_lock(AutoTox *autotoxes, uint32_t groupnumber, Tox_Group_
uint32_t count = 0; uint32_t count = 0;
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
Tox_Err_Group_State_Query err; Tox_Err_Group_State_Queries err;
Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(autotoxes[i].tox, groupnumber, &err); Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(autotoxes[i].tox, groupnumber, &err);
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK); ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
if (topic_lock == expected_lock) { if (topic_lock == expected_lock) {
++count; ++count;
@ -221,18 +205,17 @@ static void group_topic_test(AutoTox *autotoxes)
{ {
ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Tox *tox0 = autotoxes[0].tox; Tox *tox0 = autotoxes[0].tox;
Tox_Dispatch *dispatch0 = autotoxes[0].dispatch;
const State *state0 = (const State *)autotoxes[0].state; const State *state0 = (const State *)autotoxes[0].state;
tox_events_callback_group_peer_join(dispatch0, group_peer_join_handler); tox_callback_group_peer_join(tox0, group_peer_join_handler);
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler); tox_callback_group_topic(autotoxes[i].tox, group_topic_handler);
tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler); tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler);
} }
/* Tox1 creates a group and is the founder of a newly created group */ /* Tox1 creates a group and is the founder of a newly created group */
@ -250,11 +233,11 @@ static void group_topic_test(AutoTox *autotoxes)
ck_assert_msg(s_ret, "Founder failed to set topic"); ck_assert_msg(s_ret, "Founder failed to set topic");
/* Founder gets the Chat ID and implicitly shares it publicly */ /* Founder gets the Chat ID and implicitly shares it publicly */
Tox_Err_Group_State_Query id_err; Tox_Err_Group_State_Queries id_err;
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE]; uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err); tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err); ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err);
/* All other peers join the group using the Chat ID */ /* All other peers join the group using the Chat ID */
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) { for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
@ -274,9 +257,9 @@ static void group_topic_test(AutoTox *autotoxes)
wait_state_topic(autotoxes, groupnumber, TOPIC, TOPIC_LEN); wait_state_topic(autotoxes, groupnumber, TOPIC, TOPIC_LEN);
/* Founder disables topic lock */ /* Founder disables topic lock */
Tox_Err_Group_Set_Topic_Lock lock_set_err; Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err); tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d", ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
lock_set_err); lock_set_err);
fprintf(stderr, "Topic lock disabled\n"); fprintf(stderr, "Topic lock disabled\n");
@ -290,9 +273,9 @@ static void group_topic_test(AutoTox *autotoxes)
ck_assert_msg(change_count == NUM_GROUP_TOXES, "%u peers changed the topic with topic lock disabled", change_count); ck_assert_msg(change_count == NUM_GROUP_TOXES, "%u peers changed the topic with topic lock disabled", change_count);
/* founder silences the last peer he saw join */ /* founder silences the last peer he saw join */
Tox_Err_Group_Set_Role merr; Tox_Err_Group_Mod_Set_Role merr;
tox_group_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr); tox_group_mod_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr);
ck_assert_msg(merr == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr); ck_assert_msg(merr == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr);
fprintf(stderr, "Random peer is set to observer\n"); fprintf(stderr, "Random peer is set to observer\n");
@ -304,8 +287,8 @@ static void group_topic_test(AutoTox *autotoxes)
ck_assert_msg(change_count == NUM_GROUP_TOXES - 1, "%u peers changed the topic with a silenced peer", change_count); ck_assert_msg(change_count == NUM_GROUP_TOXES - 1, "%u peers changed the topic with a silenced peer", change_count);
/* Founder enables topic lock and sets topic back to original */ /* Founder enables topic lock and sets topic back to original */
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err); tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d", ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
lock_set_err); lock_set_err);
fprintf(stderr, "Topic lock enabled\n"); fprintf(stderr, "Topic lock enabled\n");

View File

@ -18,17 +18,13 @@ typedef struct State {
#define LOSSLESS_PACKET_FILLER 160 #define LOSSLESS_PACKET_FILLER 160
static void handle_lossless_packet(const Tox_Event_Friend_Lossless_Packet *event, void *user_data) static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
{ {
//const uint32_t friend_number = tox_event_friend_lossless_packet_get_friend_number(event);
const uint8_t *data = tox_event_friend_lossless_packet_get_data(event);
const uint32_t data_length = tox_event_friend_lossless_packet_get_data_length(event);
uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size());
ck_assert(cmp_packet != nullptr); ck_assert(cmp_packet != nullptr);
memset(cmp_packet, LOSSLESS_PACKET_FILLER, tox_max_custom_packet_size()); memset(cmp_packet, LOSSLESS_PACKET_FILLER, tox_max_custom_packet_size());
if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
state->custom_packet_received = true; state->custom_packet_received = true;
@ -39,7 +35,7 @@ static void handle_lossless_packet(const Tox_Event_Friend_Lossless_Packet *event
static void test_lossless_packet(AutoTox *autotoxes) static void test_lossless_packet(AutoTox *autotoxes)
{ {
tox_events_callback_friend_lossless_packet(autotoxes[1].dispatch, &handle_lossless_packet); tox_callback_friend_lossless_packet(autotoxes[1].tox, &handle_lossless_packet);
const size_t packet_size = tox_max_custom_packet_size() + 1; const size_t packet_size = tox_max_custom_packet_size() + 1;
uint8_t *packet = (uint8_t *)malloc(packet_size); uint8_t *packet = (uint8_t *)malloc(packet_size);
ck_assert(packet != nullptr); ck_assert(packet != nullptr);

View File

@ -18,17 +18,13 @@ typedef struct State {
#define LOSSY_PACKET_FILLER 200 #define LOSSY_PACKET_FILLER 200
static void handle_lossy_packet(const Tox_Event_Friend_Lossy_Packet *event, void *user_data) static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
{ {
//const uint32_t friend_number = tox_event_friend_lossy_packet_get_friend_number(event);
const uint8_t *data = tox_event_friend_lossy_packet_get_data(event);
const uint32_t data_length = tox_event_friend_lossy_packet_get_data_length(event);
uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size()); uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size());
ck_assert(cmp_packet != nullptr); ck_assert(cmp_packet != nullptr);
memset(cmp_packet, LOSSY_PACKET_FILLER, tox_max_custom_packet_size()); memset(cmp_packet, LOSSY_PACKET_FILLER, tox_max_custom_packet_size());
if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) { if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
state->custom_packet_received = true; state->custom_packet_received = true;
@ -39,7 +35,7 @@ static void handle_lossy_packet(const Tox_Event_Friend_Lossy_Packet *event, void
static void test_lossy_packet(AutoTox *autotoxes) static void test_lossy_packet(AutoTox *autotoxes)
{ {
tox_events_callback_friend_lossy_packet(autotoxes[1].dispatch, &handle_lossy_packet); tox_callback_friend_lossy_packet(autotoxes[1].tox, &handle_lossy_packet);
const size_t packet_size = tox_max_custom_packet_size() + 1; const size_t packet_size = tox_max_custom_packet_size() + 1;
uint8_t *packet = (uint8_t *)malloc(packet_size); uint8_t *packet = (uint8_t *)malloc(packet_size);
ck_assert(packet != nullptr); ck_assert(packet != nullptr);

View File

@ -20,7 +20,7 @@ static void test_addr_resolv_localhost(void)
errno = 0; errno = 0;
#endif #endif
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const char localhost[] = "localhost"; const char localhost[] = "localhost";

View File

@ -37,7 +37,7 @@ static void do_onion(Mono_Time *mono_time, Onion *onion)
static int handled_test_1; static int handled_test_1;
static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{ {
const Onion *onion = (const Onion *)object; Onion *onion = (Onion *)object;
const char req_message[] = "Install Gentoo"; const char req_message[] = "Install Gentoo";
uint8_t req_packet[1 + sizeof(req_message)]; uint8_t req_packet[1 + sizeof(req_message)];
@ -99,7 +99,7 @@ static uint8_t test_3_pub_key[CRYPTO_PUBLIC_KEY_SIZE];
static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE]; static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE];
static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{ {
const Onion *onion = (const Onion *)object; Onion *onion = (Onion *)object;
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
return 1; return 1;
@ -118,6 +118,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
return 1; return 1;
} }
if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) { if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
return 1; return 1;
} }
@ -134,7 +135,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata) void *userdata)
{ {
const Onion *onion = (const Onion *)object; Onion *onion = (Onion *)object;
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) { if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
return 1; return 1;
@ -153,6 +154,7 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t
return 1; return 1;
} }
if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) { if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
return 1; return 1;
} }
@ -169,7 +171,7 @@ static uint8_t nonce[CRYPTO_NONCE_SIZE];
static int handled_test_4; static int handled_test_4;
static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata) static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{ {
const Onion *onion = (const Onion *)object; Onion *onion = (Onion *)object;
if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") + if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") +
CRYPTO_MAC_SIZE)) { CRYPTO_MAC_SIZE)) {
@ -221,11 +223,11 @@ static Networking_Core *new_networking(const Logger *log, const Memory *mem, con
static void test_basic(void) static void test_basic(void)
{ {
uint32_t index[] = { 1, 2, 3 }; uint32_t index[] = { 1, 2, 3 };
const Network *ns = os_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *log1 = logger_new(); Logger *log1 = logger_new();
@ -286,7 +288,7 @@ static void test_basic(void)
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1);
ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
const uint8_t zeroes[64] = {0}; uint8_t zeroes[64] = {0};
random_bytes(rng, sb_data, sizeof(sb_data)); random_bytes(rng, sb_data, sizeof(sb_data));
uint64_t s; uint64_t s;
memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(&s, sb_data, sizeof(uint64_t));
@ -405,7 +407,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u
{ {
IP ip = get_loopback(); IP ip = get_loopback();
ip.ip.v6.uint8[15] = 1; ip.ip.v6.uint8[15] = 1;
const Network *ns = os_network(); const Network *ns = system_network();
Onions *on = (Onions *)malloc(sizeof(Onions)); Onions *on = (Onions *)malloc(sizeof(Onions));
if (!on) { if (!on) {
@ -574,9 +576,9 @@ static void test_announce(void)
{ {
uint32_t index[NUM_ONIONS]; uint32_t index[NUM_ONIONS];
Onions *onions[NUM_ONIONS]; Onions *onions[NUM_ONIONS];
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
ck_assert(mem != nullptr); ck_assert(mem != nullptr);
for (uint32_t i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {

View File

@ -11,13 +11,9 @@ typedef struct State {
#define NUM_MSGS 40000 #define NUM_MSGS 40000
static void handle_friend_message(const Tox_Event_Friend_Message *event, void *user_data) static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type,
const uint8_t *message, size_t length, void *user_data)
{ {
//const uint32_t friend_number = tox_event_friend_message_get_friend_number(event);
//const Tox_Message_Type type = tox_event_friend_message_get_type(event);
//const uint8_t *message = tox_event_friend_message_get_message(event);
//const uint32_t message_length = tox_event_friend_message_get_message_length(event);
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
state->recv_count++; state->recv_count++;
@ -25,7 +21,7 @@ static void handle_friend_message(const Tox_Event_Friend_Message *event, void *u
static void net_crypto_overflow_test(AutoTox *autotoxes) static void net_crypto_overflow_test(AutoTox *autotoxes)
{ {
tox_events_callback_friend_message(autotoxes[0].dispatch, handle_friend_message); tox_callback_friend_message(autotoxes[0].tox, handle_friend_message);
printf("sending many messages to tox0\n"); printf("sending many messages to tox0\n");

View File

@ -24,10 +24,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4)
tox_self_get_connection_status(tox3) != TOX_CONNECTION_NONE && tox_self_get_connection_status(tox3) != TOX_CONNECTION_NONE &&
tox_self_get_connection_status(tox4) != TOX_CONNECTION_NONE) { tox_self_get_connection_status(tox4) != TOX_CONNECTION_NONE) {
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox1),
tox_self_get_connection_status(tox2), tox_self_get_connection_status(tox2),
tox_self_get_connection_status(tox3), tox_self_get_connection_status(tox3),
tox_self_get_connection_status(tox4)); tox_self_get_connection_status(tox4));
return true; return true;
} }
@ -38,10 +38,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4)
if (i % 10 == 0) { if (i % 10 == 0) {
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
tox_self_get_connection_status(tox1), tox_self_get_connection_status(tox1),
tox_self_get_connection_status(tox2), tox_self_get_connection_status(tox2),
tox_self_get_connection_status(tox3), tox_self_get_connection_status(tox3),
tox_self_get_connection_status(tox4)); tox_self_get_connection_status(tox4));
} }
c_sleep(tox_iteration_interval(tox1)); c_sleep(tox_iteration_interval(tox1));

View File

@ -51,7 +51,7 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32
static void test_reconnect(AutoTox *autotoxes) static void test_reconnect(AutoTox *autotoxes)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const time_t test_start_time = time(nullptr); const time_t test_start_time = time(nullptr);
@ -67,12 +67,7 @@ static void test_reconnect(AutoTox *autotoxes)
do { do {
for (uint16_t i = 0; i < TOX_COUNT; ++i) { for (uint16_t i = 0; i < TOX_COUNT; ++i) {
if (i != disconnect) { if (i != disconnect) {
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(autotoxes[i].tox, &autotoxes[i]);
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
tox_events_free(events);
autotoxes[i].clock += 1000; autotoxes[i].clock += 1000;
} }
} }

View File

@ -9,8 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define LOADED_SAVE_FILE_BIG "../auto_tests/data/save.tox.big" #define LOADED_SAVE_FILE "../auto_tests/data/save.tox"
#define LOADED_SAVE_FILE_LITTLE "../auto_tests/data/save.tox.little"
// Information from the save file // Information from the save file
#define EXPECTED_NAME "name" #define EXPECTED_NAME "name"
@ -19,7 +18,7 @@
#define EXPECTED_STATUS_MESSAGE_SIZE strlen(EXPECTED_STATUS_MESSAGE) #define EXPECTED_STATUS_MESSAGE_SIZE strlen(EXPECTED_STATUS_MESSAGE)
#define EXPECTED_NUM_FRIENDS 1 #define EXPECTED_NUM_FRIENDS 1
#define EXPECTED_NOSPAM "4C762C7D" #define EXPECTED_NOSPAM "4C762C7D"
#define EXPECTED_TOX_ID "E776E9A993EE3CAE04F5946D9AC66FBBAA8C63A95A94B41942353C6DC1739B4B4C762C7DA7B9" #define EXPECTED_TOX_ID "B70E97D41F69B7F4C42A5BC7BD7A76B95B8030BE1B7C0E9E6FC19FC4ABEB195B4C762C7D800B"
static size_t get_file_size(const char *save_path) static size_t get_file_size(const char *save_path)
{ {
@ -136,13 +135,6 @@ static void test_save_compatibility(const char *save_path)
tox_kill(tox); tox_kill(tox);
} }
static bool is_little_endian(void)
{
uint16_t x = 1;
return ((uint8_t *)&x)[0] == 1;
}
// cppcheck-suppress constParameter
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char base_path[4096] = {0}; char base_path[4096] = {0};
@ -160,15 +152,10 @@ int main(int argc, char *argv[])
base_path[strrchr(base_path, '/') - base_path] = '\0'; base_path[strrchr(base_path, '/') - base_path] = '\0';
} }
if (is_little_endian()) { char save_path[4096 + sizeof(LOADED_SAVE_FILE)];
char save_path[4096 + sizeof(LOADED_SAVE_FILE_LITTLE)]; snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE);
snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_LITTLE);
test_save_compatibility(save_path); test_save_compatibility(save_path);
} else {
char save_path[4096 + sizeof(LOADED_SAVE_FILE_BIG)];
snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_BIG);
test_save_compatibility(save_path);
}
return 0; return 0;
} }

View File

@ -22,12 +22,13 @@ struct test_data {
static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length) static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length)
{ {
VLA(uint8_t, text, length); VLA(uint8_t, text, length);
uint32_t i;
for (uint32_t i = 0; i < length; ++i) { for (i = 0; i < length; ++i) {
text[i] = random_u08(rng); text[i] = random_u08(rng);
} }
setter(m, text, length, nullptr); setter(m, text, SIZEOF_VLA(text), nullptr);
} }
static void alloc_string(uint8_t **to, size_t length) static void alloc_string(uint8_t **to, size_t length)
@ -43,25 +44,18 @@ static void set_string(uint8_t **to, const uint8_t *from, size_t length)
memcpy(*to, from, length); memcpy(*to, from, length);
} }
static void namechange_callback(const Tox_Event_Friend_Name *event, void *user_data) static void namechange_callback(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data)
{ {
//const uint32_t friend_number = tox_event_friend_name_get_friend_number(event);
const uint8_t *name = tox_event_friend_name_get_name(event);
const uint32_t name_length = tox_event_friend_name_get_name_length(event);
struct test_data *to_compare = (struct test_data *)user_data; struct test_data *to_compare = (struct test_data *)user_data;
set_string(&to_compare->name, name, name_length); set_string(&to_compare->name, name, length);
to_compare->received_name = true; to_compare->received_name = true;
} }
static void statuschange_callback(const Tox_Event_Friend_Status_Message *event, void *user_data) static void statuschange_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
void *user_data)
{ {
//const uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event);
const uint8_t *message = tox_event_friend_status_message_get_message(event);
const uint32_t message_length = tox_event_friend_status_message_get_message_length(event);
struct test_data *to_compare = (struct test_data *)user_data; struct test_data *to_compare = (struct test_data *)user_data;
set_string(&to_compare->status_message, message, message_length); set_string(&to_compare->status_message, message, length);
to_compare->received_status_message = true; to_compare->received_status_message = true;
} }
@ -71,12 +65,6 @@ int main(void)
Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr);
Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr); Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr);
ck_assert(tox1 != nullptr);
ck_assert(tox2 != nullptr);
tox_events_init(tox1);
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
ck_assert(dispatch1 != nullptr);
printf("bootstrapping tox2 off tox1\n"); printf("bootstrapping tox2 off tox1\n");
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
@ -98,7 +86,7 @@ int main(void)
ck_assert(reference_name != nullptr); ck_assert(reference_name != nullptr);
ck_assert(reference_status != nullptr); ck_assert(reference_status != nullptr);
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
set_random(tox1, rng, tox_self_set_name, tox_max_name_length()); set_random(tox1, rng, tox_self_set_name, tox_max_name_length());
set_random(tox2, rng, tox_self_set_name, tox_max_name_length()); set_random(tox2, rng, tox_self_set_name, tox_max_name_length());
@ -108,8 +96,8 @@ int main(void)
tox_self_get_name(tox2, reference_name); tox_self_get_name(tox2, reference_name);
tox_self_get_status_message(tox2, reference_status); tox_self_get_status_message(tox2, reference_status);
tox_events_callback_friend_name(dispatch1, namechange_callback); tox_callback_friend_name(tox1, namechange_callback);
tox_events_callback_friend_status_message(dispatch1, statuschange_callback); tox_callback_friend_status_message(tox1, statuschange_callback);
while (true) { while (true) {
if (tox_self_get_connection_status(tox1) && if (tox_self_get_connection_status(tox1) &&
@ -119,12 +107,7 @@ int main(void)
break; break;
} }
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(tox1, &to_compare);
Tox_Events *events = tox_events_iterate(tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch1, events, &to_compare);
tox_events_free(events);
tox_iterate(tox2, nullptr); tox_iterate(tox2, nullptr);
c_sleep(tox_iteration_interval(tox1)); c_sleep(tox_iteration_interval(tox1));
@ -136,12 +119,7 @@ int main(void)
break; break;
} }
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(tox1, &to_compare);
Tox_Events *events = tox_events_iterate(tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch1, events, &to_compare);
tox_events_free(events);
tox_iterate(tox2, nullptr); tox_iterate(tox2, nullptr);
c_sleep(tox_iteration_interval(tox1)); c_sleep(tox_iteration_interval(tox1));
@ -168,7 +146,6 @@ int main(void)
"incorrect status message: should be all zeroes"); "incorrect status message: should be all zeroes");
tox_options_free(options); tox_options_free(options);
tox_dispatch_free(dispatch1);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2); tox_kill(tox2);
tox_kill(tox_to_compare); tox_kill(tox_to_compare);

View File

@ -32,24 +32,16 @@
#endif #endif
#define TCP_RELAY_PORT 33431 #define TCP_RELAY_PORT 33431
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{ {
Tox *tox = (Tox *)userdata; if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
tox_friend_add_norequest(m, public_key, nullptr);
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *message = tox_event_friend_request_get_message(event);
uint32_t message_length = tox_event_friend_request_get_message_length(event);
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
tox_friend_add_norequest(tox, public_key, nullptr);
} }
} }
static unsigned int connected_t1; static unsigned int connected_t1;
static void tox_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data) static void tox_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data)
{ {
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
if (connected_t1 && !connection_status) { if (connected_t1 && !connection_status) {
ck_abort_msg("Tox went offline"); ck_abort_msg("Tox went offline");
} }
@ -155,9 +147,6 @@ static void test_few_clients(void)
Tox *tox1 = tox_new_log(opts1, &t_n_error, &index[0]); Tox *tox1 = tox_new_log(opts1, &t_n_error, &index[0]);
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error);
tox_options_free(opts1); tox_options_free(opts1);
tox_events_init(tox1);
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
ck_assert(dispatch1 != nullptr);
struct Tox_Options *opts2 = tox_options_new(nullptr); struct Tox_Options *opts2 = tox_options_new(nullptr);
tox_options_set_ipv6_enabled(opts2, USE_IPV6); tox_options_set_ipv6_enabled(opts2, USE_IPV6);
@ -165,9 +154,6 @@ static void test_few_clients(void)
tox_options_set_local_discovery_enabled(opts2, false); tox_options_set_local_discovery_enabled(opts2, false);
Tox *tox2 = tox_new_log(opts2, &t_n_error, &index[1]); Tox *tox2 = tox_new_log(opts2, &t_n_error, &index[1]);
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error); ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error);
tox_events_init(tox2);
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
ck_assert(dispatch2 != nullptr);
struct Tox_Options *opts3 = tox_options_new(nullptr); struct Tox_Options *opts3 = tox_options_new(nullptr);
tox_options_set_ipv6_enabled(opts3, USE_IPV6); tox_options_set_ipv6_enabled(opts3, USE_IPV6);
@ -177,6 +163,7 @@ static void test_few_clients(void)
ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances"); ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances");
Time_Data time_data; Time_Data time_data;
ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex"); ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex");
time_data.clock = current_time_monotonic(tox1->mono_time); time_data.clock = current_time_monotonic(tox1->mono_time);
@ -196,8 +183,8 @@ static void test_few_clients(void)
tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr);
connected_t1 = 0; connected_t1 = 0;
tox_events_callback_self_connection_status(dispatch1, tox_connection_status); tox_callback_self_connection_status(tox1, tox_connection_status);
tox_events_callback_friend_request(dispatch2, accept_friend_request); tox_callback_friend_request(tox2, accept_friend_request);
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_self_get_address(tox2, address); tox_self_get_address(tox2, address);
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr); uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
@ -206,20 +193,8 @@ static void test_few_clients(void)
uint8_t off = 1; uint8_t off = 1;
while (true) { while (true) {
{ tox_iterate(tox1, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(tox2, nullptr);
Tox_Events *events = tox_events_iterate(tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch1, events, tox1);
tox_events_free(events);
}
{
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch2, events, tox2);
tox_events_free(events);
}
tox_iterate(tox3, nullptr); tox_iterate(tox3, nullptr);
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
@ -245,10 +220,9 @@ static void test_few_clients(void)
// We're done with this callback, so unset it to ensure we don't fail the // We're done with this callback, so unset it to ensure we don't fail the
// test if tox1 goes offline while tox2 and 3 are reloaded. // test if tox1 goes offline while tox2 and 3 are reloaded.
tox_events_callback_self_connection_status(dispatch1, nullptr); tox_callback_self_connection_status(tox1, nullptr);
reload_tox(&tox2, opts2, &index[1]); reload_tox(&tox2, opts2, &index[1]);
tox_events_init(tox2);
reload_tox(&tox3, opts3, &index[2]); reload_tox(&tox3, opts3, &index[2]);
@ -257,20 +231,8 @@ static void test_few_clients(void)
off = 1; off = 1;
while (true) { while (true) {
{ tox_iterate(tox1, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(tox2, nullptr);
Tox_Events *events = tox_events_iterate(tox1, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch1, events, tox1);
tox_events_free(events);
}
{
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch2, events, tox2);
tox_events_free(events);
}
tox_iterate(tox3, nullptr); tox_iterate(tox3, nullptr);
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2) if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
@ -295,9 +257,6 @@ static void test_few_clients(void)
printf("test_few_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); printf("test_few_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
tox_dispatch_free(dispatch1);
tox_dispatch_free(dispatch2);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2); tox_kill(tox2);
tox_kill(tox3); tox_kill(tox3);

View File

@ -14,15 +14,12 @@ typedef struct State {
#define MESSAGE_FILLER 'G' #define MESSAGE_FILLER 'G'
static void message_callback( static void message_callback(
const Tox_Event_Friend_Message *event, void *user_data) Tox *m, uint32_t friendnumber, Tox_Message_Type type,
const uint8_t *string, size_t length, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
const Tox_Message_Type type = tox_event_friend_message_get_type(event);
const uint8_t *string = tox_event_friend_message_get_message(event);
const uint32_t length = tox_event_friend_message_get_message_length(event);
if (type != TOX_MESSAGE_TYPE_NORMAL) { if (type != TOX_MESSAGE_TYPE_NORMAL) {
ck_abort_msg("Bad type"); ck_abort_msg("Bad type");
} }
@ -41,7 +38,7 @@ static void message_callback(
static void send_message_test(AutoTox *autotoxes) static void send_message_test(AutoTox *autotoxes)
{ {
tox_events_callback_friend_message(autotoxes[1].dispatch, &message_callback); tox_callback_friend_message(autotoxes[1].tox, &message_callback);
const size_t msgs_len = tox_max_message_length() + 1; const size_t msgs_len = tox_max_message_length() + 1;
uint8_t *msgs = (uint8_t *)malloc(msgs_len); uint8_t *msgs = (uint8_t *)malloc(msgs_len);

View File

@ -15,16 +15,12 @@
#define NICKNAME "Gentoo" #define NICKNAME "Gentoo"
static void nickchange_callback(const Tox_Event_Friend_Name *event, void *user_data) static void nickchange_callback(Tox *tox, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
{ {
//const uint32_t friend_number = tox_event_friend_name_get_friend_number(event); ck_assert_msg(length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)length,
const uint8_t *name = tox_event_friend_name_get_name(event);
const uint32_t name_length = tox_event_friend_name_get_name_length(event);
ck_assert_msg(name_length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)name_length,
(uint16_t)sizeof(NICKNAME)); (uint16_t)sizeof(NICKNAME));
ck_assert_msg(memcmp(name, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)name); ck_assert_msg(memcmp(string, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)string);
bool *nickname_updated = (bool *)user_data; bool *nickname_updated = (bool *)userdata;
*nickname_updated = true; *nickname_updated = true;
} }
@ -38,12 +34,6 @@ static void test_set_name(void)
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
// we only run events on tox2 in this test case
tox_events_init(tox2);
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
ck_assert(dispatch2 != nullptr);
printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); printf("tox1 adds tox2 as friend, tox2 adds tox1\n");
uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_public_key(tox2, public_key); tox_self_get_public_key(tox2, public_key);
@ -60,13 +50,7 @@ static void test_set_name(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
//tox_dispatch_invoke(dispatch2, events, nullptr);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE); tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE);
@ -76,20 +60,14 @@ static void test_set_name(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
//tox_dispatch_invoke(dispatch2, events, nullptr);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP); tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP);
printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time));
tox_events_callback_friend_name(dispatch2, nickchange_callback); tox_callback_friend_name(tox2, nickchange_callback);
Tox_Err_Set_Info err_n; Tox_Err_Set_Info err_n;
bool ret = tox_self_set_name(tox1, (const uint8_t *)NICKNAME, sizeof(NICKNAME), &err_n); bool ret = tox_self_set_name(tox1, (const uint8_t *)NICKNAME, sizeof(NICKNAME), &err_n);
ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %d\n", err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %d\n", err_n);
@ -98,13 +76,7 @@ static void test_set_name(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, &nickname_updated);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch2, events, &nickname_updated);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (!nickname_updated); } while (!nickname_updated);
@ -115,8 +87,6 @@ static void test_set_name(void)
printf("test_set_name succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); printf("test_set_name succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
tox_dispatch_free(dispatch2);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2); tox_kill(tox2);
} }

View File

@ -15,13 +15,9 @@
#define STATUS_MESSAGE "Installing Gentoo" #define STATUS_MESSAGE "Installing Gentoo"
static void status_callback(const Tox_Event_Friend_Status_Message *event, void *user_data) static void status_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, void *user_data)
{ {
//uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event); ck_assert_msg(length == sizeof(STATUS_MESSAGE) &&
const uint8_t *message = tox_event_friend_status_message_get_message(event);
uint32_t message_length = tox_event_friend_status_message_get_message_length(event);
ck_assert_msg(message_length == sizeof(STATUS_MESSAGE) &&
memcmp(message, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0, memcmp(message, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0,
"incorrect data in status callback"); "incorrect data in status callback");
bool *status_updated = (bool *)user_data; bool *status_updated = (bool *)user_data;
@ -38,12 +34,6 @@ static void test_set_status_message(void)
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances"); ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
// we only run events on tox2 in this test case
tox_events_init(tox2);
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
ck_assert(dispatch2 != nullptr);
printf("tox1 adds tox2 as friend, tox2 adds tox1\n"); printf("tox1 adds tox2 as friend, tox2 adds tox1\n");
uint8_t public_key[TOX_PUBLIC_KEY_SIZE]; uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_public_key(tox2, public_key); tox_self_get_public_key(tox2, public_key);
@ -60,12 +50,7 @@ static void test_set_status_message(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
//tox_dispatch_invoke(dispatch2, events, nullptr);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE || } while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
@ -76,12 +61,7 @@ static void test_set_status_message(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, nullptr);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
//tox_dispatch_invoke(dispatch2, events, nullptr);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP || } while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
@ -89,8 +69,8 @@ static void test_set_status_message(void)
printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time)); printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time));
tox_events_callback_friend_status_message(dispatch2, status_callback);
Tox_Err_Set_Info err_n; Tox_Err_Set_Info err_n;
tox_callback_friend_status_message(tox2, status_callback);
bool ret = tox_self_set_status_message(tox1, (const uint8_t *)STATUS_MESSAGE, sizeof(STATUS_MESSAGE), bool ret = tox_self_set_status_message(tox1, (const uint8_t *)STATUS_MESSAGE, sizeof(STATUS_MESSAGE),
&err_n); &err_n);
ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %d\n", err_n); ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %d\n", err_n);
@ -99,13 +79,7 @@ static void test_set_status_message(void)
do { do {
tox_iterate(tox1, nullptr); tox_iterate(tox1, nullptr);
tox_iterate(tox2, &status_updated);
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
Tox_Events *events = tox_events_iterate(tox2, true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch2, events, &status_updated);
tox_events_free(events);
c_sleep(ITERATION_INTERVAL); c_sleep(ITERATION_INTERVAL);
} while (!status_updated); } while (!status_updated);
@ -118,8 +92,6 @@ static void test_set_status_message(void)
printf("test_set_status_message succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); printf("test_set_status_message succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
tox_dispatch_free(dispatch2);
tox_kill(tox1); tox_kill(tox1);
tox_kill(tox2); tox_kill(tox2);
} }

View File

@ -18,7 +18,7 @@
// Set to true to produce an msgpack file at /tmp/test.mp. // Set to true to produce an msgpack file at /tmp/test.mp.
static const bool want_dump_events = false; static const bool want_dump_events = false;
static void handle_events_friend_message(const Tox_Event_Friend_Message *event, void *user_data) static void handle_events_friend_message(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data)
{ {
bool *success = (bool *)user_data; bool *success = (bool *)user_data;
@ -84,7 +84,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
} }
bool success = false; bool success = false;
tox_dispatch_invoke(dispatch, events, &success); tox_dispatch_invoke(dispatch, events, toxes[1], &success);
print_events(sys, events); print_events(sys, events);
if (success) { if (success) {
@ -169,9 +169,22 @@ static void test_tox_events(void)
} }
} }
static void fake_test_unpack(void)
{
// TODO(Green-Sky): add proper unpack tests and/or implement ngc events
(void)tox_group_privacy_state_unpack;
(void)tox_group_privacy_state_unpack;
(void)tox_group_voice_state_unpack;
(void)tox_group_topic_lock_unpack;
(void)tox_group_join_fail_unpack;
(void)tox_group_mod_event_unpack;
(void)tox_group_exit_type_unpack;
}
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
test_tox_events(); test_tox_events();
fake_test_unpack();
return 0; return 0;
} }

View File

@ -26,27 +26,16 @@
#define TOX_LOCALHOST "127.0.0.1" #define TOX_LOCALHOST "127.0.0.1"
#endif #endif
typedef struct State {
uint32_t to_comp;
Tox *tox;
} State;
static bool enable_broken_tests = false; static bool enable_broken_tests = false;
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{ {
State *state = (State *)userdata; if (*((uint32_t *)userdata) != 974536) {
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *message = tox_event_friend_request_get_message(event);
const uint32_t message_length = tox_event_friend_request_get_message_length(event);
if (state->to_comp != 974536) {
return; return;
} }
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) { if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
tox_friend_add_norequest(state->tox, public_key, nullptr); tox_friend_add_norequest(m, public_key, nullptr);
} }
} }
@ -57,7 +46,7 @@ static uint16_t tcp_relay_port = 33448;
static void test_many_clients_tcp(void) static void test_many_clients_tcp(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
long long unsigned int cur_time = time(nullptr); long long unsigned int cur_time = time(nullptr);
Tox *toxes[NUM_TOXES_TCP]; Tox *toxes[NUM_TOXES_TCP];
@ -84,7 +73,7 @@ static void test_many_clients_tcp(void)
continue; continue;
} }
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
tox_events_init(toxes[i]); tox_callback_friend_request(toxes[i], accept_friend_request);
uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(toxes[0], dpk); tox_self_get_dht_id(toxes[0], dpk);
Tox_Err_Bootstrap error; Tox_Err_Bootstrap error;
@ -96,11 +85,6 @@ static void test_many_clients_tcp(void)
tox_options_free(opts); tox_options_free(opts);
} }
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr);
tox_events_callback_friend_request(dispatch, accept_friend_request);
struct { struct {
uint16_t tox1; uint16_t tox1;
uint16_t tox2; uint16_t tox2;
@ -147,18 +131,12 @@ loop_top:
} }
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(toxes[i], &to_comp);
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
State state = {to_comp, toxes[i]};
tox_dispatch_invoke(dispatch, events, &state);
tox_events_free(events);
} }
c_sleep(50); c_sleep(50);
} }
tox_dispatch_free(dispatch);
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_kill(toxes[i]); tox_kill(toxes[i]);
} }
@ -170,7 +148,7 @@ loop_top:
static void test_many_clients_tcp_b(void) static void test_many_clients_tcp_b(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
long long unsigned int cur_time = time(nullptr); long long unsigned int cur_time = time(nullptr);
Tox *toxes[NUM_TOXES_TCP]; Tox *toxes[NUM_TOXES_TCP];
@ -189,7 +167,7 @@ static void test_many_clients_tcp_b(void)
index[i] = i + 1; index[i] = i + 1;
toxes[i] = tox_new_log(opts, nullptr, &index[i]); toxes[i] = tox_new_log(opts, nullptr, &index[i]);
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
tox_events_init(toxes[i]); tox_callback_friend_request(toxes[i], accept_friend_request);
uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk);
ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr), ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr),
@ -201,11 +179,6 @@ static void test_many_clients_tcp_b(void)
tox_options_free(opts); tox_options_free(opts);
} }
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr);
tox_events_callback_friend_request(dispatch, accept_friend_request);
struct { struct {
uint16_t tox1; uint16_t tox1;
uint16_t tox2; uint16_t tox2;
@ -259,18 +232,12 @@ loop_top:
} }
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(toxes[i], &to_comp);
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
State state = {to_comp, toxes[i]};
tox_dispatch_invoke(dispatch, events, &state);
tox_events_free(events);
} }
c_sleep(30); c_sleep(30);
} }
tox_dispatch_free(dispatch);
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_kill(toxes[i]); tox_kill(toxes[i]);
} }
@ -278,6 +245,7 @@ loop_top:
printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time); printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time);
} }
static void tox_suite(void) static void tox_suite(void)
{ {
/* Each tox connects to a single tox TCP */ /* Each tox connects to a single tox TCP */

View File

@ -13,25 +13,20 @@
#include "auto_test_support.h" #include "auto_test_support.h"
#include "check_compat.h" #include "check_compat.h"
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata) static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{ {
Tox *tox = (Tox *)userdata; if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
tox_friend_add_norequest(m, public_key, nullptr);
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
const uint8_t *message = tox_event_friend_request_get_message(event);
const uint32_t message_length = tox_event_friend_request_get_message_length(event);
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
tox_friend_add_norequest(tox, public_key, nullptr);
} }
} }
#define TCP_TEST_NUM_TOXES 90 #define TCP_TEST_NUM_TOXES 90
#define TCP_TEST_NUM_FRIENDS 50 #define TCP_TEST_NUM_FRIENDS 50
static void test_many_clients(void) static void test_many_clients(void)
{ {
const Random *rng = os_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
time_t cur_time = time(nullptr); time_t cur_time = time(nullptr);
Tox *toxes[TCP_TEST_NUM_TOXES]; Tox *toxes[TCP_TEST_NUM_TOXES];
@ -41,14 +36,9 @@ static void test_many_clients(void)
index[i] = i + 1; index[i] = i + 1;
toxes[i] = tox_new_log(nullptr, nullptr, &index[i]); toxes[i] = tox_new_log(nullptr, nullptr, &index[i]);
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
tox_events_init(toxes[i]); tox_callback_friend_request(toxes[i], accept_friend_request);
} }
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
ck_assert(dispatch != nullptr);
tox_events_callback_friend_request(dispatch, accept_friend_request);
struct { struct {
uint16_t tox1; uint16_t tox1;
uint16_t tox2; uint16_t tox2;
@ -122,17 +112,12 @@ loop_top:
} }
for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) {
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; tox_iterate(toxes[i], nullptr);
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
tox_dispatch_invoke(dispatch, events, toxes[i]);
tox_events_free(events);
} }
c_sleep(50); c_sleep(50);
} }
tox_dispatch_free(dispatch);
for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) { for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) {
tox_kill(toxes[i]); tox_kill(toxes[i]);
} }

View File

@ -1,9 +0,0 @@
#include "../toxcore/tox.h"
#include "../toxcore/ccompat.h"
int main(void)
{
tox_kill(tox_new(nullptr, nullptr));
return 0;
}

View File

@ -23,6 +23,7 @@
#define TEST_STOP_RESUME_PAYLOAD 1 #define TEST_STOP_RESUME_PAYLOAD 1
#define TEST_PAUSE_RESUME_SEND 1 #define TEST_PAUSE_RESUME_SEND 1
#define ck_assert_call_control(a, b, c) do { \ #define ck_assert_call_control(a, b, c) do { \
Toxav_Err_Call_Control cc_err; \ Toxav_Err_Call_Control cc_err; \
bool ok = toxav_call_control(a, b, c, &cc_err); \ bool ok = toxav_call_control(a, b, c, &cc_err); \
@ -33,6 +34,7 @@
ck_assert(cc_err == TOXAV_ERR_CALL_CONTROL_OK); \ ck_assert(cc_err == TOXAV_ERR_CALL_CONTROL_OK); \
} while (0) } while (0)
typedef struct { typedef struct {
bool incoming; bool incoming;
uint32_t state; uint32_t state;
@ -44,6 +46,7 @@ static void clear_call_control(CallControl *cc)
*cc = empty; *cc = empty;
} }
/** /**
* Callbacks * Callbacks
*/ */
@ -86,6 +89,7 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
} }
} }
/** /**
* Iterate helper * Iterate helper
*/ */
@ -203,6 +207,7 @@ static void test_av_flows(void)
c_sleep(20); c_sleep(20);
} }
{ {
Toxav_Err_New error; Toxav_Err_New error;
alice_av = toxav_new(alice, &error); alice_av = toxav_new(alice, &error);

View File

@ -74,6 +74,7 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
} }
} }
/** /**
* Iterate helper * Iterate helper
*/ */
@ -298,6 +299,7 @@ static void test_av_three_calls(void)
} }
} }
do { do {
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(alice, nullptr); tox_iterate(alice, nullptr);

View File

@ -17,14 +17,10 @@ typedef struct State {
#include "auto_test_support.h" #include "auto_test_support.h"
static void typing_callback(const Tox_Event_Friend_Typing *event, void *user_data) static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *user_data)
{ {
const AutoTox *autotox = (AutoTox *)user_data; const AutoTox *autotox = (AutoTox *)user_data;
State *state = (State *)autotox->state; State *state = (State *)autotox->state;
//const uint32_t friend_number = tox_event_friend_typing_get_friend_number(event);
const bool typing = tox_event_friend_typing_get_typing(event);
state->friend_is_typing = typing; state->friend_is_typing = typing;
} }
@ -32,7 +28,7 @@ static void test_typing(AutoTox *autotoxes)
{ {
time_t cur_time = time(nullptr); time_t cur_time = time(nullptr);
tox_events_callback_friend_typing(autotoxes[1].dispatch, &typing_callback); tox_callback_friend_typing(autotoxes[1].tox, &typing_callback);
tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr); tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr);
do { do {

View File

@ -48,8 +48,8 @@ function(_make_version_script target)
endfunction() endfunction()
option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF) option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF)
if((WIN32 AND NOT MINGW) OR APPLE) if(WIN32 OR APPLE)
# Windows and macOS don't have this linker functionality. # Windows and OSX don't have this linker functionality.
set(STRICT_ABI OFF) set(STRICT_ABI OFF)
endif() endif()

View File

@ -1295,6 +1295,15 @@ HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80 HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that # documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will # are dynamically created via JavaScript. If disabled, the navigation index will
@ -1941,6 +1950,14 @@ LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered, # path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the # it will be relative to the LATEX_OUTPUT directory. If left blank the
@ -2570,19 +2587,3 @@ GENERATE_LEGEND = YES
# The default value is: YES. # The default value is: YES.
DOT_CLEANUP = YES DOT_CLEANUP = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser for more accurate parsing at the cost of reduced performance.
# This can be particularly helpful with template rich C++ code for which
# doxygen's built-in parser lacks the necessary type information.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the clang parser with
# the path to the directory containing a file called compile_commands.json.
# This file is the compilation database containing the options used when the
# source files were built. This is equivalent to specifying the -p option to a
# clang tool, such as clang-check. These options will then be passed to the
# parser. Any options specified with CLANG_OPTIONS will be added as well.
CLANG_DATABASE_PATH = _build

View File

@ -2,122 +2,77 @@ Group chats.
Note: we assume everyone in the chat trusts each other. Note: we assume everyone in the chat trusts each other.
These group chats work by temporarily adding the 4 "closest" people defined by a These group chats work by temporarily adding the 4 "closest" people defined by a distance function
distance function in group.c in order to form a circle of connected peers. These in group.c in order to form a circle of connected peers. These peers then relay messages to each other.
peers then relay messages to each other.
A friend invites another friend to a group chat by sending them an invite packet. The friend either ignores
the invite or responds with a response packet if he wants to join the chat. The friend invite contains the type
of groupchat (text only, A/V) the friend is being invited to.
A friend invites another friend to a group chat by sending them an invite
packet. The friend either ignores the invite or responds with a response packet
if he wants to join the chat. The friend invite contains the type of groupchat
(text only, A/V) the friend is being invited to.
TODO(irungentoo): write more of this. TODO(irungentoo): write more of this.
## Protocol ## Protocol
Invite packets: Invite packets:
Invite packet:
### Invite packet:
```
[uint8_t id 96][uint8_t id 0][uint16_t group chat number][33 bytes group chat identifier[1 byte type][32 bytes id]] [uint8_t id 96][uint8_t id 0][uint16_t group chat number][33 bytes group chat identifier[1 byte type][32 bytes id]]
```
### Response packet Response packet
```
[uint8_t id 96][uint8_t id 1][uint16_t group chat number(local)][uint16_t group chat number to join][33 bytes group chat identifier[1 byte type][32 bytes id]] [uint8_t id 96][uint8_t id 1][uint16_t group chat number(local)][uint16_t group chat number to join][33 bytes group chat identifier[1 byte type][32 bytes id]]
```
### Peer online packet:
``` Peer online packet:
[uint8_t id 97][uint16_t group chat number (local)][33 bytes group chat identifier[1 byte type][32 bytes id]] [uint8_t id 97][uint16_t group chat number (local)][33 bytes group chat identifier[1 byte type][32 bytes id]]
```
### Peer leave packet: Peer leave packet:
```
[uint8_t id 98][uint16_t group chat number][uint8_t id 1] [uint8_t id 98][uint16_t group chat number][uint8_t id 1]
```
### Peer query packet: Peer query packet:
```
[uint8_t id 98][uint16_t group chat number][uint8_t id 8] [uint8_t id 98][uint16_t group chat number][uint8_t id 8]
```
### Peer response packet: Peer response packet:
[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]]
``` Title response packet:
[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]]
```
### Title response packet:
```
[uint8_t id 98][uint16_t group chat number][uint8_t id 10][title] [uint8_t id 98][uint16_t group chat number][uint8_t id 10][title]
```
### Message packets: Message packets:
```
[uint8_t id 99][uint16_t group chat number][uint16_t peer number][uint32_t message number][uint8_t with a value representing id of message][data] [uint8_t id 99][uint16_t group chat number][uint16_t peer number][uint32_t message number][uint8_t with a value representing id of message][data]
```
### Lossy Message packets: Lossy Message packets:
```
[uint8_t id 199][uint16_t group chat number][uint16_t peer number][uint16_t message number][uint8_t with a value representing id of message][data] [uint8_t id 199][uint16_t group chat number][uint16_t peer number][uint16_t message number][uint8_t with a value representing id of message][data]
```
## Group chat types: Group chat types:
0: text
1: AV
- 0: text
- 1: AV
Note: the message number is increased by 1 for each sent message. Note: the message number is increased by 1 for each sent message.
## message ids: message ids:
0 - ping
### 0 - ping sent every ~60 seconds by every peer.
No data.
sent every ~60 seconds by every peer. No data.
### 16 - new_peer
16 - new_peer
Tell everyone about a new peer in the chat. Tell everyone about a new peer in the chat.
```
[uint16_t peer_num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key] [uint16_t peer_num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key]
```
### 17 - kill_peer 17 - kill_peer
```
[uint16_t peer_num] [uint16_t peer_num]
```
### 48 - name change 48 - name change
```
[uint8_t name[namelen]] [uint8_t name[namelen]]
```
### 49 - groupchat title change 49 - groupchat title change
```
[uint8_t title[titlelen]] [uint8_t title[titlelen]]
```
### 64 - chat message 64 - chat message
```
[uint8_t message[messagelen]] [uint8_t message[messagelen]]
```
### 65 - action (/me) 65 - action (/me)
```
[uint8_t message[messagelen]] [uint8_t message[messagelen]]
```

View File

@ -0,0 +1,51 @@
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
# Minimal requirements
There are some minimal requirements to contribute to ``tox.h``:
* unix environment
* ``astyle`` ``>=2.03``
* [``apidsl``](https://github.com/TokTok/apidsl) (you can use provided service with curl instead)
## Quick way
If you want to do it quickly and you don't have time for anything other than copypasting commands, you should have ``curl`` installed.
1. Make sure that you have ``curl`` and ``>=astyle-2.03`` installed
2. Modify [``tox.api.h``](/toxcore/tox.api.h)
3. Run command below ↓
Command to run from ``toxcore`` directory (quick way, involves using curl):
```bash
# For tox.h:
curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \
< toxcore/tox.api.h \
| astyle --options=other/astyle/astylerc \
> toxcore/tox.h
# For toxav.h:
curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \
< toxav/toxav.api.h \
| astyle --options=other/astyle/astylerc \
> toxav/toxav.h
```
You may want to make sure with ``git diff`` that changes made in ``tox.h`` reflect changes in ``tox.in.h``.
And you're done.
## Manually
If you prefer to have more control over what is happening, there are steps below:
1. Install [``apidsl``](https://github.com/TokTok/apidsl)
2. Install ``astyle``, version 2.03 or later.
3. Modify [``tox.api.h``](/toxcore/tox.api.h)
4. Use ``apidsl`` ``??``
5. Parse generated ``tox.h`` with astyle, minimal command for it would be:
```bash
astyle --options=other/astyle/astylerc toxcore/tox.h
```
**Always pass output from ``apidsl`` through astyle.**

View File

@ -8,36 +8,38 @@
phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port); phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port);
``` ```
function initializes sample phone. `_listen_port` and `_send_port` are variables function initializes sample phone. _listen_port and _send_port are variables only meant
only meant for local testing. You will not have to do anything regarding to that for local testing. You will not have to do anything regarding to that since
since everything will be started within a messenger. everything will be started within a messenger.
Phone requires one msi session and two rtp sessions (one for audio and one for
video). Phone requires one msi session and two rtp sessions ( one for audio and one for
video ).
``` ```
msi_session_t* msi_init_session( void* _core_handler, const uint8_t* _user_agent ); msi_session_t* msi_init_session( void* _core_handler, const uint8_t* _user_agent );
``` ```
initializes msi session. Params: initializes msi session.
Params:
``` ```
void* _core_handler - pointer to an object handling networking, void* _core_handler - pointer to an object handling networking,
const uint8_t* _user_agent - string describing phone client version. const uint8_t* _user_agent - string describing phone client version.
``` ```
Return value: `msi_session_t*` - pointer to a newly created msi session handler. Return value:
msi_session_t* - pointer to a newly created msi session handler.
### `msi_session_t` reference: ### msi_session_t reference:
How to handle msi session: Controlling is done via callbacks and action How to handle msi session:
handlers. First register callbacks for every state/action received and make sure Controlling is done via callbacks and action handlers.
NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every First register callbacks for every state/action received and make sure
callback is being called directly from event loop. You can find examples in NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every callback is being called
phone.c. directly from event loop. You can find examples in phone.c.
Register callbacks:
Register callbacks:
``` ```
void msi_register_callback_call_started ( MCALLBACK ); void msi_register_callback_call_started ( MCALLBACK );
void msi_register_callback_call_canceled ( MCALLBACK ); void msi_register_callback_call_canceled ( MCALLBACK );
@ -53,9 +55,10 @@ void msi_register_callback_recv_error ( MCALLBACK );
void msi_register_callback_requ_timeout ( MCALLBACK ); void msi_register_callback_requ_timeout ( MCALLBACK );
``` ```
MCALLBACK is defined as: `void (*callback) (void* _arg)` `msi_session_t*` MCALLBACK is defined as: void (*callback) (void* _arg)
handler is being thrown as `_arg` so you can use that and `_agent_handler` to msi_session_t* handler is being thrown as \_arg so you can use that and \_agent_handler to get to your own phone handler
get to your own phone handler directly from callback. directly from callback.
Actions: Actions:
@ -63,93 +66,80 @@ Actions:
int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms ); int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms );
``` ```
Sends call invite. Before calling/sending invite `msi_session_t::_friend_id` is Sends call invite. Before calling/sending invite msi_session_t::_friend_id is needed to be set or else
needed to be set or else it will not work. `_call_type` is type of the call ( it will not work. _call_type is type of the call ( Audio/Video ) and _timeoutms is how long
Audio/Video ) and `_timeoutms` is how long will poll wait until request is will poll wait until request is terminated.
terminated.
``` ```
int msi_hangup ( msi_session_t* _session ); int msi_hangup ( msi_session_t* _session );
``` ```
Hangs up active call Hangs up active call
``` ```
int msi_answer ( msi_session_t* _session, call_type _call_type ); int msi_answer ( msi_session_t* _session, call_type _call_type );
``` ```
Answer incoming call. _call_type set's callee call type.
Answer incoming call. `_call_type` set's callee call type.
``` ```
int msi_cancel ( msi_session_t* _session ); int msi_cancel ( msi_session_t* _session );
``` ```
Cancel current request. Cancel current request.
``` ```
int msi_reject ( msi_session_t* _session ); int msi_reject ( msi_session_t* _session );
``` ```
Reject incoming call. Reject incoming call.
### Now for rtp: ### Now for rtp:
You will need 2 sessions; one for audio one for video. You start them with: You will need 2 sessions; one for audio one for video.
You start them with:
``` ```
rtp_session_t* rtp_init_session ( int _max_users, int _multi_session ); rtp_session_t* rtp_init_session ( int _max_users, int _multi_session );
``` ```
Params: Params:
``` ```
int _max_users - max users. -1 if undefined int _max_users - max users. -1 if undefined
int _multi_session - any positive number means uses multi session; -1 if not. int _multi_session - any positive number means uses multi session; -1 if not.
``` ```
Return value: Return value:
``` ```
rtp_session_t* - pointer to a newly created rtp session handler. rtp_session_t* - pointer to a newly created rtp session handler.
``` ```
### How to handle rtp session: ### How to handle rtp session:
Take a look at Take a look at
``` ```
void* phone_handle_media_transport_poll ( void* _hmtc_args_p ) in phone.c void* phone_handle_media_transport_poll ( void* _hmtc_args_p ) in phone.c
``` ```
on example. Basically what you do is just receive a message via: on example. Basically what you do is just receive a message via:
``` ```
struct rtp_msg_s* rtp_recv_msg ( rtp_session_t* _session ); struct rtp_msg_s* rtp_recv_msg ( rtp_session_t* _session );
``` ```
and then you use payload within the `rtp_msg_s` struct. Don't forget to and then you use payload within the rtp_msg_s struct. Don't forget to deallocate it with:
deallocate it with: void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg );
`void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg );`
Receiving should be thread safe so don't worry about that. Receiving should be thread safe so don't worry about that.
When you capture and encode a payload you want to send it ( obviously ). When you capture and encode a payload you want to send it ( obviously ).
first create a new message with: first create a new message with:
``` ```
struct rtp_msg_s* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length ); struct rtp_msg_s* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length );
``` ```
and then send it with: and then send it with:
``` ```
int rtp_send_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg, void* _core_handler ); int rtp_send_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg, void* _core_handler );
``` ```
`_core_handler` is the same network handler as in `msi_session_s` struct. _core_handler is the same network handler as in msi_session_s struct.
## A/V initialization: ## A/V initialization:
``` ```
int init_receive_audio(codec_state *cs); int init_receive_audio(codec_state *cs);
int init_receive_video(codec_state *cs); int init_receive_video(codec_state *cs);
@ -166,62 +156,39 @@ In the future, VP8 should be used directly and ffmpeg should be dropped from the
The variable bps is the required bitrate in bits per second. The variable bps is the required bitrate in bits per second.
``` ```
### A/V encoding/decoding:
### A/V encoding/decoding:
``` ```
void *encode_video_thread(void *arg); void *encode_video_thread(void *arg);
``` ```
Spawns the video encoding thread. The argument should hold a pointer to a codec_state.
Spawns the video encoding thread. The argument should hold a pointer to a This function should only be called if video encoding is supported (when init_send_video returns 1).
`codec_state`. This function should only be called if video encoding is Each video frame gets encoded into a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe is encoded.
supported (when `init_send_video` returns 1). Each video frame gets encoded into
a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe
is encoded.
``` ```
void *encode_audio_thread(void *arg); void *encode_audio_thread(void *arg);
``` ```
Spawns the audio encoding thread. The argument should hold a pointer to a codec_state.
Spawns the audio encoding thread. The argument should hold a pointer to a This function should only be called if audio encoding is supported (when init_send_audio returns 1).
`codec_state`. This function should only be called if audio encoding is Audio frames are read from the selected audio capture device during initialisation. This audio capturing can be rerouted to a different device on the fly.
supported (when `init_send_audio` returns 1). Audio frames are read from the Each audio frame is encoded into a packet, and sent via RTP. All audio frames have the same amount of samples, which is defined in AV_codec.h.
selected audio capture device during initialisation. This audio capturing can be
rerouted to a different device on the fly. Each audio frame is encoded into a
packet, and sent via RTP. All audio frames have the same amount of samples,
which is defined in `AV_codec.h`.
``` ```
int video_decoder_refresh(codec_state *cs, int width, int height); int video_decoder_refresh(codec_state *cs, int width, int height);
``` ```
Sets the SDL window dimensions and creates a pixel buffer with the requested size. It also creates a scaling context, which will be used to convert the input image format to YUV420P.
Sets the SDL window dimensions and creates a pixel buffer with the requested
size. It also creates a scaling context, which will be used to convert the input
image format to YUV420P.
``` ```
void *decode_video_thread(void *arg); void *decode_video_thread(void *arg);
``` ```
Spawns a video decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised video decoder.
Spawns a video decoding thread. The argument should hold a pointer to a This function reads video packets and feeds them to the video decoder. If the video frame's resolution has changed, video_decoder_refresh() is called. Afterwards, the frame is displayed on the SDL window.
`codec_state`. The `codec_state` is assumed to contain a successfully
initialised video decoder. This function reads video packets and feeds them to
the video decoder. If the video frame's resolution has changed,
`video_decoder_refresh()` is called. Afterwards, the frame is displayed on the
SDL window.
``` ```
void *decode_audio_thread(void *arg); void *decode_audio_thread(void *arg);
``` ```
Spawns an audio decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised audio decoder.
All received audio packets are pushed into a jitter buffer and are reordered. If there is a missing packet, or a packet has arrived too late, it is treated as a lost packet and the audio decoder is informed of the packet loss. The audio decoder will then try to reconstruct the lost packet, based on information from previous packets.
Audio is played on the default OpenAL output device.
Spawns an audio decoding thread. The argument should hold a pointer to a
`codec_state`. The `codec_state` is assumed to contain a successfully
initialised audio decoder. All received audio packets are pushed into a jitter
buffer and are reordered. If there is a missing packet, or a packet has arrived
too late, it is treated as a lost packet and the audio decoder is informed of
the packet loss. The audio decoder will then try to reconstruct the lost packet,
based on information from previous packets. Audio is played on the default
OpenAL output device.
If you have any more qustions/bug reports/feature request contact the following If you have any more qustions/bug reports/feature request contact the following users on the irc channel #tox-dev on irc.freenode.net:
users on the irc channel #tox-dev on irc.freenode.net: For RTP and MSI: mannol For RTP and MSI: mannol
For audio and video: Martijnvdc For audio and video: Martijnvdc

View File

@ -3,29 +3,29 @@
This document describes the "minpgc" simple persistent conferences This document describes the "minpgc" simple persistent conferences
implementation of PR #1069. implementation of PR #1069.
Many of the ideas derive from isotoxin's persistent conferences implementation, Many of the ideas derive from isotoxin's persistent conferences
PR #826. implementation, PR #826.
## Specification of changes from pre-existing conference specification ## Specification of changes from pre-existing conference specification
We add one new packet type: We add one new packet type:
Rejoin Conference packet Rejoin Conference packet
| Length | Contents | | Length | Contents |
| :----- | :-------------------- | |:-------|:--------------------------------|
| `1` | `uint8_t` (0x64) | | `1` | `uint8_t` (0x64) |
| `33` | Group chat identifier | | `33` | Group chat identifier |
A peer times out from a group if it has been inactive for 60s. When a peer times
out, we flag it as _frozen_. Frozen peers are disregarded for all purposes
except those discussed below - in particular no packets are sent to them except
as described below, they are omitted from the peer lists sent to the client or
in a Peer Response packet, and they are not considered when determining closest
peers for establishing direct connections.
A peer is considered to be active if we receive a group message or Rejoin packet A peer times out from a group if it has been inactive for 60s. When a peer
from it, or a New Peer message for it. times out, we flag it as _frozen_. Frozen peers are disregarded for all
purposes except those discussed below - in particular no packets are sent to
them except as described below, they are omitted from the peer lists sent to
the client or in a Peer Response packet, and they are not considered when
determining closest peers for establishing direct connections.
A peer is considered to be active if we receive a group message or Rejoin
packet from it, or a New Peer message for it.
If a frozen peer is seen to be active, we remove its 'frozen' flag and send a If a frozen peer is seen to be active, we remove its 'frozen' flag and send a
Name group message. (We can hold off on sending this message until the next Name group message. (We can hold off on sending this message until the next
@ -40,83 +40,77 @@ message. (This is current behaviour; it's mentioned here because it's important
and not currently mentioned in the spec.) and not currently mentioned in the spec.)
If we receive a Rejoin packet from a peer we update its DHT pubkey, add a If we receive a Rejoin packet from a peer we update its DHT pubkey, add a
temporary groupchat connection for the peer, and, once the connection is online, temporary groupchat connection for the peer, and, once the connection is
send out a New Peer message announcing the peer, and a Name message. online, send out a New Peer message announcing the peer, and a Name message.
Whenever we make a new friend connection, we check if the public key is that of Whenever we make a new friend connection, we check if the public key is that
any frozen peer. If so, we send it a Rejoin packet, add a temporary groupchat of any frozen peer. If so, we send it a Rejoin packet, add a temporary
connection for it, and, once the connection is online, send the peer a Peer groupchat connection for it, and, once the connection is online, send the
Query packet. peer a Peer Query packet.
We do the same with a peer when we are setting it as frozen if we have a friend We do the same with a peer when we are setting it as frozen if we have a
connection to it. friend connection to it.
The temporary groupchat connections established in sending and handling Rejoin The temporary groupchat connections established in sending and handling Rejoin
packets are not immediately operational (because group numbers are not known); packets are not immediately operational (because group numbers are not known);
rather, an Online packet is sent when we handle a Rejoin packet. rather, an Online packet is sent when we handle a Rejoin packet.
When a connection is set as online as a result of an Online packet, we ping the When a connection is set as online as a result of an Online packet, we ping
group. the group.
When processing the reply to a Peer Query, we update the DHT pubkey of an When processing the reply to a Peer Query, we update the DHT pubkey of an
existing peer if and only if it is frozen or has not had its DHT pubkey updated existing peer if and only if it is frozen or has not had its DHT pubkey
since it last stopped being frozen. updated since it last stopped being frozen.
When we receive a Title Response packet, we set the title if it has never been When we receive a Title Response packet, we set the title if it has never been
set or if at some point since it was last set, there were no unfrozen peers set or if at some point since it was last set, there were no unfrozen peers
(except us). (except us).
## Discussion ## Discussion
### Overview ### Overview
The intention is to recover seamlessly from splits in the group, the most
common form of which is a single peer temporarily losing all connectivity.
The intention is to recover seamlessly from splits in the group, the most common To see how this works, first note that groups (even before the changes
form of which is a single peer temporarily losing all connectivity. discussed here) have the property that for a group to be connected in the
sense that any peer will receive the messages of any other peer and have them
To see how this works, first note that groups (even before the changes discussed in their peerlist, it is necessary and sufficient that there is a path of
here) have the property that for a group to be connected in the sense that any direct group connections between any two peers.
peer will receive the messages of any other peer and have them in their
peerlist, it is necessary and sufficient that there is a path of direct group
connections between any two peers.
Now suppose the group is split into two connected components, with each member Now suppose the group is split into two connected components, with each member
of one component frozen according to the members of the other. Suppose there are of one component frozen according to the members of the other. Suppose there
two peers, one in each component, which are using the above protocol, and are two peers, one in each component, which are using the above protocol, and
suppose they establish a friend connection. Then each will rejoin the other, suppose they establish a friend connection. Then each will rejoin the other,
forming a direct group connection. Hence the whole group will become connected forming a direct group connection. Hence the whole group will become connected
(even if all other peers are using the unmodified protocol). (even if all other peers are using the unmodified protocol).
The Peer Query packet sent on rejoining hastens this process. The Peer Query packet sent on rejoining hastens this process.
Peers who leave the group during a split will not be deleted by all peers after Peers who leave the group during a split will not be deleted by all peers
the merge - but they will be set as frozen due to ping timeouts, which is after the merge - but they will be set as frozen due to ping timeouts, which
sufficient. is sufficient.
### Titles ### Titles
If we have a split into components each containing multiple peers, and the
If we have a split into components each containing multiple peers, and the title title is changed in one component, then peers will continue to disagree on the
is changed in one component, then peers will continue to disagree on the title title after the split. Short of a complicated voting system, this seems the
after the split. Short of a complicated voting system, this seems the only only reasonable behaviour.
reasonable behaviour.
### Implementation notes ### Implementation notes
Although I've described the logic in terms of an 'frozen' flag, it might
Although I've described the logic in terms of an 'frozen' flag, it might actually make more sense in the implementation to have a separate list for
actually make more sense in the implementation to have a separate list for
frozen peers. frozen peers.
## Saving ## Saving
Saving is implemented by simply saving all live groups with their group numbers Saving is implemented by simply saving all live groups with their group numbers
and full peer info for all peers. On reload, all peers are set as frozen. and full peer info for all peers. On reload, all peers are set as frozen.
Clients needs to support this by understanding that groups may exist on Clients needs to support this by understanding that groups may exist on
start-up. Clients should call `tox_conference_get_chatlist` to obtain them. A start-up. Clients should call `tox_conference_get_chatlist` to obtain them. A
group which is deleted (with `tox_conference_delete`) is removed permanently and group which is deleted (with `tox_conference_delete`) is removed permanently
will not be saved. and will not be saved.
## Limitations ## Limitations
If a peer disconnects from the group for a period short enough that group If a peer disconnects from the group for a period short enough that group
timeouts do not occur, and a name change occurs during this period, then the timeouts do not occur, and a name change occurs during this period, then the
name change will never be propagated. name change will never be propagated.
@ -126,8 +120,9 @@ requesting missed group messages. But this is considered out of scope of this
PR. PR.
If a peer changes its DHT pubkey, the change might not be properly propagated If a peer changes its DHT pubkey, the change might not be properly propagated
under various circumstances - in particular, if connections do not go down long under various circumstances - in particular, if connections do not go down
enough for the peer to become frozen. long enough for the peer to become frozen.
One way to deal with this would be to add a group message announcing the sending One way to deal with this would be to add a group message announcing the
peer's current DHT pubkey, and treat it analogously to the Name message. sending peer's current DHT pubkey, and treat it analogously to the Name
message.

View File

@ -50,6 +50,7 @@ static const char *motd_str = ""; //Change this to anything within 256 bytes(but
#define PORT 33445 #define PORT 33445
static bool manage_keys(DHT *dht) static bool manage_keys(DHT *dht)
{ {
enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE }; enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
@ -60,7 +61,7 @@ static bool manage_keys(DHT *dht)
if (keys_file != nullptr) { if (keys_file != nullptr) {
/* If file was opened successfully -- load keys, /* If file was opened successfully -- load keys,
otherwise save new keys */ otherwise save new keys */
const size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
if (read_size != KEYS_SIZE) { if (read_size != KEYS_SIZE) {
printf("Error while reading the key file\nExiting.\n"); printf("Error while reading the key file\nExiting.\n");
@ -125,7 +126,7 @@ static void print_log(void *context, Logger_Level level, const char *file, int l
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (argc == 2 && tox_strncasecmp(argv[1], "-h", 3) == 0) { if (argc == 2 && !tox_strncasecmp(argv[1], "-h", 3)) {
printf("Usage (connected) : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]); printf("Usage (connected) : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]);
printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]); printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]);
return 0; return 0;
@ -133,7 +134,7 @@ int main(int argc, char *argv[])
/* let user override default by cmdline */ /* let user override default by cmdline */
bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */ bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
const int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled); int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
if (argvoffset < 0) { if (argvoffset < 0) {
return 1; return 1;
@ -150,9 +151,9 @@ int main(int argc, char *argv[])
logger_callback_log(logger, print_log, nullptr, nullptr); logger_callback_log(logger, print_log, nullptr, nullptr);
} }
const Random *rng = os_random(); const Random *rng = system_random();
const Network *ns = os_network(); const Network *ns = system_network();
const Memory *mem = os_memory(); const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
const uint16_t start_port = PORT; const uint16_t start_port = PORT;
@ -164,12 +165,11 @@ int main(int argc, char *argv[])
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
#ifdef DHT_NODE_EXTRA_PACKETS #ifdef DHT_NODE_EXTRA_PACKETS
bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str) + 1); bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str)+1);
#endif #endif
if (onion == nullptr || forwarding == nullptr || onion_a == nullptr) { if (!(onion && forwarding && onion_a)) {
printf("Something failed to initialize.\n"); printf("Something failed to initialize.\n");
// cppcheck-suppress resourceLeak
return 1; return 1;
} }
@ -178,19 +178,17 @@ int main(int argc, char *argv[])
perror("Initialization"); perror("Initialization");
if (!manage_keys(dht)) { if (!manage_keys(dht)) {
// cppcheck-suppress resourceLeak
return 1; return 1;
} }
printf("Public key: "); printf("Public key: ");
#ifdef TCP_RELAY_ENABLED #ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3 #define NUM_PORTS 3
const uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding);
if (tcp_s == nullptr) { if (tcp_s == nullptr) {
printf("TCP server failed to initialize.\n"); printf("TCP server failed to initialize.\n");
// cppcheck-suppress resourceLeak
return 1; return 1;
} }
@ -201,7 +199,6 @@ int main(int argc, char *argv[])
if (file == nullptr) { if (file == nullptr) {
printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename); printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename);
// cppcheck-suppress resourceLeak
return 1; return 1;
} }
@ -229,8 +226,8 @@ int main(int argc, char *argv[])
const uint16_t port = net_htons((uint16_t)port_conv); const uint16_t port = net_htons((uint16_t)port_conv);
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]); uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1], int res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
ipv6enabled, port, bootstrap_key); ipv6enabled, port, bootstrap_key);
free(bootstrap_key); free(bootstrap_key);
if (!res) { if (!res) {
@ -239,17 +236,17 @@ int main(int argc, char *argv[])
} }
} }
bool is_waiting_for_dht_connection = true; int is_waiting_for_dht_connection = 1;
uint64_t last_lan_discovery = 0; uint64_t last_lan_discovery = 0;
const Broadcast_Info *broadcast = lan_discovery_init(ns); const Broadcast_Info *broadcast = lan_discovery_init(ns);
while (true) { while (1) {
mono_time_update(mono_time); mono_time_update(mono_time);
if (is_waiting_for_dht_connection && dht_isconnected(dht)) { if (is_waiting_for_dht_connection && dht_isconnected(dht)) {
printf("Connected to other bootstrap node successfully.\n"); printf("Connected to other bootstrap node successfully.\n");
is_waiting_for_dht_connection = false; is_waiting_for_dht_connection = 0;
} }
do_dht(dht); do_dht(dht);

View File

@ -3,20 +3,17 @@
CHECKS="*" CHECKS="*"
ERRORS="*" ERRORS="*"
# Can't fix this, because winsock has different HANDLE type than posix.
# Still good to occasionally look at.
ERRORS="$ERRORS,-google-readability-casting"
# Need to investigate or disable and document these. # Need to investigate or disable and document these.
# ========================================================= # =========================================================
# TODO(iphydf): Fix these. # TODO(iphydf): Fix these.
ERRORS="$ERRORS,-cert-err34-c" ERRORS="$ERRORS,-cert-err34-c"
ERRORS="$ERRORS,-readability-suspicious-call-argument" ERRORS="$ERRORS,-readability-suspicious-call-argument"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto"
CHECKS="$CHECKS,-bugprone-incorrect-roundings"
# TODO(iphydf): Fix this by making more functions set error code enums. # TODO(iphydf): Fix once cimple 0.0.19 is released.
CHECKS="$CHECKS,-google-readability-casting"
# TODO(iphydf): Fix these.
CHECKS="$CHECKS,-bugprone-switch-missing-default-case" CHECKS="$CHECKS,-bugprone-switch-missing-default-case"
# TODO(iphydf): We might want some of these. For the ones we don't want, add a # TODO(iphydf): We might want some of these. For the ones we don't want, add a
@ -33,22 +30,17 @@ CHECKS="$CHECKS,-misc-no-recursion"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables" CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables"
# TODO(iphydf): Probably fix these. # TODO(iphydf): Probably fix these.
CHECKS="$CHECKS,-cert-err33-c,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers" CHECKS="$CHECKS,-cert-err33-c"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-magic-numbers"
CHECKS="$CHECKS,-readability-magic-numbers"
# TODO(iphydf): We're using a lot of macros for constants. Should we convert
# all of them to enum?
CHECKS="$CHECKS,-modernize-macro-to-enum"
# Documented disabled checks. We don't want these for sure. # Documented disabled checks. We don't want these for sure.
# ========================================================= # =========================================================
# We want to decay many arrays to pointers. In C, we do that all the time.
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay"
# enum{} breaks comparisons and arithmetic in C++.
CHECKS="$CHECKS,-modernize-macro-to-enum"
# For most things, we do want this, but for some we want to ensure (with msan)
# that struct members are actually initialised with useful non-zero values.
# Initialising them by default takes away that validation.
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init"
# https://stackoverflow.com/questions/58672959/why-does-clang-tidy-say-vsnprintf-has-an-uninitialized-va-list-argument # https://stackoverflow.com/questions/58672959/why-does-clang-tidy-say-vsnprintf-has-an-uninitialized-va-list-argument
CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized" CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized"
@ -123,7 +115,8 @@ CHECKS="$CHECKS,-readability-redundant-control-flow"
# ^ # ^
# Trip the checker, which is true, because of integer promotion, but also not # Trip the checker, which is true, because of integer promotion, but also not
# very helpful as a diagnostic. # very helpful as a diagnostic.
CHECKS="$CHECKS,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions" CHECKS="$CHECKS,-bugprone-narrowing-conversions"
CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions"
# Mistakenly thinks that # Mistakenly thinks that
# const int a = 0, b = 1; # const int a = 0, b = 1;
@ -142,51 +135,9 @@ CHECKS="$CHECKS,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-con
# - Turning 'a' and 'b' into pre-processor macros is the only option left, but # - Turning 'a' and 'b' into pre-processor macros is the only option left, but
# #defines and #undefs in the middle of a function hurt the readability and # #defines and #undefs in the middle of a function hurt the readability and
# are less idiomatic than simply using 'const int'. # are less idiomatic than simply using 'const int'.
CHECKS="$CHECKS,-cert-dcl03-c,-hicpp-static-assert,-misc-static-assert" CHECKS="$CHECKS,-cert-dcl03-c"
CHECKS="$CHECKS,-hicpp-static-assert"
# Doesn't consider use of preprocessor macros as needing a header, breaking CHECKS="$CHECKS,-misc-static-assert"
# struct definitions that depend on size macros from e.g. crypto_core.h.
CHECKS="$CHECKS,-misc-include-cleaner"
# A bunch of checks only valid for C++, we turn off for C.
# =========================================================
# We don't use Google's int typedefs.
CHECKS="$CHECKS,-google-runtime-int"
# We write C code, so we use C arrays.
CHECKS="$CHECKS,-cppcoreguidelines-avoid-c-arrays,-hicpp-avoid-c-arrays,-modernize-avoid-c-arrays"
# C loops are ok. This one tells us to use range-for.
CHECKS="$CHECKS,-modernize-loop-convert"
# No auto in C.
CHECKS="$CHECKS,-hicpp-use-auto,-modernize-use-auto"
# Only C style casts in C.
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-cstyle-cast"
# We use malloc (for now), and MISRA checks this too.
CHECKS="$CHECKS,-cppcoreguidelines-no-malloc,-hicpp-no-malloc"
# No owning_ptr<> in C.
CHECKS="$CHECKS,-cppcoreguidelines-owning-memory"
# void foo(void) is good in C.
CHECKS="$CHECKS,-modernize-redundant-void-arg"
# No using-typedefs in C.
CHECKS="$CHECKS,-modernize-use-using"
# No namespaces in C.
CHECKS="$CHECKS,-misc-use-anonymous-namespace"
# No trailing return type in C.
CHECKS="$CHECKS,-modernize-use-trailing-return-type"
# No <cstdint> and friends in C.
CHECKS="$CHECKS,-hicpp-deprecated-headers,-modernize-deprecated-headers"
# We use varargs for logging (we could reconsider, but right now we do).
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cert-dcl50-cpp"
# We do want to use the array index operator, even when the index is non-constant.
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-constant-array-index"
# We don't want to use pointer arithmetic, but this one includes array index
# operators, which we do want to use.
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-pointer-arithmetic"
# Can't use constexpr, yet. C will have it eventually, but it'll be years
# until we can use it across all the compilers.
CHECKS="$CHECKS,-cppcoreguidelines-macro-usage"
# These are all very C++ and/or LLVM specific.
CHECKS="$CHECKS,-llvmlibc-*"
set -eux set -eux
@ -203,7 +154,7 @@ copy_files() {
find "${DIRS[@]}" \ find "${DIRS[@]}" \
-maxdepth 1 -type d -exec mkdir -p "$1/{}" \; -maxdepth 1 -type d -exec mkdir -p "$1/{}" \;
find "${DIRS[@]}" \ find "${DIRS[@]}" \
-maxdepth 1 -name "*.[ch]" -exec cp "{}" "$1/{}" \; -maxdepth 1 -name "*.c" -exec cp "{}" "$1/{}" \;
} }
run() { run() {
@ -215,7 +166,7 @@ run() {
ls .clang-tidy ls .clang-tidy
copy_files a copy_files a
if ! find "${DIRS[@]}" \ if ! find "${DIRS[@]}" \
-maxdepth 1 -name "*.[ch]" -print0 \ -maxdepth 1 -name "*.c" -print0 \
| xargs -0 -n15 -P"$(nproc)" clang-tidy \ | xargs -0 -n15 -P"$(nproc)" clang-tidy \
-p="$PWD/_build" \ -p="$PWD/_build" \
--extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \ --extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \
@ -233,6 +184,5 @@ run() {
} }
cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
sed -i -e 's/-std=c11/-xc++/' _build/compile_commands.json
. other/analysis/variants.sh . other/analysis/variants.sh

View File

@ -1,6 +1,5 @@
# Bracket Style Options # Bracket Style Options
--style=kr --style=kr
--attach-namespaces
# Tab Options # Tab Options
--indent=spaces=4 --indent=spaces=4
@ -10,21 +9,15 @@
# Padding Options # Padding Options
--pad-header --pad-header
--break-blocks
--pad-oper --pad-oper
# Not supported in restyled's astyle.
#--unpad-brackets
--unpad-paren --unpad-paren
--align-pointer=name --align-pointer=name
--align-reference=name --align-reference=name
# Disabled because it causes very large changes and it's unclear whether we
# want all of those.
#--squeeze-ws
# Formatting Options # Formatting Options
--add-braces
--convert-tabs --convert-tabs
--max-code-length=200 --max-code-length=120
--attach-return-type
# Other Options # Other Options
--preserve-date --preserve-date

View File

@ -2,6 +2,36 @@
set -ex set -ex
SOURCE_DIR="$1"
ASTYLE="$2"
# Go to the source root.
if [ -z "$SOURCE_DIR" ]; then
SOURCE_DIR=.
fi
cd "$SOURCE_DIR"
if [ -z "$ASTYLE" ] || ! which "$ASTYLE"; then
ASTYLE=astyle
fi
if ! which "$ASTYLE"; then
# If we couldn't find or install an astyle binary, don't do anything.
echo "Could not find an astyle binary; please install astyle."
exit 1
fi
readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' ')')"
CC_SOURCES+=(toxcore/crypto_core.c)
CC_SOURCES+=(toxcore/ping_array.c)
for bin in clang-format-11 clang-format-7 clang-format-6.0 clang-format-5.0 clang-format; do
if which "$bin"; then
"$bin" -i -style='{BasedOnStyle: Google, ColumnLimit: 100}' "${CC_SOURCES[@]}"
break
fi
done
FIND="find ." FIND="find ."
FIND="$FIND '(' -name '*.[ch]' ')'" FIND="$FIND '(' -name '*.[ch]' ')'"
FIND="$FIND -and -not -name '*.api.h'" FIND="$FIND -and -not -name '*.api.h'"
@ -10,15 +40,7 @@ FIND="$FIND -and -not -wholename './third_party/*'"
FIND="$FIND -and -not -wholename './toxencryptsave/crypto_pwhash*'" FIND="$FIND -and -not -wholename './toxencryptsave/crypto_pwhash*'"
readarray -t C_SOURCES <<<"$(eval "$FIND")" readarray -t C_SOURCES <<<"$(eval "$FIND")"
readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' -or -name '*.hh' ')')"
#CC_SOURCES+=(toxcore/crypto_core.c)
#CC_SOURCES+=(toxcore/ping_array.c)
# Format C++ sources with clang-format. "$ASTYLE" -n --options=other/astyle/astylerc "${C_SOURCES[@]}"
clang-format -i "${CC_SOURCES[@]}"
# Format C sources with astyle. We can't use clang-format, because it strongly
# messes up formatting of non_null annotations.
astyle -n --options=other/astyle/astylerc "${C_SOURCES[@]}"
git diff --color=always --exit-code git diff --color=always --exit-code

View File

@ -48,9 +48,8 @@ RUN CC=clang cmake -B_build -H. \
# Verify checksum from dev-built binary, so we can be sure Docker Hub doesn't # Verify checksum from dev-built binary, so we can be sure Docker Hub doesn't
# mess with your binaries. # mess with your binaries.
COPY other/bootstrap_daemon/docker/tox-bootstrapd.sha256 other/bootstrap_daemon/docker/ COPY other/bootstrap_daemon/docker/tox-bootstrapd.sha256 other/bootstrap_daemon/docker/
ARG CHECK=sha256sum RUN SHA256="$(sha256sum /usr/local/bin/tox-bootstrapd)" && \
RUN SHA256="$("$CHECK" /usr/local/bin/tox-bootstrapd)" && \ (sha256sum -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
("$CHECK" -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
(echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" && \ (echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" && \
false)) false))

View File

@ -1 +1 @@
af58a125e5c80d7a19bc7f32868c1edfdf80f366e3bf778728961a50ce63ee26 /usr/local/bin/tox-bootstrapd 0b904988d79b9576bb88c6c7316d107b5a61bd6119a0992ebd7c1fa43db70abf /usr/local/bin/tox-bootstrapd

View File

@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
/** /**
* Prints --help message * Prints --help message
*/ */
@ -47,8 +48,8 @@ static void print_help(void)
} }
Cli_Status handle_command_line_arguments( Cli_Status handle_command_line_arguments(
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
bool *run_in_foreground) bool *run_in_foreground)
{ {
if (argc < 2) { if (argc < 2) {
log_write(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n"); log_write(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");

View File

@ -32,7 +32,7 @@ typedef enum Cli_Status {
* @param run_in_foreground Sets to the provided by the user foreground option. * @param run_in_foreground Sets to the provided by the user foreground option.
*/ */
Cli_Status handle_command_line_arguments( Cli_Status handle_command_line_arguments(
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend, int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
bool *run_in_foreground); bool *run_in_foreground);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_COMMAND_LINE_ARGUMENTS_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_COMMAND_LINE_ARGUMENTS_H

View File

@ -44,13 +44,13 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS); log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS);
log_write(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS); log_write(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS);
const uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS}; uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS};
// Check to avoid calling malloc(0) later on // Check to avoid calling malloc(0) later on
// NOLINTNEXTLINE, clang-tidy: error: suspicious comparison of 'sizeof(expr)' to a constant [bugprone-sizeof-expression,-warnings-as-errors] // NOLINTNEXTLINE, clang-tidy: error: suspicious comparison of 'sizeof(expr)' to a constant [bugprone-sizeof-expression,-warnings-as-errors]
static_assert(sizeof(default_ports) > 0, "At least one default TCP relay port should be provided"); static_assert(sizeof(default_ports) > 0, "At least one default TCP relay port should be provided");
const size_t default_ports_count = sizeof(default_ports) / sizeof(*default_ports); const size_t default_ports_count = sizeof(default_ports)/sizeof(*default_ports);
for (size_t i = 0; i < default_ports_count; ++i) { for (size_t i = 0; i < default_ports_count; ++i) {
log_write(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]); log_write(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]);
@ -58,10 +58,6 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
// Similar procedure to the one of reading config file below // Similar procedure to the one of reading config file below
*tcp_relay_ports = (uint16_t *)malloc(default_ports_count * sizeof(uint16_t)); *tcp_relay_ports = (uint16_t *)malloc(default_ports_count * sizeof(uint16_t));
if (*tcp_relay_ports == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
return;
}
for (size_t i = 0; i < default_ports_count; ++i) { for (size_t i = 0; i < default_ports_count; ++i) {
@ -77,8 +73,10 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
++*tcp_relay_port_count; ++*tcp_relay_port_count;
} }
// No ports, so we free the array. // The loop above skips invalid ports, so we adjust the allocated memory size
if (*tcp_relay_port_count == 0) { if ((*tcp_relay_port_count) > 0) {
*tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t));
} else {
free(*tcp_relay_ports); free(*tcp_relay_ports);
*tcp_relay_ports = nullptr; *tcp_relay_ports = nullptr;
} }
@ -92,7 +90,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
return; return;
} }
const int config_port_count = config_setting_length(ports_array); int config_port_count = config_setting_length(ports_array);
if (config_port_count == 0) { if (config_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS); log_write(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS);
@ -100,10 +98,6 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
} }
*tcp_relay_ports = (uint16_t *)malloc(config_port_count * sizeof(uint16_t)); *tcp_relay_ports = (uint16_t *)malloc(config_port_count * sizeof(uint16_t));
if (*tcp_relay_ports == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
return;
}
for (int i = 0; i < config_port_count; ++i) { for (int i = 0; i < config_port_count; ++i) {
config_setting_t *elem = config_setting_get_elem(ports_array, i); config_setting_t *elem = config_setting_get_elem(ports_array, i);
@ -131,16 +125,18 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
++*tcp_relay_port_count; ++*tcp_relay_port_count;
} }
// No ports, so we free the array. // The loop above skips invalid ports, so we adjust the allocated memory size
if (*tcp_relay_port_count == 0) { if ((*tcp_relay_port_count) > 0) {
*tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t));
} else {
free(*tcp_relay_ports); free(*tcp_relay_ports);
*tcp_relay_ports = nullptr; *tcp_relay_ports = nullptr;
} }
} }
bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, int get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port,
int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd) uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd)
{ {
config_t cfg; config_t cfg;
@ -160,7 +156,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) { if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg); config_destroy(&cfg);
return false; return 0;
} }
// Get port // Get port
@ -181,10 +177,6 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
const size_t pid_file_path_len = strlen(tmp_pid_file) + 1; const size_t pid_file_path_len = strlen(tmp_pid_file) + 1;
*pid_file_path = (char *)malloc(pid_file_path_len); *pid_file_path = (char *)malloc(pid_file_path_len);
if (*pid_file_path == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
return false;
}
memcpy(*pid_file_path, tmp_pid_file, pid_file_path_len); memcpy(*pid_file_path, tmp_pid_file, pid_file_path_len);
// Get keys file location // Get keys file location
@ -198,10 +190,6 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
const size_t keys_file_path_len = strlen(tmp_keys_file) + 1; const size_t keys_file_path_len = strlen(tmp_keys_file) + 1;
*keys_file_path = (char *)malloc(keys_file_path_len); *keys_file_path = (char *)malloc(keys_file_path_len);
if (*keys_file_path == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
return false;
}
memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len); memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len);
// Get IPv6 option // Get IPv6 option
@ -235,7 +223,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
*enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY; *enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY;
} }
if (*enable_tcp_relay != 0) { if (*enable_tcp_relay) {
parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count); parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count);
} else { } else {
*tcp_relay_port_count = 0; *tcp_relay_port_count = 0;
@ -249,7 +237,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
*enable_motd = DEFAULT_ENABLE_MOTD; *enable_motd = DEFAULT_ENABLE_MOTD;
} }
if (*enable_motd != 0) { if (*enable_motd) {
// Get MOTD // Get MOTD
const char *tmp_motd; const char *tmp_motd;
@ -259,8 +247,8 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
tmp_motd = DEFAULT_MOTD; tmp_motd = DEFAULT_MOTD;
} }
const size_t tmp_motd_length = strlen(tmp_motd) + 1; size_t tmp_motd_length = strlen(tmp_motd) + 1;
const size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length; size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length;
*motd = (char *)malloc(motd_length); *motd = (char *)malloc(motd_length);
snprintf(*motd, motd_length, "%s", tmp_motd); snprintf(*motd, motd_length, "%s", tmp_motd);
} }
@ -271,14 +259,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH, *pid_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH, *keys_file_path);
log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port); log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT, *port);
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 != 0 ? "true" : "false"); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6, *enable_ipv6 ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback != 0 ? "true" : "false"); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery != 0 ? "true" : "false"); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay != 0 ? "true" : "false"); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
// Show info about tcp ports only if tcp relay is enabled // Show info about tcp ports only if tcp relay is enabled
if (*enable_tcp_relay != 0) { if (*enable_tcp_relay) {
if (*tcp_relay_port_count == 0) { if (*tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n"); log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
} else { } else {
@ -290,13 +278,13 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
} }
} }
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd != 0 ? "true" : "false"); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
if (*enable_motd != 0) { if (*enable_motd) {
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd); log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
} }
return true; return 1;
} }
/** /**
@ -314,12 +302,8 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
return nullptr; return nullptr;
} }
const size_t len = strlen(hex_string) / 2; size_t len = strlen(hex_string) / 2;
uint8_t *ret = (uint8_t *)malloc(len); uint8_t *ret = (uint8_t *)malloc(len);
if (ret == nullptr) {
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
return nullptr;
}
const char *pos = hex_string; const char *pos = hex_string;
@ -332,7 +316,7 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
return ret; return ret;
} }
bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6) int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
{ {
const char *const NAME_BOOTSTRAP_NODES = "bootstrap_nodes"; const char *const NAME_BOOTSTRAP_NODES = "bootstrap_nodes";
@ -347,7 +331,7 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) { if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg); config_destroy(&cfg);
return false; return 0;
} }
config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES); config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES);
@ -356,13 +340,13 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n", log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n",
NAME_BOOTSTRAP_NODES); NAME_BOOTSTRAP_NODES);
config_destroy(&cfg); config_destroy(&cfg);
return true; return 1;
} }
if (config_setting_length(node_list) == 0) { if (config_setting_length(node_list) == 0) {
log_write(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n"); log_write(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n");
config_destroy(&cfg); config_destroy(&cfg);
return true; return 1;
} }
int bs_port; int bs_port;
@ -373,15 +357,15 @@ bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6
int i = 0; int i = 0;
while (config_setting_length(node_list) != 0) { while (config_setting_length(node_list)) {
bool address_resolved; int address_resolved;
uint8_t *bs_public_key_bin; uint8_t *bs_public_key_bin;
node = config_setting_get_elem(node_list, 0); node = config_setting_get_elem(node_list, 0);
if (node == nullptr) { if (node == nullptr) {
config_destroy(&cfg); config_destroy(&cfg);
return false; return 0;
} }
// Check that all settings are present // Check that all settings are present
@ -437,5 +421,5 @@ next:
config_destroy(&cfg); config_destroy(&cfg);
return true; return 1;
} }

View File

@ -19,19 +19,19 @@
* also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports` * also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports`
* and also `motd` iff `enable_motd` is set. * and also `motd` iff `enable_motd` is set.
* *
* @return true on success, * @return 1 on success,
* false on failure, doesn't modify any data pointed by arguments. * 0 on failure, doesn't modify any data pointed by arguments.
*/ */
bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port, int get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port,
int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay, int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd); uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd);
/** /**
* Bootstraps off nodes listed in the config file. * Bootstraps off nodes listed in the config file.
* *
* @return true on success, some or no bootstrap nodes were added * @return 1 on success, some or no bootstrap nodes were added
* false on failure, an error occurred while parsing the config file. * 0 on failure, an error occurred while parsing the config file.
*/ */
bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6); int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_H

View File

@ -58,6 +58,7 @@ bool log_close(void)
return true; return true;
} }
bool log_write(LOG_LEVEL level, const char *format, ...) bool log_write(LOG_LEVEL level, const char *format, ...)
{ {
if (current_backend == INVALID_BACKEND) { if (current_backend == INVALID_BACKEND) {

View File

@ -12,7 +12,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "../../../toxcore/attributes.h" #include "../../../toxcore/ccompat.h"
typedef enum LOG_BACKEND { typedef enum LOG_BACKEND {
LOG_BACKEND_STDOUT, LOG_BACKEND_STDOUT,
@ -47,4 +47,5 @@ bool log_close(void);
*/ */
bool log_write(LOG_LEVEL level, const char *format, ...) GNU_PRINTF(2, 3); bool log_write(LOG_LEVEL level, const char *format, ...) GNU_PRINTF(2, 3);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_H

View File

@ -10,11 +10,10 @@
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
#include <stdarg.h>
#include "../../../toxcore/attributes.h"
#include "log.h" #include "log.h"
#include <stdarg.h>
void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0); void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H

View File

@ -51,7 +51,7 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
va_list args2; va_list args2;
va_copy(args2, args); va_copy(args2, args);
const int size = vsnprintf(nullptr, 0, format, args2); int size = vsnprintf(nullptr, 0, format, args2);
va_end(args2); va_end(args2);
assert(size >= 0); assert(size >= 0);
@ -61,9 +61,6 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
} }
char *buf = (char *)malloc(size + 1); char *buf = (char *)malloc(size + 1);
if (buf == nullptr) {
return;
}
vsnprintf(buf, size + 1, format, args); vsnprintf(buf, size + 1, format, args);
syslog(log_backend_syslog_level(level), "%s", buf); syslog(log_backend_syslog_level(level), "%s", buf);

View File

@ -10,13 +10,12 @@
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H #ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H #define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
#include <stdarg.h>
#include "../../../toxcore/attributes.h"
#include "log.h" #include "log.h"
#include <stdarg.h>
void log_backend_syslog_open(void); void log_backend_syslog_open(void);
void log_backend_syslog_close(void); void log_backend_syslog_close(void);
void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0); void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H #endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H

View File

@ -50,6 +50,7 @@
#include "global.h" #include "global.h"
#include "log.h" #include "log.h"
static void sleep_milliseconds(uint32_t ms) static void sleep_milliseconds(uint32_t ms)
{ {
struct timespec req; struct timespec req;
@ -60,10 +61,10 @@ static void sleep_milliseconds(uint32_t ms)
// Uses the already existing key or creates one if it didn't exist // Uses the already existing key or creates one if it didn't exist
// //
// returns true on success // returns 1 on success
// false on failure - no keys were read or stored // 0 on failure - no keys were read or stored
static bool manage_keys(DHT *dht, const char *keys_file_path) static int manage_keys(DHT *dht, const char *keys_file_path)
{ {
enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE }; enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
uint8_t keys[KEYS_SIZE]; uint8_t keys[KEYS_SIZE];
@ -76,7 +77,7 @@ static bool manage_keys(DHT *dht, const char *keys_file_path)
if (read_size != KEYS_SIZE) { if (read_size != KEYS_SIZE) {
fclose(keys_file); fclose(keys_file);
return false; return 0;
} }
dht_set_self_public_key(dht, keys); dht_set_self_public_key(dht, keys);
@ -88,21 +89,21 @@ static bool manage_keys(DHT *dht, const char *keys_file_path)
keys_file = fopen(keys_file_path, "wb"); keys_file = fopen(keys_file_path, "wb");
if (keys_file == nullptr) { if (!keys_file) {
return false; return 0;
} }
const size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); const size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
if (write_size != KEYS_SIZE) { if (write_size != KEYS_SIZE) {
fclose(keys_file); fclose(keys_file);
return false; return 0;
} }
} }
fclose(keys_file); fclose(keys_file);
return true; return 1;
} }
// Prints public key // Prints public key
@ -163,6 +164,7 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path)
return CLI_STATUS_ERROR; return CLI_STATUS_ERROR;
} }
// Change the current working directory // Change the current working directory
if ((chdir("/")) < 0) { if ((chdir("/")) < 0) {
log_write(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
@ -220,7 +222,7 @@ int main(int argc, char *argv[])
bool run_in_foreground = false; bool run_in_foreground = false;
// Choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal // Choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal
LOG_BACKEND log_backend = isatty(STDOUT_FILENO) != 0 ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG; LOG_BACKEND log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
log_open(log_backend); log_open(log_backend);
switch (handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground)) { switch (handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground)) {
@ -281,7 +283,7 @@ int main(int argc, char *argv[])
free(pid_file_path); free(pid_file_path);
IP ip; IP ip;
ip_init(&ip, enable_ipv6 != 0); ip_init(&ip, enable_ipv6);
Logger *logger = logger_new(); Logger *logger = logger_new();
@ -290,16 +292,16 @@ int main(int argc, char *argv[])
} }
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Memory *mem = os_memory(); const Memory *mem = system_memory();
const Random *rng = os_random(); const Random *rng = system_random();
const Network *ns = os_network(); const Network *ns = system_network();
Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
if (enable_ipv6 != 0 && enable_ipv4_fallback != 0) { if (enable_ipv6 && enable_ipv4_fallback) {
log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
enable_ipv6 = 0; enable_ipv6 = 0;
ip_init(&ip, enable_ipv6 != 0); ip_init(&ip, enable_ipv6);
net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
@ -334,7 +336,7 @@ int main(int argc, char *argv[])
mono_time_update(mono_time); mono_time_update(mono_time);
DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery != 0); DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery);
if (dht == nullptr) { if (dht == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
@ -394,7 +396,7 @@ int main(int argc, char *argv[])
Onion *onion = new_onion(logger, mem, mono_time, rng, dht); Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
if (onion == nullptr) { if (!onion) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
kill_gca(group_announce); kill_gca(group_announce);
kill_announcements(announce); kill_announcements(announce);
@ -411,7 +413,7 @@ int main(int argc, char *argv[])
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
if (onion_a == nullptr) { if (!onion_a) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
kill_gca(group_announce); kill_gca(group_announce);
kill_onion(onion); kill_onion(onion);
@ -429,7 +431,7 @@ int main(int argc, char *argv[])
gca_onion_init(group_announce, onion_a); gca_onion_init(group_announce, onion_a);
if (enable_motd != 0) { if (enable_motd) {
if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) { if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n"); log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
free(motd); free(motd);
@ -472,7 +474,7 @@ int main(int argc, char *argv[])
TCP_Server *tcp_server = nullptr; TCP_Server *tcp_server = nullptr;
if (enable_tcp_relay != 0) { if (enable_tcp_relay) {
if (tcp_relay_port_count == 0) { if (tcp_relay_port_count == 0) {
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
@ -488,7 +490,7 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6 != 0, tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6,
tcp_relay_port_count, tcp_relay_ports, tcp_relay_port_count, tcp_relay_ports,
dht_get_self_secret_key(dht), onion, forwarding); dht_get_self_secret_key(dht), onion, forwarding);
@ -504,7 +506,7 @@ int main(int argc, char *argv[])
assert(rlim_suggested >= rlim_min); assert(rlim_suggested >= rlim_min);
if (getrlimit(RLIMIT_NOFILE, &limit) == 0) { if (!getrlimit(RLIMIT_NOFILE, &limit)) {
if (limit.rlim_cur < limit.rlim_max) { if (limit.rlim_cur < limit.rlim_max) {
// Some systems have a hard limit of over 1000000 open file descriptors, so let's cap it at something reasonable // Some systems have a hard limit of over 1000000 open file descriptors, so let's cap it at something reasonable
// so that we don't set it to an unreasonably high number. // so that we don't set it to an unreasonably high number.
@ -513,7 +515,7 @@ int main(int argc, char *argv[])
} }
} }
if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < rlim_min) { if (!getrlimit(RLIMIT_NOFILE, &limit) && limit.rlim_cur < rlim_min) {
log_write(LOG_LEVEL_WARNING, log_write(LOG_LEVEL_WARNING,
"Current limit on the number of files this process can open (%ju) is rather low for the proper functioning of the TCP server. " "Current limit on the number of files this process can open (%ju) is rather low for the proper functioning of the TCP server. "
"Consider raising the limit to at least %ju or the recommended %ju. " "Consider raising the limit to at least %ju or the recommended %ju. "
@ -535,7 +537,7 @@ int main(int argc, char *argv[])
} }
} }
if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6 != 0)) { if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n"); log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
} else { } else {
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
@ -557,11 +559,11 @@ int main(int argc, char *argv[])
uint64_t last_lan_discovery = 0; uint64_t last_lan_discovery = 0;
const uint16_t net_htons_port = net_htons(start_port); const uint16_t net_htons_port = net_htons(start_port);
bool waiting_for_dht_connection = true; int waiting_for_dht_connection = 1;
Broadcast_Info *broadcast = nullptr; Broadcast_Info *broadcast = nullptr;
if (enable_lan_discovery != 0) { if (enable_lan_discovery) {
broadcast = lan_discovery_init(ns); broadcast = lan_discovery_init(ns);
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
} }
@ -576,25 +578,25 @@ int main(int argc, char *argv[])
// Prevent the signal handler from being called again before it returns // Prevent the signal handler from being called again before it returns
sigfillset(&sa.sa_mask); sigfillset(&sa.sa_mask);
if (sigaction(SIGINT, &sa, nullptr) != 0) { if (sigaction(SIGINT, &sa, nullptr)) {
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n"); log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
} }
if (sigaction(SIGTERM, &sa, nullptr) != 0) { if (sigaction(SIGTERM, &sa, nullptr)) {
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n"); log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
} }
while (caught_signal == 0) { while (!caught_signal) {
mono_time_update(mono_time); mono_time_update(mono_time);
do_dht(dht); do_dht(dht);
if (enable_lan_discovery != 0 && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) { if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port); lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port);
last_lan_discovery = mono_time_get(mono_time); last_lan_discovery = mono_time_get(mono_time);
} }
if (enable_tcp_relay != 0) { if (enable_tcp_relay) {
do_tcp_server(tcp_server, mono_time); do_tcp_server(tcp_server, mono_time);
} }
@ -602,7 +604,7 @@ int main(int argc, char *argv[])
if (waiting_for_dht_connection && dht_isconnected(dht)) { if (waiting_for_dht_connection && dht_isconnected(dht)) {
log_write(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n"); log_write(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n");
waiting_for_dht_connection = false; waiting_for_dht_connection = 0;
} }
sleep_milliseconds(30); sleep_milliseconds(30);

View File

@ -2,6 +2,6 @@ module github.com/TokTok/c-toxcore/other/bootstrap_daemon/websocket/websockify
go 1.17 go 1.17
require github.com/gorilla/websocket v1.5.1 require (
github.com/gorilla/websocket master
require golang.org/x/net v0.17.0 // indirect )

View File

@ -1,42 +0,0 @@
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -18,7 +18,6 @@ package main
import ( import (
"encoding/hex" "encoding/hex"
"flag" "flag"
"fmt"
"log" "log"
"net" "net"
"net/http" "net/http"
@ -105,10 +104,7 @@ func main() {
if r.Header.Get("Upgrade") == "websocket" { if r.Header.Get("Upgrade") == "websocket" {
serveWs(w, r) serveWs(w, r)
} else { } else {
w.Header().Set("Content-Type", "text/plain") http.ServeFile(w, r, r.URL.Path[1:])
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "404 Not Found")
} }
}) })
log.Fatal(http.ListenAndServe(*sourceAddr, nil)) log.Fatal(http.ListenAndServe(*sourceAddr, nil))

View File

@ -35,7 +35,7 @@ static int handle_info_request(void *object, const IP_Port *source, const uint8_
uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH]; uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH];
data[0] = BOOTSTRAP_INFO_PACKET_ID; data[0] = BOOTSTRAP_INFO_PACKET_ID;
memcpy(data + 1, &bootstrap_version, sizeof(bootstrap_version)); memcpy(data + 1, &bootstrap_version, sizeof(bootstrap_version));
const uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length; uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length;
memcpy(data + 1 + sizeof(bootstrap_version), bootstrap_motd, bootstrap_motd_length); memcpy(data + 1 + sizeof(bootstrap_version), bootstrap_motd, bootstrap_motd_length);
if (sendpacket(nc, source, data, len) == len) { if (sendpacket(nc, source, data, len) == len) {

View File

@ -1,6 +1,5 @@
################################################ ################################################
# autotools-linux # autotools-linux
FROM toxchat/c-toxcore:sources AS sources
FROM ubuntu:22.04 FROM ubuntu:22.04
RUN apt-get update && \ RUN apt-get update && \
@ -25,12 +24,7 @@ USER builder
WORKDIR /home/builder WORKDIR /home/builder
# Copy autotools-specific build scripts not present in the sources image.
# These change less frequently than the sources, thus are copied first.
COPY --chown=builder:builder . /home/builder/c-toxcore/
# Copy the sources and run the build. # Copy the sources and run the build.
COPY --chown=builder:builder --from=sources /src/ /home/builder/c-toxcore/ COPY --chown=builder:builder . /home/builder/c-toxcore/
WORKDIR /home/builder/c-toxcore WORKDIR /home/builder/c-toxcore
RUN CC=gcc .github/scripts/autotools-linux RUN CC=gcc .github/scripts/autotools-linux

View File

@ -1,12 +0,0 @@
**/*
!.github/scripts/autotools-linux
!m4/*
!configure.ac
!*.pc.in
!*.spec.in
!**/Makefile.am
!**/Makefile.inc
!docs/updates/*
!other/DHTnodes
!other/astyle/*
!other/tox.png

View File

@ -2,5 +2,4 @@
set -eux set -eux
BUILD=autotools BUILD=autotools
other/docker/sources/build docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" .
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .

View File

@ -1,4 +1,3 @@
FROM toxchat/c-toxcore:sources AS sources
FROM alpine:3.19.0 FROM alpine:3.19.0
RUN ["apk", "add", "--no-cache", \ RUN ["apk", "add", "--no-cache", \
@ -17,8 +16,6 @@ RUN ["apk", "add", "--no-cache", \
ENV CC=clang CXX=clang++ ENV CC=clang CXX=clang++
COPY --from=sources /src/ /c-toxcore/ COPY . /c-toxcore/
COPY other/analysis/run-clang-tidy other/analysis/variants.sh /c-toxcore/other/analysis/
COPY .clang-tidy /c-toxcore/
WORKDIR /c-toxcore WORKDIR /c-toxcore
RUN other/analysis/run-clang-tidy RUN other/analysis/run-clang-tidy

Some files were not shown because too many files have changed in this diff Show More