Smart Network Configuration

From openPicus Wiki
Jump to: navigation, search

Contents

What you are going to learn

You'll understand all the steps needed to include the Smart Configure page and functionality in your own project.

Smart config.jpg

FlyportPRO warning

This tutorial is made for Flyport modules but works on FlyportPRO as well. Just adapt the code since the pinout is slightly different.

Disclaimer

As always this is all free software provided as is, no explicit and/or implied responsibilities are admitted and/or accepted.

Code Explanation

The code to obtain this functionality is not simple. First of all the amount of information that is passed is so large that it exceeds the space in a GET request thus requiring the POST method. Then many options are interlinked or anyway related so the javascript behind the page has to do a lot of checks to ensure no interfering options are passed. This adds a lot of complexity, even if apparently the functionalities aren't so complex.

Custom network setup

The network setup is fairly complex. The webpage side has to check every entered parameter, and also prevent conflicting configurations from being selected. To achieve this we have added another script file containing only the code to manage the selection and entry of parameters in the available field. This is called main_conf.js and is placed in the scripts subfolder. It is composed of about 400 lines of code, all having to do with inter-linked parameter selection. So we will not cover this in detail.

The Flyport code instead is interesting. First of all lets start from the HTTP parser which, this time, works with a POST request due to the length of the parameter string.

01 HTTP_IO_RESULT HTTPExecutePost(void)
02 {
03 // Resolve which function to use and pass along
04 	BYTE filename[20];
05 	int len;
06 	// Load the file name
07 	// Make sure BYTE filename[] above is large enough for your longest name
08 	MPFSGetFilename(curHTTP.file, filename, sizeof(filename));
09 	
10 	while(curHTTP.byteCount)
11 	{
12 		// Check for a complete variable
13 		len = TCPFind(sktHTTP, '&', 0, FALSE);
14 		if(len == 0xffff)
15 		{
16 			// Check if is the last post, otherwise continue in the loop
17 			if( TCPIsGetReady(sktHTTP) == curHTTP.byteCount)
18 				len = curHTTP.byteCount - 1;
19 			else 
20 			{	
21 				return HTTP_IO_NEED_DATA; // No last post, we need more data
22 			}
23 		}
24 
25 	 
26 		if(len > HTTP_MAX_DATA_LEN - 2)
27 		{
28 			// Make sure we don't overflow
29 			curHTTP.byteCount -= TCPGetArray(sktHTTP, (BYTE*)String_post, len+1);
30 			continue;
31 		}
32 
33 		len = TCPGetArray(sktHTTP,curHTTP.data, len+1);
34 
35 		curHTTP.byteCount -= len;
36 		curHTTP.data[len] = '\0';
37 		HTTPURLDecode(curHTTP.data);

Parsing a POST request string is done iterating on the string and checking the size limit and terminator. The loop beginning is at line 10, and uses a variable which is later checked and decremented inside the loop itself. The first check, at line 13 and 14, is necessary to determine if the POST has been split into multiple segments. If that is the case, the TCPIP stack is instructed to wait for other data before calling the parser again. At line 26 the max length check ensures no overflow of the space allotted to the buffer occurs. From line 33 through 37, there are counter update and URL decoding.

Next are the IFs that parse every possible parameter, like

//	NETWORK TYPE SELECTION: ADHOC/INFRASTRUCTURE/SOFTAP(WIFI G only)
if(memcmppgm2ram(curHTTP.data,(ROM void*)"NETTYPE", 7) == 0)
{
	memcpy(String_post,(void*)&curHTTP.data[8], len-8);			
	WFSetParam(NETWORK_TYPE, String_post);
}		  
//	DHCP CLIENT ENABLING/DISABLING
else if(memcmppgm2ram(curHTTP.data,(ROM void*)"DHCPCL", 6) == 0)
{
	memcpy(String_post,(void*)&curHTTP.data[7], len-7);
	if (String_post [0] == 'd')
		WFSetParam(DHCP_ENABLE , DISABLED);
	else 
		WFSetParam(DHCP_ENABLE , ENABLED);
}


Last series of checks are those for the various security options. After each of these check, the parsing is complete and the ParamSet flag is set, thus passing control to the main loop.

//	EXAMPLE: WEP40 KEY INDEX
else if (memcmppgm2ram(curHTTP.data,(ROM void*)"WEP40KEYID", 10) == 0)
{	
	memcpy(String_post,(void*)&curHTTP.data[11], len-11);
	int k_index;
	k_index = atoi(String_post);
	k_index--;
	if (security == 1)
	{
		WFSetSecurity(WF_SECURITY_WEP_40, PassKey, 20, k_index);
		ParamSet = TRUE;
	}
}


The main loop then checks the flag and saves the new parameters initiating a new connection.

01 if (ParamSet)
02 {
03 	UARTWrite(1, "Params changed!\r\n");
04 	WFDisconnect();
05 	while (WFStatus != NOT_CONNECTED);
06 	vTaskDelay(50);
07 	WFCustomSave();
08 	UARTWrite(1,"Custom config saved!\r\n");
09 	UARTWrite(1,"Connecting custom...\r\n");
10 	WFConnect(WF_CUSTOM);
11 	while (WFStatus != CONNECTED);
12 	ParamSet = FALSE;
13 }

Conclusions

In this tutorial you learned how the Smart Network Configuration works. Now you can embed the system in your own projects, giving them the ability to be dynamically configured on the fly and at the install location.

Code

Source Code - WIFI PRO
Source Code - WIFI G
Source Code - WIFI B

Personal tools
Namespaces

Variants
Actions
START HERE
DEVELOPMENT
HARDWARE INFO
RESOURCES
PHASED OUT
Toolbox