-
Notifications
You must be signed in to change notification settings - Fork 9
/
c_speak.c
221 lines (188 loc) · 7.02 KB
/
c_speak.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include "include/libcomponent.h"
#include "enet/enet.h"
#include <log.h>
#define TYPE_LOGIN 0x01
#define TYPE_REQ_SPEAK 0x02
#define TYPE_LOGOUT 0x03
#define TYPE_ACK 0x04
#define TYPE_REJ 0x05
#define MAX_CHN 5
#define MAX_CONN 5
ENetPeer *g_peers[MAX_CHN][MAX_CONN];
unsigned int g_nPeers[MAX_CHN];
static ENetAddress address;
static ENetHost * server;
bool c_init_speak_server(int port)
{
int i, j;
for(i = 0; i < MAX_CHN; i++)
{
for(j = 0; j < MAX_CONN; j++)
{
g_peers[i][j] = NULL;
}
}
if (enet_initialize () != 0)
{
spook_log(SL_ERR, "An error occurred while initializing ENet.\n");
return false;
}
spook_log(SL_INFO, "success of initializing ENet.\n");
/* Bind the server to the default localhost. */
/* A specific host address can be specified by */
/* enet_address_set_host (& address, "x.x.x.x"); */
address.host = ENET_HOST_ANY;
/* Bind the server to port 1234. */
address.port = 12345;
server = enet_host_create (& address /* the address to bind the server host to */,
1 /* allow up to 32 clients and/or outgoing connections */,
2 /* allow up to 2 channels to be used, 0 and 1 */,
0 /* assume any amount of incoming bandwidth */,
0 /* assume any amount of outgoing bandwidth */);
if (server == NULL)
{
spook_log(SL_ERR,
"An error occurred while trying to create an ENet server host.\n");
enet_deinitialize();
return false;
}
spook_log(SL_INFO,
"Successed to create an ENet server host.\n");
return true;
}
bool c_do_speak_server_handler()
{
int i;
ENetEvent event;
ENetPacket * packet;
/* Wait up to 1000 milliseconds for an event. */
if (enet_host_service (server, & event, 10) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
spook_log(SL_INFO, "A new client connected from %x:%u.\n",
event.peer -> address.host,
event.peer -> address.port);
/* Store any relevant client information here. */
event.peer -> data = 0;
break;
case ENET_EVENT_TYPE_RECEIVE:
/*
spook_log(SL_INFO,
"A packet of length %u was received on channel %u",
event.packet->dataLength,
event.channelID);
*/
if((event.peer->data == 0) && (event.channelID == 0))
{
unsigned char szReply[32];
szReply[0] = 0x01;
szReply[1] = TYPE_ACK;
packet = enet_packet_create(szReply, 2, ENET_PACKET_FLAG_RELIABLE);
if(packet)
{
for(i = 0; i < MAX_CONN; i++)
{
if(!g_peers[1][i])
{
g_peers[1][i] = event.peer;
break;
}
}
if(i == MAX_CONN)
{
enet_packet_destroy(packet);
}
else
{
if(enet_peer_send (event.peer, 0, packet) < 0)
{
g_peers[1][i] = NULL;
enet_packet_destroy(packet);
}
else
{
// c_request_video(get_video1_frame_cb,1);
if(!c_request_speak(50))
{
spook_log(SL_ERR, "call c_request_speak error");
}
event.peer->data = 1;
g_nPeers[1]++;
spook_log(SL_INFO, "Receive Login Request!");
}
}
}
}
else if(event.channelID == 1)
{
AUDIO_CHUNK *pChunk;
//@TODO: enum of AUDIO_CHUNK' size is diff on diff platform
pChunk = (AUDIO_CHUNK *)event.packet->data;
if(pChunk->len == (event.packet->dataLength - sizeof(AUDIO_CHUNK) + sizeof(struct list_head)))
{
pChunk = (AUDIO_CHUNK *)malloc(sizeof(AUDIO_CHUNK));
if(pChunk)
{
// copy the header
memcpy(pChunk, event.packet->data, sizeof(AUDIO_CHUNK));
pChunk->data = malloc(pChunk->len + 4);
if(pChunk->data)
{
memcpy(pChunk->data + 4,
event.packet->data + sizeof(AUDIO_CHUNK)-sizeof(struct list_head),
pChunk->len);
pChunk->len += 4;
*((short*)(pChunk->data)) = pChunk->sample;
*((short*)(pChunk->data + 2)) = pChunk->index;
INIT_LIST_HEAD(&pChunk->list);
if(!c_speak(pChunk))
{
spook_log(SL_ERR, "call c_speak error:len %d", pChunk->len);
}
//get_audio_chunk_cb(pChunk);
}
else
{
free(pChunk);
}
}
}
}
else
{
spook_log(SL_WARN, "Receive Unknown Request!");
enet_peer_reset (event.peer);
if(!c_end_speak())
{
spook_log(SL_ERR, "call c_end_speak error");
}
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
spook_log(SL_INFO, "%d disconected.\n", event.peer -> data);
/* Reset the peer's client information. */
event.peer -> data = NULL;
for(i = 0; i < MAX_CONN; i++)
{
if(g_peers[1][i] == event.peer)
{
g_peers[1][i] = NULL;
g_nPeers[1]--;
}
}
c_end_speak();
//c_end_video(get_video1_frame_cb,1);
}
}
return true;
}
void c_deinit_speak_server()
{
spook_log(SL_INFO, "speak quited\n");
enet_host_destroy(server);
enet_deinitialize();
}