?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
2 *
3 * Telnet Server
4 * Module for Microchip TCP/IP Stack
5 * -Provides Telnet services on TCP port 23
6 * -Reference: RFC 854
7 *
8 *********************************************************************
9 * FileName: Telnet.c
10 * Dependencies: TCP
11 * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
12 * Compiler: Microchip C32 v1.05 or higher
13 * Microchip C30 v3.12 or higher
14 * Microchip C18 v3.30 or higher
15 * HI-TECH PICC-18 PRO 9.63PL2 or higher
16 * Company: Microchip Technology, Inc.
17 *
18 * Software License Agreement
19 *
20 * Copyright (C) 2002-2009 Microchip Technology Inc. All rights
21 * reserved.
22 *
23 * Microchip licenses to you the right to use, modify, copy, and
24 * distribute:
25 * (i) the Software when embedded on a Microchip microcontroller or
26 * digital signal controller product ("Device") which is
27 * integrated into Licensee's product; or
28 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
29 * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
30 * used in conjunction with a Microchip ethernet controller for
31 * the sole purpose of interfacing with the ethernet controller.
32 *
33 * You should refer to the license agreement accompanying this
34 * Software for additional information regarding your rights and
35 * obligations.
36 *
37 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
38 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
39 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
40 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
42 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
43 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
44 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
45 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
46 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
47 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
48 *
49 *
50 * Author Date Comment
51 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52 * Howard Schlunder 9/12/06 Original
53 ********************************************************************/
54 #define __TELNET_C
55  
56 #include "TCPIPConfig.h"
57  
58 #if defined(STACK_USE_TELNET_SERVER)
59  
60 #include "TCPIP Stack/TCPIP.h"
61  
62 // Set up configuration parameter defaults if not overridden in
63 // TCPIPConfig.h
64 #if !defined(TELNET_PORT)
65 // Unsecured Telnet port
66 #define TELNET_PORT 23
67 #endif
68 #if !defined(TELNETS_PORT)
69 // SSL Secured Telnet port (ignored if STACK_USE_SSL_SERVER is undefined)
70 #define TELNETS_PORT 992
71 #endif
72 #if !defined(MAX_TELNET_CONNECTIONS)
73 // Maximum number of Telnet connections
74 #define MAX_TELNET_CONNECTIONS (3u)
75 #endif
76 #if !defined(TELNET_USERNAME)
77 // Default Telnet user name
78 #define TELNET_USERNAME "admin"
79 #endif
80 #if !defined(TELNET_PASSWORD)
81 // Default Telnet password
82 #define TELNET_PASSWORD "microchip"
83 #endif
84  
85 // Demo title string
86 static ROM BYTE strTitle[] = "\x1b[2J\x1b[31m\x1b[1m" // 2J is clear screen, 31m is red, 1m is bold
87 "Microchip Telnet Server 1.1\x1b[0m\r\n" // 0m is clear all attributes
88 "(for this demo, type 'admin' for the login and 'microchip' for the password.)\r\n"
89 "Login: ";
90 // Demo password
91 static ROM BYTE strPassword[] = "Password: \xff\xfd\x2d"; // DO Suppress Local Echo (stop telnet client from printing typed characters)
92 // Access denied message
93 static ROM BYTE strAccessDenied[] = "\r\nAccess denied\r\n\r\n";
94 // Successful authentication message
95 static ROM BYTE strAuthenticated[] = "\r\nLogged in successfully\r\n\r\n"
96 "\r\nPress 'q' to quit\r\n";
97 // Demo output string
98 static ROM BYTE strDisplay[] = "\r\nSNTP Time: (disabled)"
99 "\r\nAnalog: 1023"
100 "\r\nButtons: 3 2 1 0"
101 "\r\nLEDs: 7 6 5 4 3 2 1 0";
102 // String with extra spaces, for Demo
103 static ROM BYTE strSpaces[] = " ";
104 // Demo disconnection message
105 static ROM BYTE strGoodBye[] = "\r\n\r\nGoodbye!\r\n";
106  
107 extern BYTE AN0String[8];
108  
109 /*********************************************************************
110 * Function: void TelnetTask(void)
111 *
112 * PreCondition: Stack is initialized()
113 *
114 * Input: None
115 *
116 * Output: None
117 *
118 * Side Effects: None
119 *
120 * Overview: Performs Telnet Server related tasks. Contains
121 * the Telnet state machine and state tracking
122 * variables.
123 *
124 * Note: None
125 ********************************************************************/
126 void TelnetTask(void)
127 {
128 BYTE i;
129 BYTE vTelnetSession;
130 WORD w, w2;
131 TCP_SOCKET MySocket;
132 enum
133 {
134 SM_HOME = 0,
135 SM_PRINT_LOGIN,
136 SM_GET_LOGIN,
137 SM_GET_PASSWORD,
138 SM_GET_PASSWORD_BAD_LOGIN,
139 SM_AUTHENTICATED,
140 SM_REFRESH_VALUES
141 } TelnetState;
142 static TCP_SOCKET hTelnetSockets[MAX_TELNET_CONNECTIONS];
143 static BYTE vTelnetStates[MAX_TELNET_CONNECTIONS];
144 static BOOL bInitialized = FALSE;
145  
146 // Perform one time initialization on power up
147 if(!bInitialized)
148 {
149 for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
150 {
151 hTelnetSockets[vTelnetSession] = INVALID_SOCKET;
152 vTelnetStates[vTelnetSession] = SM_HOME;
153 }
154 bInitialized = TRUE;
155 }
156  
157  
158 // Loop through each telnet session and process state changes and TX/RX data
159 for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
160 {
161 // Load up static state information for this session
162 MySocket = hTelnetSockets[vTelnetSession];
163 TelnetState = vTelnetStates[vTelnetSession];
164  
165 // Reset our state if the remote client disconnected from us
166 if(MySocket != INVALID_SOCKET)
167 {
168 if(TCPWasReset(MySocket))
169 TelnetState = SM_PRINT_LOGIN;
170 }
171  
172 // Handle session state
173 switch(TelnetState)
174 {
175 case SM_HOME:
176 // Connect a socket to the remote TCP server
177 MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
178  
179 // Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
180 // If this ever happens, you need to go add one to TCPIPConfig.h
181 if(MySocket == INVALID_SOCKET)
182 break;
183  
184 // Open an SSL listener if SSL server support is enabled
185 #if defined(STACK_USE_SSL_SERVER)
186 TCPAddSSLListener(MySocket, TELNETS_PORT);
187 #endif
188  
189 TelnetState++;
190 break;
191  
192 case SM_PRINT_LOGIN:
193 #if defined(STACK_USE_SSL_SERVER)
194 // Reject unsecured connections if TELNET_REJECT_UNSECURED is defined
195 #if defined(TELNET_REJECT_UNSECURED)
196 if(!TCPIsSSL(MySocket))
197 {
198 if(TCPIsConnected(MySocket))
199 {
200 TCPDisconnect(MySocket);
201 TCPDisconnect(MySocket);
202 break;
203 }
204 }
205 #endif
206  
207 // Don't attempt to transmit anything if we are still handshaking.
208 if(TCPSSLIsHandshaking(MySocket))
209 break;
210 #endif
211  
212 // Make certain the socket can be written to
213 if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle))
214 break;
215  
216 // Place the application protocol data into the transmit buffer.
217 TCPPutROMString(MySocket, strTitle);
218  
219 // Send the packet
220 TCPFlush(MySocket);
221 TelnetState++;
222  
223 case SM_GET_LOGIN:
224 // Make sure we can put the password prompt
225 if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
226 break;
227  
228 // See if the user pressed return
229 w = TCPFind(MySocket, '\n', 0, FALSE);
230 if(w == 0xFFFFu)
231 {
232 if(TCPGetRxFIFOFree(MySocket) == 0u)
233 {
234 TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
235 TCPDisconnect(MySocket);
236 }
237  
238 break;
239 }
240  
241 // Search for the username -- case insensitive
242 w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_USERNAME, sizeof(TELNET_USERNAME)-1, 0, TRUE);
243 if((w2 != 0u) || !((sizeof(TELNET_USERNAME)-1 == w) || (sizeof(TELNET_USERNAME) == w)))
244 {
245 // Did not find the username, but let's pretend we did so we don't leak the user name validity
246 TelnetState = SM_GET_PASSWORD_BAD_LOGIN;
247 }
248 else
249 {
250 TelnetState = SM_GET_PASSWORD;
251 }
252  
253 // Username verified, throw this line of data away
254 TCPGetArray(MySocket, NULL, w + 1);
255  
256 // Print the password prompt
257 TCPPutROMString(MySocket, strPassword);
258 TCPFlush(MySocket);
259 break;
260  
261 case SM_GET_PASSWORD:
262 case SM_GET_PASSWORD_BAD_LOGIN:
263 // Make sure we can put the authenticated prompt
264 if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
265 break;
266  
267 // See if the user pressed return
268 w = TCPFind(MySocket, '\n', 0, FALSE);
269 if(w == 0xFFFFu)
270 {
271 if(TCPGetRxFIFOFree(MySocket) == 0u)
272 {
273 TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
274 TCPDisconnect(MySocket);
275 }
276  
277 break;
278 }
279  
280 // Search for the password -- case sensitive
281 w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_PASSWORD, sizeof(TELNET_PASSWORD)-1, 0, FALSE);
282 if((w2 != 3u) || !((sizeof(TELNET_PASSWORD)-1 == w-3) || (sizeof(TELNET_PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
283 {
284 // Did not find the password
285 TelnetState = SM_PRINT_LOGIN;
286 TCPPutROMString(MySocket, strAccessDenied);
287 TCPDisconnect(MySocket);
288 break;
289 }
290  
291 // Password verified, throw this line of data away
292 TCPGetArray(MySocket, NULL, w + 1);
293  
294 // Print the authenticated prompt
295 TCPPutROMString(MySocket, strAuthenticated);
296 TelnetState = SM_AUTHENTICATED;
297 // No break
298  
299 case SM_AUTHENTICATED:
300 if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4)
301 break;
302  
303 TCPPutROMString(MySocket, strDisplay);
304 TelnetState++;
305  
306 // All future characters will be bold
307 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m");
308  
309 case SM_REFRESH_VALUES:
310 if(TCPIsPutReady(MySocket) >= 78u)
311 {
312 //[10;1]
313 //"SNTP Time: (disabled)\r\n"
314 //"Analog: 1023\r\n"
315 //"Buttons: 3 2 1 0\r\n"
316 //"LEDs: 7 6 5 4 3 2 1 0\r\n"
317  
318 // Write current UTC seconds from SNTP module, if it is enable
319 // and has changed. Note that conversion from a DWORD to an
320 // ASCII string can take a lot of CPU power, so we only print
321 // this if the value has changed.
322 #if defined(STACK_USE_SNTP_CLIENT)
323 {
324 static DWORD dwTime;
325 BYTE vTime[11];
326  
327 if(dwTime != SNTPGetUTCSeconds())
328 {
329  
330 // Position cursor at Line 10, Col 15
331 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;15f");
332 dwTime = SNTPGetUTCSeconds();
333 ultoa(dwTime, vTime);
334 TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 10-strlen((char*)vTime));
335 TCPPutString(MySocket, vTime);
336 }
337 }
338 #endif
339  
340 // Position cursor at Line 11, Col 21
341 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;21f");
342  
343 // Put analog value with space padding on right side for 4 characters
344 TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 4-strlen((char*)AN0String));
345 TCPPutString(MySocket, AN0String);
346  
347 // Put Buttons
348 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;18f");
349 TCPPut(MySocket, BUTTON3_IO ? '1':'0');
350 TCPPut(MySocket, ' ');
351 TCPPut(MySocket, BUTTON2_IO ? '1':'0');
352 TCPPut(MySocket, ' ');
353 TCPPut(MySocket, BUTTON1_IO ? '1':'0');
354 TCPPut(MySocket, ' ');
355 TCPPut(MySocket, BUTTON0_IO ? '1':'0');
356  
357  
358 // Put LEDs
359 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;10f");
360 TCPPut(MySocket, LED7_IO ? '1':'0');
361 TCPPut(MySocket, ' ');
362 TCPPut(MySocket, LED6_IO ? '1':'0');
363 TCPPut(MySocket, ' ');
364 TCPPut(MySocket, LED5_IO ? '1':'0');
365 TCPPut(MySocket, ' ');
366 TCPPut(MySocket, LED4_IO ? '1':'0');
367 TCPPut(MySocket, ' ');
368 TCPPut(MySocket, LED3_IO ? '1':'0');
369 TCPPut(MySocket, ' ');
370 TCPPut(MySocket, LED2_IO ? '1':'0');
371 TCPPut(MySocket, ' ');
372 TCPPut(MySocket, LED1_IO ? '1':'0');
373 TCPPut(MySocket, ' ');
374 TCPPut(MySocket, LED0_IO ? '1':'0');
375  
376  
377 // Put cursor at beginning of next line
378 TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[14;1f");
379  
380 // Send the data out immediately
381 TCPFlush(MySocket);
382 }
383  
384 if(TCPIsGetReady(MySocket))
385 {
386 TCPGet(MySocket, &i);
387 switch(i)
388 {
389 case '\r':
390 case 'q':
391 case 'Q':
392 if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye))
393 TCPPutROMString(MySocket, strGoodBye);
394 TCPDisconnect(MySocket);
395 TelnetState = SM_PRINT_LOGIN;
396 break;
397 }
398 }
399  
400 break;
401 }
402  
403  
404 // Save session state back into the static array
405 hTelnetSockets[vTelnetSession] = MySocket;
406 vTelnetStates[vTelnetSession] = TelnetState;
407 }
408 }
409  
410 #endif //#if defined(STACK_USE_TELNET_SERVER)
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3