USERNAME PASSWORD LOST PASSWORD? REGISTER
"A Complete Mobile Application Development Environment"
Advertisement

Downloads
Documentation
Forums
Blog
Press
Bug Tracking
Creator IDs
Contact Us




Programming Networked Applications PDF Print E-mail
Documentation »  ACCESS Linux Platform Native Development »  Networking Guide »  Programming Networked Applications

This chapter describes how to use the Connection Manager to manage network connections in an application.

Managing Profiles ^TOP^

The Connection Manager handles network interfaces on request from an application by manipulating connection profiles. A connection profile can be described as a configuration setup of a network interface. It is represented by a string. For example, the following profile sets up the interface eth0 and assign it the IPv4 address 10.0.0.3. :


"NetOut/IPIF:LoIP='10.0.0.3'/Ethernet:DDev='eth0'"  

Slashes ("/") separate the various plug-ins of a profile. A plug-in handles the configuration of a physical interface (e.g. Ethernet) or a protocol (e.g. IPIF for IPv4). Each plug-in imports and exports parameters (such as LoIP='10.0.0.3') that can be hard-coded in the profile or filled at connection time. (For more information on profiles see "Connecting Profiles".)

Profiles may also be tagged for specific use (web, IM, etc...)

Profiles fall into three main categories:

  • NetOut/* for profiles supporting connection to the outside world
  • VPN/* for VPN profiles
  • NetIn/* for connection sharing profiles (see "Connection Sharing")

Data Channels ^TOP^

Before using standard socket functions to communicate, an application must connect a data channel. This brings up the right interface for the application's needs, and ensures that all of the application's network traffic goes through that interface.

A data channel contains a list of suitable profiles sorted by priority. Trying to connect a data channel involves attempting to connect profiles of the list until one succeeds. If a profile is already connected, it is chosen.

Binding Sockets ^TOP^

When a data channel is connected, sockets created in the same thread are bound to the channel interface. It is possible to change the active data channel with alp_cnc_channel_select(). Note that this does not change the binding of already created sockets.

The Connection Manager provides an API to create bound sockets: alp_cnc_socket(). An application can also include the file cnc_inet.h, which overrides socket() with alp_cnc_socket(). This is automatically done for ACCESS Linux Platform applications. Such sockets are bound to the network interface of the selected channel.

If an application wants to create an unbound socket, for example to be able to bind it later to a well-known port, it can use alp_cnc_socket_unbound(). This function simply uses the standard socket() call, and does not bind it to the network interface.

Disconnecting Channels ^TOP^

Disconnecting a channel may not immediately disconnect the profile, since it may be used by other channels in the system. Moreover, the disconnection of a profile is postponed in time. This mechanism avoids losing time when an application connects and disconnects channels quickly.

Channels do not survive their creating application.

Programming Examples ^TOP^

Opening and Closing a Data Channel ^TOP^

First, create a data channel matching the application's needs.

tagStr is a string containing the search criteria. Interfaces should to communicate using IPv4, thus "NetOut/IPIF/*".

Some carriers force developers to use well-defined connections for some services (for example, MMS, or WAP-only APN). The example in this section uses a web profile or a generic one, which is reflected by the "srv0" parameter.

For the data channel, you must specify flags. The standard progress user interface should be displayed during the connection process. The CHOOSER flag is provided for the user to validate the next profile to try.


// build the channel search string: only consider  
// web or generic profiles using IPv4 
snprintf(tagStr, 
      TAG_STRING_SIZE - 1, 
      "NetOut:srv0=%d/IPIF/*", 
      ALP_CNC_CHANNEL_SRV_WEB | ALP_CNC_CHANNEL_SRV_GENERIC); 
 
// set the channel flags 
cncFlags =  
   ALP_CNC_CONNECT_PROGRESS_UI|ALP_CNC_CONNECT_CHOOSER_UI; 
 
// create a CNC channel 
   err = alp_cnc_channel_create(tagStr, cncFlags, &chanId); 

Next, connect the data channel:


err = alp_cnc_channel_connect(chanId); 

When the channel is connected, all data traffic goes through the network interface associated with the channel.

You can also use an existing channel that is connected in another thread - and may be in another process - by selecting it:


err = alp_cnc_channel_select(chanId);  

The calling thread becomes an owner of the channel. Channel IDs are integers, so they can be exchanged between processes. Note that selecting a channel is the same as reopening it; a channel used by several threads - the thread that created it and the threads that selected it - must be closed in all threads.

The third step in the process of opening and closing a data channel involves sending and receiving data using standard socket functions.

If a thread is the owner of a channel, the alp_cnc_socket() function returns a socket bound to the interface associated with the channel. If a thread is not the owner of a channel, alp_cnc_socket() returns a normal socket, not bound to any interface.

In ACCESS Linux Platform applications, the socket function is automatically redirected to alp_cnc_socket(), which automatically binds the socket to the interface associated with the active channel.

Send and receive data using standard socket functions:


host = gethostbyname(hostName); 
memcpy(&to_addr.sin_addr, host->h_addr, 
        sizeof(to_addr.sin_addr)); 
to_addr.sin_family = AF_INET; 
to_addr.sin_port = htons(HTTP_PORT); 
 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
 
connect(sockfd, (struct sockaddr *)&to_addr,  
       sizeof(struct sockaddr_in)); 
 
send(sockfd, buffer, strlen(buffer), 0); 
recv(sockfd, buffer, MAX_BUFFER_SIZE, 0); 
 
close(sockfd); 

In an application where the socket is redirected to alp_cnc_socket(), all sockets are bound to the interface associated with the active channel. To create an unbound socket, (for example, to manually bind it to a port and listen on it) an application should use alp_cnc_unbound_socket(). This will not bind the socket to the interface.

Outside of an ACCESS Linux Platform application, you can bind the sockets to the active channel using one of the following methods:

  • Redirect socket() calls to alp_cnc_socket(): Include cnc_inet.h in one file of your main code module (for example, where you declare the main() function).
  • Bind the sockets to the right interface by hand: Get the LoIP parameter of the active channel (see "Getting Connection Information"). Store the information and use the libc bind() function to bind sockets to the interface.

Next, disconnect the data channel. Here we can specify the reason of the disconnection. ALP_CNC_DISCONNECTED_USER is the most standard reason for application.


err = alp_cnc_channel_disconnect(chanId,  
       ALP_CNC_DISCONNECTED_USER); 

Finally, destroy the data channel:


err = alp_cnc_channel_destroy(chanId); 

Note that calls to alp_cnc_channel_create() and alp_cnc_channel_connect() can be replaced by a call to alp_cnc_channel_open(). For example:


err = alp_cnc_channel_open(tagStr, cncFlags, &chanId); 

In the same way, calls to alp_cnc_channel_disconnect() and alp_cnc_channel_destroy() can be replaced by a call to alp_cnc_channel_close():


err = alp_cnc_channel_close(chanId, 
     ALP_CNC_DISCONNECTED_USER); 

Getting Connection Information ^TOP^

An application can retrieve a description of a channel calling alp_cnc_channel_get(). This returns an AlpCncChannel structure:


struct _AlpCncChannel { 
   AlpCncChannelProfile *profiles;	   // information about all profiles 
                  // compatible with this channel (computed by 
                  // alp_cnc_channel_create, including unavailable) 
   uint32_t flags;    // connection flags (ui, etc) 
   uint16_t timeout;  // 0 = disabled, else seconds of inactivity 
   uint16_t global_state;   // incremented each time a change is made on the 
             //channel (not useful for an app) 
   alp_status_t error;     // error (when state is disconnected) 
   int fd;             // fd (when state is connected) 
   uint32_t plugin_id;  // the current plug-in id (progress) 
   uint32_t profile_id;  // the current profile id 
   int8_t plugin_index;  // the current plugin index in the profile 
   int8_t plugins_count;  // the items total count in the current profile 
   uint8_t channel_id;    // unique channel id allocated by the server 
   int8_t profiles_count;  // number of items in the "profiles" list 
   int8_t profile_index;			   // index of the current profile in "profiles" list 
   uint8_t state;          // connection state 
   uint8_t cancelled;     // the cancel reason if != 0 
}; 

If the channel is connected, the ID of the connected profile is stored in the profile_id field.

An application can also retrieve a description of a profile by calling alp_cnc_object_get_info(). This returns an AlpCncObjectInfo structure:


struct _AlpCncObjectInfo { 
	char name[ALP_CNC_MAX_NAME_LENGTH + 1];   // object name 
	uint32_t object_id;                      // object id 
	uint8_t version;                        // version 
	uint8_t type;                          // object type 
	uint16_t count;                       // item count in the object 
	uint8_t priority;                    // object priority 
	uint8_t availability;                // profile availability 
	uint16_t options;                    // options 
	uint32_t manual_id;                 // reserved 
	char avail_icon_name[ALP_CNC_ICON_NAME_MAX_SIZE]; // profile avail. icon id 
}; 

A profile's parameters are retrieved by calling alp_cnc_object_get_parameters(), which takes an array of AlpCncParameter as an In/Out parameter:


struct _AlpCncParameter { 
     uint32_t name;        // parameter name 
     uint16_t size;        // size of the value in bytes 
     uint8_t type;         // parameter type (see kCncXxxxParameterType) 
     uint8_t flags;        // flags for parameter checking 
     union { 
     uint32_t asInteger; 
     char *asString; 
     uint8_t *asBinary; 
     } value;              // parameter value 
}; 

If size and flags are set, alp_cnc_object_get_parameters() performs checks on the parameters and returns an error if they do not match. Otherwise, it is the application's responsibility to do these checks.

If the parameter is not present in the profile, its name in the array is set to ALP_CNC_PARAMETER_UNDEFINED.


void prv_get_info(uint8_t chanId) 
{ 
   AlpCncChannel        *chan; 
   alp_status_t          err; 
   AlpCncObjectInfo      info; 
 
   // list of parameters we want 
   AlpCncParameter params[] = { 
       { 
         .name = ALP_CNC_PARAMETER_INTERFACE_NAME, 
         .size = ALP_CNC_PARAMETER_NO_SIZE, 
         .type = ALP_CNC_PARAMETER_TYPE_INTEGER, 
         .flags = ALP_CNC_PARAMETER_CHECK_TYPE_AND_SIZE, 
         .value = {0} 
         }, 
         { 
         .name = ALP_CNC_PARAMETER_LOCAL_IP, 
         .size = ALP_CNC_PARAMETER_NO_SIZE, 
         .type = ALP_CNC_PARAMETER_TYPE_STRING, 
         .flags = ALP_CNC_PARAMETER_CHECK_TYPE_AND_SIZE | 
                      ALP_CNC_PARAMETER_CHECK_MANDATORY, 
         .value = {0} 
         }, 
         { 
         .name = ALP_CNC_PARAMETER_GATEWAYS, 
         .size = ALP_CNC_PARAMETER_NO_SIZE, 
         .type = ALP_CNC_PARAMETER_TYPE_INTEGER, 
         .flags = ALP_CNC_PARAMETER_CHECK_TYPE_AND_SIZE, 
         .value = {0} 
         }, 
         { 
         .name = ALP_CNC_PARAMETER_DNS_SERVERS, 
         .size = ALP_CNC_PARAMETER_NO_SIZE, 
         .type = ALP_CNC_PARAMETER_TYPE_INTEGER, 
         .flags = ALP_CNC_PARAMETER_CHECK_TYPE_AND_SIZE, 
         .value = {0} 
         }, 
         { 
         .name = ALP_CNC_PARAMETER_TABLE_END, 
         } 
         }; 
 
   // get the channel description 
	chan = alp_cnc_channel_get(chanId, &err); 
	if (chan == NULL) 
	{ 
    printf("Channel get failed (0X%08X)\r\n", (uint32_t)err); 
    return; 
	} 
	// chan->profile_id is the ID of the connected profile 
	// get info on the connected profile 
	err = alp_cnc_object_get_info(chan->profile_id, &info); 
	if (err != ALP_STATUS_OK) 
	{ 
    printf("Get info failed (0X%08X)\r\n", (uint32_t)err); 
    return; 
	} 
	// retrieve profile's parameter 
	err = alp_cnc_object_get_parameters(chan->profile_id, 
           0,  
           ALP_CNC_GET_PARAMETERS_WHOLE_PROFILE|ALP_CNC_GET_PARAMETERS_ACTIVE, 
           params); 
	 
	// display info 
	printf("Connected through profile \"%s\" ID: %d\r\n", info.name,  
					chan->profile_id); 
	 
	// display parameters 
	if (params[0].name != ALP_CNC_PARAMETER_UNDEFINED) 
	{ 
		printf("\tInterface is %s\r\n", params[0].value.asString); 
	} 
	if (params[1].name != ALP_CNC_PARAMETER_UNDEFINED) 
	{ 
		printf("\tIP address is %s\r\n", params[1].value.asString); 
	} 
	if (params[2].name != ALP_CNC_PARAMETER_UNDEFINED) 
	{ 
		printf("\tGateway is %s\r\n", params[2].value.asString); 
	} 
	if (params[3].name != ALP_CNC_PARAMETER_UNDEFINED) 
	{ 
		printf("\tDNS servers are %s\r\n", params[3].value.asString); 
	} 
 
} 

Advanced: Using Provisioned Profiles ^TOP^

Connection manager profiles can be provisioned using OMA DM and/or OMA CP. The Connection Manager library provides functions to facilitate the enumeration and connection of provisioned applications to provisioned profiles, as well as to related proxy information.

An application that creates a data channel uses either the alp_cnc_channel_create(), or directly calls the alp_cnc_channel_open() function. The first parameter of these functions is a search string that gives criteria to the Connection Manager to make the list of connection profiles compatible with the application. To use provisioned profiles, the application uses the same functions, passing a special search string that is given by OMA DM provisioning API.


NOTE: The alp_cnc_channel_create() function accepts several search strings separated by the ";" (semicolon) character.

The following example illustrates how a browser application generates a search string:


alp_status_t status; 
	OMADM_AccountListType accounts; 
	OMADM_BrowserSettingsType browser_settings; 
	OMADM_PXLogicalType proxy; 
	char* omadm_search_string = ""; 
	char* legacy_search_string = "NetOut:srv0=0x100000004/
IPIF/*"; 
	char* search_string; 
	uint8_t channel_id; 
	size_t len; 
	 
	status = alp_omadm_browser_account_get_list(&accounts); 
	if (status == ALP_STATUS_OK) 
	{ 
		if (accounts.itsCount >= 1) 
		{ 
			status = 
alp_omadm_browser_account_get_settings(accounts.itsKey[0], 
&browser_settings); 
			if (status == ALP_STATUS_OK && 
browser_settings.itsConnInfo != NULL) 
				omadm_search_string = browser_settings.itsConnInfo; 
		} 
	} 
 
	len = strlen(omadm_search_string); 
	if (len != 0) 			// Add space for ';' 
		len++;			 
	search_string = malloc(len + strlen(legacy_search_string) 
+ 1); 
	if (!search_string) 
		goto finalize; 
 
	strcpy(search_string, omadm_search_string); 
	if (*omadm_search_string) 
		strcat(search_string, ";"); 
	strcat(search_string, legacy_search_string); 

After creating the search string, an application can usually connect:


status = alp_cnc_channel_open(searchString, 
ALP_CNC_CONNECT_PROGRESS_UI, &channel_id); 
        if(status != 0) 
	{ 
                channel_id = 0; 
		return status; 
        } 

When the channel is connected, the application can retrieve proxy information associated with the connection. The application (and the application developers) must decide how to handle the following potential cases:

Table 3.1  Handling Proxy Information

Case

Possible Actions

One and only one proxy is associated with the connection

Use proxy settings specified by the application

No proxy settings are associated with the connection

Use default proxy settings, user-defined settings, or refuse the connection and close the channel

More than one proxy is associated with the connection

Use only the first proxy. Alternatively, use the first proxy, but if it does not respond, fall back to the next proxy.

After a channel is connected, you can get proxy information associated with the connected profile as shown in the following example.


	// The 2nd parameter (0) will return the first proxy 
  // associated with the connected profile 
	// An application that wants information about other  
	// proxies must call the same function with the value 
	// 0, 1, 2, etc. The function returns an error when there  
	// is no proxy. 
 
	status = alp_cnc_channel_proxy_get_settings(channel_id, 0, 
&proxy); 
	if (status != ALP_STATUS_OK) 
	{ 
		// No proxy information 
	} 
	else 
	{ 
		// Proxy defines the logical proxy associated with the  
		// connected profile. 
		// proxy.itsPxPhysical points to the physical proxy  
		// associated with the connected profile. 
		// Use proxy settings. 
	} 

The application should free the memory allocated by the provisioning API as soon as the application no longer needs the information. The provisioning API provides special functions to handle freeing of memory, as shown in the following example:


alp_omadm_browser_account_free_settings(&browser_settings); 
	alp_omadm_account_free_list(&accounts); 
	alp_omadm_pxlogical_free_settings(&proxy); 

Setting the Default Profile ¶

An application can define a default profile that will be chosen when connecting a channel. The application must not use a custom setting to store a profile ID because the OMA DM provisioned profile ID may change from one session to another. Instead, applications must use alp_cnc_channel_set_default() to store a channel default profile.

To set or unset a default profile, an application must perform the following operations:

  1. Call alp_cnc_channel_create() with the tags it normally uses to open a channel.
  2. Use alp_cnc_channel_get() to get the list of profiles that are compatible with the application
  3. Display the profile list to the user, from which the user will select one profile (or "none" for an automatic connection).
  4. Use alp_cnc_channel_set_default() to store the user's choice of profiles.

An application can also directly call alp_cnc_channel_settings(), which provides a user interface that presents a choice of default profiles.

Applications that support provisioning and that use the alp_cnc_channel_set_default() to allow users to change the default profile must call alp_cnc_channel_set_default() to set the default profile back to "Auto" when the provisioned settings change. When a user accepts a new set of provisioned settings, the provisioned settings should become the default settings.

To determine whether provisioning settings have changed, an application can register for the appropriate notification, defined in omadm_provisiong.h, or by checking the application version number on start up, using one of the alp_omadm_*_settings_version methods.

Obtaining the Default Profile from a User

The Connection Manager defines the alp_cnc_channel_settings(char* tags) function, which displays a list of compatible profiles to the user, given a search string. The user can choose a default profile. Whenever an application tries to connect a channel using this search string in alp_cnc_channel_create() or alp_cnc_channel_open(), it attempts to use the default profile first.

Networked applications should add a menu option to allow the user to choose a default profile. They must use the same search strings used in alp_cnc_channel_create() and/or alp_cnc_channel_open().

Working with the Disconnection Timeout

The disconnection timeout feature avoids multiple connections or disconnections of the same profile when an application tries to frequently open or close a data channel. The feature also allows an application to avoid disconnecting a profile when switching from one networked application to another.

The disconnection timeout feature is defined on a per-profile basis: the special DisT parameter can be set to values from 0 (no disconnection timeout, i.e. disconnection is done when the channel is closed) up to 3600 (no disconnection at all). If a profile does not define the DisT parameter, the default disconnection timeout is applied.

In ACCESS Linux Platform, all profiles use the default disconnection timeout of 10 minutes.

In some situations, carrier or licencees may want to disable this feature for some profiles or some applications. For example, a MMS application that works in the background may want to disconnect the profile as soon as the communication is terminated. The configuration of the disconnection timeout is performed in the Connection Manager's configuration files (located in /etc/cnc/<target>.cnc). This means that the configuration is target- specific and can be easily performed by carriers, licencees, or integrators by editing these configuration files.

In ACCESS Linux Platform, there are two ways to alter the disconnection timeout:

  • Built-in profiles: Disconnection timeout can have different values given the link used for the connection. For example the Wi-Fi profile can have a disconnection timeout of 30 seconds. Just add a DisT=time-in-seconds parameter to the NetOut plug-in of the network profile.
  • Built-in templates: If user or OMA-provisioned profiles must have a disconnection timeout, you can add a DisT parameter to a template. Templates are used when creating a new network profile. For example, add DisT=30 to a GSM profile and DisT=120 to a GPRS profile.

The Connection Manager also allows carriers and licencees to have better control of the disconnection timeout using the following two methods:

  • Auto-profiles: New profiles that associate an application class with automatic parameters. When an application from a specific class creates a channel, and if there are automatic parameters associated with this application class, these parameters will be automatically set in the connected profile.
  • Background flag: New ALP_CNC_CONNECT_BACKGROUND flag that can be used by applications when creating a new channel:

    status = alp_cnc_channel_open("NetOut?:srv0=0x2", 
    ALP_CNC_CONNECT_BACKGROUND, &chan_id) 
    

Channels connected with this flag are marked as "background" channels, and the flag is internally handled as a class. Therefore, the carrier, licensee, or integrator can create an auto-profile for such channels.

Advanced: Using Several Channels (Multi-homing) ^TOP^

Use case: a mail client receiving an HTML email with link to web images. Carriers may ask mail client to use a specific 3GPP data APN to connect the carrier email server.

The application first uses a data channel to connect its mail server:


uint8_t mailChanId; 
 
snprintf(tagStr, 
		 TAG_STRING_SIZE - 1, 
		 "NetOut:srv0=%d/IPIF/*", 
		 ALP_CNC_CHANNEL_SRV_MAIL); 
 
cncFlags = ALP_CNC_CONNECT_PROGRESS_UI; 
 
err = alp_cnc_channel_create(tagStr, cncFlags, &mailChanId); 
err = alp_cnc_channel_connect(mailChanId); 

Then it creates a socket to retrieve new emails:


int mailSock; 
 
mailSock = socket(AF_INET, SOCK_STREAM, 0); 
 
connect(mailSock, (struct sockaddr *)&srv_addr,  
									sizeof(struct sockaddr_in)); 
 
send(mailSock, buffer, strlen(buffer), 0); 
recv(mailSock, buffer, MAX_BUFFER_SIZE, 0); 

When needed, it creates a channel to retrieve web images:


uint8_t  webChanId; 
 
snprintf(tagStr, 
		 TAG_STRING_SIZE - 1, 
		 "NetOut:srv0=%d/IPIF/*", 
		 ALP_CNC_CHANNEL_SRV_WEB); 
 
cncFlags = ALP_CNC_CONNECT_PROGRESS_UI; 
 
err = alp_cnc_channel_create(tagStr, cncFlags, &mailChanId); 
err = alp_cnc_channel_connect(mailChanId); 

Once the channel is connected, it is the active channel. A newly created socket uses it to send and retrieve data.


int webSock; 
 
webSock = socket(AF_INET, SOCK_STREAM, 0); 
 
connect(webSock, (struct sockaddr *)&web_addr,  
								sizeof(struct sockaddr_in)); 
 
send(webSock, buffer, strlen(buffer), 0); 
recv(webSock, buffer, MAX_BUFFER_SIZE, 0); 
 
close(webSock); 

To create another socket to the mail server, first return to the context of the mail data channel, and then create the socket:


int anotherMailSock; 
 
err = alp_cnc_channel_select(mailChanId); 
 
anotherMailSock = socket(AF_INET, SOCK_STREAM, 0); 
 
connect(anotherMailSock, (struct sockaddr *)&srv_addr, 
			sizeof(struct sockaddr_in)); 

Note that active channels are thread-wide.

Using a Custom Progress UI ^TOP^

Example:


cncwget -t http://www.google.com  

(-t for Text interface)

An application can override the default progress UI used during the channel connection. It has to implement a callback:


void *prv_progress(int request, void *data, void *uData) 

It can then set the global variable gcnc_progress exported by the Connection Manager library.

ALP_CNC_CONNECT_PROGRESS_UI set in the data channel's flags activates the default UI. The callback is called whenever the flags are called.

The callback returns NULL in case of error. In other cases the pointer returned is passed as uData at next callback call.

Callback's parameters are:

data
A pointer to an AlpCncChannel structure describing the channel being connected.
uData
A pointer to callback's own data. Contains what was returned by the callback at previous call.
request
One the following values:
  • ALP_CNC_PROGRESS_INIT : Initialization. Called before actually connecting the data channel.
  • ALP_CNC_PROGRESS_UPDATE : Called between connection of individual plug-ins.
  • ALP_CNC_PROGRESS_CHOOSER : Called only if ALP_CNC_CONNECT_CHOOSER_UI is set in the data channel's flags. This is called if the connection of a profile fails. Here the application can modify which profile will be connected next by changing 'profile_index' in the AlpCncChannel structure. It can also cancel the connection by setting the 'cancelled' field.
  • ALP_CNC_PROGRESS_FINI : Finalize. Called at the end of the connection (successful or not).

For example:


void *prv_progress(int request, void *data, void *uData) 
{ 
	AlpCncChannel *chan = (AlpCncChannel *) data; 
 
	switch (request) 
	{ 
		case ALP_CNC_PROGRESS_INIT: 
			uData = (void *) (1);	// must not be NULL (NULL == cancel) 
			break; 
 
		case ALP_CNC_PROGRESS_CHOOSER: 
			{ 
				char line[16]; 
				int8_t index; 
				 
				printf("*** Chooser: Automatic choosen profile is: %u (index %d  
							in [0-%d])\n",  
					chan->profile_index >= 0 ? chan->profiles[chan->profile_index].id  
						: 0, chan->profile_index, chan->profiles_count - 1); 
				for (index = 0; index < chan->profiles_count; index++) 
				{ 
					AlpCncObjectInfo info; 
					alp_cnc_object_get_info(chan->profiles[index].id, &info); 
					printf("%s%d. %s%s\n", index == chan->profile_index ? "->" : "  ", 
index, info.name, index == chan->profile_index ? "<-" : "  "); 
				} 
				printf("*** Chooser: Enter to accept, a profile index to change, or c 
to cancel: "); 
				fgets(line, 16, stdin); 
				if (*line == 0 || *line == '\n') 
					break; 
				if (*line == 'c') 
				{ 
					chan->cancelled = ALP_CNC_CANCELLED_USER; 
					break; 
				} 
				index = atoi(line); 
				if (index < 0 || index >= chan->profiles_count) 
					break; 
				chan->profile_index = index; 
				break; 
			} 
 
		case ALP_CNC_PROGRESS_UPDATE: 
			{ 
				char *stateStr; 
				AlpCncObjectInfo info; 
 
				if ((chan->flags & ALP_CNC_CONNECT_END) != 0) 
					break; 
 
				switch (chan->state) 
				{ 
					case ALP_CNC_STATE_CONNECTED: 
						stateStr = "Connected"; 
						break; 
					case ALP_CNC_STATE_CONNECTING: 
						stateStr = "Connecting"; 
						break; 
					case ALP_CNC_STATE_DISCONNECTED: 
						stateStr = "Disconnected"; 
						break; 
					case ALP_CNC_STATE_DISCONNECTING: 
						stateStr = "Disconnecting"; 
						break; 
					case ALP_CNC_STATE_SUSPENDED: 
						stateStr = "Suspended"; 
						break; 
					case ALP_CNC_STATE_NOT_CONNECTED: 
						stateStr = "Not connected"; 
						break; 
					default: 
						stateStr = "unknown"; 
						break; 
				} 
 
				if (chan->plugin_id) 
				{ 
					alp_cnc_object_get_info(chan->plugin_id, &info); 
				} 
				else 
				{ 
					*info.name = 0; 
				} 
 
				if (chan->error) 
					printf("*** error = 0x%x ***\n", chan->error); 
				printf("%s %d%s%s\n", stateStr, chan->profile_id,  
									*info.name ? ": " : "", info.name); 
			} 
			break; 
 
		case ALP_CNC_PROGRESS_FINI: 
			break; 
 
	} 
 
	return uData; 
} 

Using VPN ^TOP^

VPN profiles are described as other profiles for the Connection Manager. For example:


"VPN:ReHt='vpn.company.com',User='me',Pass=0x00000001/IPIF/
IPSEC:GrpN='company'/NetAccess:CPro='Wifi Connection') 

A VPN profile needs a NetOut profile. When connected, the VPN profile patches the underlying NetOut profile so data traffic on this profile can reach the private network.


NOTE: The effect of the VPN profile is system wide. Every application using the patched NetOut profile gains access to the private network.
 

Add as favourites (37) | Quote this article on your site | Views: 1951

Be first to comment this article
RSS comments

Only registered users can write comments.
Please login or register.

Powered by AkoComment Tweaked Special Edition v.1.4.6
AkoComment © Copyright 2004 by Arthur Konze - www.mamboportal.com
All right reserved

 


© 2008 ACCESS Developer Network    |    Joomla! is Free Software released under the GNU/GPL License.    |    ACCESS Global Website
Events Support Community Platforms Home