blob: 5ba57e887efdc0718a11a095ca824b28dd6db433 [file] [log] [blame]
adamdunkelsca9ddcb2003-03-19 14:13:31 +00001/*
2 * Copyright (c) 2002, Adam Dunkels.
3 * All rights reserved.
4 *
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.
adamdunkels06f897e2004-06-06 05:59:20 +000014 * 3. The name of the author may not be used to endorse or promote
adamdunkelsca9ddcb2003-03-19 14:13:31 +000015 * products derived from this software without specific prior
16 * written permission.
17 *
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.
29 *
30 * This file is part of the Contiki desktop environment
31 *
oliverschmidtbe6e4dc2005-04-16 14:17:32 +000032 * $Id: simpletelnet.c,v 1.14 2005/04/16 14:17:32 oliverschmidt Exp $
adamdunkelsca9ddcb2003-03-19 14:13:31 +000033 *
34 */
35
adamdunkelsf2f8cb22004-07-04 11:35:07 +000036#include <string.h>
37
38#include "ek.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000039#include "petsciiconv.h"
adamdunkelsdb300d22004-02-24 09:57:49 +000040#include "uiplib.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000041#include "uip.h"
42#include "ctk.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000043#include "resolv.h"
44#include "telnet.h"
45#include "simpletelnet.h"
adamdunkels8af703e2003-04-08 11:50:20 +000046#include "loader.h"
adamdunkelsf2f8cb22004-07-04 11:35:07 +000047#include "tcpip.h"
oliverschmidt3901c232004-06-13 09:48:32 +000048
adamdunkelsca9ddcb2003-03-19 14:13:31 +000049/* Telnet window */
50static struct ctk_window telnetwindow;
51
52static struct ctk_label telnethostlabel =
53 {CTK_LABEL(1, 0, 4, 1, "Host")};
54static char telnethost[25];
55static struct ctk_textentry telnethosttextentry =
56 {CTK_TEXTENTRY(0, 1, 24, 1, telnethost, 24)};
57
58static struct ctk_label telnetportlabel =
59 {CTK_LABEL(31, 0, 4, 1, "Port")};
60static char telnetport[6];
61static struct ctk_textentry telnetporttextentry =
62 {CTK_TEXTENTRY(30, 1, 5, 1, telnetport, 5)};
63
64static struct ctk_button telnetconnectbutton =
65 {CTK_BUTTON(2, 3, 7, "Connect")};
66static struct ctk_button telnetdisconnectbutton =
67 {CTK_BUTTON(25, 3, 10, "Disconnect")};
68
69static char telnetline[31];
70static struct ctk_textentry telnetlinetextentry =
71 {CTK_TEXTENTRY(0, 5, 30, 1, telnetline, 30)};
72
73
74static struct ctk_button telnetsendbutton =
75 {CTK_BUTTON(32, 5, 4, "Send")};
76
77static struct ctk_label telnetstatus =
78 {CTK_LABEL(0, 19, 38, 1, "")};
79
80static struct ctk_separator telnetsep1 =
81 {CTK_SEPARATOR(0, 7, 38)};
82
83static struct ctk_separator telnetsep2 =
84 {CTK_SEPARATOR(0, 18, 38)};
85
86static char telnettext[38*10];
87static struct ctk_label telnettextarea =
88 {CTK_LABEL(0, 8, 38, 10, telnettext)};
89
90static struct telnet_state ts_appstate;
91
92#define ISO_NL 0x0a
93#define ISO_CR 0x0d
94
oliverschmidtbe6e4dc2005-04-16 14:17:32 +000095static char sendline[31+2];
96
adamdunkelsf2f8cb22004-07-04 11:35:07 +000097EK_EVENTHANDLER(simpletelnet_eventhandler, ev, data);
98EK_PROCESS(p, "Telnet client", EK_PRIO_NORMAL,
99 simpletelnet_eventhandler, NULL, NULL);
100static ek_id_t id = EK_ID_NONE;
101/*
adamdunkels78c03dc2003-04-09 13:45:05 +0000102static DISPATCHER_SIGHANDLER(simpletelnet_sighandler, s, data);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000103static struct dispatcher_proc p =
adamdunkels78c03dc2003-04-09 13:45:05 +0000104 {DISPATCHER_PROC("Simple telnet", NULL, simpletelnet_sighandler,
adamdunkels2e415422003-04-10 09:04:49 +0000105 telnet_app)};
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000106 static ek_id_t id;*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000107
108/*-----------------------------------------------------------------------------------*/
adamdunkels8bb5cca2003-08-24 22:41:31 +0000109LOADER_INIT_FUNC(simpletelnet_init, arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000110{
111 if(id == EK_ID_NONE) {
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000112 id = ek_start(&p);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000113 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000114}
115/*-----------------------------------------------------------------------------------*/
116static void
117scrollup(void)
118{
119 unsigned char i;
120 for(i = 1; i < 10; ++i) {
121 memcpy(&telnettext[(i - 1) * 38], &telnettext[i * 38], 38);
122 }
123 memset(&telnettext[9 * 38], 0, 38);
124}
125/*-----------------------------------------------------------------------------------*/
126static void
127add_text(char *text)
128{
129 unsigned char i;
130 unsigned int len;
131
132 len = strlen(text);
133
134 i = 0;
135 while(len > 0) {
136 if(*text == '\n') {
137 scrollup();
138 i = 0;
139 } else if(*text == '\r') {
140 i = 0;
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000141 } else if(*text >= ' ') {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000142 telnettext[9 * 38 + i] = *text;
143 ++i;
144 if(i == 38) {
145 scrollup();
146 i = 0;
147 }
148 }
149 ++text;
150 --len;
151 }
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000152
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000153 /* if(strlen(text) > 37) {
154 memcpy(&telnettext[9 * 38], text, 37);
155 } else {
156 memcpy(&telnettext[9 * 38], text, strlen(text));
157 }
158 */
159}
160/*-----------------------------------------------------------------------------------*/
161static void
162show(char *text)
163{
164 add_text(text);
165 add_text("\n");
166 ctk_label_set_text(&telnetstatus, text);
167 ctk_window_redraw(&telnetwindow);
168}
169/*-----------------------------------------------------------------------------------*/
170static void
171connect(void)
172{
173 u16_t addr[2], *addrptr;
174 u16_t port;
175 char *cptr;
176 struct uip_conn *conn;
177
178 /* Find the first space character in host and put a zero there
179 to end the string. */
180 for(cptr = telnethost; *cptr != ' ' && *cptr != 0; ++cptr);
181 *cptr = 0;
182
183 addrptr = &addr[0];
adamdunkelsdb300d22004-02-24 09:57:49 +0000184 if(uiplib_ipaddrconv(telnethost, (unsigned char *)addr) == 0) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000185 addrptr = resolv_lookup(telnethost);
186 if(addrptr == NULL) {
187 resolv_query(telnethost);
188 show("Resolving host...");
189 return;
190 }
191 }
192
193 port = 0;
194 for(cptr = telnetport; *cptr != ' ' && *cptr != 0; ++cptr) {
195 if(*cptr < '0' || *cptr > '9') {
196 show("Port number error");
197 return;
198 }
199 port = 10 * port + *cptr - '0';
200 }
201
202
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000203 conn = tcp_connect(addrptr, htons(port), &ts_appstate);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000204 if(conn == NULL) {
205 show("Out of memory error");
206 return;
207 }
208
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000209 show("Connecting...");
210
211}
212/*-----------------------------------------------------------------------------------*/
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000213EK_EVENTHANDLER(simpletelnet_eventhandler, ev, data)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000214{
215 struct ctk_widget *w;
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000216 int sendlen;
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000217 EK_EVENTHANDLER_ARGS(ev, data);
218
219 if(ev == EK_EVENT_INIT) {
220 /* Create Telnet window. */
221 ctk_window_new(&telnetwindow, 38, 20, "Simple telnet");
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000222
223 strcpy(telnetport, "23");
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000224
225 CTK_WIDGET_ADD(&telnetwindow, &telnethostlabel);
226 CTK_WIDGET_ADD(&telnetwindow, &telnetportlabel);
227 CTK_WIDGET_ADD(&telnetwindow, &telnethosttextentry);
228 CTK_WIDGET_ADD(&telnetwindow, &telnetporttextentry);
229 CTK_WIDGET_ADD(&telnetwindow, &telnetconnectbutton);
230 CTK_WIDGET_ADD(&telnetwindow, &telnetdisconnectbutton);
231 CTK_WIDGET_ADD(&telnetwindow, &telnetlinetextentry);
232 CTK_WIDGET_ADD(&telnetwindow, &telnetsendbutton);
233
234 CTK_WIDGET_ADD(&telnetwindow, &telnetsep1);
235 CTK_WIDGET_ADD(&telnetwindow, &telnettextarea);
236
237 CTK_WIDGET_ADD(&telnetwindow, &telnetsep2);
238 CTK_WIDGET_ADD(&telnetwindow, &telnetstatus);
239
240 CTK_WIDGET_FOCUS(&telnetwindow, &telnethosttextentry);
241
242 /* Attach as a listener to the CTK button press signal. */
243 /* dispatcher_listen(ctk_signal_button_activate);
244 dispatcher_listen(ctk_signal_window_close);
245 dispatcher_listen(resolv_signal_found);*/
246
247 ctk_window_open(&telnetwindow);
248
249 } else if(ev == ctk_signal_button_activate) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000250
251 w = (struct ctk_widget *)data;
252 if(w == (struct ctk_widget *)&telnetsendbutton) {
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000253 strcpy(sendline, telnetline);
254 sendlen = strlen(sendline);
255 petsciiconv_toascii(sendline, sendlen);
256 sendline[sendlen++] = ISO_CR;
257 sendline[sendlen++] = ISO_NL;
258 if(telnet_send(&ts_appstate, sendline, sendlen)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000259 /* Could not send. */
260 ctk_label_set_text(&telnetstatus, "Could not send");
261 ctk_window_redraw(&telnetwindow);
262 /* } else {*/
263 /* Could send */
264 }
265 } else if(w == (struct ctk_widget *)&telnetdisconnectbutton) {
266 telnet_close(&ts_appstate);
267 show("Closing...");
268 } else if(w == (struct ctk_widget *)&telnetconnectbutton) {
269 connect();
270 ctk_window_redraw(&telnetwindow);
271 }
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000272 } else if(ev == resolv_event_found) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000273 if(strcmp(data, telnethost) == 0) {
274 if(resolv_lookup(telnethost) != NULL) {
275 connect();
276 } else {
277 show("Host not found");
278 }
279 }
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000280 } else if(ev == ctk_signal_window_close ||
281 ev == EK_EVENT_REQUEST_EXIT) {
282 ek_exit();
283 ctk_window_close(&telnetwindow);
oliverschmidtb1041b82004-09-12 20:02:16 +0000284 id = EK_ID_NONE;
adamdunkels8af703e2003-04-08 11:50:20 +0000285 LOADER_UNLOAD();
adamdunkelsf2f8cb22004-07-04 11:35:07 +0000286 } else if(ev == tcpip_event) {
287 telnet_app(data);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000288 }
289}
290/*-----------------------------------------------------------------------------------*/
291void
292telnet_connected(struct telnet_state *s)
293{
294 show("Connected");
295}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000296/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000297void
298telnet_closed(struct telnet_state *s)
299{
300 show("Connection closed");
301}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000302/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000303void
304telnet_sent(struct telnet_state *s)
305{
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000306 petsciiconv_topetscii(sendline, sizeof(sendline));
307 scrollup();
308 add_text(sendline);
309 CTK_TEXTENTRY_CLEAR(&telnetlinetextentry);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000310 ctk_window_redraw(&telnetwindow);
311}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000312/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000313void
314telnet_aborted(struct telnet_state *s)
315{
316 show("Connection reset by peer");
317}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000318/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000319void
320telnet_timedout(struct telnet_state *s)
321{
322 show("Connection timed out");
323}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000324/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000325void
326telnet_newdata(struct telnet_state *s, char *data, u16_t len)
327{
328 petsciiconv_topetscii(data, len);
329 data[len] = 0;
330 add_text(data);
331 ctk_window_redraw(&telnetwindow);
332}
oliverschmidtbe6e4dc2005-04-16 14:17:32 +0000333/*-----------------------------------------------------------------------------------*/