Open C Networking and Sockets |
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.
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; }
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.
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; }
These interface functions are C interface functions provided using ioctl( ). The functions provided in this category are:
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); }
©Nokia 2007 |