-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmain.c
183 lines (151 loc) · 5.79 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright Edgeware AB 2020, Agile Content 2021-2022
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN64
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "elastic_frame_protocol_c_api.h"
#define TEST_MTU 300
#define TEST_DATA_SIZE 10000
char *embedd_me = "This is a embedded string";
uint8_t test_data[TEST_DATA_SIZE];
uint64_t efp_object_handle_receive;
int drop_counter = 0;
int first_frame_broken_counter = 0;
int the_context = 123;
void send_data_callback(const uint8_t *data, size_t size, uint8_t stream_id, void* ctx) {
drop_counter++;
if (drop_counter == 5) {
//Drop the ^ fragment
return;
}
int16_t result = efp_receive_fragment(efp_object_handle_receive, data, size, 0);
if (result < 0) {
printf("Error %d sending\n", result);
} else if (result > 0) {
printf("Notification %d sending\n", result);
}
}
void receive_embedded_data_callback(uint8_t *data, size_t size, uint8_t data_type, uint64_t pts, void* ctx) {
printf("Got embedded data: %zu bytes size and of type %d pts: %lu\n", size, data_type, pts);
//In this example we know it's a string, print it.
printf("Data: %s \n", data);
printf("Context: %d \n\n", *(int*)ctx);
}
void receive_data_callback(uint8_t *data,
size_t size,
uint8_t data_content,
uint8_t broken,
uint64_t pts,
uint64_t dts,
uint32_t code,
uint8_t stream_id,
uint8_t source,
uint8_t flags,
void* ctx) {
if (first_frame_broken_counter == 0 && broken) {
printf("The first frame is broken. We know that. Let's not parse it since we don't know the integrity\n");
first_frame_broken_counter++;
return;
} else if (first_frame_broken_counter == 0 && !broken) {
printf("Test failed. First frame not broken.\n");
return;
}
printf("Got this data:\n");
printf("mFrameSize: %zu\n", size);
printf("mDataContent: %d\n", data_content);
printf("mBroken: %d\n", broken);
printf("mPts: %lu\n", pts);
printf("mDts: %lu\n", dts);
printf("mCode: %d\n", code);
printf("mStreamID: %d\n", stream_id);
printf("mSource: %d\n", source);
printf("mFlags: %d\n", flags);
printf("Context: %d\n\n", *(int*)ctx);
int test_failed = 0;
if (size != TEST_DATA_SIZE) {
printf("Test failed. Size mismatch.\n");
test_failed = 1;
}
for (int x = 0; x < TEST_DATA_SIZE; x++) {
if (data[x] != (uint8_t) x) {
printf("Test failed. Data vector missmatch.\n");
test_failed = 1;
}
}
if (!test_failed) {
printf("C-API tests passed.\n");
}
}
int main() {
printf("EFP Version %d.%d \n", efp_get_version() >> 8, efp_get_version() & 0x00ff);
void* context=(void*)&the_context;
//EFP Send
printf("Create sender.\n");
uint64_t efp_object_handle_send = efp_init_send(TEST_MTU, &send_data_callback, context);
if (!efp_object_handle_send) {
printf("Fatal. Failed creating EFP sender");
return 1;
}
printf("Sender created.\n");
//EFP receive
printf("Create receiver.\n");
efp_object_handle_receive = efp_init_receive(30, 10, &receive_data_callback, &receive_embedded_data_callback, context, EFP_MODE_THREAD);
if (!efp_object_handle_receive) {
printf("Fatal. Failed creating EFP receiver");
return 1;
}
printf("Receiver created.\n");
//Prepare data
for (int x = 0; x < TEST_DATA_SIZE; x++) {
test_data[x] = (uint8_t) x;
}
printf("\nEmbedd data.\n\n");
size_t alloc_size = efp_add_embedded_data(NULL, (uint8_t *) embedd_me, &test_data[0], strlen(embedd_me) + 1,
TEST_DATA_SIZE, 1, 1);
uint8_t *sendThisData = (uint8_t *) malloc(alloc_size);
efp_add_embedded_data(sendThisData, (uint8_t *) embedd_me, &test_data[0], strlen(embedd_me) + 1, TEST_DATA_SIZE, 1, 1);
printf("\nTransmit data.\n\n");
//So this frame contains inline embedded payload. This is signaled using INLINE_PAYLOAD in C++ in the C-APi there are no defines so we need
//to follow the C++ api 0b00010000 == 16
//The first time we send the data. We will drop a fragment.
//The expected behaviour is that the embedded data callback should not be triggered and the
//EFP (receive_data_callback) should be called with broken set.
int16_t result = efp_send_data(efp_object_handle_send, sendThisData, alloc_size, 10, 100, 100,
EFP_CODE('A', 'V', 'C', 'C'), 2, 16);
if (result < 0) {
printf("Error %d sending\n", result);
} else if (result > 0) {
printf("Notification %d sending\n", result);
}
//This time we don't drop anything.. We should receive the embedded data and the EFP frame with broken == 0
result = efp_send_data(efp_object_handle_send, sendThisData, alloc_size, 10, 200, 200, EFP_CODE('A', 'V', 'C', 'C'),
2, 16);
if (result < 0) {
printf("Error %d sending\n", result);
} else if (result > 0) {
printf("Notification %d sending\n", result);
}
free(sendThisData);
#ifndef _WIN64
sleep(1);
#else
Sleep(1000);
#endif
result = efp_end_send(efp_object_handle_send);
if (result < 0) {
printf("Error %d efp_end\n", result);
} else if (result > 0) {
printf("Notification %d efp_end\n", result);
}
result = efp_end_receive(efp_object_handle_receive);
if (result < 0) {
printf("Error %d efp_end\n", result);
} else if (result > 0) {
printf("Notification %d efp_end\n", result);
}
return 0;
}