Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages   Examples  

tcp_server_demo.c

An example TCP application working as a server (waiting for an external host to establish a connection and then exchanging some data with it).

Basically all OpenTCP applications are divided in three separate functions:

More details about this example:

/*
 *Copyright (c) 2000-2002 Viola Systems Ltd.
 *All rights reserved.
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions 
 *are met:
 *
 *1. Redistributions of source code must retain the above copyright 
 *notice, this list of conditions and the following disclaimer.
 *
 *2. Redistributions in binary form must reproduce the above copyright 
 *notice, this list of conditions and the following disclaimer in the 
 *documentation and/or other materials provided with the distribution.
 *
 *3. The end-user documentation included with the redistribution, if 
 *any, must include the following acknowledgment:
 *      "This product includes software developed by Viola 
 *      Systems (http://www.violasystems.com/)."
 *
 *Alternately, this acknowledgment may appear in the software itself, 
 *if and wherever such third-party acknowledgments normally appear.
 *
 *4. The names "OpenTCP" and "Viola Systems" must not be used to 
 *endorse or promote products derived from this software without prior 
 *written permission. For written permission, please contact 
 *opentcp@opentcp.org.
 *
 *5. Products derived from this software may not be called "OpenTCP", 
 *nor may "OpenTCP" appear in their name, without prior written 
 *permission of the Viola Systems Ltd.
 *
 *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 
 *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE 
 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *====================================================================
 *
 *OpenTCP is the unified open source TCP/IP stack available on a series 
 *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
 *
 *For more information on how to network-enable your devices, or how to 
 *obtain commercial technical support for OpenTCP, please see 
 *<http://www.violasystems.com/>.
 */

#include <inet/debug.h>
#include <inet/datatypes.h>
#include <inet/globalvariables.h>
#include <inet/system.h>
#include <inet/tcp_ip.h>



/* The applications that use TCP must implement following function stubs                        */
/* void application_name_init (void) - call once when processor starts                          */
/* void application_name_run (void) - call periodically on main loop                            */
/* INT32 application_name_eventlistener (INT8, UINT8, UINT32, UINT32)                           */
/* - called by TCP input process to inform arriving data, errors etc */

/* These will probably go to some include file */
void tcps_demo_init(void);
void tcps_demo_run(void);
INT32 tcps_demo_eventlistener(INT8 , UINT8 , UINT32 , UINT32 );

INT8 tcps_demo_soch;

UINT8 tcps_demo_senddata; 
#define TCPS_DEMO_PORT  5001 
/* Internal function used for sending data to a predefined host */
INT16 tcps_demo_send(void);

/* Initialize resources needed for the TCP server application */
void tcps_demo_init(void)
{
        
        DEBUGOUT("Initializing TCP server application. \r\n");
                
        /* Get socket:
         *      TCP_TYPE_SERVER - type of TCP socket is server
         *      TCP_TOS_NORMAL  - no other type of service implemented so far
         *      TCP_DEF_TOUT    - timeout value in seconds. If for this many seconds
         *              no data is exchanged over the TCP connection the socket will be
         *              closed.
         *      tcps_demo_eventlistener - pointer to event listener function for
         *              this socket.    
         */

        tcps_demo_soch = tcp_getsocket(TCP_TYPE_SERVER, TCP_TOS_NORMAL, TCP_DEF_TOUT, tcps_demo_eventlistener);
        
        if( tcps_demo_soch < 0 )
        {
                DEBUGOUT("TCP server unable to get socket. Resetting!!!\r\n");
                RESET_SYSTEM();
        }
        
        /* Put it to listen on some port        */
        tcp_listen(tcps_demo_soch,TCPS_DEMO_PORT);
        
        /* for now no data sending */
        tcps_demo_senddata=0;
}

void tcps_demo_run(void)
{
        
        UINT8   i;
        
        /* do maybe some other TCP server app stuff
         * .....
         */
        
        if(tcps_demo_senddata){
                if(tcps_demo_send()!=-1)                
                        tcps_demo_senddata=0;
        }
}

 /*
 * Event listener invoked when TCP/IP stack receives TCP data for
 * a given socket. Parameters:
 * - cbhandle - handle of the socket this packet is intended for. Check it
 *      just to be sure, but in general case not needed
 * - event - event that is notified. For TCP there are quite a few possible
 *      events, check switch structure below for more information
 * - par1, par2 - parameters who's use depends on the event that is notified
 */
INT32 tcps_demo_eventlistener(INT8 cbhandle, UINT8 event, UINT32 par1, UINT32 par2)
{
/* This function is called by TCP stack to inform about events  */
        UINT16 i;
        
        if( cbhandle != tcps_demo_soch)         /* Not our handle       */
                return(-1);
        
        switch( event ){
                
                /* Connection request event. Used by TCP/IP stack to inform
                 * the application someone is trying to establish a connection.
                 * Server can decide, based on provided IP address and port number,
                 * whether to allow or not connection establishment.
                 * Parameters:
                 *  - par1 - remote hosts IP address
                 *  - par2 - remote hosts port number
                 * 
                 * Return values from event listener:
                 * -1 - do not allow connection to be established (send reset)
                 * -2 - do not send any response for now to the SYN packet (let's
                 *              think a little before answering)
                 * 1  - allow connection to be established
                 */
                case TCP_EVENT_CONREQ:
                        DEBUGOUT("Connection request arrived!\r\n");
                        
                        /* Enable all connections       */
                        return(1);
                
                        break;
                        
                /* Connection abort event. Connection on a given socket is beeing 
                 * aborted for somereason (usually retransmissions are used up or 
                 * some abnormal situation in communication happened).
                 * Parameters:
                 *  - par1 - remote hosts IP address
                 *  - par2 - remote hosts port number
                 */
                case TCP_EVENT_ABORT:
                        DEBUGOUT("Connection aborting!\r\n");
                        break;
                
                /* Connection established event - three-way handshaking performed
                 * OK and connection is established.
                 * Parameters:
                 *  - par1 - remote hosts IP address
                 *  - par2 - remote hosts port number
                 */
                case TCP_EVENT_CONNECTED:
                        DEBUGOUT("TCP connection established!\r\n");
                
                        break;
                        
                /* Connection closing event. Happens when TCP connection is
                 * intentionally close by some side calling close function and
                 * initializing proper TCP connection close procedure.
                 * Parameters:
                 *  - par1 - remote hosts IP address
                 *  - par2 - remote hosts port number
                 */
                case TCP_EVENT_CLOSE:
                        DEBUGOUT("TCP Connection closing...!\r\n");
                        break;
                        
                /* Data acknowledgment event. Happens when data that was
                 * previously sent gets acknowledged. This means we can now
                 * send some more data! :-)
                 * Parameters:
                 *  - par1 - remote hosts IP address
                 *  - par2 - remote hosts port number
                 */
                case TCP_EVENT_ACK:
                        DEBUGOUT("Data acknowledged!\r\n");
                        /* if more data should be sent, adjust variables and
                                set tcps_demo_senddata variable */
                                
                        break;
                
                /* Data received event. Happens when we receive some data over the
                 * TCP connection.
                 * Parameters:
                 *  - par1 - number of data bytes received
                 *  - par2 = 0
                 */
                case TCP_EVENT_DATA:
                        DEBUGOUT("Data arrived!\r\n");
                        /* read data that was received (and 
                         * probably do something with it :-)
                         */
                        for(i=0;i<par1;i++)
                                RECEIVE_NETWORK_B();
                                
                        /* If needed initialize data sending
                         * by setting tcps_demo_senddata variable
                         */
                        break;
                        
                /* Regenerate data event. Happens when data needs to be
                 * retransmitted because of possible loss on the network.
                 * Note that THE SAME DATA must be sent over and over again
                 * until TCP_EVENT_ACK is generated (for that data)! 
                 * Parameters:
                 *  - par1 - amount of data to regenerate (usually all)
                 *      - par2 = 0
                 */
                case TCP_EVENT_REGENERATE:
                        tcps_demo_send();
                        break;
        
        
                default:
                        return(-1);
        }
}

INT16 tcps_demo_send(void){
        UINT16 i;
        /* first check if data sending is possible (it may be that
         * previously sent data is not yet acknowledged)
         */
        if(tcp_checksend(tcps_demo_soch) < 0 ){
                /* Not yet */
                return -1;
        }
        
        /* put message in buffer. Message needs to start from TCP_APP_OFFSET
         * because TCP/IP stack will put headers in front of the message to
         * avoid data copying
         */
        for(i=0;i<32;i++)
                net_buf[TCP_APP_OFFSET+i]='A'+(i%25);

        /* send data */
        return tcp_send(tcps_demo_soch, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 32);

}

Generated on Sun Aug 3 20:32:59 2003 for OpenTCP by doxygen1.2.18