Contiki 3.x
shell-tcpsend.c
1 /*
2  * Copyright (c) 2004, 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 copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * Author: Adam Dunkels <adam@sics.se>
32  *
33  */
34 
35 #include <string.h>
36 #include <stddef.h>
37 
38 #include "contiki.h"
39 #include "shell.h"
40 #include "telnet.h"
41 
42 #ifndef MIN
43 #define MIN(a, b) ((a) < (b)? (a) : (b))
44 #endif /* MIN */
45 
46 /*---------------------------------------------------------------------------*/
47 PROCESS(shell_tcpsend_process, "tcpsend");
48 SHELL_COMMAND(tcpsend_command,
49  "tcpsend",
50  "tcpsend <host> <port>: open a TCP connection",
51  &shell_tcpsend_process);
52 /*---------------------------------------------------------------------------*/
53 
54 #define MAX_SERVERLEN 16
55 
56 static uip_ipaddr_t serveraddr;
57 static char server[MAX_SERVERLEN + 1];
58 
59 static struct telnet_state s;
60 
61 static unsigned char running;
62 
63 #define MAX_LINELEN 80
64 
65 static char outputline[MAX_LINELEN];
66 static uint8_t sending;
67 /*---------------------------------------------------------------------------*/
68 void
69 telnet_text_output(struct telnet_state *s, char *text1, char *text2)
70 {
71  char buf1[MAX_SERVERLEN];
72  int len;
73 
74  strncpy(buf1, text1, sizeof(buf1));
75  len = strlen(buf1);
76  if(len < sizeof(buf1) - 1) {
77  buf1[len] = ' ';
78  buf1[len + 1] = 0;
79  }
80  shell_output_str(&tcpsend_command, buf1, text2);
81 }
82 /*---------------------------------------------------------------------------*/
83 void
84 telnet_newdata(struct telnet_state *s, char *data, uint16_t len)
85 {
86  shell_output(&tcpsend_command, data, len, "", 0);
87 }
88 /*---------------------------------------------------------------------------*/
89 static void
90 send_line(struct telnet_state *s, char *data, int len)
91 {
92  if(!sending) {
93  strncpy(outputline, data, MIN(sizeof(outputline), len));
94  telnet_send(s, data, len);
95  sending = 1;
96  } else {
97  shell_output_str(&tcpsend_command, "Cannot send data, still sending previous data", "");
98  }
99 }
100 /*---------------------------------------------------------------------------*/
101 void
102 telnet_sent(struct telnet_state *s)
103 {
104  sending = 0;
105 }
106 /*---------------------------------------------------------------------------*/
107 void
108 telnet_closed(struct telnet_state *s)
109 {
110  telnet_text_output(s, server, "connection closed");
111  running = 0;
112 }
113 /*---------------------------------------------------------------------------*/
114 void
115 telnet_aborted(struct telnet_state *s)
116 {
117  telnet_text_output(s, server, "connection aborted");
118  running = 0;
119 }
120 /*---------------------------------------------------------------------------*/
121 void
122 telnet_timedout(struct telnet_state *s)
123 {
124  telnet_text_output(s, server, "connection timed out");
125  running = 0;
126 }
127 /*---------------------------------------------------------------------------*/
128 void
129 telnet_connected(struct telnet_state *s)
130 {
131  telnet_text_output(s, server, "connected");
132 }
133 /*---------------------------------------------------------------------------*/
134 PROCESS_THREAD(shell_tcpsend_process, ev, data)
135 {
136  char *next;
137  const char *dummy;
138  struct shell_input *input;
139  uint16_t port;
140 
141  PROCESS_BEGIN();
142 
143  next = strchr(data, ' ');
144  if(next == NULL) {
145  shell_output_str(&tcpsend_command,
146  "tcpsend <server> <port>: server as address", "");
147  PROCESS_EXIT();
148  }
149  *next = 0;
150  ++next;
151  strncpy(server, data, sizeof(server));
152  port = shell_strtolong(next, &dummy);
153 
154  running = 1;
155 
156  uiplib_ipaddrconv(server, &serveraddr);
157  telnet_connect(&s, &serveraddr, port);
158  while(running) {
160 
161  if(ev == shell_event_input) {
162  input = data;
163  if(input->len1 + input->len2 == 0) {
164  PROCESS_EXIT();
165  }
166 
167  if(input->len1 > 0) {
168  send_line(&s, input->data1, input->len1);
169  }
170  } else if(ev == tcpip_event) {
171  telnet_app(data);
172 #if 0
173  } else if(ev == resolv_event_found) {
174  /* Either found a hostname, or not. */
175  if((char *)data != NULL &&
176  resolv_lookup((char *)data, &ipaddr) == RESOLV_STATUS_CACHED) {
177  uip_ipaddr_copy(serveraddr, ipaddr);
178  telnet_connect(&s, server, serveraddr, nick);
179  } else {
180  shell_output_str(&tcpsend_command, "Host not found.", "");
181  }
182 #endif /* 0 */
183  }
184  }
185 
186  PROCESS_END();
187 }
188 /*---------------------------------------------------------------------------*/
189 void
190 shell_tcpsend_init(void)
191 {
192  shell_register_command(&tcpsend_command);
193 }
194 /*---------------------------------------------------------------------------*/
Hostname is fresh and usable.
Definition: resolv.h:68
void shell_output_str(struct shell_command *c, char *text1, const char *text2)
Output strings from a shell command.
Definition: shell.c:383
#define PROCESS_EXIT()
Exit the currently running process.
Definition: process.h:200
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
Main header file for the Contiki shell
#define NULL
The null pointer.
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
void shell_output(struct shell_command *c, void *data1, int len1, const void *data2, int len2)
Output data from a shell command.
Definition: shell.c:395
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
unsigned long shell_strtolong(const char *str, const char **retstr)
Convert a string to a number.
Definition: shell.c:521
CCIF process_event_t resolv_event_found
Event that is broadcasted when a DNS name has been resolved.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1026
Structure for shell input data.
Definition: shell.h:365
void shell_register_command(struct shell_command *c)
Register a command with the shell.
Definition: shell.c:413
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
int shell_event_input
The event number for shell input data.
Definition: shell.c:70
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:75
#define SHELL_COMMAND(name, command, description, process)
Define a shell command.
Definition: shell.h:219