source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/unix/port/netif/sio.c

Last change on this file was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 11.9 KB
Line 
1/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
2
3/* to get rid of implicit function declarations */
4#define _XOPEN_SOURCE 600
5#define _GNU_SOURCE
6
7/* build with Darwin C extensions not part of POSIX, i.e. FASYNC, SIGIO.
8 we can't use LWIP_UNIX_MACH because extensions need to be turned
9 on before any system headers (which are pulled in through cc.h)
10 are included */
11#if defined(__APPLE__)
12#define _DARWIN_C_SOURCE
13#endif
14
15#include "netif/sio.h"
16#include "netif/fifo.h"
17#include "lwip/debug.h"
18#include "lwip/def.h"
19#include "lwip/sys.h"
20#include "lwip/arch.h"
21#include "lwip/sio.h"
22#include "netif/ppp/ppp_opts.h"
23
24/* Following #undefs are here to keep compiler from issuing warnings
25 about them being double defined. (They are defined in lwip/inet.h
26 as well as the Unix #includes below.) */
27#undef htonl
28#undef ntohl
29#undef htons
30#undef ntohs
31#undef HTONL
32#undef NTOHL
33#undef HTONS
34#undef NTOHS
35
36#include <stdlib.h>
37#include <stdio.h>
38#if defined(LWIP_UNIX_OPENBSD)
39#include <util.h>
40#endif
41#include <termios.h>
42#include <stdio.h>
43#include <unistd.h>
44#include <fcntl.h>
45#include <signal.h>
46#include <string.h>
47#include <sys/signal.h>
48#include <sys/types.h>
49
50#ifndef LWIP_HAVE_SLIPIF
51#define LWIP_HAVE_SLIPIF 0
52#endif
53
54#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF) && defined(LWIP_UNIX_LINUX)
55#include <pty.h>
56#endif
57
58/*#define BAUDRATE B19200 */
59/*#define BAUDRATE B57600 */
60#define BAUDRATE B115200
61
62#ifndef TRUE
63#define TRUE 1
64#endif
65#ifndef FALSE
66#define FALSE 0
67#endif
68
69/* for all of you who dont define SIO_DEBUG in debug.h */
70#ifndef SIO_DEBUG
71#define SIO_DEBUG 0
72#endif
73
74
75/* typedef struct siostruct_t */
76/* { */
77/* sio_status_t *sio; */
78/* } siostruct_t; */
79
80/** array of ((siostruct*)netif->state)->sio structs */
81static sio_status_t statusar[4];
82
83#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
84/* --private-functions----------------------------------------------------------------- */
85/**
86 * Signal handler for ttyXX0 to indicate bytes received
87 * one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
88 */
89static void signal_handler_IO_0( int status )
90{
91 LWIP_UNUSED_ARG(status);
92 LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 0\n"));
93 fifoPut( &statusar[0].myfifo, statusar[0].fd );
94}
95
96/**
97 * Signal handler for ttyXX1 to indicate bytes received
98 * one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
99 */
100static void signal_handler_IO_1( int status )
101{
102 LWIP_UNUSED_ARG(status);
103 LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 1\n"));
104 fifoPut( &statusar[1].myfifo, statusar[1].fd );
105}
106#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
107
108/**
109* Initiation of serial device
110* @param device string with the device name and path, eg. "/dev/ttyS0"
111* @param devnum device number
112* @param siostat status
113* @return file handle to serial dev.
114*/
115static int sio_init( char * device, int devnum, sio_status_t * siostat )
116{
117 struct termios oldtio,newtio;
118#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
119 struct sigaction saio; /* definition of signal action */
120#endif
121 int fd;
122 LWIP_UNUSED_ARG(siostat);
123 LWIP_UNUSED_ARG(devnum);
124
125 /* open the device to be non-blocking (read will return immediately) */
126 fd = open( device, O_RDWR | O_NOCTTY | O_NONBLOCK );
127 if ( fd < 0 )
128 {
129 perror( device );
130 exit( -1 );
131 }
132
133#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
134 /* install the signal handler before making the device asynchronous */
135 switch ( devnum )
136 {
137 case 0:
138 LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_0\n") );
139 saio.sa_handler = signal_handler_IO_0;
140 break;
141 case 1:
142 LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_1\n") );
143 saio.sa_handler = signal_handler_IO_1;
144 break;
145 default:
146 LWIP_DEBUGF( SIO_DEBUG,("sioinit, devnum not allowed\n") );
147 break;
148 }
149
150 saio.sa_flags = 0;
151#if defined(LWIP_UNIX_LINUX)
152 saio.sa_restorer = NULL;
153#endif /* LWIP_UNIX_LINUX */
154 sigaction( SIGIO,&saio,NULL );
155
156 /* allow the process to receive SIGIO */
157 if ( fcntl( fd, F_SETOWN, getpid( ) ) != 0)
158 {
159 perror( device );
160 exit( -1 );
161 }
162 /* Make the file descriptor asynchronous (the manual page says only
163 O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
164 if ( fcntl( fd, F_SETFL, FASYNC ) != 0)
165 {
166 perror( device );
167 exit( -1 );
168 }
169#else
170 if ( fcntl( fd, F_SETFL, 0 ) != 0)
171 {
172 perror( device );
173 exit( -1 );
174 }
175
176#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
177
178 tcgetattr( fd,&oldtio ); /* save current port settings */
179 /* set new port settings */
180 /* see 'man termios' for further settings */
181 memset(&newtio, 0, sizeof(newtio));
182 newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
183 newtio.c_iflag = 0;
184 newtio.c_oflag = 0;
185 newtio.c_lflag = 0; /*ECHO; */
186 newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
187 newtio.c_cc[VTIME] = 0;
188
189 tcsetattr( fd,TCSANOW,&newtio );
190 tcflush( fd, TCIOFLUSH );
191
192 return fd;
193}
194
195/**
196*
197*/
198static void sio_speed( int fd, int speed )
199{
200 struct termios oldtio,newtio;
201 /* int fd; */
202
203 LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: baudcode:%d enter\n", fd, speed));
204
205 if ( fd < 0 )
206 {
207 LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: fd ERROR\n", fd));
208 exit( -1 );
209 }
210
211 tcgetattr( fd,&oldtio ); /* get current port settings */
212
213 /* set new port settings
214 * see 'man termios' for further settings */
215 memset(&newtio, 0, sizeof(newtio));
216 newtio.c_cflag = speed | CS8 | CLOCAL | CREAD; /* | CRTSCTS; */
217 newtio.c_iflag = 0;
218 newtio.c_oflag = 0;
219 newtio.c_lflag = 0; /*ECHO; */
220 newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
221 newtio.c_cc[VTIME] = 0;
222
223 tcsetattr( fd,TCSANOW,&newtio );
224 tcflush( fd, TCIOFLUSH );
225
226 LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: leave\n", fd));
227}
228
229/* --public-functions----------------------------------------------------------------------------- */
230void sio_send( u8_t c, sio_status_t * siostat )
231{
232 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
233
234 if ( write( siostat->fd, &c, 1 ) <= 0 )
235 {
236 LWIP_DEBUGF(SIO_DEBUG, ("sio_send[%d]: write refused\n", siostat->fd));
237 }
238}
239
240void sio_send_string( u8_t *str, sio_status_t * siostat )
241{
242 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
243 int len = strlen( (const char *)str );
244
245 if ( write( siostat->fd, str, len ) <= 0 )
246 {
247 LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: write refused\n", siostat->fd));
248 }
249 LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: sent: %s\n", siostat->fd, str));
250}
251
252
253void sio_flush( sio_status_t * siostat )
254{
255 LWIP_UNUSED_ARG(siostat);
256 /* not implemented in unix as it is not needed */
257 /*sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
258}
259
260
261#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
262/*u8_t sio_recv( struct netif * netif )*/
263u8_t sio_recv( sio_status_t * siostat )
264{
265 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
266 return fifoGet( &(siostat->myfifo) );
267}
268
269s16_t sio_poll(sio_status_t * siostat)
270{
271 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
272 return fifoGetNonBlock( &(siostat->myfifo) );
273}
274
275
276void sio_expect_string( u8_t *str, sio_status_t * siostat )
277{
278 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
279 u8_t c;
280 int finger=0;
281
282 LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: %s\n", siostat->fd, str));
283 while ( 1 )
284 {
285 c=fifoGet( &(siostat->myfifo) );
286 LWIP_DEBUGF(SIO_DEBUG, ("_%c", c));
287 if ( c==str[finger] )
288 {
289 finger++;
290 } else if ( finger > 0 )
291 {
292 /*it might fit in the beginning? */
293 if ( str[0] == c )
294 {
295 finger = 1;
296 }
297 }
298 if ( 0 == str[finger] )
299 break; /* done, we have a match */
300 }
301 LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: [match]\n", siostat->fd));
302}
303#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
304
305#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
306u32_t sio_write(sio_status_t * siostat, u8_t *buf, u32_t size)
307{
308 ssize_t wsz = write( siostat->fd, buf, size );
309 return wsz < 0 ? 0 : wsz;
310}
311
312u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
313{
314 ssize_t rsz = read( siostat->fd, buf, size );
315 return rsz < 0 ? 0 : rsz;
316}
317
318void sio_read_abort(sio_status_t * siostat)
319{
320 LWIP_UNUSED_ARG(siostat);
321 printf("sio_read_abort[%d]: not yet implemented for unix\n", siostat->fd);
322}
323#endif /* (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
324
325sio_fd_t sio_open(u8_t devnum)
326{
327 char dev[20];
328
329 /* would be nice with dynamic memory alloc */
330 sio_status_t * siostate = &statusar[ devnum ];
331/* siostruct_t * tmp; */
332
333
334/* tmp = (siostruct_t*)(netif->state); */
335/* tmp->sio = siostate; */
336
337/* tmp = (siostruct_t*)(netif->state); */
338
339/* ((sio_status_t*)(tmp->sio))->fd = 0; */
340
341 LWIP_DEBUGF(SIO_DEBUG, ("sio_open: for devnum %d\n", devnum));
342
343#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
344 fifoInit( &siostate->myfifo );
345#endif /* ! PPP_SUPPORT */
346
347 snprintf( dev, sizeof(dev), "/dev/ttyS%d", devnum );
348
349 if ( (devnum == 1) || (devnum == 0) )
350 {
351 if ( ( siostate->fd = sio_init( dev, devnum, siostate ) ) == 0 )
352 {
353 LWIP_DEBUGF(SIO_DEBUG, ("sio_open: ERROR opening serial device dev=%s\n", dev));
354 abort( );
355 return NULL;
356 }
357 LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: dev=%s open.\n", siostate->fd, dev));
358 }
359#if PPP_SUPPORT
360 else if (devnum == 2) {
361 pid_t childpid;
362 char name[256];
363 childpid = forkpty(&siostate->fd, name, NULL, NULL);
364 if(childpid < 0) {
365 perror("forkpty");
366 exit (1);
367 }
368 if(childpid == 0) {
369 execl("/usr/sbin/pppd", "pppd",
370 "ms-dns", "198.168.100.7",
371 "local", "crtscts",
372 "debug",
373#ifdef LWIP_PPP_CHAP_TEST
374 "auth",
375 "require-chap",
376 "remotename", "lwip",
377#else
378 "noauth",
379#endif
380#if LWIP_IPV6
381 "+ipv6",
382#endif
383 "192.168.1.1:192.168.1.2",
384 NULL);
385 perror("execl pppd");
386 exit (1);
387 } else {
388 LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned pppd pid %d on %s\n",
389 siostate->fd, childpid, name));
390 }
391
392 }
393#endif
394#if LWIP_HAVE_SLIPIF
395 else if (devnum == 3) {
396 pid_t childpid;
397 /* create PTY pair */
398 siostate->fd = posix_openpt(O_RDWR | O_NOCTTY);
399 if (siostate->fd < 0) {
400 perror("open pty master");
401 exit (1);
402 }
403 if (grantpt(siostate->fd) != 0) {
404 perror("grant pty master");
405 exit (1);
406 }
407 if (unlockpt(siostate->fd) != 0) {
408 perror("unlock pty master");
409 exit (1);
410 }
411 LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: for %s\n",
412 siostate->fd, ptsname(siostate->fd)));
413 /* fork for slattach */
414 childpid = fork();
415 if(childpid < 0) {
416 perror("fork");
417 exit (1);
418 }
419 if(childpid == 0) {
420 /* esteblish SLIP interface on host side connected to PTY slave */
421 execl("/sbin/slattach", "slattach",
422 "-d", "-v", "-L", "-p", "slip",
423 ptsname(siostate->fd),
424 NULL);
425 perror("execl slattach");
426 exit (1);
427 } else {
428 int ret;
429 char buf[1024];
430 LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned slattach pid %d on %s\n",
431 siostate->fd, childpid, ptsname(siostate->fd)));
432 /* wait a moment for slattach startup */
433 sleep(1);
434 /* configure SLIP interface on host side as P2P interface */
435 snprintf(buf, sizeof(buf),
436 "/sbin/ifconfig sl0 mtu %d %s pointopoint %s up",
437 SLIP_MAX_SIZE, "192.168.2.1", "192.168.2.2");
438 LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: system(\"%s\");\n", siostate->fd, buf));
439 ret = system(buf);
440 if (ret < 0) {
441 perror("ifconfig failed");
442 exit(1);
443 }
444 }
445 }
446#endif /* LWIP_HAVE_SLIPIF */
447 else
448 {
449 LWIP_DEBUGF(SIO_DEBUG, ("sio_open: device %s (%d) is not supported\n", dev, devnum));
450 return NULL;
451 }
452
453 return siostate;
454}
455
456/**
457*
458*/
459void sio_change_baud( sioBaudrates baud, sio_status_t * siostat )
460{
461 /* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
462
463 LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]\n", siostat->fd));
464
465 switch ( baud )
466 {
467 case SIO_BAUD_9600:
468 sio_speed( siostat->fd, B9600 );
469 break;
470 case SIO_BAUD_19200:
471 sio_speed( siostat->fd, B19200 );
472 break;
473 case SIO_BAUD_38400:
474 sio_speed( siostat->fd, B38400 );
475 break;
476 case SIO_BAUD_57600:
477 sio_speed( siostat->fd, B57600 );
478 break;
479 case SIO_BAUD_115200:
480 sio_speed( siostat->fd, B115200 );
481 break;
482
483 default:
484 LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]: Unknown baudrate, code:%d\n",
485 siostat->fd, baud));
486 break;
487 }
488}
489
Note: See TracBrowser for help on using the repository browser.