Added Breadbox64 to the Atari Makefile (now that I ported BB64 to that target). This...
[contiki-2.x.git] / apps / telnet / simpletelnet.c
blobe6cc77cddf7db43093e54746d09d448329d704af
1 /*
2 * Copyright (c) 2002, Adam Dunkels.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior
16 * written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * This file is part of the Contiki desktop environment
32 * $Id: simpletelnet.c,v 1.6 2010/05/31 15:22:08 nifi Exp $
36 #include <string.h>
38 #include "contiki-net.h"
39 #include "lib/petsciiconv.h"
40 #include "ctk/ctk.h"
42 #include "telnet.h"
43 #include "simpletelnet.h"
45 /* Telnet window */
46 static struct ctk_window telnetwindow;
48 static struct ctk_label telnethostlabel =
49 {CTK_LABEL(0, 0, 4, 1, "Host")};
50 static char telnethost[25];
51 static struct ctk_textentry telnethosttextentry =
52 {CTK_TEXTENTRY(4, 0, 24, 1, telnethost, 24)};
54 static struct ctk_label telnetportlabel =
55 {CTK_LABEL(0, 1, 4, 1, "Port")};
56 static char telnetport[6];
57 static struct ctk_textentry telnetporttextentry =
58 {CTK_TEXTENTRY(4, 1, 5, 1, telnetport, 5)};
60 static struct ctk_button telnetconnectbutton =
61 {CTK_BUTTON(2, 2, 7, "Connect")};
62 static struct ctk_button telnetdisconnectbutton =
63 {CTK_BUTTON(15, 2, 10, "Disconnect")};
65 static char telnetline[31];
66 static struct ctk_textentry telnetlinetextentry =
67 {CTK_TEXTENTRY(0, 3, TELNET_ENTRY_WIDTH, 1, telnetline, TELNET_ENTRY_WIDTH)};
69 static struct ctk_button telnetsendbutton =
70 {CTK_BUTTON(TELNET_ENTRY_WIDTH + 2, 3, 4, "Send")};
72 static struct ctk_label telnetstatus =
73 {CTK_LABEL(0, TELNET_WINDOW_HEIGHT - 1, TELNET_WINDOW_WIDTH, 1, "")};
75 static struct ctk_separator telnetsep1 =
76 {CTK_SEPARATOR(0, 4, TELNET_WINDOW_WIDTH)};
78 static struct ctk_separator telnetsep2 =
79 {CTK_SEPARATOR(0, TELNET_WINDOW_HEIGHT - 2, TELNET_WINDOW_WIDTH)};
81 static char telnettext[TELNET_WINDOW_WIDTH*TELNET_TEXTAREA_HEIGHT];
82 static struct ctk_label telnettextarea =
83 {CTK_LABEL(0, 5, TELNET_WINDOW_WIDTH, TELNET_TEXTAREA_HEIGHT, telnettext)};
85 static struct telnet_state ts_appstate;
87 #define ISO_NL 0x0a
88 #define ISO_CR 0x0d
90 static char sendline[31+2];
92 PROCESS(simpletelnet_process, "Telnet client");
94 AUTOSTART_PROCESSES(&simpletelnet_process);
96 /*-----------------------------------------------------------------------------------*/
97 static void
98 scrollup(void)
100 unsigned char i;
101 for(i = 1; i < TELNET_TEXTAREA_HEIGHT; ++i) {
102 memcpy(&telnettext[(i - 1) * TELNET_WINDOW_WIDTH], &telnettext[i * TELNET_WINDOW_WIDTH], TELNET_WINDOW_WIDTH);
104 memset(&telnettext[(TELNET_TEXTAREA_HEIGHT - 1) * TELNET_WINDOW_WIDTH], 0, TELNET_WINDOW_WIDTH);
106 /*-----------------------------------------------------------------------------------*/
107 static void
108 add_text(char *text)
110 unsigned char i;
111 unsigned int len;
113 len = (unsigned int)strlen(text);
115 i = 0;
116 while(len > 0) {
117 if(*text == '\n') {
118 scrollup();
119 i = 0;
120 } else if(*text == '\r') {
121 i = 0;
122 } else if(*text >= ' ') {
123 telnettext[(TELNET_TEXTAREA_HEIGHT - 1) * TELNET_WINDOW_WIDTH + i] = *text;
124 ++i;
125 if(i == TELNET_WINDOW_WIDTH) {
126 scrollup();
127 i = 0;
130 ++text;
131 --len;
134 /* if(strlen(text) > 37) {
135 memcpy(&telnettext[9 * 38], text, 37);
136 } else {
137 memcpy(&telnettext[9 * 38], text, strlen(text));
141 /*-----------------------------------------------------------------------------------*/
142 static void
143 show(char *text)
145 add_text(text);
146 add_text("\n");
147 ctk_label_set_text(&telnetstatus, text);
148 ctk_window_redraw(&telnetwindow);
150 /*-----------------------------------------------------------------------------------*/
151 static void
152 connect(void)
154 uip_ipaddr_t addr, *addrptr;
155 u16_t port;
156 char *cptr;
157 struct uip_conn *conn;
159 /* Find the first space character in host and put a zero there
160 to end the string. */
161 for(cptr = telnethost; *cptr != ' ' && *cptr != 0; ++cptr);
162 *cptr = 0;
164 addrptr = &addr;
165 #if UIP_UDP
166 if(uiplib_ipaddrconv(telnethost, &addr) == 0) {
167 addrptr = resolv_lookup(telnethost);
168 if(addrptr == NULL) {
169 resolv_query(telnethost);
170 show("Resolving host...");
171 return;
174 #else /* UIP_UDP */
175 uiplib_ipaddrconv(telnethost, &addr);
176 #endif /* UIP_UDP */
178 port = 0;
179 for(cptr = telnetport; *cptr != ' ' && *cptr != 0; ++cptr) {
180 if(*cptr < '0' || *cptr > '9') {
181 show("Port number error");
182 return;
184 port = 10 * port + *cptr - '0';
188 conn = tcp_connect(addrptr, htons(port), &ts_appstate);
189 if(conn == NULL) {
190 show("Out of memory error");
191 return;
194 show("Connecting...");
197 /*-----------------------------------------------------------------------------------*/
198 PROCESS_THREAD(simpletelnet_process, ev, data)
200 struct ctk_widget *w;
201 int sendlen;
203 PROCESS_BEGIN();
205 ctk_window_new(&telnetwindow, TELNET_WINDOW_WIDTH, TELNET_WINDOW_HEIGHT, "Simple telnet");
207 strcpy(telnetport, "23");
209 CTK_WIDGET_ADD(&telnetwindow, &telnethostlabel);
210 CTK_WIDGET_ADD(&telnetwindow, &telnetportlabel);
211 CTK_WIDGET_ADD(&telnetwindow, &telnethosttextentry);
212 CTK_WIDGET_ADD(&telnetwindow, &telnetporttextentry);
213 CTK_WIDGET_ADD(&telnetwindow, &telnetconnectbutton);
214 CTK_WIDGET_ADD(&telnetwindow, &telnetdisconnectbutton);
215 CTK_WIDGET_ADD(&telnetwindow, &telnetlinetextentry);
216 CTK_WIDGET_ADD(&telnetwindow, &telnetsendbutton);
218 CTK_WIDGET_ADD(&telnetwindow, &telnetsep1);
219 CTK_WIDGET_ADD(&telnetwindow, &telnettextarea);
221 CTK_WIDGET_ADD(&telnetwindow, &telnetsep2);
222 CTK_WIDGET_ADD(&telnetwindow, &telnetstatus);
224 CTK_WIDGET_FOCUS(&telnetwindow, &telnethosttextentry);
226 ctk_window_open(&telnetwindow);
228 while(1) {
229 PROCESS_WAIT_EVENT();
230 if(ev == ctk_signal_button_activate) {
232 w = (struct ctk_widget *)data;
233 if(w == (struct ctk_widget *)&telnetsendbutton) {
234 strcpy(sendline, telnetline);
235 sendlen = (int)strlen(sendline);
236 petsciiconv_toascii(sendline, sendlen);
237 sendline[sendlen++] = ISO_CR;
238 sendline[sendlen++] = ISO_NL;
239 if(telnet_send(&ts_appstate, sendline, sendlen)) {
240 /* Could not send. */
241 ctk_label_set_text(&telnetstatus, "Could not send");
242 ctk_window_redraw(&telnetwindow);
243 /* } else {*/
244 /* Could send */
246 } else if(w == (struct ctk_widget *)&telnetdisconnectbutton) {
247 telnet_close(&ts_appstate);
248 show("Closing...");
249 } else if(w == (struct ctk_widget *)&telnetconnectbutton) {
250 connect();
251 ctk_window_redraw(&telnetwindow);
253 #if UIP_UDP
254 } else if(ev == resolv_event_found) {
255 if(strcmp(data, telnethost) == 0) {
256 if(resolv_lookup(telnethost) != NULL) {
257 connect();
258 } else {
259 show("Host not found");
262 #endif /* UIP_UDP */
263 } else if(
264 #if CTK_CONF_WINDOWCLOSE
265 ev == ctk_signal_window_close ||
266 #endif /* CTK_CONF_WINDOWCLOSE */
267 ev == PROCESS_EVENT_EXIT) {
268 process_exit(&simpletelnet_process);
269 ctk_window_close(&telnetwindow);
270 LOADER_UNLOAD();
271 } else if(ev == tcpip_event) {
272 telnet_app(data);
275 PROCESS_END();
277 /*-----------------------------------------------------------------------------------*/
278 void
279 telnet_connected(struct telnet_state *s)
281 show("Connected");
283 /*-----------------------------------------------------------------------------------*/
284 void
285 telnet_closed(struct telnet_state *s)
287 show("Connection closed");
289 /*-----------------------------------------------------------------------------------*/
290 void
291 telnet_sent(struct telnet_state *s)
293 petsciiconv_topetscii(sendline, sizeof(sendline));
294 scrollup();
295 add_text(sendline);
296 CTK_TEXTENTRY_CLEAR(&telnetlinetextentry);
297 ctk_window_redraw(&telnetwindow);
299 /*-----------------------------------------------------------------------------------*/
300 void
301 telnet_aborted(struct telnet_state *s)
303 show("Connection reset by peer");
305 /*-----------------------------------------------------------------------------------*/
306 void
307 telnet_timedout(struct telnet_state *s)
309 show("Connection timed out");
311 /*-----------------------------------------------------------------------------------*/
312 void
313 telnet_newdata(struct telnet_state *s, char *data, u16_t len)
315 petsciiconv_topetscii(data, len);
316 data[len] = 0;
317 add_text(data);
318 ctk_window_redraw(&telnetwindow);
320 /*-----------------------------------------------------------------------------------*/