1 /*
2  *  Copyright 2006  Serge van den Boom <svdb@stack.nl>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #define NETCONNECTION_INTERNAL
20 #include "../netplay.h"
21 #include "npconfirm.h"
22 
23 #include "types.h"
24 #include "../netmisc.h"
25 #include "../packetsenders.h"
26 
27 #include <assert.h>
28 #include <errno.h>
29 
30 int
Netplay_confirm(NetConnection * conn)31 Netplay_confirm(NetConnection *conn) {
32 	assert(handshakeMeaningful(NetConnection_getState(conn)));
33 
34 	if (conn->stateFlags.handshake.localOk) {
35 		// Already confirmed
36 		errno = EINVAL;
37 		return -1;
38 	}
39 
40 	conn->stateFlags.handshake.localOk = true;
41 
42 	if (conn->stateFlags.handshake.canceling) {
43 		// If a previous confirmation was cancelled, but the cancel
44 		// is not acknowledged yet, we don't have to send anything yet.
45 		// The handshake0 packet will be sent when the acknowledgement
46 		// arrives.
47 	} else if (conn->stateFlags.handshake.remoteOk) {
48 		// A Handshake0 is implied by the following Handshake1.
49 		sendHandshake1(conn);
50 	} else {
51 		sendHandshake0(conn);
52 	}
53 
54 	return 0;
55 }
56 
57 int
Netplay_cancelConfirmation(NetConnection * conn)58 Netplay_cancelConfirmation(NetConnection *conn) {
59 	assert(handshakeMeaningful(NetConnection_getState(conn)));
60 
61 	if (!conn->stateFlags.handshake.localOk) {
62 		// Not confirmed, or already canceling.
63 		errno = EINVAL;
64 		return -1;
65 	}
66 
67 	conn->stateFlags.handshake.localOk = false;
68 	if (conn->stateFlags.handshake.canceling) {
69 		// If previous cancellation is still waiting to be acknowledged,
70 		// the confirmation we are cancelling here, has not actually been
71 		// sent yet. By setting the localOk flag to false, it is
72 		// cancelled, without the need for any packets to be sent.
73 	} else {
74 		conn->stateFlags.handshake.canceling = true;
75 		sendHandshakeCancel(conn);
76 	}
77 
78 	return 0;
79 }
80 
81 
82