Sony Ericsson Embedded Applications Application Note

Application Note
Embedded Applications
Using the on board TCP/IP stack
First edition (September 2004)
Sony Ericsson Mobile Communications. publishes this manual without making any warranty as to the content contained herein. Further Sony Ericsson Mobile Communications. reserves the right to make modifications,
additions and deletions to this manual due to typographical errors, inaccurate information, or improvements to programs and/or equipment at any time and without notice. Such changes will, nevertheless be incorporated into new editions of this manual.
All rights reserved.
© Sony Ericsson Mobile Communications., 2004
EMBEDDED APPLICATIONS FCT
Contents
Contents.....................................................................................................3
1 Introduction ........................................................................................4
2 Using the Embedded Application TCP/IP Functions for Data
Exchange....................................................................................................5
2.1 Overview of Embedded Applications TCP/IP ............................................5
2.2 Basic Usage of TCP/IP Features...............................................................6
2.2.1 Protocols........................................................................................6
2.2.2 GPRS Transport for IP...................................................................6
2.2.3 Flow of TCP/IP Operations in a Script ...........................................6
2.2.4 TCP Connect Operations...............................................................7
2.2.5 Testing Communications over TCP/IP...........................................8
2.3 General Restrictions ..................................................................................8
2.4 Resource Restrictions ...............................................................................8
2.4.1 Packet Buffers ...............................................................................8
2.4.2 IP Fragmentation ...........................................................................9
2.4.3 Performance ..................................................................................9
2.5 UDP Example Script {UDP_transfer.sc} ..................................................10
2.6 TCP Example Script {TCP_transfer.sc} ...................................................12
2.7 TCP Send Function Script {TCP_send.sc} ..............................................14
2.8 Host Name Resolution.............................................................................15
2.9 IP Status Flags and Bytes .......................................................................15
2.10 Advanced Technical Details ....................................................................16
2.10.1 Time-to-Live (TTL) .......................................................................16
2.10.2 DNS Name Caching Period .........................................................16
LZT 123 8019 R1A 3
EMBEDDED APPLICATIONS FCT
1 Introduction
This application note describes the use of the TCP/IP sack that is resident on the module within the embedded applications environment.
LZT 123 8019 R1A 4
EMBEDDED APPLICATIONS FCT
2 Using the Embedded Application TCP/IP Functions for Data Exchange
2.1 Overview of Embedded Applications TCP/IP
The TCP/IP features provided by the embedded application functions of the radio device are intended to provide a subset of the features normally available at the socket level when using a conventional TCP/IP stack, with some simplification and customization based on the specific features of the radio device.
The features allow the application-writer to create and destroy UDP and TCP sockets, to control underlying GPRS PDP contexts, to transfer data to and from the radio device, and to interrogate IP status information about the active link.
The socket interface is provided by a series of functions outlined below:
pdpa() Activate and deactivate a PDP context for TCP/IP over GPRS
ipo() Open a UDP or TCP socket for data transfer
ipc() Close a previously opened UDP or TCP socket
tcpc() Connect to a TCP server specifying IP address and port
tcps() Send data over a previously connected TCP socket
tcpr() Receive data over a previously connected TCP socket
udps() Send data over a UDP socket
udpr() Receive data over a UDP socket
ipi() Obtain IP-related information associated with the GPRS link
iprh() Perform a text-to-IP-address hostname resolution
For full details of these functions, their parameters and possible return values, refer to the syntax data in the M2mpower IDE Help files.
The majority of the functions, with the exception of the tcpc() function, will only return once the requested operation is complete. More detail regarding tcpc() is provided in later sections of this application note.
LZT 123 8019 R1A 5
EMBEDDED APPLICATIONS FCT
2.2 Basic Usage of TCP/IP Features
2.2.1 Protocols
The radio device embedded application functions provide support for the IP, UDP and TCP protocols. The user has no direct control over the IP layer (for instance a raw sockets interface is not provided), it is simply used as a transport by the higher-level protocols.
UDP provides for fast connectionless, less reliable communications between the radio device and remote hosts; TCP provides slower but reliable, connection­oriented communications, with flow-control, sequence checking and reordering.
Whilst the lower-level stack provides support for ICMP (Internet Control Messaging Protocol) features, and ICMP packets influence the operation and performance of the lower-level TCP/IP stack, the application-writer has no direct access to any ICMP features.
2.2.2 GPRS Transport for IP
In order to use the embedded TCP/IP functions, a GPRS PDP context must be activated first, to provide the underlying IP transport. This should be done using the pdpa() function, not by using direct AT dial commands. The embedded applications TCP/IP cannot properly make use of a PDP context that has been created using the ATD command.
In order to activate a PDP context, the details associated with the context (such as APN) must have been previously established. This is achieved using the AT+CGDCONT command. Use of AT commands to define PDP contexts alongside TCP/IP functions is normal; it is the PDP activation and deactivation that should not be performed using AT commands.
Once the PDP context is active, a socket can be created to enable bi-directional communications using TCP or UDP.
2.2.3 Flow of TCP/IP Operations in a Script
The basic flow of the TCP/IP operations within a script will normally take the following form:
LZT 123 8019 R1A 6
EMBEDDED APPLICATIONS FCT
1
2
3
4
5
6
7
8
9
10
1
Define an appropriate PDP context according to Service Provider data
Activate the required PDP context
Create a socket
For TCP only, perform a Connect to a remote host
Send data or status information over the socket to a remote host
Receive data or status information over the socket from a remote host
Repeat steps 5 and 6 for as long as the connection is required
Once communications are complete, close the socket
Repeat steps 3 to 8 for communications with different remote hosts
Deactivate the PDP context
2.2.4 TCP Connect Operations
A TCP connect operation can take quite a long time to complete, depending upon the link performance, lost packets etc. Therefore the tcpc() function has been made non-blocking to avoid stalling the script for long periods.
A call to tcpc() will initiate a connection but return immediately, leaving the lower level system to connect as responses are received. If no connection is achieved within a timeout of approximately 75 seconds, an indication of the failure at the script level will occur when a send or receive is attempted on a socket for which the connection is not yet active. This means that the application-writer should do one of two things to ensure that send and receive operations do not fail because a connection has not yet completed, either
Before a send or receive operation check the connection status by using the gtb(TCP_STATUS_BYTE) function and checking against TCP_CONNECTED (where
LZT 123 8019 R1A 7
EMBEDDED APPLICATIONS FCT
TCP_STATUS_BYTE = 14, TCP_CONNECTED = 2), or
2 Check the result code from a send or receive operation
and if the code indicates CONNECTING (1) then retry the operation, with appropriate timeouts applied.
2.2.5 Testing Communications over TCP/IP
The TCP/IP stack supports ICMP operations, such as ping responses these influence the operation of the low-level stack. However, the application-writer cannot perform ping tests from within a script. The only method for testing whether a remote site can be accessed is to attempt either a UDP or TCP operation to the host.
2.3 General Restrictions
The TCP/IP interface supports a single socket meaning that the embedded application can have only a single active socket at any one time. Use of, for instance, a UDP socket and a TCP socket in the same application requires that the script closes one socket before attempting to open or re-open another. For the majority of applications, the module is only ever transferring data over a single socket, so the restriction will not cause problems.
2.4 Resource Restrictions
2.4.1 Packet Buffers
The TCP/IP system supports a maximum of six simultaneous packets of size 1-1536 bytes, plus an additional two packets of size 1537-3100 bytes. If, having assigned all of these buffers, additional packets are received, or queued for transmit, the packets will be silently dropped. The packet buffers are shared with the lower-level GPRS system, hence the limits apply to the total data being buffered within GPRS and TCP/IP software layers.
Due to the buffer considerations, it is strongly recommended to use TCP rather than UDP to transfer larger volumes of data, or any quantity of critical data. The likelihood of packet loss within the radio device when using UDP is quite high, even for infrequent ‘bursts’ of data transfer.
LZT 123 8019 R1A 8
EMBEDDED APPLICATIONS FCT
2.4.2 IP Fragmentation
The radio device stack supports IP fragmentation and will successfully reconstruct fragmented packets provided:
1
2
3
No individual fragment exceeds the maximum packet size of 3100 bytes
The total reconstructed size of the fragmented packet does not exceed 3100 bytes
The internal packet buffers are not exhausted during the period that the fragments are being received.
The TCP/IP stack will, especially during busy periods, buffer and consolidate transmit data. This will sometimes result in data being sent from the radio device in larger units than submitted by the application. However, the largest sent-packet size will not exceed the reported Maximum Transmission Unit (MTU) of the underlying link.
2.4.3 Performance
Both the GSM module and the underlying GPRS transport infrastructure impose performance restrictions that can influence the effective IP performance of the application such that throughput can not be guaranteed.
LZT 123 8019 R1A 9
EMBEDDED APPLICATIONS FCT
2.5 UDP Example Script {UDP_transfer.sc}
A simple example of a UDP data transfer script is listed below. The script creates a UDP socket, sends some start data and then sits in a receive loop until a ‘$’ character is received, after which it closes the socket and exits.
int Err; int Port = 3000; int Address = 0x0A8402A3; /* 10.132.2.163 */ int RXTX_SIZE = 1000; char RxTxBuf[RXTX_SIZE] = “Starting! “; char Complete = FALSE; int APPS_IP_ERROR_TRIGGER = 36; int APPS_IP_ERROR_STATUSBYTE = 13; int APPS_IP_DATA_RECVD = 13; int APPS_IP_TCPSTATUS_BYTE = 14;
/* Reset the IP error flag by reading it */ gtf( APPS_IP_ERROR_TRIGGER ); Err = pdpa( 1, 1 ); prtf( "\n PDP activate result = %d\n", Err ); if ( Err == 0 ) { Val = ipi( 0 ); prtf(" IP Address = %x", Val ); Val = ipi( 1 ); prtf( "\n DNS 1 = %x", Val ); Val = ipi( 2 ); prtf( "\n DNS 2 = %x\n", Val ); } else { prtf( "\n PDP activation failed!\n" ); return; } Err = ipo( 0, &SckNum ); if( Err != 0 ) { prtf( “ \n UDP Socket open failed!\n” ); } else { int len;
prtf( "\n UDP Socket Opened!\n" ); prtf( "\n Sending start data...\n" ); len = 10; Err = udps( SckNum, Port, Address, RxTxBuf, len ); while( !Complete && (gtb( APPS_IP_ERROR_STATUSBYTE ) == 0) ) { /* Receive some data */ if( gtf( APPS_IP_DATA_RECVD ) ) { prtf( "\n IP DATA RECVD" ); len = RXTX_SIZE; Err = udpr( SckNum, &Port, &Address, RxTxBuf, RXTX_SIZE, &len ); if( Err != 0 ) { prtf( "\n UDP receive error!\n" ); } }
LZT 123 8019 R1A 10
EMBEDDED APPLICATIONS FCT
else { prtf( “\nReceived %d bytes of data.\n”, len ); if ( RxTxBuf[0] == ‘$’ ) { prtf( “\n Breaking out of receive loop!\n” ); Complete = TRUE; } } }
/* Log status monitoring */ if( gtf( APPS_IP_ERROR_TRIGGER ) ) { prtf( "\n IP ERROR = %d\n", gtb( APPS_IP_ERROR_STATUSBYTE ) ); } } Err = ipc( SckNum ); if ( Err != 0 ) { prtf( “\n Socket close failed!\n” ); } Err = pdpa( 0, 1 ); prtf( "\n PDP deactivate result = %d\n", Err );
LZT 123 8019 R1A 11
EMBEDDED APPLICATIONS FCT
2.6 TCP Example Script {TCP_transfer.sc}
A simple example of a TCP data transfer script is listed below. The script creates a TCP socket, connects to a remote site and then sits in a receive loop until a ‘$’ character is received, after which it closes the socket and exits.
int Err; int PORTNUM = 3000; int IPADDRESS = 0x0A8402A3; /* 10.132.2.163 */ int RXTX_SIZE = 1000; char RxTxBuf[RXTX_SIZE] = “Starting! “; char Complete = FALSE; int APPS_IP_ERROR_TRIGGER = 36; int APPS_IP_ERROR_STATUSBYTE = 13; int APPS_IP_DATA_RECVD = 13; int APPS_IP_TCPSTATUS_BYTE = 14; int TCP_NOT_CONNECTED = 1; int TCP_CONNECTING = 2; int TCP_CONNECTED = 3;
/* Reset the IP error flag by reading it */ gtf( APPS_IP_ERROR_TRIGGER ); Err = pdpa( 1, 1 ); prtf( "\n PDP activate result = %d\n", Err ); if ( Err == 0 ) { Val = ipi( 0 ); prtf( " IP Address = %x", Val ); Val = ipi( 1 ); prtf( "\n DNS 1 = %x", Val ); Val = ipi( 2 ); prtf( "\n DNS 2 = %x\n", Val ); } else { prtf( "\n PDP activation failed!\n" ); return; } Err = ipo( 1, &SckNum ); if( Err != 0 ) { prtf( “ \n TCP Socket open failed!\n” ); } else { prtf( "\n TCP Socket Opened!\n" ); Err = tcpc( SckNum, Port, Address ); if( (Err == 0) || (Err == TCP_CONNECTING) || (Err == TCP_CONNECTED) ) { while( !Complete && (gtb( APPS_IP_ERROR_STATUSBYTE ) == 0) ) { int len;
/* Receive some data */ if( gtf( APPS_IP_DATA_RECVD ) ) { prtf( "\n IP DATA RECVD" );
LZT 123 8019 R1A 12
EMBEDDED APPLICATIONS FCT
len = RXTX_SIZE; Err = tcpr( SckNum, RxTxBuf, &len); if( Err != 0 ) { prtf( "\n *** Error in TCP Receive (%d). ***\n\n", Err ); } else { if( gtb( APPS_IP_TCPSTATUS_BYTE ) == TCP_CONNECTING ) { prtf( "\n Delaying while TCP Connect occurs...\n\n" ); } else { prtf( "\n Received %d bytes of data.\n\n", len ); } } }
/* Log status monitoring */ if( gtf( APPS_IP_ERROR_TRIGGER ) ) { prtf( "\n IP ERROR = %d\n", gtb( APPS_IP_ERROR_STATUSBYTE ) ); Complete = 1; }
if( gtb( APPS_IP_TCPSTATUS_BYTE ) == TCP_NOT_CONNECTED ) { prtf( "\n *** TCP Connection lost - dropping out! ***\n\n" ); Complete = 1; } } } Err = ipc( SckNum ); if ( Err != 0 ) { prtf( “\n Socket close failed!\n” ); } } Err = pdpa( 0, 1 ); prtf( "\n PDP deactivate result = %d\n", Err );
LZT 123 8019 R1A 13
EMBEDDED APPLICATIONS FCT
2.7 TCP Send Function Script {TCP_send.sc}
It is important to note that when using tcps(), the intrinsic TCP send function, the application-writer must check the number of bytes sent on successful return from the function, because a successful return is possible with the number of bytes actually sent being less than the number requested. In this case it is the responsibility of the application-writer to ensure that the remainder of the data buffer is re-submitted to the function.
The following is an example of a TCP send script function that checks for and corrects problems when not all data requested is sent by the tcps() function.
TCPSend( char cSckNum, char *cpTxBuffer, int *ipLen ) { int MAX_TX_ATTEMPTS = 20; int TX_FAILED = -2; int TCP_BACKOFF_DLYS = 2; int iResult = 0, iInitLen = *ipLen, iSent = 0, iTxAttempts = 0; int iReqLen; char *cpBuffer;
while ( (iSent != iInitLen) && (iResult == 0) ) { iReqLen = iInitLen - iSent; cpBuffer = cpTxBuffer + iSent;
iResult = tcps( cSckNum, cpBuffer, &iReqLen ); while ( (iResult != 0) && (iTxAttempts < MAX_TX_ATTEMPTS) ) { dlys( TCP_BACKOFF_DLYS ); iResult = tcps( cSckNum, cpBuffer, &iReqLen ); iTxAttempts++; } if ( iTxAttempts >= MAX_TX_ATTEMPTS ) { return TX_FAILED; }
iSent = iSent + iReqLen; if ( iSent != iInitLen ) { dlys( TCP_BACKOFF_DLYS ); } iTxAttempts++; }
return iResult; }
The parameters for the call to TCPSend are the same as for tcps(), but the length parameter is an input only. The function will not return until either all the data has been sent, or a failure has occurred. Obviously the values for
LZT 123 8019 R1A 14
EMBEDDED APPLICATIONS FCT
back-off delay and transmission retries can be adjusted to suit the application.
This function assumes that the caller has already checked that the TCP socket is connected, or if not, that the connection will become active within the timeout/retry period.
2.8 Host Name Resolution
Host name resolution in a script is performed using the iprh() function. The application-writer should be aware that the name lookup is effectively a blocking function. The script interpreter process will be blocked until the lookup is completed. This can lead to long script processing delays if something with the name resolution fails.
The name servers used by the lower-level stack are usually obtained dynamically when a PDP context is activated. The active settings can be interrogated using the ipi() function. A DNS lookup has a minimum timeout of approximately 124 seconds. Hence if all DNS servers are inaccessible (up to 3 are supported), or if the domain name does not resolve, there can be an overall delay of between 125 and 140 seconds before the iprh() function returns. During this delay script operation will stall, therefore the use of unreliable DNS servers could cause long pauses in operation.
2.9 IP Status Flags and Bytes
There are two status bytes and one status flag associated with the TCP/IP features. These are interrogated using the gtb() and gtf() script functions respectively.
The IP status flag APPS_IP_ERROR_TRIGGER (36) is set whenever an error occurs in the lower level IP system. The flag remains set until it is read, and is reset upon reading. The error that gave rise to the flag is obtained by reading the status byte APPS_IP_ERROR_STATUSBYTE (13). If several IP errors occur before the status flag is set the last error will be reported in the status byte.
The TCP system has a separate status byte called APPS_IP_TCPSTATUS_BYTE (14) which reports the current status of the TCP connection. This status can indicate that TCP is not-connected, connecting, or connected.
LZT 123 8019 R1A 15
EMBEDDED APPLICATIONS FCT
LZT 123 8019 R1A 16
2.10 Advanced Technical Details
This section lists a number of advanced technical points for users who wish to understand more of the fine details of the TCP/IP stack in the radio device. For most readers this information will not be relevant.
2.10.1 Time-to-Live (TTL)
The radio device IP stack uses a Time-to-Live (TTL) setting of 64. This figure is fixed as far as the application­writer is concerned; there is no high-level method for changing it. Many modern systems use a TTL of 128, but apart from the most complex of routing arrangements, a figure of 64 will be perfectly adequate.
2.10.2 DNS Name Caching Period
The TCP/IP stack of the radio device caches DNS name to address mapping data for a period of approximately 120 seconds after a successful lookup. During this period subsequent name lookups for the same host will be serviced from the cache with no query being sent to the servers.
A maximum of six resolved hosts can be held in the cache at any one time. If the cache is full and a new lookup is submitted, the new lookup will fail until such time as the oldest entry in the cache is deleted due to expiry of its timeout.
Loading...