S60 Open C
Open C Networking and Sockets

Open C Networking and Sockets

Table of Contents

Multihoming and socket communication
Classification of APIs
Browsing the AP table
Choosing connection or subconnection for socket communication
Example code to connect to an IP address
Interface functions

 


Multihoming and socket communication

In desktop OS, multiple connections are managed by having a different IP address for each connection. The application chooses the IP address. In Symbian OS, connections are managed by the RConnection class and access points are stored in an ‘IAP’ table. The IAP table is accessed using the CommDB class. Libc provides simple and easy-to-use C interfaces to access CommDB, RConnection and RSubConnection functionality. This functionality is provided at libc layer through ioctl() and if_<function>().

Please note that RConnection/RSubConnection code cannot be intermixed with ioctls() discussed here.

 


Classification of APIs

 


Browsing the AP table

There are two possibilities:the programmer either wants to read access point details or wants to read active access point details. The SIOCGIFCONF and SIOCGIFACTIVECONF APIs can be used here.

void AccessPoints()
	{
	struct ifconf ifc;
	int sockfd;
	int count;
	int ret;
 	
	sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        
	ifc.ifc_len = sizeof(struct ifreq) * 20;
	ifc.ifc_buf = (caddr_t)malloc( ifc.ifc_len );

 	// This will fetch the access point list, ifc.ifc_len will contain the size of the buffer
	ret = ioctl(sockfd, SIOCGIFCONF, &ifc);

	// count will contain the number of access points
	count = ifc.ifc_len / sizeof(struct ifreq) 

	close(sockfd);
	free(ifc.ifc_buf);
	return;
	}

 


Choosing connection or subconnection for socket communication

Once the user knows the access point list or connection list, the same can be displayed to the user to select the proper access point. The SIOCSIFNAME API can be used to select the access point. The following code shows how to start a new connection using available access points.

void ChooseInterface(char *ifname)
	{
	ifreq ifr;
	int sockfd;

	// Name of the interface
	strcpy(ifr.ifr_name, ifname);
	
	sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);	
	ioctl(sockfd,SIOCSIFNAME, &ifr);
	ioctl(sockfd, SIOCIFSTART , &ifr);	
	////
	//// recvfrom() and sendto() operations on socket sockfd
	////
	ioctl(sockfd, SIOCIFSTOP, &ifr);

	close(sockfd);
	return ret;
	}

The following code shows how to start a new subconnection using an existing connection.

void ChooseActiveInterface(char *ifname)
	{
	ifreq ifr;
	int sockfd1, sockfd2;
		
	// Name of the interface
	strcpy(ifr.ifr_name, ifname);
	
	sockfd1 = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	ioctl(sockfd1,SIOCSIFNAME, &ifr);
	ioctl(sockfd1, SIOCIFSTART , &ifr);
		
	sockfd2 = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	ioctl(sockfd2,SIOCSIFNAME, &ifr);
  	// Start subconnection using a connection created earlier using SIOCSIFNAME
	ioctl(sockfd2, SIOCIFACTIVESTART , &ifr);

	////
	//// recvfrom() and sendto() operations on socket sockfd2 and sockfd1
	////

	ioctl(sockfd2, SIOCIFSTOP, &ifr); // Stop the connection
	ioctl(sockfd1, SIOCIFSTOP, &ifr); // Stop the connection
	close(sockfd2);
	close(sockfd1);
	}

SIOCIFSTART and SIOCIFACTIVESTART are actual ioctl( ) calls which would start a connection or subconnection. All the socket communication calls such as connect(), read(), write(), send(), receive(), sendto(), and recvfrom() should come after calling SIOCIFSTART and SIOCIFACTIVESTART. Calls such as getsockopt(), and getsockname() that do not require any connection do not have any dependency on SIOCIFSTART and SIOCIFACTIVESTART.

 


Example code to connect to an IP address

Please note that the error checking code has been removed deliberately to improve the readability of the code.

int ConnectToIpUsingConnection( char *apname, char *ipaddr , int port)
	{
	ifreq ifr;
	int sockfd;
	struct sockaddr_in destAddr, selfAddr;	
		
	// Name of the interface
	strcpy(ifr.ifr_name, apname);
	
	sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);	
	ioctl(sockfd,SIOCSIFNAME, &ifr);
	ioctl(sockfd, SIOCIFSTART , &ifr);
	
	selfAddr.sin_family = AF_INET;
	selfAddr.sin_addr.s_addr = INADDR_ANY;
	selfAddr.sin_port = htons(port);
	
	bind(sockfd,(struct sockaddr*)&selfAddr, sizeof(selfAddr));
	
	destAddr.sin_family = AF_INET;
	destAddr.sin_addr.s_addr = inet_addr( ipaadr );
	destAddr.sin_port = htons(port);
	connect(sockfd, (struct sockaddr*)&destAddr, sizeof(destAddr));

	ioctl(sockfd, SIOCIFSTOP, &ifr);
	close(sockfd);
	return;
	}

 


Interface functions

These interface functions are C interface functions provided using ioctl( ). The functions provided in this category are:

Refer to the Open C API reference for a detailed description.

Example code is given below.

if_nameindex()

void TestIfNameIndex()
 	{
 	struct if_nameindex *ifname;
 	ifname = if_nameindex(); 	// ifname will contain the access point information
 	if_freenameindex(ifname);
 	} 

if_indextoname() and if_nametoindex()

void TestIfIndexToName(int index)
 	{
 	char ifName[255];
	 	if_indextoname(index , ifName); // ifName would contain the interface name
 	// ifindex would contain the interface index. In this case index and ifindex would match
 	ifindex = if_nametoindex(ifName);
 	}

Give feedback of this section


©Nokia 2007

Back to top


This material, including documentation and any related computer programs, is protected by copyright controlled by Nokia. All rights are reserved. Copying, including reproducing, storing, adapting or translating, any or all of this material requires the prior written consent of Nokia. This material also contains confidential information, which may not be disclosed to others without the prior written consent of Nokia.

Nokia is a registered trademark of Nokia Corporation. S60 and logo is a trademark of Nokia Corporation. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. Other company and product names mentioned herein may be trademarks or tradenames of their respective owners.