1 #include "mock_fixtures.h"
2 #include "toxext.h"
3 #include "mock_tox.h"
4 
5 #include <assert.h>
6 #include <string.h>
7 
8 static uint8_t const my_extension_uuid[16] = {};
9 static uint8_t const buf_a[TOXEXT_MAX_SEGMENT_SIZE] = { 0x00, 0x01, 0x02, 0x03 };
10 static uint8_t const buf_b[TOXEXT_MAX_SEGMENT_SIZE] = { 0xff, 0xfe, 0xfd, 0xfc };
11 static uint8_t const buf_c[TOXEXT_MAX_SEGMENT_SIZE] = { 0xfe, 0xfe, 0xfd, 0xfc };
12 static uint8_t const buf_d[TOXEXT_MAX_SEGMENT_SIZE] = { 0xfd, 0xfe, 0xfd, 0xfc };
13 
14 struct MyExtensionUser {
15 	struct ToxExtUser toxext_user;
16 	struct ToxExtExtension *extension_handle;
17 	uint8_t buf_a[TOXEXT_MAX_SEGMENT_SIZE];
18 	uint8_t buf_b[TOXEXT_MAX_SEGMENT_SIZE];
19 	uint8_t buf_c[TOXEXT_MAX_SEGMENT_SIZE];
20 	uint8_t buf_d[TOXEXT_MAX_SEGMENT_SIZE];
21 };
22 
my_extension_create_buf_request(struct ToxExtExtension * extension,uint8_t const * data,size_t size,struct ToxExtPacketList * packet)23 int my_extension_create_buf_request(struct ToxExtExtension *extension,
24 				    uint8_t const *data, size_t size,
25 				    struct ToxExtPacketList *packet)
26 {
27 	return toxext_segment_append(packet, extension, data, size);
28 }
29 
my_extension_recv_callback(struct ToxExtExtension * extension,uint32_t friend_id,void const * data_v,size_t size,void * userdata,struct ToxExtPacketList * response_packet)30 void my_extension_recv_callback(struct ToxExtExtension *extension,
31 				uint32_t friend_id, void const *data_v,
32 				size_t size, void *userdata,
33 				struct ToxExtPacketList *response_packet)
34 {
35 	(void)extension;
36 	(void)friend_id;
37 	(void)response_packet;
38 	uint8_t const *data = data_v;
39 	struct MyExtensionUser *my_extension_user = userdata;
40 
41 	uint8_t *output;
42 	switch (*data) {
43 	case 0x00:
44 		output = my_extension_user->buf_a;
45 		break;
46 	case 0xff:
47 		output = my_extension_user->buf_b;
48 		break;
49 	case 0xfe:
50 		output = my_extension_user->buf_c;
51 		break;
52 	case 0xfd:
53 		output = my_extension_user->buf_d;
54 		break;
55 	default:
56 		assert(false);
57 		return;
58 	}
59 
60 	memcpy(output, data_v, size);
61 }
62 
my_extension_neg_callback(struct ToxExtExtension * extension,uint32_t friend_id,bool compatible,void * userdata,struct ToxExtPacketList * packet)63 void my_extension_neg_callback(struct ToxExtExtension *extension,
64 			       uint32_t friend_id, bool compatible,
65 			       void *userdata, struct ToxExtPacketList *packet)
66 {
67 	assert(compatible);
68 	(void)extension;
69 	(void)friend_id;
70 	(void)userdata;
71 	(void)packet;
72 }
73 
init_my_extension_user(struct MyExtensionUser * my_extension_user)74 void init_my_extension_user(struct MyExtensionUser *my_extension_user)
75 {
76 	toxext_test_init_tox_ext_user(&my_extension_user->toxext_user);
77 	my_extension_user->extension_handle =
78 		toxext_register(my_extension_user->toxext_user.toxext,
79 				my_extension_uuid, my_extension_user,
80 				my_extension_recv_callback,
81 				my_extension_neg_callback);
82 }
83 
84 /*
85  * Tests that large buffers will be correctly split across multiple toxcore
86  * packets
87  */
main(void)88 int main(void)
89 {
90 	struct MyExtensionUser user_a;
91 	init_my_extension_user(&user_a);
92 
93 	struct MyExtensionUser user_b;
94 	init_my_extension_user(&user_b);
95 
96 	toxext_negotiate_connection(user_a.extension_handle,
97 				    user_b.toxext_user.tox_user.id);
98 
99 	tox_iterate(user_b.toxext_user.tox_user.tox,
100 		    &user_b.toxext_user.tox_user);
101 	tox_iterate(user_a.toxext_user.tox_user.tox,
102 		    &user_b.toxext_user.tox_user);
103 
104 	/* Limit sendq size to check behavior when buffer fills */
105 	tox_set_sendq_size(user_a.toxext_user.tox_user.tox, 2);
106 	tox_set_sendq_size(user_b.toxext_user.tox_user.tox, 2);
107 
108 	struct ToxExtPacketList *packet = toxext_packet_list_create(
109 		user_a.toxext_user.toxext, user_b.toxext_user.tox_user.id);
110 	int err = my_extension_create_buf_request(
111 		user_a.extension_handle, buf_a, TOXEXT_MAX_SEGMENT_SIZE, packet);
112 
113 	assert(err == TOXEXT_SUCCESS);
114 
115 	err = my_extension_create_buf_request(user_a.extension_handle, buf_b,
116 					      TOXEXT_MAX_SEGMENT_SIZE, packet);
117 
118 	assert(err == TOXEXT_SUCCESS);
119 
120 	toxext_send(packet);
121 
122 	tox_iterate(user_b.toxext_user.tox_user.tox,
123 		    &user_b.toxext_user.tox_user);
124 
125 	/*
126 	 * With 2 big buffers we expect the message to fit within two packets, so no
127 	 * toxext_iterate should be sufficient
128 	 */
129 	assert(memcmp(user_b.buf_a, buf_a, TOXEXT_MAX_SEGMENT_SIZE) == 0);
130 	assert(memcmp(user_b.buf_b, buf_b, TOXEXT_MAX_SEGMENT_SIZE) == 0);
131 
132 	/*
133 	 * Reset the buffers of user_b to ensure that the next tests are valid too
134 	 */
135 	memset(user_b.buf_a, 0, TOXEXT_MAX_SEGMENT_SIZE);
136 	memset(user_b.buf_b, 0, TOXEXT_MAX_SEGMENT_SIZE);
137 	memset(user_b.buf_c, 0, TOXEXT_MAX_SEGMENT_SIZE);
138 	memset(user_b.buf_d, 0, TOXEXT_MAX_SEGMENT_SIZE);
139 
140 	packet = toxext_packet_list_create(user_a.toxext_user.toxext,
141 					   user_b.toxext_user.tox_user.id);
142 	err = my_extension_create_buf_request(user_a.extension_handle, buf_a,
143 					      TOXEXT_MAX_SEGMENT_SIZE, packet);
144 
145 	assert(err == TOXEXT_SUCCESS);
146 
147 	err = my_extension_create_buf_request(user_a.extension_handle, buf_b,
148 					      TOXEXT_MAX_SEGMENT_SIZE, packet);
149 
150 	assert(err == TOXEXT_SUCCESS);
151 
152 	err = my_extension_create_buf_request(user_a.extension_handle, buf_c,
153 					      TOXEXT_MAX_SEGMENT_SIZE, packet);
154 
155 	assert(err == TOXEXT_SUCCESS);
156 
157 	err = my_extension_create_buf_request(user_a.extension_handle, buf_d,
158 					      TOXEXT_MAX_SEGMENT_SIZE, packet);
159 
160 	assert(err == TOXEXT_SUCCESS);
161 
162 	toxext_send(packet);
163 
164 	tox_iterate(user_b.toxext_user.tox_user.tox,
165 		    &user_b.toxext_user.tox_user);
166 
167 	/* We expect buffers a and b to be complete here but c and d to require a toxext_iterate call */
168 	assert(memcmp(user_b.buf_a, buf_a, TOXEXT_MAX_SEGMENT_SIZE) == 0);
169 	assert(memcmp(user_b.buf_b, buf_b, TOXEXT_MAX_SEGMENT_SIZE) == 0);
170 	assert(memcmp(user_b.buf_c, buf_c, TOXEXT_MAX_SEGMENT_SIZE) != 0);
171 	assert(memcmp(user_b.buf_d, buf_d, TOXEXT_MAX_SEGMENT_SIZE) != 0);
172 
173 	toxext_iterate(user_a.toxext_user.toxext);
174 	tox_iterate(user_b.toxext_user.tox_user.tox,
175 		    &user_b.toxext_user.tox_user);
176 
177 	assert(memcmp(user_b.buf_c, buf_c, TOXEXT_MAX_SEGMENT_SIZE) == 0);
178 	assert(memcmp(user_b.buf_d, buf_d, TOXEXT_MAX_SEGMENT_SIZE) == 0);
179 
180 	toxext_test_cleanup_tox_ext_user(&user_a.toxext_user);
181 	toxext_test_cleanup_tox_ext_user(&user_b.toxext_user);
182 }
183