2 * This file is part of the Nice GLib ICE library.
4 * (C) 2010 Collabora Ltd.
5 * Contact: Youness Alaoui
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Youness Alaoui, Collabora Ltd.
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
44 #include "pseudotcp.h"
46 PseudoTcpSocket
*left
;
47 PseudoTcpSocket
*right
;
48 GMainLoop
*mainloop
= NULL
;
54 guint right_clock
= 0;
56 static void adjust_clock (PseudoTcpSocket
*sock
);
58 static void write_to_sock (PseudoTcpSocket
*sock
)
66 len
= fread (buf
, 1, sizeof(buf
), in
);
68 g_debug ("Done reading data from file");
69 pseudo_tcp_socket_close (sock
, FALSE
);
72 wlen
= pseudo_tcp_socket_send (sock
, buf
, len
);
73 g_debug ("Sending %d bytes : %d", len
, wlen
);
77 fseek (in
, wlen
- len
, SEEK_CUR
);
78 g_debug ("Socket queue full after %d bytes written", total
);
86 static void opened (PseudoTcpSocket
*sock
, gpointer data
)
88 g_debug ("Socket %p Opened", sock
);
93 pseudo_tcp_socket_send (sock
, "abcdefghijklmnopqrstuvwxyz", 26);
94 pseudo_tcp_socket_close (sock
, FALSE
);
99 static void readable (PseudoTcpSocket
*sock
, gpointer data
)
103 g_debug ("Socket %p Readable", sock
);
106 len
= pseudo_tcp_socket_recv (sock
, buf
, sizeof(buf
));
109 g_debug ("Read %d bytes", len
);
111 if (fwrite (buf
, len
, 1, out
) == 0)
112 g_debug ("Error writing to output file");
116 g_debug ("Written %d bytes, need %d bytes", total_wrote
, total_read
);
117 if (total_wrote
>= total_read
&& feof (in
)) {
118 pseudo_tcp_socket_close (left
, FALSE
);
119 pseudo_tcp_socket_close (right
, FALSE
);
123 if (len
== 26 && strncmp (buf
, "abcdefghijklmnopqrstuvwxyz", len
) == 0) {
124 pseudo_tcp_socket_close (left
, FALSE
);
125 pseudo_tcp_socket_close (right
, FALSE
);
127 g_debug ("Error reading data.. read %d bytes : %s", len
, buf
);
135 pseudo_tcp_socket_get_error (sock
) != EWOULDBLOCK
) {
136 g_debug ("Error reading from socket : %d",
137 pseudo_tcp_socket_get_error (sock
));
144 static void writable (PseudoTcpSocket
*sock
, gpointer data
)
146 g_debug ("Socket %p Writable", sock
);
148 write_to_sock (sock
);
151 static void closed (PseudoTcpSocket
*sock
, guint32 err
, gpointer data
)
153 g_debug ("Socket %p Closed : %d", sock
, err
);
157 PseudoTcpSocket
*sock
;
162 static gboolean
notify_packet (gpointer user_data
)
164 struct notify_data
*data
= (struct notify_data
*) user_data
;
165 if (!data
->sock
|| (data
->sock
!= left
&& data
->sock
!= right
))
167 pseudo_tcp_socket_notify_packet (data
->sock
, data
->buffer
, data
->len
);
168 adjust_clock (data
->sock
);
169 g_free (data
->buffer
);
174 static PseudoTcpWriteResult
write (PseudoTcpSocket
*sock
,
175 const gchar
*buffer
, guint32 len
, gpointer user_data
)
177 struct notify_data
*data
;
178 PseudoTcpState state
;
179 int drop_rate
= rand () % 100;
180 g_object_get (sock
, "state", &state
, NULL
);
183 g_debug ("*********************Dropping packet (%d)", drop_rate
);
187 data
= g_new0 (struct notify_data
,1);
189 g_debug ("Socket %p(%d) Writing : %d bytes", sock
, state
, len
);
191 data
->buffer
= g_malloc (len
);
192 memcpy (data
->buffer
, buffer
, len
);
201 g_idle_add (notify_packet
, data
);
207 static gboolean
notify_clock (gpointer data
)
209 PseudoTcpSocket
*sock
= (PseudoTcpSocket
*)data
;
210 if (sock
!= left
&& sock
!= right
)
212 //g_debug ("Socket %p: Notifying clock", sock);
213 pseudo_tcp_socket_notify_clock (sock
);
218 static void adjust_clock (PseudoTcpSocket
*sock
)
221 if (pseudo_tcp_socket_get_next_clock (sock
, &timeout
)) {
222 //g_debug ("Socket %p: Adjuting clock to %ld ms", sock, timeout);
225 g_source_remove (left_clock
);
226 left_clock
= g_timeout_add (timeout
, notify_clock
, sock
);
228 if (right_clock
!= 0)
229 g_source_remove (right_clock
);
230 right_clock
= g_timeout_add (timeout
, notify_clock
, sock
);
233 g_debug ("Socket %p should be destroyed", sock
);
234 g_object_unref (sock
);
240 g_main_loop_quit (mainloop
);
245 int main (int argc
, char *argv
[])
247 PseudoTcpCallbacks cbs
= {NULL
, opened
, readable
, writable
, closed
, write
};
249 mainloop
= g_main_loop_new (NULL
, FALSE
);
253 pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE
);
255 left
= pseudo_tcp_socket_new (0, &cbs
);
256 right
= pseudo_tcp_socket_new (0, &cbs
);
257 g_debug ("Left: %p. Right: %p", left
, right
);
259 pseudo_tcp_socket_notify_mtu (left
, 1496);
260 pseudo_tcp_socket_notify_mtu (right
, 1496);
262 pseudo_tcp_socket_connect (left
);
264 adjust_clock (right
);
267 in
= fopen (argv
[1], "r");
268 out
= fopen (argv
[2], "w");
271 g_main_loop_run (mainloop
);