summaryrefslogtreecommitdiff
path: root/src/net/comm.c
blob: 2bfacfa526c8443199964ad6eb20a19ddafced71 (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
#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;
}