ISockPort supports multiple address families, which is specified once during ISockPort_OpenEx() and later by using the appropriate address structure. Currently, AEE_AF_INET and AEE_AF_INET6 address families are supported. IPv6 mapped IPv4 addresses are not supported.
ISockPort_OpenEx() is used to open a socket. When calling this function the following is specified - address family (e.g. AEE_AF_INET), socket type (e.g AEE_SOCKPORT_STREAM) and protocol (e.g. AEE_IPPROTO_TCP).
ISockPort_Connect() is called after opening a TCP socket. If the network subsystem (physical layer, RLP and PPP, etc.) of the device is not active, this function first establishes the necessary lower-layer protocol connections. For TCP sockets, ISockPort_Connect() then sets up a TCP connection to the specified IP address and port number.
After the TCP socket has been connected, read and write operations may be used to exchange data over it. All data transfer operations are non-blocking and asynchronous. Callback objects are used to notify the caller of the availability of socket for read or write operations. The caller can use ISockPort_Readable() to provide a callback object that will be resumed when there is data available to read. Similarly, ISockPort_Writeable() registers a callback object that gets resumed when the socket is available for writing. Registered callback objects are also resumed whenever BREW detects any error conditions on the socket that require the application using this socket to take action.
To cancel a pending callback operation, use CALLBACK_Cancel() on a callback object that was previously registered with ISockPort_Readable() or ISockPort_Writeable(). This will prevent the application from receiving notification when there is a change in the status of the socket it is waiting on.
ISockPort_Read() and ISockPort_Write() are used for reading data from and writing data to TCP sockets. If the read or write do not make progress, ISockPort_Read() and ISockPort_Write() returns an indication that blocking has occurred. The caller can then use ISockPort_Readable() or ISockPort_Writeable() to arrange to be notified when blocking is no longer present. If the number of bytes actually read or written is less than the number requested, repeat calls to ISockPort_Read() or ISockPort_Write() to complete the data transfer.
ISockPort_ReadV() and ISockPort_WriteV() are used to receive and send data on TCP sockets when the application uses multiple, non-contiguous buffers for reading and writing. In place of the single buffer pointer supplied as a parameter to ISockPort_Read() and ISockPort_Write(), ISockPort_ReadV() and ISockPort_WriteV() each take an array of buffer descriptors as input, with each array element specifying the length in bytes and starting address of a buffer. These functions attempt to transfer an amount of data equal to the accumulated length of all buffers, starting with the first buffer in the array.
ISockPort_RecvFrom() and ISockPort_SendTo() are used to exchange data over UDP sockets. Both these functions allow data to be sent to and received from multiple IP addresses and port numbers. As with TCP sockets, the application may call ISockPort_Readable() or ISockPort_Writeable() to designate a callback object if the read or write operation does not make progress immediately.
ISockPort_Bind() associates a local port number with a socket (if an application does not call this function before ISockPort_Connect(), or ISockPort_SendTo() a default value is used for the local port number).
ISockPort_Listen() and ISockPort_Accept() are used to implement a server that can accept incoming TCP connections.
ISockPort_GetLastError() returns the error code for the last error detected by a function in the ISockPort Interface. In cases where such a function returns something other than success, ISockPort_GetLastError() provides more detailed information about why the function failed to perform its task.
ISockPort_GetPeerName() returns the IP address and port number of the entity with which data was most recently exchanged on the TCP socket.
ISockPort_GetSockName() returns the IP address and port number of the local socket.
ISockPort_GetOpt() and ISockPort_SetOpt() retrieve and specify optional parameters for a socket and/or the underlying network stack. See AEESockOpt for the supported options.
Receiving multicast datagrams is enabled by setting the AEE_IP_ADD_MEMBERSHIP socket option. Note that multicast is only supported on a small subset of devices and carrier networks; please verify support before making use of this feature.
ISockPort_Shutdown() or ISockPort_Close() are used to gracefully close a TCP connection.
A call to ISockPort_Release() also closes any socket connection and releases the ISockPort Interface and frees the associated resources.
ISockPort_IOCtl() allows some control over the behavior of an ISockPort, i.e. connect time-outs.
ISockPort provides several additional interfaces; please see the corresponding header file for complete documentation:
IQUERYINTERFACE AEEIQI.h ISockPort_AddRef() ISockPort_Release() ISockPort_QueryInterface() ISOURCE AEEISource.h ISockPort_Read() ISockPort_Readable() IPORT AEEIPort.h ISockPort_GetLastError() ISockPort_Write() ISockPort_Writeable() ISockPort_IOCtl() ISockPort_Close() ISockPort_Open()
To use a TCP client socket services 1. Call IEnv_CreateInstance() to create an instance of the ISockPort Interface. 2. Call ISockPort_OpenEx() to specify address family, type and protocol for the socket. 3. Call ISockPort_Connect() to establish a TCP socket connection with the network entity with which the application communicates. 4. Use the functions in the ISockPort Interface to operate on the socket.
To use a TCP server socket services 1. Call IEnv_CreateInstance() to create an instance of the ISockPort Interface. 2. Call ISockPort_OpenEx() to specify address family, type and protocol for the socket. 3. Call ISockPort_Bind() to specify the socket's local port number. 4. Call ISockPort_Listen() to set a queue of pending connections for the socket. 5. Call ISockPort_Accept() to accept an incoming TCP connections. 6. Use the functions in the ISockPort Interface to operate on the new ISockPort returned from ISockPort_Accept().
To read or write data over the socket 1. Call the relevant (TCP/UDP, single/multiple I/O buffers) read or write functions described above. 2. If the function returns a blocking indication (AEE_NET_EWOULDBLOCK), call ISockPort_Readable() or ISockPort_Writeable() to attempt the operation at a later time. Note also the existence of the helper macros - ISockPort_ReadableEx() and ISockPort_WriteableEx(). 3. If less than the requested number of bytes were transferred, call the read or write function again to effect the transfer of the remaining data. 4. Repeat steps 1-3, until all of your data has been transferred.
To receive ICMP error information ISockPort provides the ability to receive ICMP error information. The client can be notified of ICMP errors that are not handled at a lower level. The specific ICMP errors that can be returned are documented in the functions that return them.
There are two modes of operation: 1. Simple mode - only the latest error code can be received. Relevant socket options: AEE_SO_ERROR_ENABLE, AEE_SO_ERROR. Relevant functions: ISockPort_Connect(), ISockPort_SendTo(), ISockPort_RecvFrom() and ISockPort_RecvMsg(). 2. Extended mode - full error information can be received, errors are queued. Relevant socket option: AEE_IP_RECVERR. Relevant function: ISockPort_RecvMsg().
Simple mode: 1. To receive notifications about ICMP errors, the AEE_SO_ERROR_ENABLE socket option must be set. 2. When an ICMP error arrives, clients that registered callbacks using ISockPort_Readable() or ISockPort_Writeable() are notified. 3. When there is a pending ICMP error on the socket: a. ISockPort_SendTo() will return IPORT_ERROR, and the error code can be retrieved using ISockPort_GetLastError(). b. If there is no data pending on the socket, ISockPort_RecvFrom() and ISockPort_RecvMsg() will return IPORT_ERROR, and the error code can be retrieved using ISockPort_GetLastError(). c. The ICMP error can be retrieved by calling ISockPort_GetOpt() with the AEE_SO_ERROR socket option. d. ISockPort_Connect() can also return IPORT_ERROR that is caused by an ICMP connection error. Here too the error code can be retrieved using ISockPort_GetLastError(). 4. A pending ICMP error is cleared from the socket once the client was notified about it, even if ISockPort_GetLastError() wasn't called. For example: if the application called ISockPort_SendTo() and it returned IPORT_ERROR that is due to a pending ICMP error, a call to ISockPort_GetOpt() with AEE_SO_ERROR will not return the ICMP error and a subsequent call to ISockPort_SendTo() will not fail due to the same ICMP error (it might fail because of other reasons).
Extended mode: 1. To enable queuing of extended ICMP error information, the AEE_IP_RECVERR socket option must be set. This option is only available for UDP sockets. 2. When a new ICMP error arrives, applications that registered callbacks using ISockPort_Readable() are notified. 3. When there are pending ICMP errors, calling ISockPort_RecvMsg() with no flags will notify the caller about the pending ICMP errors by setting the SOCKPORT_FLAG_RECVMSG_ERRQUEUE flag in the output flags field. The notification flag doesn't interfere with the regular return value of ISockPort_RecvMsg(). For example, if the user has both a pending datagram and a pending ICMP error, the datagram will be returned together with the SOCKPORT_FLAG_RECVMSG_ERRQUEUE flag. 4. The application can retrieve a queued ICMP error by calling ISockPort_RecvMsg() with the SOCKPORT_FLAG_RECVMSG_ERRQUEUE input flag. Such a call will remove and return the oldest error information in the queue. The SOCKPORT_FLAG_RECVMSG_ERRQUEUE output flag will be set in case there are still more errors in the queue.
It is possible to use both socket options (AEE_SO_ERROR_ENABLE & AEE_IP_RECVERR) simultaneously. In such a case, both modes described above will be combined: the last received error code will be returned in the cases described under simple mode, and extended error information will be queued as described under extended mode. When both socket options are used together, every error return should be immediately followed by retrieving the ICMP information with no intervening operations. Following this guideline will ensure that the first error information in the queue refers to the latest error code that was returned to the client. The use of both socket options is discouraged, as it does make it harder for the client to keep the queue and the latest error in sync. When using this feature, care should be taken to implement it correctly to enable reliable ICMP error tracking.
The following header file is required:
BREW 4.0 - AEEISockPort.h BREW 3.1 - AEESockPort.h