-
Notifications
You must be signed in to change notification settings - Fork 3
/
handler.c
157 lines (135 loc) · 4.06 KB
/
handler.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
#include <Arduino.h>
#include "handler.h"
#include "protocol.h"
#include "serial.h"
static void handler_process_cmd_stop(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
static void handler_process_cmd_move(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
static void handler_process_cmd_pour(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
static void handler_process_cmd_status(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
static void handler_process_cmd_location(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
static void handler_process_unknown_cmd(handler_t *handler, uint8_t *buffer, uint8_t *rsp);
void handler_init(handler_t *handler, bartender_t *bartender)
{
handler->bartender = bartender;
}
void handler_handle(handler_t *handler, uint8_t *cmd)
{
uint8_t rsp[MSG_SIZE];
// Make sure we have a valid packet
if (cmd[I_START] != MSG_START || cmd[I_END] != MSG_END)
{
// Send back a malformed packet error
protocol_build_error_rsp(rsp, BLANK, RSP_MAL_MSG);
serial_write_chunk(rsp, MSG_SIZE);
return;
}
// See if the type is command
if (cmd[I_TYPE] == TYPE_CMD)
{
// Find the function to handle the command
switch(cmd[I_CMD])
{
case CMD_STOP:
handler_process_cmd_stop(handler, cmd, rsp);
break;
case CMD_MOVE:
handler_process_cmd_move(handler, cmd, rsp);
break;
case CMD_POUR:
handler_process_cmd_pour(handler, cmd, rsp);
break;
case CMD_STATUS:
handler_process_cmd_status(handler, cmd, rsp);
break;
case CMD_LOCATION:
handler_process_cmd_location(handler, cmd, rsp);
break;
default:
handler_process_unknown_cmd(handler, cmd, rsp);
break;
}
}
else if (cmd[I_TYPE] == TYPE_RSP)
{
// Send back a not implemented type error
protocol_build_error_rsp(rsp, BLANK, RSP_NOT_IMPL);
serial_write_chunk(rsp, MSG_SIZE);
}
else
{
// Send back an unknown type error
protocol_build_error_rsp(rsp, BLANK, RSP_UNK_TYPE);
serial_write_chunk(rsp, MSG_SIZE);
}
}
static void handler_process_cmd_stop(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
protocol_build_ok_rsp(rsp, CMD_STOP);
}
static void handler_process_cmd_move(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
//Grab the variables from the content
uint8_t location = buffer[PARAM_MOVE_LOC];
// Make sure the location is in range
if (location > 12)
{
// Let them know we are not happy
protocol_build_error_rsp(rsp, CMD_MOVE, RSP_ERROR);
serial_write_chunk(rsp, MSG_SIZE);
return;
}
// We are processing the command
protocol_build_ok_rsp(rsp, CMD_MOVE);
serial_write_chunk(rsp, MSG_SIZE);
// Start moving
uint8_t code = bartender_move_to_location(handler->bartender, location);
if (code == E_NO_ERROR)
{
// We have processed the command
protocol_build_complete_rsp(rsp, CMD_MOVE);
serial_write_chunk(rsp, MSG_SIZE);
}
else
{
// TODO better error code
protocol_build_error_rsp(rsp, CMD_MOVE, RSP_ERROR);
serial_write_chunk(rsp, MSG_SIZE);
}
}
static void handler_process_cmd_pour(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
// We have received the command
protocol_build_ok_rsp(rsp, CMD_POUR);
serial_write_chunk(rsp, MSG_SIZE);
uint8_t amount = buffer[PARAM_POUR_AMOUNT];
uint8_t code = bartender_pour(handler->bartender, amount);
if (code == E_NO_ERROR)
{
// The command has been completed
protocol_build_complete_rsp(rsp, CMD_POUR);
serial_write_chunk(rsp, MSG_SIZE);
}
else
{
//TODO better error codes
protocol_build_error_rsp(rsp, CMD_MOVE, RSP_ERROR);
serial_write_chunk(rsp, MSG_SIZE);
}
}
static void handler_process_cmd_status(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
// Build a response
protocol_build_ok_rsp(rsp, CMD_STATUS);
// Put in the bartender's current status
rsp[RES_STATUS_STATUS] = handler->bartender->status;
// Write the command back
serial_write_chunk(rsp, MSG_SIZE);
}
static void handler_process_cmd_location(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
protocol_build_ok_rsp(rsp, CMD_LOCATION);
}
static void handler_process_unknown_cmd(handler_t *handler, uint8_t *buffer, uint8_t *rsp)
{
protocol_build_error_rsp(rsp, BLANK, RSP_UNK_CMD);
}