--- In "juanyrascon" <> wrote:
>
>
> How can i do one serial to ethernet converter with my ts7300.
// -------------------------------------------------------------------
---
// Default values:
//
// /dev/ttyAM0 -d{value} overrides this setting
// 115200 baud -b{value} overrides this settings
// TCP port 10023 -t{value} overrides this setting
// Fragile enabled -f{yes | no} overrides this setting
//
// make CROSS_COMPILE=arm-unknown-linux-gnu- factest
//
// -------------------------------------------------------------------
---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <sys/mman.h> // We seize control of memory mapped
devices
#include "nvcore.h" // For standard types
#include "stunnel.h" // Always include ourself
#include "myutils.h" // For general utility functions
// -------------------------------------------------------------------
---
// General local data storage for this process
//
// -------------------------------------------------------------------
---
static int mem_handle;
static vuint8 * watchdog_feed_p;
static vuint8 * watchdog_control_p;
static int module_serial_port;
static uint8 process_kill_yourself;
// -------------------------------------------------------------------
---
// Local data storage for TCP connections
//
// -------------------------------------------------------------------
---
static SOCKET socket_listen;
static SOCKET socket_accepted;
static struct sockaddr_in channel_listen;
static uint8 listen_connected;
static fd_set read_tcp_set;
// -------------------------------------------------------------------
---
// Command line arguments can alter these values
//
// -------------------------------------------------------------------
---
static uint8 serial_device[101];
static uint16 baud_rate;
static uint16 tcp_port;
static uint8 fragile_sockets;
//--------------------------------------------------------------------
------------------------------
// Function Name: initialize_process()
//
// Description: This function will initialize the local data
storage
// for this process.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void initialize_process(void)
{
// Initialize this process' data
watchdog_feed_p = (vuint8 *)NULL;
watchdog_control_p = (vuint8 *)NULL;
module_serial_port = 0;
socket_listen = (SOCKET)-1;
socket_accepted = (SOCKET)-1;
listen_connected = FALSE;
process_kill_yourself = FALSE;
// Get a handle on device memory
mem_handle = open("/dev/mem", O_RDWR);
// Create pointers to the watchdog memory
watchdog_control_p = (uint8 *)mmap(0, getpagesize(),
PROT_READ | PROT_WRITE, MAP_SHARED, mem_handle, 0x23800000);
watchdog_feed_p = (uint8 *)mmap(0, getpagesize(),
PROT_READ | PROT_WRITE, MAP_SHARED, mem_handle, 0x23C00000);
// Kick and then configure the watchdog
*watchdog_feed_p = 0x05;
*watchdog_control_p = 0x07;
// Set up the default configurable items
(void)strcpy(serial_device, DEFAULT_SERIAL_DEVICE);
baud_rate = DEFAULT_BAUD_RATE;
tcp_port = DEFAULT_TCP_PORT;
fragile_sockets = DEFAULT_FRAGILITY;
}
//--------------------------------------------------------------------
------------------------------
// Function Name: kick_watchdog()
//
// Description: Kick the watchdog to keep the timer from resetting
// the CPU while we are working with it.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void kick_watchdog(void)
{
// Kick the watchdog to reset its timeout timer
*watchdog_feed_p = 0x05;
}
//--------------------------------------------------------------------
------------------------------
// Function Name: compute_baud()
//
// Description: This function will take an ASCII baud rate value
and
// convert it in to the Linux index value for the
baud rate,
// returning the value.
//
// Pre-Conditions:
//
// Parameters
// Local: argument_p -- A pointer to the ASCII string which
// contains the baud rate that was selected on the
// command line.
//
// Globals:
//
// Returns: The Linux defined constant for the selected baud
rate.
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static uint16 compute_baud(char * argument_p)
{
switch(atoi(argument_p))
{
case 1200: return(B1200);
case 4800: return(B4800);
case 9600: return(B9600);
case 19200: return(B19200);
case 38400: return(B38400);
case 57600: return(B57600);
case 115200: return(B115200);
default: return(B115200);
}
}
//--------------------------------------------------------------------
------------------------------
// Function Name: open_serial_interface()
//
// Description: The seriual interface is opened and configured
here.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void open_serial_interface(void)
{
struct termios newtio = { 0 };
// Open the serial interface
module_serial_port =
open(serial_device, O_RDWR | O_NDELAY | O_NOCTTY, 0);
// Set up the serial interface
tcgetattr(module_serial_port, &newtio);
newtio.c_cflag = CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNBRK | IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
cfsetispeed(&newtio, baud_rate);
cfsetospeed(&newtio, baud_rate);
tcsetattr(module_serial_port, TCSANOW, &newtio);
// Discard anything being sent or received
tcflush(module_serial_port, TCIFLUSH);
}
//--------------------------------------------------------------------
------------------------------
// Function Name: establish_telnet_listen()
//
// Description: A TCP listen is established on the configured TCP
port
// number, and the connection is made non-blocking.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void establish_telnet_listen(void)
{
uint16 option = 1;
// Create listening socket
socket_listen = socket(AF_INET, SOCK_STREAM, 0);
// Zero the associated control block
(void)memset((uint8 *)&channel_listen, 0x00, sizeof
(channel_listen));
// And set its values
channel_listen.sin_family = AF_INET;
channel_listen.sin_addr.s_addr = INADDR_ANY;
channel_listen.sin_port = htons(tcp_port);
// Set the listen socket for non-blocking
myutils_set_non_blocking(socket_listen, TRUE);
// Set socket options
(void)setsockopt(socket_listen, SOL_SOCKET, SO_REUSEADDR,
(char *)&option, sizeof(uint16));
// Let's set keep alive on the socket
option = 1;
(void)setsockopt(socket_listen, SOL_SOCKET, SO_KEEPALIVE,
(char *)&option, sizeof(uint16));
// And bind the socket
(void)bind(socket_listen,
(struct sockaddr *)&channel_listen,
sizeof(channel_listen));
// Set up the listen on that
(void)listen(socket_listen, 5);
// We want to select() on that TCP socket we listen on
FD_ZERO(&read_tcp_set);
}
//--------------------------------------------------------------------
------------------------------
// Function Name: check_for_serial_data()
//
// Description: The serial interface is checked to see if there is
any
// data waiting. If there is, it is read out and if
there
// is a Telnet session established, the data is sent
out
// the Telnet socket.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void check_for_serial_data(void)
{
uint8 in_buffer[1001] = { 0, 0 };
int32 write_result = 0L;
int32 updated_count = 0L;
uint8 * slow_write_p = (uint8 *)NULL;
// Let's make sure that the serial interface is open
if (module_serial_port == 0)
{
// We didn't open the device
return;
}
// Get characters into our local stack buffer
updated_count =
read(module_serial_port, in_buffer, (sizeof(in_buffer)));
// Are there any characters read?
if (updated_count > 0)
{
// Is there a Telnet TCP connection up?
if (TRUE == listen_connected)
{
// Write the serial data out the TCP connection
slow_write_p = in_buffer;
write_result =
write(socket_accepted, slow_write_p, updated_count);
// Let's confirm that the write was fully successful
while (write_result >= 0 && write_result < updated_count)
{
// We must wait for room to be made
usleep(TS72XX_USLEEP_GRANULARITY * 20);
// Update the count remaining
updated_count -= write_result;
// Point to the remaining to be sent
slow_write_p += write_result;
// And attempt to write the remaining block
write_result =
write(socket_accepted, slow_write_p,
updated_count);
}
}
}
}
//--------------------------------------------------------------------
------------------------------
// Function Name: check_for_tcp_data()
//
// Description: If a Telnet session is established, this function
will
// read out the data and send it out the serial
interface.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void check_for_tcp_data(void)
{
uint8 in_buffer[1001] = { 0, 0 };
struct timeval timeout = { 0 };
SOCKET socket_drop = (SOCKET)-1;
int32 write_result = 0L;
int32 updated_count = 0L;
uint8 * slow_write_p = (uint8 *)NULL;
// Is the inbound TCP being listened on? Should be.
if ((SOCKET)-1 == socket_listen)
{
// We are not listening so do nothing
(void)printf("Error: We are no longer listening\n");
return;
}
// Do we currently have a connection?
if (FALSE == listen_connected)
{
// See if it's waiting for an accept to an inbound
timeout.tv_sec = 0;
timeout.tv_usec = 10;
// Make sure that we are selecting for readability
FD_ZERO(&read_tcp_set);
FD_SET(socket_listen, &read_tcp_set);
updated_count = select((socket_listen + 1),
&read_tcp_set, NULL, NULL, &timeout);
// Check for an error condition
if (updated_count < 0)
{
return;
}
// Check for no read or exception
if (updated_count == 0)
{
// Apparently we don't have a connection yet
return;
}
// We're supposedly readable now
if (FD_ISSET(socket_listen, &read_tcp_set))
{
// Accept server connection
socket_accepted = accept(socket_listen, NULL, NULL);
// Was the accept successful?
if (socket_accepted < 0)
{
// We had a problem with accepting the connection
return;
}
else
{
// Flag the fact that we're connected
listen_connected = TRUE;
// Set the accepted TCP connection to non-blocking
myutils_set_non_blocking(socket_accepted, TRUE);
(void)printf("TCP connection established\n");
}
}
else
{
// No connection is waiting to be accepted
return;
}
}
else
{
// We have a connection already. Is another pending?
timeout.tv_sec = 0;
timeout.tv_usec = 10;
// Make sure that we are selecting for readability
FD_ZERO(&read_tcp_set);
FD_SET(socket_listen, &read_tcp_set);
updated_count = select((socket_listen + 1),
&read_tcp_set, NULL, NULL, &timeout);
// Check for no read or exception
if (updated_count != 0)
{
if (FD_ISSET(socket_listen, &read_tcp_set))
{
// Accept that connection
socket_drop = accept(socket_listen, NULL, NULL);
// Let's swap processes to let that accept take
usleep(TS72XX_USLEEP_GRANULARITY);
// Check for fragility
if (TRUE == fragile_sockets)
{
// Adopt the new connection. First we drop the
old
(void)close(socket_accepted);
// Then we adopt the new socket
socket_accepted = socket_drop;
(void)printf("Secondary connection adopted, old
dropped\n");
}
else
{
(void)printf("Disallowed secondary connection\n");
// And then drop it
(void)close(socket_drop);
}
}
}
}
// Verify that we have an accepted socket
if ((SOCKET)-1 == socket_accepted)
{
// Something happened so we're no longer connected
listen_connected = FALSE;
// We can't do anything else
return;
}
// Get characters into our local stack buffer
updated_count =
read(socket_accepted, in_buffer, (sizeof(in_buffer) - 1));
// Check to see if the socket closed
if (updated_count == 0)
{
// The socket did close on us
listen_connected = FALSE;
socket_accepted = (SOCKET)-1;
(void)printf("TCP connection has been dropped\n");
// And we are done here
return;
}
// Make sure that we got a positive byte count
if (updated_count > 0)
{
// Send the TCP data out the serial interface
slow_write_p = in_buffer;
write_result =
write(module_serial_port, slow_write_p, updated_count);
// Let's confirm that the write was fully successful
while (write_result >= 0 && write_result < updated_count)
{
// We must wait for room to be made
usleep(TS72XX_USLEEP_GRANULARITY * 20);
// Update the count remaining
updated_count -= write_result;
// Point to the remaining to be sent
slow_write_p += write_result;
// And attempt to write the remaining block
write_result =
write(module_serial_port, slow_write_p,
updated_count);
}
}
}
//--------------------------------------------------------------------
------------------------------
// Function Name: display_process_help_screen()
//
// Description: The help screen for the process is displayed here.
//
// Pre-Conditions:
//
// Parameters
// Local: void
//
// Globals:
//
// Returns: void
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void display_process_help_screen(void)
{
(void)printf("\n");
(void)printf("This process will create a serial-to-ethernet
tunnel so\n");
(void)printf("that people may telnet to serial devices which are
plugged\n");
(void)printf("in to the Safetran product's serial interface. You
may\n");
(void)printf("specify the serial interface, baud rate, the TCP
port to\n");
(void)printf("listen on, and whether fragile sockets is enabled
or not.\n");
(void)printf("\n");
(void)printf("Default values:\n");
(void)printf(" /dev/ttyAM0 -d{value} overrides this
setting\n");
(void)printf(" 115200 baud -b{value} overrides this
settings\n");
(void)printf(" TCP port 10023 -t{value} overrides this
setting\n");
(void)printf(" Fragile enabled -f{yes | no} overrides this
setting\n");
(void)printf("\n");
}
//--------------------------------------------------------------------
------------------------------
// Function Name: handle_command_arguments()
//
// Description: This function checks to see if any command line
arguments
// were received and if there were, they get handled.
//
// Pre-Conditions:
//
// Parameters
// Local: argc -- The number of command line arguments that
// were received when the process was launched
//
// argv -- A pointer to an array of pointers which
point to
// the optional command like arguments entered when
this
// process was launched
//
// Globals:
//
// Returns:
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
static void handle_command_arguments(int argc, char * * argv)
{
uint8 * first_argument_p = (uint8 *)NULL;
uint8 which_argument = 0;
// Go through any arguments passed on the command line
for (which_argument = 1; which_argument < argc; which_argument++)
{
// Point to the argument
first_argument_p = &argv[which_argument][0];
// Discard any leading spaces or tabs
skipspace(first_argument_p)
{
// Determine what the first characer of the argument is
switch(*first_argument_p)
{
default:
{
// It's not an argument that we understand
break;
}
case '-':
{
// Discard all dashes that may exist
while (*first_argument_p == '-')
{
first_argument_p++;
}
// Discard any leading space or tabs
skipspace(first_argument_p);
// Find out what the argument for the switch
// command is and act on that command
switch(*first_argument_p)
{
case 'd':
case 'D':
{
// Point to the start of the serial device
first_argument_p++;
// Store the new serial device
(void)strcpy(serial_device,
first_argument_p);
break;
}
case 'b':
case 'B':
{
// Point to the start of the baud rate
first_argument_p++;
// Extract and convert baud rate
baud_rate = compute_baud
(first_argument_p);
break;
}
case 't':
case 'T':
{
// Point to the start of the TCP port
number
first_argument_p++;
// Extract the new TCP port number
tcp_port = atoi(first_argument_p);
break;
}
case 'f':
case 'F':
{
// Point to the start of the fragility
setting
first_argument_p++;
// See if there is a valid boolean
if (! my_strnicmp
(first_argument_p, "yes", 3))
{
fragile_sockets = TRUE;
}
else if (! my_strnicmp
(first_argument_p, "no", 2))
{
fragile_sockets = FALSE;
}
else if (! my_strnicmp
(first_argument_p, "true", 4))
{
fragile_sockets = TRUE;
}
else if (! my_strnicmp
(first_argument_p, "false", 5))
{
fragile_sockets = FALSE;
}
break;
}
case 'h':
case 'H':
{
// Display some helpful information
display_process_help_screen();
// Since it was only a help request, exit
exit(0);
// Should never get to this point
break;
}
default:
{
// It's not a switch statement that we
// understand so pretty much ignore it.
break;
}
}
}
}
}
}
}
//--------------------------------------------------------------------
------------------------------
// Function Name: main()
//
// Description: This is the main entry point for the serial tunnel.
//
// Pre-Conditions:
//
// Parameters
// Local: argc -- The number of arguments passed to this
process
//
// argv -- A pointer to an array or pointers which
point
// to optional arguments passed to this process
//
// Globals:
//
// Returns: An error code or 0
//
// Reference: none
//
//--------------------------------------------------------------------
------------------------------
int main(int argc, char * * argv)
{
// Initialize this process and select default values
initialize_process();
// Check to see if command line arguments will be altering the
// way we do things here.
handle_command_arguments(argc, argv);
kick_watchdog();
// Acquire the serial interface
open_serial_interface();
// Set up the listen on the TCP port
establish_telnet_listen();
// This process goes into a forever loop
while(! process_kill_yourself)
{
// Let some other process have control for 20ms
usleep(TS72XX_USLEEP_GRANULARITY);
// See if there is serial data waiting
check_for_serial_data();
// See if there is TCP data waiting
check_for_tcp_data();
}
// Should never be able to get to this point
return(0);
}
// End of file
// -------------------------------------------------------------------
---
// stunnel.h
//
// -------------------------------------------------------------------
---
#ifndef STUNNEL_H
#define STUNNEL_H 1
// -------------------------------------------------------------------
---
// Defined constants which we will use
//
// -------------------------------------------------------------------
---
#define DEFAULT_SERIAL_DEVICE "/dev/ttyAM0"
#define DEFAULT_BAUD_RATE B115200
#define DEFAULT_TCP_PORT 10023
#define DEFAULT_FRAGILITY TRUE
#endif
// End of file
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|