Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / diagnostic_station / station / comm_server.c @ 1185

History | View | Annotate | Download (4.5 KB)

1
#include "comm_server.h"
2

    
3
#include <avr/pgmspace.h>
4

    
5
#include "global.h"
6
#include "tests.h"
7

    
8
// ##############
9
// ## Settings ##
10
// ##############
11

    
12
#define comm_server_debug
13

    
14
// ###############
15
// ## Constants ##
16
// ###############
17

    
18
#define buffer_size 120
19

    
20

    
21
// ####################
22
// ## Initialization ##
23
// ####################
24

    
25
void comm_server_init ()
26
{
27
        usb_init ();
28
}
29

    
30

    
31
// ########################
32
// ## Message processing ##
33
// ########################
34

    
35
// This function is copied from XNS
36
//static void serial_send_string_P (const char *s)/*{{{*/
37
//{
38
//    char buf;
39
//    while (memcpy_P (&buf, s, sizeof (char)), buf!=0)
40
//    {
41
//        serial_transmit (buf);
42
//        s++;
43
//    }
44
//}
45

    
46
/** Check if the buffer starts with the given text, followed by a space */
47
// This function is copied from XNS
48
static bool serial_match (PGM_P text, uint8_t *buffer, uint8_t size)
49
{
50
        uint8_t text_len=strlen_P (text);
51

    
52
        // If the buffer is shorter than the text, there is no match
53
        if (size<text_len) return false;
54

    
55
        // If the buffer is longer than the text, it must have a space at position after the text
56
        if (size>text_len && buffer[text_len]!=' ') return false;
57

    
58
        // Test for match
59
        if (strncmp_P ((char *)buffer, text, text_len)==0) return true;
60
        
61
        return false;
62
}
63

    
64

    
65

    
66

    
67

    
68

    
69
// ########################
70
// ## Messages (sending) ##
71
// ########################
72

    
73
void server_send_finished ()
74
{
75
        usb_puts ("finished");
76
}
77

    
78

    
79
// ######################
80
// ## Message handlers ##
81
// ######################
82

    
83
static void handle_message_ping (uint8_t *buffer, uint8_t size)
84
{
85
        usb_puts ("pong" NL);
86
        orbs_set (255, 127, 0, 0, 255, 0);
87
        delay_ms (400);
88
        orbs_set (0, 255, 0, 255, 127, 0);
89
}
90

    
91
static void handle_message_start_test (uint8_t *buffer, uint8_t size)
92
{
93
        // FIXME parameter handling
94
        // Parameters: all/rangefinder/motor/encoder all/<num>
95
        test_all ();
96
}
97

    
98

    
99
// ##########################
100
// ## Messages (receiving) ##
101
// ##########################
102

    
103

    
104
// Put all symbolic string constants into the program memory because else all of them would be copied into the RAM (see
105
// the avr-libc documentation, chapter "Data in Program Space").
106
const char command_ping          [] PROGMEM = "ping"      ;
107
const char command_start_test    [] PROGMEM = "start_test";
108

    
109
static void handle_message (uint8_t *message, uint8_t size)
110
{
111
#ifdef comm_server_debug
112
        // Output: "# Received a message, size <size>: [<message>]"
113
        usb_puts ("# Received a message, size ");
114
        usb_puti(size);
115
        usb_puts (": [");
116
        usb_puts ((char *)message);
117
        usb_puts ("]" NL);
118
#endif
119
        
120
        bool handled=false;
121
        if (serial_match (command_ping      , message, size)) { handle_message_ping       (message, size); handled=true; }
122
        if (serial_match (command_start_test, message, size)) { handle_message_start_test (message, size); handled=true; }
123
        // More messages go here
124
        
125
        if (!handled)
126
        {
127
                usb_puts ("# Warning: unhandled message: [");
128
                usb_puts ((char *)message);
129
                usb_puts ("]" NL);
130
        }
131
}
132

    
133

    
134
// ###############
135
// ## Debugging ##
136
// ###############
137

    
138
void byte_transmission_test (void)
139
{
140
        uint8_t c;
141
        
142
        while (1)
143
        {
144
                c=usb_getc ();
145
                usb_puts ("[");
146
                usb_puti (c);
147
                usb_puts ("] ");
148
        }
149
}
150

    
151

    
152
// ###############
153
// ## Main loop ##
154
// ###############
155

    
156
void server_main (void)
157
{
158
        uint8_t buffer[buffer_size];
159
        uint8_t c;
160
        uint8_t buffer_fill=0;
161

    
162
        //byte_transmission_test (); // Does not return
163

    
164
        usb_puts (NL);
165
        usb_puts ("# Diagnostic station server mode" NL);
166
        
167
        while (1)
168
        {
169
                // Do nothing until we receive a byte (this function will return 0 when a character has been read)
170
                // (Yes, we could use the blocking function for now, but we may need the non-blocking later)
171
                while (usb_getc_nb ((char *)&c));
172
                
173
                if (c=='\r' || c=='\n')
174
                {
175
                        // A newline character was received. This terminates the message.
176
                        
177
                        // Empty lines are ignored.
178
                        if (buffer_fill>0)
179
                        {
180
                                // Add a terminating 0 to the buffer so the string functions won't try to read outside the buffer.
181
                                buffer[buffer_fill]=0;
182
                                
183
                                // Handle the message.
184
                                handle_message (buffer, buffer_fill);
185
                        
186
                                // Reset the buffer
187
                                buffer_fill=0;
188
                        }
189
                }
190
                else
191
                {
192
                        // If there is enough space left in the buffer, add the character we just received. Leave one byte for a
193
                        // terminating 0. If there is not enough space in the buffer, the rest of the message is ignored.
194
                        if (buffer_fill<buffer_size-1)
195
                        {
196
                                buffer[buffer_fill]=c;
197
                                ++buffer_fill;
198
                        }
199
                }
200
        
201
        }
202
}