summaryrefslogtreecommitdiff
path: root/src/net/comm.c
blob: fff661dbcaff7648ef5d53cc77b58e60dff154ac (plain)
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
/*****************************************************************************
 *                          ___ __  __ ___ _ __                              *
 *                         / _ \\ \/ // _ \ '_ \                             *
 *                        | (_) |>  <|  __/ | | |                            *
 *                         \___//_/\_\\___|_| |_|                            *
 *                                                                           *
 *                             The card game                                 *
 *                                                                           *
 *  Copyright (C) 2011, Reiner Herrmann <reiner@reiner-h.de>                 *
 *                      Mario Kilies <MarioKilies@GMX.net>                   *
 *                                                                           *
 *  This program is free software; you can redistribute it and/or modify     *
 *  it under the terms of the GNU General Public License as published by     *
 *  the Free Software Foundation; either version 3 of the License, or        *
 *  (at your option) any later version.                                      *
 *                                                                           *
 *  This program is distributed in the hope that it will be useful,          *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
 *  GNU General Public License for more details.                             *
 *                                                                           *
 *  You should have received a copy of the GNU General Public License        *
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.     *
 *                                                                           *
 *****************************************************************************/

#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "comm.h"
#include "client.h"
#include "server.h"

/**
 * Generic receive function.\n
 * Receives specified message type from socket. Blocks until message is fully received.
 * @param[in] sock Socket on which to receive
 * @param[in] type Message type to receive
 * @return Indicates success of receiving
 */
bool net_recv(const int sock, const msg_type_t type)
{
	msg_t m;
	bool result;
	ssize_t len = recv(sock, &m.hdr, sizeof(msg_header_t), MSG_PEEK|MSG_WAITALL); // just peek into packet to determine message header

	assert(len != -1);

	if(m.hdr.type != type)
	{
		printf("net_recv: received message type %d instead of %d", m.hdr.type, type);
		return false;
	}

	m.payload = malloc(m.hdr.payload_length);	// Allocate space for message payload
	recv(sock, &m.hdr, sizeof(msg_header_t), MSG_WAITALL);	// Remove message header from socket
	recv(sock, m.payload, m.hdr.payload_length, MSG_WAITALL);// And then receive the payload

	//printf("net_recv: received msg type %d with payload length %d\n", m.hdr.type, m.hdr.payload_length);

	switch(type)
	{
		case msg_type_hello_c:
			result = server_parse_hello(&m);
			break;
		case msg_type_hello_s:
			result = client_parse_hello(&m);
			break;
		case msg_type_start_game:
			result = client_parse_player_list(&m);
			break;
		case msg_type_deal_hand:
			result = client_parse_deal_hand(&m);
			break;
		case msg_type_initial_stacks:
			result = client_parse_initial_stacks(&m);
			break;
		case msg_type_selected_card:
			result = server_parse_selected_card(&m);
			break;
		case msg_type_selected_card_all:
			result = client_parse_selected_card_all(&m);
			break;
		case msg_type_selected_stack_c:
			result = server_parse_selected_stack(&m);
			break;
		case msg_type_selected_stack_s:
			result = client_parse_selected_stack(&m);
			break;
		case msg_type_next_action:
			result = client_parse_next_action(&m);
			break;
		default:
			printf("net_recv: Unknown message type %d received!\n", type);
			exit(EXIT_FAILURE);
			break;
	}

	free(m.payload);

	return result;
}

/**
 * Generic send function.\n
 * Transmits specified message type on socket.
 * @param[in] sock Socket on which to send
 * @param[in] type Message type to send
 * @param[in] data Optional pointer to extra data needed by some message types
 * @return Indicates success of sending
 */
bool net_send(const int sock, const msg_type_t type, const void *data)
{
	bool result = true;

	msg_t m;
	m.payload = malloc(NET_MSG_MAX_PAYLOAD_LENGTH);

	switch(type)
	{
		case msg_type_hello_c:
			client_prep_hello(&m);
			break;
		case msg_type_hello_s:
			server_prep_hello(&m, data);
			break;
		case msg_type_selected_card:
			client_prep_selected_card(&m);
			break;
		case msg_type_selected_stack_c:
			client_prep_selected_stack(&m);
			break;
		case msg_type_start_game:
			server_prep_start_game(&m);
			break;
		case msg_type_selected_stack_s:
			server_prep_selected_stack(&m);
			break;
		case msg_type_deal_hand:
			server_prep_deal_hand(&m, data);
			break;
		case msg_type_initial_stacks:
			server_prep_initial_stacks(&m);
			break;
		case msg_type_selected_card_all:
			server_prep_selected_card_all(&m);
			break;
		case msg_type_next_action:
			server_prep_next_action(&m);
			break;
		default:
			printf("net_send: Unknown message type %d given\n", type);
			exit(EXIT_FAILURE);
			break;
	}

	//printf("net_send: sending msg type %d with payload length %d\n", m.hdr.type, m.hdr.payload_length);
	send(sock, &m, sizeof(msg_header_t), 0);	// Send message header first
	send(sock, m.payload, m.hdr.payload_length, 0);	// Then send payload

	free(m.payload);

	return result;
}