Initial commit

This commit is contained in:
ChesterTseng 2017-10-15 14:36:37 +08:00
commit 6f665866d6
3358 changed files with 1106791 additions and 0 deletions

View file

@ -0,0 +1,81 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip_netconf.h>
#include <lwip/netif.h>
static void example_bcast_thread(void *param)
{
int socket = -1;
int broadcast = 1;
struct sockaddr_in bindAddr;
uint16_t port = 49152;
unsigned char packet[1024];
// Create socket
if((socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("ERROR: socket failed\n");
goto err;
}
// Set broadcast socket option
if(setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0){
printf("ERROR: setsockopt failed\n");
goto err;
}
// Set the bind address
memset(&bindAddr, 0, sizeof(bindAddr));
bindAddr.sin_family = AF_INET;
bindAddr.sin_port = htons(port);
bindAddr.sin_addr.s_addr = INADDR_ANY;
if(bind(socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr)) < 0){
printf("ERROR: bind failed\n");
goto err;
}
while(1) {
// Receive broadcast
int packetLen;
struct sockaddr from;
struct sockaddr_in *from_sin = (struct sockaddr_in*) &from;
socklen_t fromLen = sizeof(from);
if((packetLen = recvfrom(socket, &packet, sizeof(packet), 0, &from, &fromLen)) >= 0) {
uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr;
uint16_t from_port = ntohs(from_sin->sin_port);
printf("recvfrom - %d bytes from %d.%d.%d.%d:%d\n", packetLen, ip[0], ip[1], ip[2], ip[3], from_port);
}
// Send broadcast
if(packetLen > 0) {
int sendLen;
struct sockaddr to;
struct sockaddr_in *to_sin = (struct sockaddr_in*) &to;
to_sin->sin_family = AF_INET;
to_sin->sin_port = htons(port);
to_sin->sin_addr.s_addr = INADDR_ANY;
if((sendLen = sendto(socket, packet, packetLen, 0, &to, sizeof(struct sockaddr))) < 0)
printf("ERROR: sendto broadcast\n");
else
printf("sendto - %d bytes to broadcast:%d\n", sendLen, port);
}
}
err:
printf("ERROR: broadcast example failed\n");
close(socket);
vTaskDelete(NULL);
return;
}
void example_bcast(void)
{
if(xTaskCreate(example_bcast_thread, ((const char*)"example_bcast_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_BCAST_H
#define EXAMPLE_BCAST_H
void example_bcast(void);
#endif /* EXAMPLE_BCAST_H */

View file

@ -0,0 +1,28 @@
LWIP BROADCAST EXAMPLE
Description:
Listen broadcast message on port 49152.
Send packet with the content of received packet to broadcast address.
Configuration:
[lwipopts.h]
#define LWIP_UDP 1
[platform_opts.h]
#define CONFIG_EXAMPLE_BCAST 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A broadcast example thread will be started automatically when booting.
Test:
1. Prepare a NB and connect to the same AP Ameba connected.
2. NB: iperf -c 192.168.1.255 -t 60 -i 1 -p 49152 -u
3. The recv/send messages should be printed out on Ameba console.
4. Use sniffer to make sure the packets send from Ameba are broadcast messages.
Note:
If you encounter some message like:
ERROR: sendto broadcast
[Driver]: skb_unavailable=1 in last 2 seconds
It means that the skb buffer is not enough for the massive UDP packets to be sent.
If you want to prevent the error you can add some delay time between sending packets or enlarge the skb buffer configuration.

View file

@ -0,0 +1,84 @@
#include "cmsis_os.h"
#include <cJSON.h>
#define malloc pvPortMalloc
#define free vPortFree
/* The data structure for this example
{
"Motion_Sensor" : "i",
"Light" : {
"Red" : "0",
"Green" : "0",
"Blue" : "0",
}
}
*/
static void gen_json_data(int i, int r, int g, int b)
{
cJSON_Hooks memoryHook;
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
cJSON *IOTJSObject = NULL, *colorJSObject = NULL;
char *iot_json = NULL;
if((IOTJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(IOTJSObject, "Motion_Sensor", cJSON_CreateNumber(i));
cJSON_AddItemToObject(IOTJSObject, "Light", colorJSObject = cJSON_CreateObject());
cJSON_AddItemToObject(colorJSObject, "Red", cJSON_CreateNumber(r));
cJSON_AddItemToObject(colorJSObject, "Green", cJSON_CreateNumber(g));
cJSON_AddItemToObject(colorJSObject, "Blue", cJSON_CreateNumber(b));
iot_json = cJSON_Print(IOTJSObject);
cJSON_Delete(IOTJSObject);
}
}
static void handle_json_data(char *iot_json)
{
cJSON_Hooks memoryHook;
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
cJSON *IOTJSObject, *sensorJSObject, *lightJSObject, *redJSObject, *greenJSObject, *blueJSObject;
int sensor_data, red, green, blue;
if((IOTJSObject = cJSON_Parse(iot_json)) != NULL) {
sensorJSObject = cJSON_GetObjectItem(IOTJSObject, "Motion_Sensor");
if(sensorJSObject)
sensor_data = sensorJSObject->valueint;
lightJSObject = cJSON_GetObjectItem(IOTJSObject, "Light");
if(lightJSObject){
redJSObject = cJSON_GetObjectItem(lightJSObject, "Red");
greenJSObject = cJSON_GetObjectItem(lightJSObject, "Green");
blueJSObject = cJSON_GetObjectItem(lightJSObject, "Blue");
if(redJSObject)
red = redJSObject->valueint;
if(greenJSObject)
green = greenJSObject->valueint;
if(blueJSObject)
blue = blueJSObject->valueint;
}
cJSON_Delete(IOTJSObject);
}
}

View file

@ -0,0 +1,16 @@
DCT example
Description:
This example shows device configuration table API usage, and user can use DCT api to replace file system.
Configuration:
1. [platform_opts.h]
#define CONFIG_EXAMPLE_DCT 1
Execution:
it will show:
variable0: value0
variable1: value1
Delete variable0 success.
Remaining amount: 61
if DCT is correctly used.

View file

@ -0,0 +1,90 @@
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include <basic_types.h>
#include <platform_opts.h>
#include <dct/dct.h>
#if CONFIG_EXAMPLE_DCT
#if defined(CONFIG_PLATFORM_8195A)
#define DCT_BEGIN_ADDR 0x100000 /*!< DCT begin address of flash, ex: 0x100000 = 1M */
#elif defined(CONFIG_PLATFORM_8711B)
#define DCT_BEGIN_ADDR 0x0F5000
#else
#endif
#define MODULE_NUM 6 /*!< max number of module */
#define VARIABLE_NAME_SIZE 32 /*!< max size of the variable name */
#define VARIABLE_VALUE_SIZE 32 /*!< max size of the variable value */
static char example_dct_module[] = "dct_test_module";
static char example_dct_variable0[] = "variable0";
static char example_dct_variable1[] = "variable1";
static char example_dct_value0[] = "value0";
static char example_dct_value1[] = "value1";
void example_dct_thread(void* param){
int32_t ret = -1;
dct_handle_t dct_handle;
char value[16];
// format DCT, use for the first time
ret = dct_format(DCT_BEGIN_ADDR, MODULE_NUM, VARIABLE_NAME_SIZE, VARIABLE_VALUE_SIZE, 1);
// initial DCT
ret = dct_init(DCT_BEGIN_ADDR);
// register module
ret = dct_register_module(example_dct_module);
// open module
ret = dct_open_module(&dct_handle, example_dct_module);
if(ret == DCT_SUCCESS){
// set test variable 0
ret = dct_set_variable(&dct_handle, example_dct_variable0, example_dct_value0);
// set test variable 1
ret = dct_set_variable(&dct_handle, example_dct_variable1, example_dct_value1);
// get value of test variable 0
memset(value, 0, sizeof(value));
ret = dct_get_variable(&dct_handle, example_dct_variable0, value, sizeof(value));
if(ret == DCT_SUCCESS)
printf("%s: %s\n", example_dct_variable0, value);
// get value of test variable 1
memset(value, 0, sizeof(value));
ret = dct_get_variable(&dct_handle, example_dct_variable1, value, sizeof(value));
if(ret == DCT_SUCCESS)
printf("%s: %s\n", example_dct_variable1, value);
// delete test variable 0
ret = dct_delete_variable(&dct_handle, example_dct_variable0);
// get value of test variable 0
memset(value, 0, sizeof(value));
ret = dct_get_variable(&dct_handle, example_dct_variable0, value, sizeof(value));
if(ret == DCT_ERR_NOT_FIND)
printf("Delete %s success.\n", example_dct_variable0);
// get variable remaining amount
ret = dct_remain_variable(&dct_handle);
if(ret > 0)
printf("Remaining variable amount:%d\n", ret);
// close module
ret = dct_close_module(&dct_handle);
}
vTaskDelete(NULL);
}
void example_dct(void)
{
if(xTaskCreate(example_dct_thread, ((const char*)"example_dct_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_dct_thread) failed", __FUNCTION__);
}
#endif // #if CONFIG_DCT

View file

@ -0,0 +1,7 @@
#ifndef _EXAMPLE_DCT_H
#define _EXAMPLE_DCT_H
void example_dct(void);
#endif /* _EXAMPLE_DCT_H */

View file

@ -0,0 +1,164 @@
#include <platform_opts.h>
#include <eap/example_eap.h>
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#if CONFIG_EXAMPLE_EAP
// get config arguments from wifi_eap_config.c
extern char *eap_target_ssid;
extern char *eap_identity;
extern char *eap_password;
extern const unsigned char *eap_ca_cert;
extern const unsigned char *eap_client_cert;
extern const unsigned char *eap_client_key;
extern char *eap_client_key_pwd;
void example_eap_config(void){
eap_target_ssid = "Test_eap";
eap_identity = "guest2";
eap_password = "test2";
/*
Set client cert is only used for EAP-TLS connection.
If you are not using EAP-TLS method, no need to set eap_client_cert and eap_client_key value. (leave them to NULL value)
*/
/*
eap_client_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIC9TCCAd0CAQIwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \
"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \
"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \
"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE0MTEzNjMy\r\n" \
"WhcNMTcwMzE0MTEzNjMyWjBxMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \
"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGTAXBgNVBAMUEHVzZXJAZXhhbXBsZS5j\r\n" \
"b20xHzAdBgkqhkiG9w0BCQEWEHVzZXJAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcN\r\n" \
"AQEBBQADgY0AMIGJAoGBAODvCWRRjVQnUyQS/OqHS8MA94Dc5UOtLagKTOMJayB5\r\n" \
"3MZyreWBkNg6sDfDG6OSD9tkVzwcp8CtZNflJc3i+d+nAnPM+kJedPJN5YVO+uwc\r\n" \
"+K+QObH7fEOq8hnFIvOtYOfnMAxQKaVIKk0EOqqQv06BDvLyxoDCZNpAn4NQ8ZkR\r\n" \
"AgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAItqpmFftRu8ugTy4fRFwpjJNUuMRe83\r\n" \
"Pm5Dv3V/byCHHdmIy0UI+6ZiMEtYrpvz4ZPgk0BDeytYooT7/kEUb8niQ64bDLYo\r\n" \
"NcXctCmn5fjyX2M6Z3lQXCxX0XdFiukWlR21w4HO0nx7OJjrcjdpP9Tyk/kzCFl7\r\n" \
"pblIavkfSmFtcxzcp0IoCupkUjFkA+MftZF82eQx4bE0jjiw2KgGwnzyYAdgtFXv\r\n" \
"Ednj3ZyOuTlOQNGJgLQxyHooEJ/Tol/8p9EO5S6eQaHgZhbGP3AZ3SWV5oA0e6eT\r\n" \
"D5JXti/LhyZhcbbJFawGXFI96ZOpHJ0EW12Osx/21oqmMp12AotS5Vw=\r\n" \
"-----END CERTIFICATE-----\r\n";
eap_client_key = \
"-----BEGIN RSA PRIVATE KEY-----\r\n" \
"Proc-Type: 4,ENCRYPTED\r\n" \
"DEK-Info: DES-EDE3-CBC,79675299AD6E2237\r\n" \
"\r\n" \
"ZYY2hv1PYEsrhYbCip98XNpS6XxbntynEEp6aO9UgWeQ4I1pNOUptPUE+yNhbA7X\r\n" \
"59ueT3yzx5L2ObImlJ3eIEvWq+iB8DdcPqFAo3c4dgfw/wPEhmxVPKvIyDQfaEuA\r\n" \
"kWUno6b07n5uLTpQjIXQSdMTMYjYS+yPQy7ONC/vl/Ce+RMzrQAZkp5xcNNarUpl\r\n" \
"2J1D2t+eRih/zRrgeVXztMiW2uyIT5a0IPoeBTPkPVb00kWYzn8eT9doN/ZCyr83\r\n" \
"mv/uXF5ZOHnSNleOn1NiCZ8Uu3SHnmGhMBBMI75OghpEezQQCmtefYvtRxzGjMVB\r\n" \
"UoRIlbATAleUjk3bmqRxfA2QZJj/GFWc9grxEerHWrdThSQ0w+fvwKBjTmEtUO2+\r\n" \
"stKBJQi9RKFq4naM8UhtxojHIscXCx/wKrRZHS4QJYOQYelzfhTRUuTf3Czm/iTh\r\n" \
"MQvX7dITNlLE3SW2MjzHb2ON9qUaKVnQPk53DO1zYgoxgDbQrw6FXDNMtYVv8SYf\r\n" \
"JJZp66jGX6e1t4ziPHVqlDi5D2nWQ2DPNHO/rsoydA7icncKsC0iVzeUm7XgesxD\r\n" \
"QEZoQIQDVS1aRE7qJCk9S2Hfe5Gfqnrp4110YuN/4khjMW2cOCKa/Yjgjyy2QQXT\r\n" \
"nn6dBAeSWGzRM059VzhOyls5FIfnJIisZvF3JG518SzBU/YUGHEVN1XsfDS2M9/q\r\n" \
"VkqhJ8/vbmIddKGeYULYW+xs3LvU1hnWiOodd9tuSeg5PxAbkJsV1nW06mVkgBqA\r\n" \
"zqqEvwvY+6+9QW4PClKNKSocvM6yC+uhRi0sOZ+ckOv7f+uuMyw5FQ==\r\n" \
"-----END RSA PRIVATE KEY-----\r\n";
eap_client_key_pwd = "testca";
*/
eap_client_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIC9zCCAd8CAQMwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \
"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \
"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \
"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE1MDgwNzEx\r\n" \
"WhcNMTcwMzE1MDgwNzExWjBzMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \
"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGjAYBgNVBAMUEXVzZXIyQGV4YW1wbGUu\r\n" \
"Y29tMSAwHgYJKoZIhvcNAQkBFhF1c2VyMkBleGFtcGxlLmNvbTCBnzANBgkqhkiG\r\n" \
"9w0BAQEFAAOBjQAwgYkCgYEAqESlV4OYfBcIgZ+Cs8mWpiBjhvKoa0/kIe7saqhC\r\n" \
"e5q4snox0jdkUpLcc4vOs3vQ7ZGnimqTltA9oF6XNUzTWW4vlJTKEfrCWK085l7c\r\n" \
"DHFvHavH3E6vuP71lI7jq4PLXbo2TvZK+uBul4ozjzVWihaZBtz8eLHq446h/D/p\r\n" \
"kzkCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAAfhVAIkNdeeUNJud720uUHVnIcxz\r\n" \
"GXWI+Svi1qchuTEnRNhLwXmnE+A0WWSHyfdR6FvzdT3xtz3K50iOif8jY2gCGkSK\r\n" \
"8RjKr97228SwbrGO9y9+dYIjH1uz9cBpoVKcpzdsWpKObrDPDYyReHSWo99jM2+O\r\n" \
"vfJxnBw4PLiBj7Q0/dpd6o4JXyp7Cxa0mB4/+cZqjCzzuKfuK3WP7j6laMCV6mg4\r\n" \
"wRZ528IdwDqB7OOqsDm1PVQM8vzny9PM6ikWUCRTVNQJN8RDLkrHR3FRjy15YLdt\r\n" \
"yOfDqVnT/z0wGBaxnNziSJjqPGHPpRi4bJFGXwXOhtknKmciKzfj9/npoQ==\r\n" \
"-----END CERTIFICATE-----\r\n";
eap_client_key = \
"-----BEGIN RSA PRIVATE KEY-----\r\n" \
"MIICXQIBAAKBgQCoRKVXg5h8FwiBn4KzyZamIGOG8qhrT+Qh7uxqqEJ7mriyejHS\r\n" \
"N2RSktxzi86ze9DtkaeKapOW0D2gXpc1TNNZbi+UlMoR+sJYrTzmXtwMcW8dq8fc\r\n" \
"Tq+4/vWUjuOrg8tdujZO9kr64G6XijOPNVaKFpkG3Px4serjjqH8P+mTOQIDAQAB\r\n" \
"AoGARI+LyweshssfxSkIKVc3EcNaqi6PHwJzUrw2ChM624AkR1xwllXJg7ehKVdK\r\n" \
"xmjprRLO8CASuL1qjsBb3fTKnBl+sIVxIFS0AI4Y3ri8VUKbangvSsI7pCzAFry7\r\n" \
"p1gmy9WWRV2ZEa+dV8xcrjb3bloT7hcdeLehgBCvExJIQM0CQQDXlSAKdW3AhYyj\r\n" \
"1A+pfyBSGxJbpSwNyyWgwHIHHjxendxmdUbrc8EbAu1eNKbP58TLgdCZsKcMonAv\r\n" \
"MY1Y2/nnAkEAx9CrUaCU8pJqXTRypM5JtexLKnYMJhpnA9uUILBQOq4Oe0eruyF5\r\n" \
"SaSxhyJYXY491ahWYPF0PTb3jkUhoN+l3wJBAJZthjgGDJlEFwjSFkOtYz4nib3N\r\n" \
"GVpeoFj1MBvrazCScpJDz0LIOLzCZCNSFfwIu3dNk+NKMqZMSn+D0h9pD40CQQC5\r\n" \
"K9n4NXaTLbjAU2CC9mE85JPr76XmkcUxwAWQHZTcLH1jJdIyAx1hb+zNLLjzSmRn\r\n" \
"Yi9ae6ibKhtUjyBQ87HFAkA2Bb3z7NUx+AA2g2HZocFZFShBxylACyQkl8FAFZtf\r\n" \
"osudmKdFQHyAWuBMex4tpz/OLTqJ1ecL1JQeC7OvlpEX\r\n" \
"-----END RSA PRIVATE KEY-----\r\n";
/*
Verify server's certificate is an optional feature.
If you want to use it please make sure ENABLE_EAP_SSL_VERIFY_SERVER in platform_opts.h is set to 1,
and the eap_ca_cert is set correctly.
*/
eap_ca_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIEpzCCA4+gAwIBAgIJAPvZaozpdfjkMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\n" \
"VQQGEwJGUjEPMA0GA1UECBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTAT\r\n" \
"BgNVBAoTDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\r\n" \
"ZS5jb20xJjAkBgNVBAMTHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\r\n" \
"DTE2MDMxNDExMjU0OVoXDTE2MDQxMzExMjU0OVowgZMxCzAJBgNVBAYTAkZSMQ8w\r\n" \
"DQYDVQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhh\r\n" \
"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG\r\n" \
"A1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\r\n" \
"DQEBAQUAA4IBDwAwggEKAoIBAQC9pireu0aCDLNfMaGv3vId7RXjUhQwSK0jV2Oc\r\n" \
"SyvlKWH3P/N+5kLrP2iL6SCzyETVDXZ0vOsAMjcBF0zHp16prXV0d51cTUqeWBb0\r\n" \
"I5UnGxleIuuOfSg8zLUJoBWZPqLv++eZ5WgOKHt7SXocjvg7TU5t/TMB0Y8OCz3H\r\n" \
"CW2vJ/XKMgMA9HDUu4g57cJu88i1JPRpyFaz/HIQBc7+UNb9z+q09uTZKWTmEMqi\r\n" \
"E2U0EEIs7EtbxnOze1/8C4XNlmztrEdwvu6UEBU/TFkUoh9M646NkkBK7wP9n9pv\r\n" \
"T0nPQRJiiCrICzVqUtlEi9lIKpbBSMbQ0KzrGF7lGTgm4rz9AgMBAAGjgfswgfgw\r\n" \
"HQYDVR0OBBYEFIVyecka74kvOKIW0BjlTc/B+a2NMIHIBgNVHSMEgcAwgb2AFIVy\r\n" \
"ecka74kvOKIW0BjlTc/B+a2NoYGZpIGWMIGTMQswCQYDVQQGEwJGUjEPMA0GA1UE\r\n" \
"CBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTATBgNVBAoTDEV4YW1wbGUg\r\n" \
"SW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xJjAkBgNVBAMT\r\n" \
"HUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggkA+9lqjOl1+OQwDAYDVR0T\r\n" \
"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZYHM26sxbKOckVqJJ1QY0U2QFlGP\r\n" \
"1GYd8v27znxdnRmSonDvv3GjFfhwoyDk0JUuxkK/33ikCxihrgoO/EQTY9BV2OpW\r\n" \
"qkB1PDtb3i5ZRNvfjmW0pVA4p+GmdTGaEE5pTlcVnorzVrUeFKaZakb+IDFYzmeF\r\n" \
"xp8B3Bb5wvinDligLOaJnSlgS8QeeIab9HZfaVTTuPmVK6zE6D54Y0dJPnykvDdE\r\n" \
"cGN0FC+migfilFjJgkDJ0r78nwes55L8zjoofiZuO03rrHww6ARc3v1jYzAufddk\r\n" \
"QTiZHgjlMQb2XXMmXLn8kBgoDnqkXFNe8j0h8uxIJSrjOoIyn1h1wvX5/w==\r\n" \
"-----END CERTIFICATE-----\r\n";
}
static void example_eap_thread(void *method){
example_eap_config();
if(strcmp(method, "tls") == 0){
// tls must present client_cert, client_key
eap_start("tls");
}
else if(strcmp(method, "peap") == 0){
eap_start("peap");
}
else if(strcmp(method, "ttls") == 0){
eap_start("ttls");
}
else
printf("Invalid method\n");
vTaskDelete(NULL);
}
void example_eap(char *method){
if(xTaskCreate(example_eap_thread, ((const char*)"example_eap_thread"), 1024, method, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed\n", __FUNCTION__);
}
#endif /* CONFIG_EXAMPLE_EAP */

View file

@ -0,0 +1,9 @@
#ifndef EXAMPLE_EAP_H
#define EXAMPLE_EAP_H
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
void example_eap(char *method);
#endif

View file

@ -0,0 +1,34 @@
802.1X EAP METHOD SUPPLICANT EXAMPLE
Description:
Use 802.1X EAP methods to connect to AP and authenticate with backend radius server.
Current supported methods are EAP-TLS, PEAPv0/EAP-MSCHAPv2, and EAP-TTLS/MSCHAPv2.
Configuration:
Modify the argument of example_eap() in example_entry.c to set which EAP methods you want to use.
Modify the connection config (ssid, identity, password, cert) in example_eap_config() of example_eap.c based on your server's setting.
[FreeRTOSConfig.h]
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 70 * 1024 ) )
[platform_opts.h]
# define CONFIG_EXAMPLE_EAP 1
// Turn on/off the specified method
# define CONFIG_ENABLE_PEAP 1
# define CONFIG_ENABLE_TLS 1
# define CONFIG_ENABLE_TTLS 1
// If you want to verify the certificate of radius server, turn this on
# define ENABLE_EAP_SSL_VERIFY_SERVER 1
Execution:
An EAP connection thread will be started automatically when booting.
Note:
Please make sure the lib_wps, polarssl, ssl_ram_map are also builded.
If the connection failed, you can try the following directions to make it work:
1. Make sure the config_rsa.h of PolarSSL include the SSL/TLS cipher suite supported by radius server.
2. Set a larger value to SSL_MAX_CONTENT_LEN in config_rsa.h
3. Increase the FreeRTOS heap in FreeRTOSConfig.h, for example you can increase the heap to 80kbytes:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) )
4. Try to change using SW crypto instead of HW crypto.

View file

@ -0,0 +1,449 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include <platform_opts.h>
#include "main.h"
#if ATCMD_VER == ATVER_2
#include "flash_api.h"
#include "device_lock.h"
#endif
#if CONFIG_EXAMPLE_MDNS
#include <mdns/example_mdns.h>
#endif
#if CONFIG_EXAMPLE_MCAST
#include <mcast/example_mcast.h>
#endif
#if CONFIG_EXAMPLE_XML
#include <xml/example_xml.h>
#endif
#if CONFIG_EXAMPLE_SOCKET_SELECT
#include <socket_select/example_socket_select.h>
#endif
#if CONFIG_EXAMPLE_NONBLOCK_CONNECT
#include <nonblock_connect/example_nonblock_connect.h>
#endif
#if CONFIG_EXAMPLE_SOCKET_TCP_TRX
#include <socket_tcp_trx/example_socket_tcp_trx.h>
#endif
#if CONFIG_EXAMPLE_SSL_DOWNLOAD
#include <ssl_download/example_ssl_download.h>
#endif
#if CONFIG_EXAMPLE_HTTP_DOWNLOAD
#include <http_download/example_http_download.h>
#endif
#if CONFIG_EXAMPLE_HTTPC
#include <httpc/example_httpc.h>
#endif
#if CONFIG_EXAMPLE_HTTPD
#include <httpd/example_httpd.h>
#endif
#if CONFIG_EXAMPLE_TCP_KEEPALIVE
#include <tcp_keepalive/example_tcp_keepalive.h>
#endif
#if CONFIG_EXAMPLE_SNTP_SHOWTIME
#include <sntp_showtime/example_sntp_showtime.h>
#endif
#if CONFIG_EXAMPLE_PPPOE
#include <pppoe/example_pppoe.h>
#endif
#if CONFIG_EXAMPLE_MEDIA_SIGNLE_STREAM
#include <media_single_stream/example_media_ss.h>
#endif
#if CONFIG_EXAMPLE_MEDIA_MULTI_STREAM
#include <media_multi_stream/example_media_ms.h>
#endif
#if CONFIG_EXAMPLE_MEDIA_AUDIO_FROM_RTP
#include <media_audio_from_rtp/example_media_audio_from_rtp.h>
#endif
#if CONFIG_EXAMPLE_AUDIO_MP3
#include <audio_mp3/example_audio_mp3.h>
#endif
#if CONFIG_EXAMPLE_GOOGLE_NEST
#include <googlenest/example_google.h>
#define FromDevice 1
#define ToDevice 2
#define BOTH 3
#define TYPE "ToDevice"
#endif
#if CONFIG_EXAMPLE_MJPEG_CAPTURE
#include <mjpeg_capture/example_mjpeg.h>
#endif
#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#include <wlan_fast_connect/example_wlan_fast_connect.h>
#endif
#if CONFIG_EXAMPLE_WIGADGET
#include <wigadget/wigadget.h>
#endif
#if CONFIG_EXAMPLE_MQTT
#include <mqtt/example_mqtt.h>
#endif
#if CONFIG_EXAMPLE_FATFS
#include <fatfs/example_fatfs.h>
#endif
#if CONFIG_EXAMPLE_DCT
#include <dct/example_dct.h>
#endif
#if CONFIG_EXAMPLE_INIC_GSPI_HOST
#include <inic_gspi/example_inic_gspi.h>
#endif
#if CONFIG_EXAMPLE_ARDUINO_WIFI
#include <arduino_wifi/ard_spi.h>
#endif
#if CONFIG_EXAMPLE_GET_BEACON_FRAME
#include <get_beacon_frame/example_get_beacon_frame.h>
#endif
#if CONFIG_EXAMPLE_USB_MASS_STORAGE
#include <usb_mass_storage/example_usb_msc.h>
#endif
#if CONFIG_EXAMPLE_EAP
#include <eap/example_eap.h>
#endif
#if CONFIG_EXAMPLE_AJ_BASIC
#include <alljoyn/example_aj_basic.h>
#endif
#if CONFIG_EXAMPLE_AJ_AMEBA_LED
#include <alljoyn/example_aj_ameba_led.h>
#endif
#if CONFIG_EXAMPLE_COAP
#include <coap/example_coap.h>
#endif
#if CONFIG_EXAMPLE_WEBSOCKET
#include <websocket/example_wsclient.h>
#endif
#if CONFIG_EXAMPLE_WLAN_SCENARIO
#include <wlan_scenario/example_wlan_scenario.h>
#endif
#if CONFIG_EXAMPLE_BCAST
#include <bcast/example_bcast.h>
#endif
#if CONFIG_EXAMPLE_AUDIO
#include <audio/example_audio.h>
#endif
#if CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE
#include <high_load_memory_use/example_high_load_memory_use.h>
#endif
#if CONFIG_EXAMPLE_WIFI_MAC_MONITOR
#include <wifi_mac_monitor/example_wifi_mac_monitor.h>
#endif
#if CONFIG_EXAMPLE_RARP
#include <rarp/example_rarp.h>
#endif
#if CONFIG_EXAMPLE_SSL_SERVER
#include <ssl_server/example_ssl_server.h>
#endif
#if CONFIG_EXAMPLE_OTA_HTTP
#include <ota_http/example_ota_http.h>
#endif
#if CONFIG_EXAMPLE_AMAZON_AWS_IOT
#include <amazon_awsiot/example_amazon_awsiot.h>
#endif
/*
Preprocessor of example
*/
void pre_example_entry(void)
{
#if ATCMD_VER == ATVER_2
flash_t flash;
struct wlan_fast_reconnect read_data = {0};
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
#endif
#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#if ATCMD_VER == ATVER_2
if(read_data.enable == 1)
#endif
{
example_wlan_fast_connect();
}
#endif
#if CONFIG_JD_SMART
example_jdsmart_init();
#endif
#if CONFIG_EXAMPLE_UART_ADAPTER
example_uart_adapter_init();
#endif
#if CONFIG_EXAMPLE_ARDUINO_WIFI
/*To ensure the application has enough heap size, please goto FreeRTOSConfig.h to change configTOTAL_HEAP_SIZE at least to 80*1024 */
example_arduino_wifi_init();
#endif
#if defined(FREERTOS_PMU_TICKLESS_PLL_RESERVED) && (FREERTOS_PMU_TICKLESS_PLL_RESERVED==1)
pmu_set_pll_reserved(1);
#endif
#if (configGENERATE_RUN_TIME_STATS == 1)
pmu_enable_wakelock_stats(1);
#endif
}
/*
All of the examples are disabled by default for code size consideration
The configuration is enabled in platform_opts.h
*/
void example_entry(void)
{
#if (CONFIG_EXAMPLE_MDNS && !CONFIG_EXAMPLE_UART_ADAPTER)
example_mdns();
#endif
#if CONFIG_EXAMPLE_MCAST
example_mcast();
#endif
#if CONFIG_EXAMPLE_XML
example_xml();
#endif
#if CONFIG_EXAMPLE_SOCKET_SELECT
example_socket_select();
#endif
#if CONFIG_EXAMPLE_NONBLOCK_CONNECT
example_nonblock_connect();
#endif
#if CONFIG_EXAMPLE_SOCKET_TCP_TRX == 1
example_socket_tcp_trx_1();
#elif CONFIG_EXAMPLE_SOCKET_TCP_TRX == 2
example_socket_tcp_trx_2();
#endif
#if CONFIG_EXAMPLE_SSL_DOWNLOAD
example_ssl_download();
#endif
#if CONFIG_EXAMPLE_HTTP_DOWNLOAD
example_http_download();
#endif
#if CONFIG_EXAMPLE_HTTPC
example_httpc();
#endif
#if CONFIG_EXAMPLE_HTTPD
example_httpd();
#endif
#if CONFIG_EXAMPLE_TCP_KEEPALIVE
example_tcp_keepalive();
#endif
#if CONFIG_EXAMPLE_SNTP_SHOWTIME
example_sntp_showtime();
#endif
#if CONFIG_EXAMPLE_PPPOE
example_pppoe();
#endif
#if CONFIG_EXAMPLE_MEDIA_SS
example_media_ss();
#endif
#if CONFIG_EXAMPLE_MEDIA_MS
example_media_ms();
#endif
#if CONFIG_EXAMPLE_MEDIA_AUDIO_FROM_RTP
example_media_audio_from_rtp();
#endif
#if CONFIG_EXAMPLE_AUDIO_MP3
example_audio_mp3();
#endif
#if CONFIG_EXAMPLE_GOOGLE_NEST
example_google(TYPE);
#endif
#if CONFIG_UART_UPDATE
example_uart_update();
#endif
#if CONFIG_EXAMPLE_WIGADGET
/*To ensure the application has enough heap size, please goto FreeRTOSConfig.h to change configTOTAL_HEAP_SIZE at least to 115*1024 */
example_wigadget();
#endif
#if CONFIG_EXAMPLE_MQTT
example_mqtt();
#endif
#if CONFIG_QQ_LINK
example_qq_link();
#endif
#if CONFIG_JOYLINK
example_joylink();
#endif
#if CONFIG_AIRKISS_CLOUD
example_airkiss_cloud();
#endif
#if CONFIG_EXAMPLE_WIFI_MAC_MONITOR
example_wifi_mac_monitor();
#endif
#if CONFIG_EXAMPLE_HTTP_CLIENT
example_http_client();
#endif
#if CONFIG_JOINLINK
example_joinlink();
#endif
#if CONFIG_EXAMPLE_GET_BEACON_FRAME
example_get_beacon_frame();
#endif
#if CONFIG_EXAMPLE_FATFS
example_fatfs();
#endif
#if CONFIG_EXAMPLE_DCT
example_dct();
#endif
#if CONFIG_GAGENT
example_gagent();
#endif
#if CONFIG_EXAMPLE_INIC_GSPI_HOST
example_inic_gspi();
#endif
#if CONFIG_EXAMPLE_USB_MASS_STORAGE
example_mass_storage();
#endif
#if CONFIG_EXAMPLE_UART_ATCMD
example_uart_atcmd();
#endif
#if CONFIG_EXAMPLE_SPI_ATCMD
example_spi_atcmd();
#endif
#if CONFIG_EXAMPLE_MJPEG_CAPTURE
example_mjpeg();
#endif
// supported eap methods: tls, peap, ttls
// make sure the corresponding config has been turned on before you use it
// e.g. set CONFIG_ENABLE_TLS to 1 if you want to use TLS eap method
#if CONFIG_EXAMPLE_EAP
example_eap("tls");
//example_eap("peap");
//example_eap("ttls");
#endif
#if CONFIG_EXAMPLE_AJ_BASIC
example_aj_basic();
#endif
#if CONFIG_EXAMPLE_AJ_AMEBA_LED
example_aj_ameba_led();
#endif
#if CONFIG_EXAMPLE_COAP
example_coap();
#endif
#if CONFIG_EXAMPLE_WEBSOCKET
example_wsclient();
#endif
#if CONFIG_EXAMPLE_WLAN_SCENARIO
// For Network Scan, Authentication, Mode Switch, Sequence Senario cases
// Para: S/ A/ M1/ M2/ M3/ M4/ M5/ M6/ M7/ S1/ S2/ S3/ S4/ S5/ S6
example_wlan_scenario("S");
#endif
#if CONFIG_EXAMPLE_BCAST
example_bcast();
#endif
#if CONFIG_EXAMPLE_AUDIO
example_audio();
#endif
#if CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE
example_high_load_memory_use();
#endif
#if CONFIG_EXAMPLE_RARP
example_rarp();
#endif
#if CONFIG_EXAMPLE_SSL_SERVER
example_ssl_server();
#endif
#if CONFIG_EXAMPLE_TIMELAPSE
example_media_tl();
#endif
#if CONFIG_EXAMPLE_OTA_HTTP
example_ota_http();
#endif
#if CONFIG_EXAMPLE_AMAZON_AWS_IOT
example_amazon_awsiot();
#endif
#if CONFIG_ALINK
example_alink();
#endif
#if CONFIG_HILINK
example_hilink();
#endif
}

View file

@ -0,0 +1,8 @@
#ifndef __EXAMPLE_ENTRY_H__
#define __EXAMPLE_ENTRY_H__
void example_entry(void);
void pre_example_entry(void);
#endif //#ifndef __EXAMPLE_ENTRY_H__

View file

@ -0,0 +1,48 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include <platform_opts.h>
#include <get_beacon_frame/example_get_beacon_frame.h>
#include <platform/platform_stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
typedef int (*get_beacon_frame_func_ptr)(BEACON_INFO_T beacon_frame);
extern get_beacon_frame_func_ptr get_beacon_frame_callback;
int get_beacon_frame_func(BEACON_INFO_T beacon_frame)
{
printf("\nbeacon frame_ctl = %02x %02x\n",beacon_frame.frame_ctl[0],beacon_frame.frame_ctl[1]);
printf("\nbeacon duration_id = %02x %02x\n",beacon_frame.duration_id[0],beacon_frame.duration_id[1]);
printf("\nbeacon addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n",\
beacon_frame.addr1[0],beacon_frame.addr1[1],beacon_frame.addr1[2],beacon_frame.addr1[3],beacon_frame.addr1[4],beacon_frame.addr1[5]);
printf("\nbeacon addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n",\
beacon_frame.addr2[0],beacon_frame.addr2[1],beacon_frame.addr2[2],beacon_frame.addr2[3],beacon_frame.addr2[4],beacon_frame.addr2[5]);
printf("\nbeacon addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n",\
beacon_frame.addr3[0],beacon_frame.addr3[1],beacon_frame.addr3[2],beacon_frame.addr3[3],beacon_frame.addr3[4],beacon_frame.addr3[5]);
printf("\nbeacon seq_ctl = %02x %02x\n",beacon_frame.seq_ctl[0],beacon_frame.seq_ctl[1]);
printf("\nbeacon timestamp = %02x %02x %02x %02x %02x %02x %02x %02x\n",\
beacon_frame.timestamp[0],beacon_frame.timestamp[1],beacon_frame.timestamp[2],beacon_frame.timestamp[3],beacon_frame.timestamp[4],beacon_frame.timestamp[5],beacon_frame.timestamp[6],beacon_frame.timestamp[7]);
return 0;
}
void get_beacon_frame_thread(void *param)
{
vTaskDelay(10000);//a rough time for waiting wifi connected
//Register callback function until wifi connected
get_beacon_frame_callback = get_beacon_frame_func;
vTaskDelete(NULL);
return;
}
void example_get_beacon_frame(void)
{
if(xTaskCreate(get_beacon_frame_thread, ((const char*)"get_beacon_frame_thread"), 256, NULL, tskIDLE_PRIORITY , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(get_beacon_frame_thread) failed", __FUNCTION__);
return;
}

View file

@ -0,0 +1,26 @@
#ifndef __EXAMPLE_GET_BEACON_FRAME_H__
#define __EXAMPLE_GET_BEACON_FRAME_H__
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
typedef struct beacon_info_str{
//802.11 MAC header
unsigned char frame_ctl[2];
unsigned char duration_id[2];
unsigned char addr1[6];
unsigned char addr2[6];
unsigned char addr3[6];
unsigned char seq_ctl[2];
//802.11 beacon IE
unsigned char timestamp[8];
}BEACON_INFO_T;
void example_get_beacon_frame(void);
int get_beacon_frame_func(BEACON_INFO_T beacon_frame);
#endif //#ifndef __EXAMPLE_GET_BEACON_FRAME_H__

View file

@ -0,0 +1,13 @@
GET BEACON FRAME EXAMPLE
Description:
Get beacon frame information in station mode
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_GET_BEACON_FRAME 1
Execution:
Call example_get_beacon_frame() to create get beacon frame thread.
It can collect the beacon of AP in the air.

View file

@ -0,0 +1,607 @@
#include <platform_opts.h>
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip_netconf.h>
#include <lwip/sockets.h>
#include "wifi_constants.h"
#include "wifi_structures.h"
#include "lwip_netconf.h"
#if CONFIG_USE_POLARSSL
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/error.h"
#include "polarssl/memory.h"
#elif CONFIG_USE_MBEDTLS
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#endif
#if CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE
#define PRIORITY_OFFSET 1
static void heap_monitor_handler(void *param);
void ssl_client_thread(char *server_host);
static void ssl_client_handler(void *param);
static void udp_server_handler(void *param);
static void udp_client_handler(void *param);
/*
* @brief Memory usage for high-load use case.
* Contains 3 TLS sessions and 6 UDP sessions.
* @note Process Flow:
* - Start heap monitor thread
* - Enable Wi-Fi with STA mode
* - Connect to AP by WPA2-AES
* - Start 3 TLS sessions
* - Start 6 UDP sessions
*/
static void high_load_case_memory_usage(void){
printf("\n\nMemory usage for high-load use case...\n");
/**********************************************************************************
* 1. Start heap monitor thread
**********************************************************************************/
// Start a thread that would check minimun available heap size periodically during the execution.
if(xTaskCreate(heap_monitor_handler, "heap_monitor_handler", 256,(void *) NULL, tskIDLE_PRIORITY + 1 + PRIORITY_OFFSET, NULL) != pdPASS)
printf("\r\nERROR: Create heap monitor task failed.");
/**********************************************************************************
* 2. Enable Wi-Fi with STA mode
**********************************************************************************/
printf("\n\rEnable Wi-Fi\n");
if(wifi_on(RTW_MODE_STA) < 0){
printf("\n\rERROR: wifi_on failed\n");
return;
}
/**********************************************************************************
* 3. Connect to AP by WPA2-AES
**********************************************************************************/
// Connect to AP with PSK-WPA2-AES.
char *ssid = "Test_ap";
char *password = "12345678";
if(wifi_connect(ssid, RTW_SECURITY_WPA2_AES_PSK, password, strlen(ssid), strlen(password), -1, NULL) == RTW_SUCCESS)
LwIP_DHCP(0, DHCP_START);
/**********************************************************************************
* 4. Start 3 TLS sessions
**********************************************************************************/
// Start SSL connection
// For each session, it will setup the connection and transfer data 10 times with 5s interval
ssl_client_thread("192.168.1.101");
ssl_client_thread("192.168.1.101");
ssl_client_thread("192.168.1.101");
/**********************************************************************************
* 5. Start 6 UDP sessions (5 servers, 1 client)
**********************************************************************************/
// Start UDP servers for ports from 6001 to 6005 by using socket select
if(xTaskCreate(udp_server_handler, "udp_server_handler", 1024, NULL, tskIDLE_PRIORITY + 1 + PRIORITY_OFFSET, NULL) != pdPASS)
printf("\r\nUDP ERROR: Create UDP server task failed.");
// Start UDP client that simply sends data to 192.168.1.101 port 6001
if(xTaskCreate(udp_client_handler, "udp_client_handler", 1024,NULL, tskIDLE_PRIORITY + 1 + PRIORITY_OFFSET, NULL) != pdPASS)
printf("\r\nUDP ERROR: Create UDP client task failed.");
}
// Heap monitor which will report the minimum available heap size during the execution.
static int minHeap = 0;
static void heap_monitor_handler(void *param){
while(1){
int getHeap = xPortGetFreeHeapSize();
if(minHeap == 0 || minHeap > getHeap)
minHeap = getHeap;
printf("\n\nMin Available Heap: %d\n", minHeap);
vTaskDelay(1000);
}
vTaskDelete(NULL);
}
/*
* @brief SSL/TLS connection.
* @note Please refer to component\common\utilities\ssl_client.c.
*/
void ssl_client_thread(char *server_host){
if(xTaskCreate(ssl_client_handler, "ssl_client_handler", 1150, server_host, tskIDLE_PRIORITY + 3 + PRIORITY_OFFSET, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
#if CONFIG_USE_POLARSSL
static void* my_malloc(size_t size)
{
void *ptr = pvPortMalloc(size);
return ptr;
}
#define my_free vPortFree
static void ssl_client_handler(void *param){
char *server_host = param;
int server_port = 443;
char *get_request = "GET / HTTP/1.0\r\nConnection: Keep-Alive\r\n\r\n";
int ret, len, server_fd = -1;
unsigned char buf[512];
ssl_context ssl;
int retry_count = 0;
memory_set_own(my_malloc, my_free);
/*
* 1. Start the connection
*/
printf("\n\r . Connecting to tcp/%s/%d...", server_host, server_port);
if((ret = net_connect(&server_fd, server_host, server_port)) != 0) {
printf(" failed\n\r ! net_connect returned %d\n", ret);
goto exit1;
}
printf(" ok\n");
/*
* 2. Setup stuff
*/
printf("\n\r . Setting up the SSL/TLS structure..." );
if((ret = ssl_init(&ssl)) != 0) {
printf(" failed\n\r ! ssl_init returned %d\n", ret);
goto exit;
}
ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
ssl_set_rng(&ssl, my_random, NULL);
ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd);
printf(" ok\n");
/*
* 3. Handshake
*/
printf("\n\r . Performing the SSL/TLS handshake...");
while((ret = ssl_handshake(&ssl)) != 0) {
if((ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE
&& ret != POLARSSL_ERR_NET_RECV_FAILED) || retry_count >= 5) {
printf(" failed\n\r ! ssl_handshake returned -0x%x\n", -ret);
goto exit;
}
retry_count++;
}
printf(" ok\n");
printf("\n\r . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl));
// Data transfer for 10 times
for(int i = 0; i < 10; i++){
/*
* 4. Write the GET request
*/
printf("\n\r > Write to server %s:", server_host);
len = sprintf((char *) buf, get_request);
while((ret = ssl_write(&ssl, buf, len)) <= 0) {
if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
printf(" failed\n\r ! ssl_write returned %d\n", ret);
goto exit;
}
}
len = ret;
printf(" %d bytes written\n\r\n\r%s\n", len, (char *) buf);
/*
* 5. Read the HTTP response
*/
printf("\n\r < Read from server %s:", server_host);
int read_size = 0, resource_size = 0, content_len = 0, header_removed = 0;
while((read_size = ssl_read(&ssl, buf, sizeof(buf) - 1)) > 0) {
if(header_removed == 0) {
char *header = NULL;
buf[read_size] = 0;
header = strstr(buf, "\r\n\r\n");
if(header) {
char *body, *content_len_pos;
body = header + strlen("\r\n\r\n");
*(body - 2) = 0;
header_removed = 1;
printf("\nHTTP Header: %s\n", buf);
// Remove header size to get first read size of data from body head
read_size = read_size - ((unsigned char *) body - buf);
content_len_pos = strstr(buf, "Content-Length: ");
if(content_len_pos) {
content_len_pos += strlen("Content-Length: ");
*(char*)(strstr(content_len_pos, "\r\n")) = 0;
content_len = atoi(content_len_pos);
}
}
else {
printf("ERROR: HTTP header\n");
goto exit;
}
}
else {
printf("\n%s\n", buf);
}
printf("\nread resource %d bytes\n", read_size);
resource_size += read_size;
memset(buf, 0, sizeof(buf));
if(resource_size == content_len)
break;
}
printf("\nhttp read resource size = %d bytes\n", resource_size);
vTaskDelay(5000);
}
ssl_close_notify(&ssl);
exit:
net_close(server_fd);
ssl_free(&ssl);
exit1:
vTaskDelete(NULL);
}
#elif CONFIG_USE_MBEDTLS /* CONFIG_USE_POLARSSL */
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
#define my_free vPortFree
static char *hl_itoa(int value){
char *val_str;
int tmp = value, len = 1;
while((tmp /= 10) > 0)
len ++;
val_str = (char *) pvPortMalloc(len + 1);
sprintf(val_str, "%d", value);
return val_str;
}
static void ssl_client_handler(void *param){
char *server_host = param;
int server_port = 443;
char *get_request = "GET / HTTP/1.0\r\nConnection: Keep-Alive\r\n\r\n";
int ret, len;
unsigned char buf[512];
int retry_count = 0;
mbedtls_net_context server_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
/*
* 1. Start the connection
*/
printf("\n\r . Connecting to tcp/%s/%d...", server_host, server_port);
mbedtls_net_init(&server_fd);
char *server_port_str = hl_itoa(server_port);
if((ret = mbedtls_net_connect(&server_fd, server_host, server_port_str, MBEDTLS_NET_PROTO_TCP)) != 0) {
printf(" failed\n\r ! net_connect returned %d\n", ret);
goto exit1;
}
printf(" ok\n");
/*
* 2. Setup stuff
*/
printf("\n\r . Setting up the SSL/TLS structure..." );
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
if((ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf(" failed\n\r ! ssl_config_defaults returned %d\n", ret);
goto exit;
}
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, my_random, NULL);
if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf(" failed\n\r ! ssl_setup returned %d\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 3. Handshake
*/
printf("\n\r . Performing the SSL/TLS handshake...");
while((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if(ret != MBEDTLS_ERR_NET_RECV_FAILED || retry_count >= 5) {
printf(" failed\n\r ! ssl_handshake returned -0x%x\n", -ret);
goto exit;
}
retry_count++;
}
printf(" ok\n");
printf("\n\r . Use ciphersuite %s\n", mbedtls_ssl_get_ciphersuite(&ssl));
// Data transfer for 10 times
for(int i = 0; i < 10; i++){
/*
* 4. Write the GET request
*/
printf("\n\r > Write to server %s:", server_host);
len = sprintf((char *) buf, get_request);
while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) {
printf(" failed\n\r ! ssl_write returned %d\n", ret);
goto exit;
}
len = ret;
printf(" %d bytes written\n\r\n\r%s\n", len, (char *) buf);
/*
* 5. Read the HTTP response
*/
printf("\n\r < Read from server %s:", server_host);
int read_size = 0, resource_size = 0, content_len = 0, header_removed = 0;
while((read_size = mbedtls_ssl_read(&ssl, buf, sizeof(buf) - 1)) > 0) {
if(header_removed == 0) {
char *header = NULL;
buf[read_size] = 0;
header = strstr(buf, "\r\n\r\n");
if(header) {
char *body, *content_len_pos;
body = header + strlen("\r\n\r\n");
*(body - 2) = 0;
header_removed = 1;
printf("\nHTTP Header: %s\n", buf);
// Remove header size to get first read size of data from body head
read_size = read_size - ((unsigned char *) body - buf);
content_len_pos = strstr(buf, "Content-Length: ");
if(content_len_pos) {
content_len_pos += strlen("Content-Length: ");
*(char*)(strstr(content_len_pos, "\r\n")) = 0;
content_len = atoi(content_len_pos);
}
}
else {
printf("ERROR: HTTP header\n");
goto exit;
}
}
else {
printf("\n%s\n", buf);
}
printf("\nread resource %d bytes\n", read_size);
resource_size += read_size;
memset(buf, 0, sizeof(buf));
if(resource_size == content_len)
break;
}
printf("\nhttp read resource size = %d bytes\n", resource_size);
vTaskDelay(5000);
}
mbedtls_ssl_close_notify(&ssl);
exit:
mbedtls_net_free(&server_fd);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
exit1:
vTaskDelete(NULL);
}
#endif /* CONFIG_USE_POLARSSL */
/*
* @brief Use socket select for 5 UDP server ports from 6001 to 6005.
* @note Please refer to component\common\example\socket_select\example_socket_select.c for socket select example.
*/
#define MAX_SOCKETS 10
#define SELECT_TIMEOUT 60
int socket_used[MAX_SOCKETS];
int udp_server_bind_socket(int server_port){
int server_fd = -1;
struct sockaddr_in server_addr;
if((server_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0) {
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
server_addr.sin_addr.s_addr = INADDR_ANY;
int sock_opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &sock_opt, sizeof( sock_opt ));
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("Bind error\n");
return -1;
}
socket_used[server_fd] = 1;
printf("Success bind UDP port %d with socket fd %d\n", server_port, server_fd);
return server_fd;
}
else {
printf("Socket error\n");
return -1;
}
}
static void udp_server_handler(void *param)
{
int max_socket_fd = -1;
int min_socket_fd = 20;
struct sockaddr_in client_addr;
int addrlen = sizeof(struct sockaddr_in);
int server_fd_1 = -1, server_fd_2 = -1, server_fd_3 = -1, server_fd_4 = -1, server_fd_5 = -1;
memset(socket_used, 0, sizeof(socket_used));
// bind udp server socket from port 6001 to 6005
int server_fd = -1;
for(int i=0; i<5; i++){
server_fd = -1;
server_fd = udp_server_bind_socket(6001 + i);
if(server_fd != -1 && server_fd > max_socket_fd)
max_socket_fd = server_fd;
if(server_fd != -1 && server_fd < min_socket_fd)
min_socket_fd = server_fd;
}
while(1) {
int socket_fd;
unsigned char buf[512];
fd_set read_fds;
struct timeval timeout;
FD_ZERO(&read_fds);
timeout.tv_sec = SELECT_TIMEOUT;
timeout.tv_usec = 0;
for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++)
if(socket_used[socket_fd])
FD_SET(socket_fd, &read_fds);
if(select(max_socket_fd + 1, &read_fds, NULL, NULL, &timeout)) {
for(socket_fd = min_socket_fd; socket_fd < max_socket_fd + 1; socket_fd ++) {
if(socket_used[socket_fd] && FD_ISSET(socket_fd, &read_fds)) {
int read_size = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr*) &client_addr, &addrlen);
if(read_size > 0) {
printf("socket fd(%d) recv data size: %d\n", socket_fd, read_size);
sendto(socket_fd, buf, read_size, 0, (struct sockaddr*) &client_addr, addrlen);
}
else {
printf("socket fd(%d) recv data failed\n", socket_fd);
socket_used[socket_fd] = 0;
close(socket_fd);
}
}
}
}
else {
printf("UDP server: no data in %d seconds\n", SELECT_TIMEOUT);
}
}
exit:
for(int socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++)
if(socket_used[socket_fd])
close(socket_fd);
vTaskDelete(NULL);
}
/*
* @brief Simple UDP client.
*/
static void udp_client_handler(void *param){
char* ip = "192.168.1.101";
int port = 6001;
struct sockaddr_in ser_addr;
int client_fd = -1;
unsigned char buf[512];
//filling the buffer
for (int i = 0; i < sizeof(buf); i++)
buf[i] = (unsigned char)(i % 10);
if( (client_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
printf("\n\r[ERROR] %s: Create UDP socket failed",__func__);
goto exit;
}
memset(&ser_addr, 0, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(port);
ser_addr.sin_addr.s_addr = inet_addr(ip);
printf("\n\r%s: Server IP=%s, port=%d", __func__,ip, port);
while(1){
if(sendto(client_fd, buf, sizeof(buf),0,(struct sockaddr*)&ser_addr, sizeof(struct sockaddr_in)) < 0)
break;
else
printf("Send UDP data to %s: %d\n", ip, port);
vTaskDelay(1000);
}
close(client_fd);
exit:
vTaskDelete(NULL);
}
static void example_high_load_memory_use_thread(void){
vTaskDelay(4000);
// High-load use case memory usage: 3 TLS + 6 UDP
high_load_case_memory_usage();
vTaskDelete(NULL);
}
void example_high_load_memory_use(void){
if(xTaskCreate(example_high_load_memory_use_thread, ((const char*)"example_high_load_memory_use_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed\n", __FUNCTION__);
}
#endif /* CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE */

View file

@ -0,0 +1,9 @@
#ifndef EXAMPLE_HIGH_LOAD_MEMORY_USE_H
#define EXAMPLE_HIGH_LOAD_MEMORY_USE_H
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
void example_high_load_memory_use(void);
#endif

View file

@ -0,0 +1,41 @@
HIGH-LOAD USE CASE MEMORY USAGE EXAMPLE
Description:
Example to monitor the memory usage for high-load use case.
Includes:
- 3 TLS sessions
- 6 UDP sessions including 5 UDP servers on different ports and 1 UDP client
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#define CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE 1
[lwipopts.h]
#define MEMP_NUM_NETCONN 20
#define MEMP_NUM_UDP_PCB MEMP_NUM_NETCONN
[FreeRTOSConfig.h]
// Configure this if the heap size is not enough
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) )
Execution:
The example thread will be started automatically when booting.
You may need to change the IP/Port used in this example to make it work properly.
To verify the TLS sessions, you can setup an apache server for yourself and make sure the KeepAliveTimeout is larger than 5s.
To verify UDP server session, you can use iperf with following command to send UDP data:
$ iperf.exe -c 192.168.1.123 -u -p 6001 -t 30 -i 1
To verify UDP client session, you can use iperf with following command to start UDP server:
$ iperf.exe -s -p 6001 -u -i 1
Note:
Example work flow:
Start heap monitor thread
-> Enable Wi-Fi with STA mode
-> Connect to AP by WPA2-AES
-> Start 3 TLS sessions
-> Start 6 UDP sessions
If you want to use ECDHE as TLS cipher suite, you can modify:
[config_rsa.h]
#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define POLARSSL_ECDH_C
#define POLARSSL_ECP_C

View file

@ -0,0 +1,86 @@
#include <platform_opts.h>
#include "FreeRTOS.h"
#include "task.h"
#include "lwip/netdb.h"
#include "http_client.h"
#include "http_client/example_http_client.h"
#include <platform/platform_stdlib.h>
#define THREAD_STACK_SIZE 1024
#define HOST_NAME "www.google.com.tw"
#define HOST_PORT 80
extern char *http_post_header(char *host, char *resource, char *type, int data_len);
extern char *http_get_header(char *host, char *resource);
void http_client(void)
{
int port = HOST_PORT;
char *host = HOST_NAME;
char *message_fmt = "POST / HTTP/1.0\r\n\r\n";
struct hostent *server;
struct sockaddr_in serv_addr;
int sockfd, bytes;
char message[256],*response;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
printf("[ERROR] Create socket failed\n");
server = gethostbyname(host);
if(server == NULL)
printf("[ERROR] Get host ip failed\n");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0){
printf("[ERROR] connect failed\n");
return ;
}
//send request
sprintf(message,"%s",http_get_header(HOST_NAME,"/"));
printf("\nRequest:\n%s\n",message);
bytes = write(sockfd,message,256);
if (bytes < 0)
printf("[ERROR] send packet failed\n");
//receive response
response = malloc(1500);
if(response ==NULL)
printf("[ERROR] malloc failed\n");
printf("Response:\n");
do {
memset(response,0,1500);
bytes = read(sockfd,response,1500-1);
if (bytes < 0)
printf("[ERROR] receive packet failed\n");
if (bytes == 0)
break;
printf("%s",response);
} while (bytes > 0);
//close the socket
close(sockfd);
return;
}
static void http_client_thread(void *param)
{
//wait for wifi connected, a rough time
vTaskDelay(10000);
http_client();
vTaskDelete(NULL);
}
void example_http_client(void)
{
if(xTaskCreate(http_client_thread, ((const char*)"http_client_thread"), THREAD_STACK_SIZE, NULL, tskIDLE_PRIORITY , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(http_client_thread) failed\n", __FUNCTION__);
return;
}

View file

@ -0,0 +1,13 @@
#ifndef __EXAMPLE_HTTP_CLIENT_H__
#define __EXAMPLE_HTTP_CLIENT_H__
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
void example_http_client(void);
#endif //#ifndef __EXAMPLE_HTTP_CLIENT_H__

View file

@ -0,0 +1,13 @@
HTTP CLIENT EXAMPLE
Description:
Http client send request to get server response.
Configuration:
Change HOST_NAME and HOST_PORT to user define.
[platform_opts.h]
#define CONFIG_EXAMPLE_HTTP_CLIENT 1
Execution:
Call http_client() to send http request.

View file

@ -0,0 +1,116 @@
#include <platform_opts.h>
#if defined(CONFIG_EXAMPLE_HTTP_DOWNLOAD) && (CONFIG_EXAMPLE_HTTP_DOWNLOAD == 1)
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#define SERVER_HOST "tpdb.speed2.hinet.net"
#define SERVER_PORT 80
#define RESOURCE "/test_010m.zip"
#define BUFFER_SIZE 2048
#define RECV_TO 5000 // ms
static void example_http_download_thread(void *param)
{
int server_fd = -1, ret;
struct sockaddr_in server_addr;
struct hostent *server_host;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: HTTP download\n");
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("ERROR: socket\n");
goto exit;
}
else {
int recv_timeout_ms = RECV_TO;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0) // lwip 1.5.0
struct timeval recv_timeout;
recv_timeout.tv_sec = recv_timeout_ms / 1000;
recv_timeout.tv_usec = recv_timeout_ms % 1000 * 1000;
setsockopt(server_fd, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
#else // lwip 1.4.1
setsockopt(server_fd, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout_ms, sizeof(recv_timeout_ms));
#endif
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
// Support SERVER_HOST in IP or domain name
server_host = gethostbyname(SERVER_HOST);
memcpy((void *) &server_addr.sin_addr, (void *) server_host->h_addr, server_host->h_length);
if(connect(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == 0) {
unsigned char buf[BUFFER_SIZE + 1];
int pos = 0, read_size = 0, resource_size = 0, content_len = 0, header_removed = 0;
sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", RESOURCE, SERVER_HOST);
write(server_fd, buf, strlen(buf));
while((read_size = read(server_fd, buf + pos, BUFFER_SIZE - pos)) > 0) {
if(header_removed == 0) {
char *header = NULL;
pos += read_size;
buf[pos] = 0;
header = strstr(buf, "\r\n\r\n");
if(header) {
char *body, *content_len_pos;
body = header + strlen("\r\n\r\n");
*(body - 2) = 0;
header_removed = 1;
printf("\nHTTP Header: %s\n", buf);
// Remove header size to get first read size of data from body head
read_size = pos - ((unsigned char *) body - buf);
pos = 0;
content_len_pos = strstr(buf, "Content-Length: ");
if(content_len_pos) {
content_len_pos += strlen("Content-Length: ");
*(char*)(strstr(content_len_pos, "\r\n")) = 0;
content_len = atoi(content_len_pos);
}
}
else {
if(pos >= BUFFER_SIZE){
printf("ERROR: HTTP header\n");
goto exit;
}
continue;
}
}
printf("read resource %d bytes\n", read_size);
resource_size += read_size;
}
printf("exit read. ret = %d\n", read_size);
printf("http content-length = %d bytes, download resource size = %d bytes\n", content_len, resource_size);
}
else {
printf("ERROR: connect\n");
}
exit:
if(server_fd >= 0)
close(server_fd);
vTaskDelete(NULL);
}
void example_http_download(void)
{
if(xTaskCreate(example_http_download_thread, ((const char*)"example_http_download_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
#endif //CONFIG_EXAMPLE_HTTP_DOWNLOAD

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_HTTP_DOWNLOAD_H
#define EXAMPLE_HTTP_DOWNLOAD_H
void example_http_download(void);
#endif /* EXAMPLE_HTTP_DOWNLOAD_H */

View file

@ -0,0 +1,15 @@
HTTP DOWNLOAD EXAMPLE
Description:
Download file from Web server via http.
Configuration:
Modify SERVER_HOST, SERVER_PORT and RESOURCE in example_http_download.c based on your HTTP server.
[platform_opts.h]
#define CONFIG_EXAMPLE_HTTP_DOWNLOAD 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A http download example thread will be started automatically when booting.

View file

@ -0,0 +1,137 @@
#include <FreeRTOS.h>
#include <task.h>
#include <platform_stdlib.h>
#include <httpc/httpc.h>
#define USE_HTTPS 0
#define SERVER_HOST "httpbin.org"
static void example_httpc_thread(void *param)
{
struct httpc_conn *conn = NULL;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: HTTPC\n");
/* test GET to http://httpbin.org/get?param1=test_data1&param2=test_data2 */
#if USE_HTTPS
conn = httpc_conn_new(HTTPC_SECURE_TLS, NULL, NULL, NULL);
#else
conn = httpc_conn_new(HTTPC_SECURE_NONE, NULL, NULL, NULL);
#endif
if(conn) {
#if USE_HTTPS
if(httpc_conn_connect(conn, SERVER_HOST, 443, 0) == 0) {
#else
if(httpc_conn_connect(conn, SERVER_HOST, 80, 0) == 0) {
#endif
/* HTTP GET request */
// start a header and add Host (added automatically), Content-Type and Content-Length (added by input param)
httpc_request_write_header_start(conn, "GET", "/get?param1=test_data1&param2=test_data2", NULL, 0);
// add other required header fields if necessary
httpc_request_write_header(conn, "Connection", "close");
// finish and send header
httpc_request_write_header_finish(conn);
// receive response header
if(httpc_response_read_header(conn) == 0) {
httpc_conn_dump_header(conn);
// receive response body
if(httpc_response_is_status(conn, "200 OK")) {
uint8_t buf[1024];
int read_size = 0, total_size = 0;
while(1) {
memset(buf, 0, sizeof(buf));
read_size = httpc_response_read_data(conn, buf, sizeof(buf) - 1);
if(read_size > 0) {
total_size += read_size;
printf("%s", buf);
}
else {
break;
}
if(conn->response.content_len && (total_size >= conn->response.content_len))
break;
}
}
}
}
else {
printf("\nERROR: httpc_conn_connect\n");
}
httpc_conn_close(conn);
httpc_conn_free(conn);
}
/* test POST to http://httpbin.org/post with data of param1=test_data1&param2=test_data2 */
#if USE_HTTPS
conn = httpc_conn_new(HTTPC_SECURE_TLS, NULL, NULL, NULL);
#else
conn = httpc_conn_new(HTTPC_SECURE_NONE, NULL, NULL, NULL);
#endif
if(conn) {
#if USE_HTTPS
if(httpc_conn_connect(conn, SERVER_HOST, 443, 0) == 0) {
#else
if(httpc_conn_connect(conn, SERVER_HOST, 80, 0) == 0) {
#endif
/* HTTP POST request */
char *post_data = "param1=test_data1&param2=test_data2";
// start a header and add Host (added automatically), Content-Type and Content-Length (added by input param)
httpc_request_write_header_start(conn, "POST", "/post", NULL, strlen(post_data));
// add other header fields if necessary
httpc_request_write_header(conn, "Connection", "close");
// finish and send header
httpc_request_write_header_finish(conn);
// send http body
httpc_request_write_data(conn, post_data, strlen(post_data));
// receive response header
if(httpc_response_read_header(conn) == 0) {
httpc_conn_dump_header(conn);
// receive response body
if(httpc_response_is_status(conn, "200 OK")) {
uint8_t buf[1024];
int read_size = 0, total_size = 0;
while(1) {
memset(buf, 0, sizeof(buf));
read_size = httpc_response_read_data(conn, buf, sizeof(buf) - 1);
if(read_size > 0) {
total_size += read_size;
printf("%s", buf);
}
else {
break;
}
if(conn->response.content_len && (total_size >= conn->response.content_len))
break;
}
}
}
}
else {
printf("\nERROR: httpc_conn_connect\n");
}
httpc_conn_close(conn);
httpc_conn_free(conn);
}
vTaskDelete(NULL);
}
void example_httpc(void)
{
if(xTaskCreate(example_httpc_thread, ((const char*)"example_httpc_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_httpc_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_HTTPC_H
#define EXAMPLE_HTTPC_H
void example_httpc(void);
#endif /* EXAMPLE_HTTPC_H */

View file

@ -0,0 +1,15 @@
HTTPC EXAMPLE
Description:
Based on HTTPC API, an HTTP/HTTPS client example to access httpbin.org for test are provided
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_HTTPC 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A httpc example thread is started automatically when booting.
GET to http://httpbin.org/get and POST to http://httpbin.org/post will be verified.
Both HTTP and HTTPS are supported by this exmaple, and can be changed by modifying USE_HTTPS.
Should link PolarSSL bignum.c to SRAM to speed up SSL handshake for HTTPS client.

View file

@ -0,0 +1,191 @@
#include <FreeRTOS.h>
#include <task.h>
#include <platform_stdlib.h>
#include <httpd/httpd.h>
#define USE_HTTPS 0
#if USE_HTTPS
// use test_srv_crt, test_srv_key, test_ca_list in PolarSSL certs.c
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
#include <polarssl/certs.h>
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
#include <mbedtls/certs.h>
#endif
#endif
void homepage_cb(struct httpd_conn *conn)
{
char *user_agent = NULL;
// test log to show brief header parsing
httpd_conn_dump_header(conn);
// test log to show extra User-Agent header field
if(httpd_request_get_header_field(conn, "User-Agent", &user_agent) != -1) {
printf("\nUser-Agent=[%s]\n", user_agent);
httpd_free(user_agent);
}
// GET homepage
if(httpd_request_is_method(conn, "GET")) {
char *body = \
"<HTML><BODY>" \
"It Works<BR>" \
"<BR>" \
"Can test GET by <A href=\"/test_get?test1=one%20%26%202&test2=three%3D3\">/test_get?test1=one%20%26%202&test2=three%3D3</A><BR>" \
"Can test POST by UI in <A href=\"/test_post.htm\">/test_post.htm</A><BR>" \
"</BODY></HTML>";
// write HTTP response
httpd_response_write_header_start(conn, "200 OK", "text/html", strlen(body));
httpd_response_write_header(conn, "Connection", "close");
httpd_response_write_header_finish(conn);
httpd_response_write_data(conn, body, strlen(body));
}
else {
// HTTP/1.1 405 Method Not Allowed
httpd_response_method_not_allowed(conn, NULL);
}
httpd_conn_close(conn);
}
void test_get_cb(struct httpd_conn *conn)
{
// GET /test_post
if(httpd_request_is_method(conn, "GET")) {
char *test1 = NULL, *test2 = NULL;
// get 'test1' and 'test2' in query string
if((httpd_request_get_query_key(conn, "test1", &test1) != -1) &&
(httpd_request_get_query_key(conn, "test2", &test2) != -1)) {
// write HTTP response
httpd_response_write_header_start(conn, "200 OK", "text/plain", 0);
httpd_response_write_header(conn, "Connection", "close");
httpd_response_write_header_finish(conn);
httpd_response_write_data(conn, "\r\nGET query string", strlen("\r\nGET query string"));
httpd_response_write_data(conn, "\r\ntest1: ", strlen("\r\ntest1: "));
httpd_response_write_data(conn, test1, strlen(test1));
httpd_response_write_data(conn, "\r\ntest2: ", strlen("\r\ntest2: "));
httpd_response_write_data(conn, test2, strlen(test2));
}
else {
// HTTP/1.1 400 Bad Request
httpd_response_bad_request(conn, "Bad Request - test1 or test2 not in query string");
}
if(test1)
httpd_free(test1);
if(test2)
httpd_free(test2);
}
else {
// HTTP/1.1 405 Method Not Allowed
httpd_response_method_not_allowed(conn, NULL);
}
httpd_conn_close(conn);
}
void test_post_htm_cb(struct httpd_conn *conn)
{
// GET /test_post.htm
if(httpd_request_is_method(conn, "GET")) {
char *body = \
"<HTML><BODY>" \
"<FORM action=\"/test_post\" method=\"post\">" \
"Text1: <INPUT type=\"text\" name=\"text1\" size=\"50\" maxlength=\"50\"><BR>" \
"Text2: <INPUT type=\"text\" name=\"text2\" size=\"50\" maxlength=\"50\"><BR>" \
"<INPUT type=\"submit\" value=\"POST\"><BR>" \
"</FORM>" \
"</BODY></HTML>";
// write HTTP response
httpd_response_write_header_start(conn, "200 OK", "text/html", strlen(body));
httpd_response_write_header(conn, "Connection", "close");
httpd_response_write_header_finish(conn);
httpd_response_write_data(conn, body, strlen(body));
}
else {
// HTTP/1.1 405 Method Not Allowed
httpd_response_method_not_allowed(conn, NULL);
}
httpd_conn_close(conn);
}
void test_post_cb(struct httpd_conn *conn)
{
// POST /test_post
if(httpd_request_is_method(conn, "POST")) {
size_t read_size;
uint8_t buf[50];
size_t content_len = conn->request.content_len;
uint8_t *body = (uint8_t *) malloc(content_len + 1);
if(body) {
// read HTTP body
memset(body, 0, content_len + 1);
read_size = httpd_request_read_data(conn, body, content_len);
// write HTTP response
httpd_response_write_header_start(conn, "200 OK", "text/plain", 0);
httpd_response_write_header(conn, "Connection", "close");
httpd_response_write_header_finish(conn);
memset(buf, 0, sizeof(buf));
sprintf(buf, "%d bytes from POST: ", read_size);
httpd_response_write_data(conn, buf, strlen(buf));
httpd_response_write_data(conn, body, strlen(body));
free(body);
}
else {
// HTTP/1.1 500 Internal Server Error
httpd_response_internal_server_error(conn, NULL);
}
}
else {
// HTTP/1.1 405 Method Not Allowed
httpd_response_method_not_allowed(conn, NULL);
}
httpd_conn_close(conn);
}
static void example_httpd_thread(void *param)
{
#if USE_HTTPS
#if (HTTPD_USE_TLS == HTTPD_TLS_POLARSSL)
if(httpd_setup_cert(test_srv_crt, test_srv_key, test_ca_crt) != 0) {
#elif (HTTPD_USE_TLS == HTTPD_TLS_MBEDTLS)
if(httpd_setup_cert(mbedtls_test_srv_crt, mbedtls_test_srv_key, mbedtls_test_ca_crt) != 0) {
#endif
printf("\nERROR: httpd_setup_cert\n");
goto exit;
}
#endif
httpd_reg_page_callback("/", homepage_cb);
httpd_reg_page_callback("/index.htm", homepage_cb);
httpd_reg_page_callback("/test_get", test_get_cb);
httpd_reg_page_callback("/test_post.htm", test_post_htm_cb);
httpd_reg_page_callback("/test_post", test_post_cb);
#if USE_HTTPS
if(httpd_start(443, 5, 4096, HTTPD_THREAD_SINGLE, HTTPD_SECURE_TLS) != 0) {
#else
if(httpd_start(80, 5, 4096, HTTPD_THREAD_SINGLE, HTTPD_SECURE_NONE) != 0) {
#endif
printf("ERROR: httpd_start");
httpd_clear_page_callbacks();
}
exit:
vTaskDelete(NULL);
}
void example_httpd(void)
{
if(xTaskCreate(example_httpd_thread, ((const char*)"example_httpd_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_httpd_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_HTTPD_H
#define EXAMPLE_HTTPD_H
void example_httpd(void);
#endif /* EXAMPLE_HTTPD_H */

View file

@ -0,0 +1,23 @@
HTTPD EXAMPLE
Description:
Based on HTTPD API, an HTTP/HTTPS server example with a simple homepage and GET/POST method test pages are provided
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_HTTPD 1
[lwipopts.h]
#define SO_REUSE 1
SSL Configuration for HTTPS:
[config_rsa.h]
#define POLARSSL_CERTS_C
#define POLARSSL_SSL_SRV_C
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A httpd example thread is started automatically when booting.
Both HTTP and HTTPS are supported by this exmaple, and can be changed by modifying USE_HTTPS.
Can test with a Web browser connecting to the homepage of httpd server.
Should link PolarSSL bignum.c to SRAM to speed up SSL handshake if starting HTTPS server.

View file

@ -0,0 +1,98 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip_netconf.h>
#include <lwip/netif.h>
extern struct netif xnetif[];
static void example_mcast_thread(void *param)
{
#if LWIP_IGMP
int err = 0;
int socket = -1;
char *group_ip = "224.0.0.251";
uint16_t port = 5353;
// Set NETIF_FLAG_IGMP flag for netif which should process IGMP messages
xnetif[0].flags |= NETIF_FLAG_IGMP;
if((socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("ERROR: socket - AF_INET, SOCK_DGRAM\n");
err = -1;
}
// Add multicast group membership on this interface
if(err == 0) {
struct ip_mreq imr;
imr.imr_multiaddr.s_addr = inet_addr(group_ip);
imr.imr_interface.s_addr = INADDR_ANY;
err = setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr));
if(err < 0) printf("ERROR: setsockopt - IP_ADD_MEMBERSHIP\n");
}
// Specify outgoing interface too
if(err == 0) {
struct in_addr intfAddr;
intfAddr.s_addr = INADDR_ANY;
err = setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, &intfAddr, sizeof(struct in_addr));
if(err < 0) printf("ERROR: setsockopt - IP_MULTICAST_IF\n");
}
// And start listening for packets
if(err == 0) {
struct sockaddr_in bindAddr;
bindAddr.sin_family = AF_INET;
bindAddr.sin_port = htons(port);
bindAddr.sin_addr.s_addr = INADDR_ANY;
err = bind(socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr));
if(err < 0) printf("ERROR: bind\n");
}
if(err == 0) {
unsigned char packet[1024];
while(1) {
// Receive multicast
int packetLen;
struct sockaddr from;
struct sockaddr_in *from_sin = (struct sockaddr_in*) &from;
socklen_t fromLen = sizeof(from);
if((packetLen = recvfrom(socket, &packet, sizeof(packet), 0, &from, &fromLen)) >= 0) {
uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr;
uint16_t from_port = ntohs(from_sin->sin_port);
printf("recvfrom - %d bytes from %d.%d.%d.%d:%d\n", packetLen, ip[0], ip[1], ip[2], ip[3], from_port);
}
// Send multicast
if(packetLen > 0) {
int sendLen;
struct sockaddr to;
struct sockaddr_in *to_sin = (struct sockaddr_in*) &to;
to_sin->sin_family = AF_INET;
to_sin->sin_port = htons(port);
to_sin->sin_addr.s_addr = inet_addr(group_ip);
if((sendLen = sendto(socket, packet, packetLen, 0, &to, sizeof(struct sockaddr))) < 0)
printf("ERROR: sendto %s\n", group_ip);
else
printf("sendto - %d bytes to %s:%d\n", sendLen, group_ip, port);
}
}
}
else if(socket != -1) {
close(socket);
}
#else
printf("\nSHOULD ENABLE LWIP_IGMP\n");
#endif
vTaskDelete(NULL);
}
void example_mcast(void)
{
if(xTaskCreate(example_mcast_thread, ((const char*)"example_mcast_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_MCAST_H
#define EXAMPLE_MCAST_H
void example_mcast(void);
#endif /* EXAMPLE_MCAST_H */

View file

@ -0,0 +1,17 @@
LWIP MULTICAST EXAMPLE
Description:
Join multicast group of 224.0.0.251 and listen on port 5353.
Send packet with the content of received packet to multicast group of 224.0.0.251.
Configuration:
[lwipopts.h]
#define LWIP_UDP 1
#define LWIP_IGMP 1
[platform_opts.h]
#define CONFIG_EXAMPLE_MCAST 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A multicast example thread will be started automatically when booting.

View file

@ -0,0 +1,55 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <mDNS/mDNS.h>
#include <lwip_netconf.h>
#include <lwip/netif.h>
extern struct netif xnetif[];
static void example_mdns_thread(void *param)
{
DNSServiceRef dnsServiceRef = NULL;
TXTRecordRef txtRecord;
unsigned char txt_buf[100]; // use fixed buffer for text record to prevent malloc/free
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nmDNS Init\n");
if(mDNSResponderInit() == 0) {
printf("mDNS Register service\n");
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content"), "text1_content");
TXTRecordSetValue(&txtRecord, "text2", strlen("text2_content"), "text2_content");
dnsServiceRef = mDNSRegisterService("ameba", "_service1._tcp", "local", 5000, &txtRecord);
TXTRecordDeallocate(&txtRecord);
printf("wait for 30s ... \n");
vTaskDelay(30*1000);
printf("mDNS Update service\n");
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content_new"), "text1_content_new");
mDNSUpdateService(dnsServiceRef, &txtRecord, 0);
TXTRecordDeallocate(&txtRecord);
printf("wait for 30s ... \n");
vTaskDelay(30*1000);
if(dnsServiceRef)
mDNSDeregisterService(dnsServiceRef);
// deregister service before mdns deinit is not necessary
// mDNS deinit will also deregister all services
printf("mDNS Deinit\n");
mDNSResponderDeinit();
}
vTaskDelete(NULL);
}
void example_mdns(void)
{
if(xTaskCreate(example_mdns_thread, ((const char*)"example_mdns_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_MDNS_H
#define EXAMPLE_MDNS_H
void example_mdns(void);
#endif /* EXAMPLE_MDNS_H */

View file

@ -0,0 +1,194 @@
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "MQTTClient.h"
#include "wifi_conf.h"
#define MQTT_SELECT_TIMEOUT 1
void messageArrived(MessageData* data)
{
mqtt_printf(MQTT_INFO, "Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data,
data->message->payloadlen, (char*)data->message->payload);
}
//This example is original and cannot restart if failed. To use this example, define WAIT_FOR_ACK and not define MQTT_TASK in MQTTClient.h
static void prvMQTTEchoTask(void *pvParameters)
{
/* connect to gpssensor.ddns.net, subscribe to a topic, send and receive messages regularly every 5 sec */
MQTTClient client;
Network network;
unsigned char sendbuf[512], readbuf[80];
int rc = 0, count = 0;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
char* address = "gpssensor.ddns.net";
char* sub_topic = "LASS/Test/Pm25Ameba/#";
char* pub_topic = "LASS/Test/Pm25Ameba/FT1_018";
NetworkInit(&network);
MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
mqtt_printf(MQTT_INFO, "Wait Wi-Fi to be connected.");
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS) {
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
mqtt_printf(MQTT_INFO, "Wi-Fi connected.");
mqtt_printf(MQTT_INFO, "Connect Network \"%s\"", address);
while ((rc = NetworkConnect(&network, address, 1883)) != 0){
mqtt_printf(MQTT_INFO, "Return code from network connect is %d\n", rc);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
mqtt_printf(MQTT_INFO, "\"%s\" Connected", address);
connectData.MQTTVersion = 3;
connectData.clientID.cstring = "FT1_018";
mqtt_printf(MQTT_INFO, "Start MQTT connection");
while ((rc = MQTTConnect(&client, &connectData)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT connect is %d\n", rc);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
mqtt_printf(MQTT_INFO, "MQTT Connected");
mqtt_printf(MQTT_INFO, "Subscribe to Topic: %s", sub_topic);
if ((rc = MQTTSubscribe(&client, sub_topic, QOS2, messageArrived)) != 0)
mqtt_printf(MQTT_INFO, "Return code from MQTT subscribe is %d\n", rc);
mqtt_printf(MQTT_INFO, "Publish Topics: %s", pub_topic);
while (++count)
{
MQTTMessage message;
char payload[300];
message.qos = QOS1;
message.retained = 0;
message.payload = payload;
sprintf(payload, "hello from AMEBA %d", count);
message.payloadlen = strlen(payload);
if ((rc = MQTTPublish(&client, pub_topic, &message)) != 0)
mqtt_printf(MQTT_INFO,"Return code from MQTT publish is %d\n", rc);
if ((rc = MQTTYield(&client, 1000)) != 0)
mqtt_printf(MQTT_INFO,"Return code from yield is %d\n", rc);
vTaskDelay(5000);
}
/* do not return */
}
#if defined(MQTT_TASK)
void MQTTPublishMessage(MQTTClient* c, char *topic)
{
int rc = 0;
static int count = 0;
MQTTMessage message;
char payload[300];
message.qos = QOS1;
message.retained = 0;
message.payload = payload;
if(c->mqttstatus == MQTT_RUNNING){
count++;
sprintf(payload, "hello from AMEBA %d", count);
message.payloadlen = strlen(payload);
mqtt_printf(MQTT_INFO, "Publish Topic %s : %d", topic, count);
if ((rc = MQTTPublish(c, topic, &message)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT publish is %d\n", rc);
MQTTSetStatus(c, MQTT_START);
c->ipstack->disconnect(c->ipstack);
}
}
}
static void prvMQTTTask(void *pvParameters)
{
MQTTClient client;
Network network;
static unsigned char sendbuf[MQTT_SENDBUF_LEN], readbuf[MQTT_READBUF_LEN];
int rc = 0, mqtt_pub_count = 0;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
connectData.MQTTVersion = 3;
connectData.clientID.cstring = "FT1_018";
char* address = "gpssensor.ddns.net";
char* sub_topic = "LASS/Test/Pm25Ameba/#";
char* pub_topic = "LASS/Test/Pm25Ameba/FT1_018";
NetworkInit(&network);
MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
while (1)
{
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS) {
mqtt_printf(MQTT_INFO, "Wait Wi-Fi to be connected.");
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
fd_set read_fds;
fd_set except_fds;
struct timeval timeout;
FD_ZERO(&read_fds);
FD_ZERO(&except_fds);
timeout.tv_sec = MQTT_SELECT_TIMEOUT;
timeout.tv_usec = 0;
if(network.my_socket >= 0){
FD_SET(network.my_socket, &read_fds);
FD_SET(network.my_socket, &except_fds);
rc = FreeRTOS_Select(network.my_socket + 1, &read_fds, NULL, &except_fds, &timeout);
if(FD_ISSET(network.my_socket, &except_fds))
{
mqtt_printf(MQTT_INFO, "except_fds is set");
MQTTSetStatus(&client, MQTT_START); //my_socket will be close and reopen in MQTTDataHandle if STATUS set to MQTT_START
}
else if(rc == 0) //select timeout
{
if(++mqtt_pub_count == 5) //Send MQTT publish message every 5 seconds
{
MQTTPublishMessage(&client, pub_topic);
mqtt_pub_count = 0;
}
}
}
MQTTDataHandle(&client, &read_fds, &connectData, messageArrived, address, sub_topic);
}
}
#endif
void vStartMQTTTasks(uint16_t usTaskStackSize, UBaseType_t uxTaskPriority)
{
BaseType_t x = 0L;
#if defined(MQTT_TASK)
xTaskCreate(prvMQTTTask, /* The function that implements the task. */
"MQTTTask", /* Just a text name for the task to aid debugging. */
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
(void *)x, /* The task parameter, not used in this case. */
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
NULL); /* The task handle is not used. */
#else
xTaskCreate(prvMQTTEchoTask, /* The function that implements the task. */
"MQTTEcho0", /* Just a text name for the task to aid debugging. */
usTaskStackSize + 128, /* The stack size is defined in FreeRTOSIPConfig.h. */
(void *)x, /* The task parameter, not used in this case. */
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
NULL); /* The task handle is not used. */
#endif
}
void example_mqtt(void)
{
vStartMQTTTasks(4096, tskIDLE_PRIORITY + 4);
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_MQTT_H
#define EXAMPLE_MQTT_H
void example_mqtt(void);
#endif /* EXAMPLE_MQTT_H */

View file

@ -0,0 +1,56 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#define SERVER_IP "192.168.13.1"
#define SERVER_PORT 80
// Need to define ERRNO in lwipopts.h
int errno = 0;
static void example_nonblock_connect_thread(void *param)
{
int server_fd = -1;
struct sockaddr_in server_addr;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: Non-blocking socket connect\n");
server_fd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL, 0) | O_NONBLOCK);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(SERVER_PORT);
connect(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
if(errno == EINPROGRESS) {
fd_set wfds;
struct timeval time_out;
time_out.tv_sec = 3; // Set select timeout of 3 seconds
time_out.tv_usec = 0;
FD_ZERO(&wfds) ;
FD_SET(server_fd, &wfds); // Only set server fd
// Use select to wait for non-blocking connect
if(select(server_fd + 1, NULL, &wfds, NULL, &time_out) == 1)
printf("Server connection successful\n");
else
printf("Server connection failed\n");
}
else {
printf("ERROR: connect\n");
}
close(server_fd);
vTaskDelete(NULL);
}
void example_nonblock_connect(void)
{
if(xTaskCreate(example_nonblock_connect_thread, ((const char*)"example_nonblock_connect_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_NONBLOCK_CONNECT_H
#define EXAMPLE_NONBLOCK_CONNECT_H
void example_nonblock_connect(void);
#endif /* EXAMPLE_NONBLOCK_CONNECT_H */

View file

@ -0,0 +1,16 @@
LWIP SOCKET NONBLOCKING CONNECT EXAMPLE
Description:
TCP nonblocking connect with use of select() for connection timeout handling.
Configuration:
Modify SERVER_IP and SERVER_PORT in example_nonblock_connect.c for server connection
[platform_opts.h]
#define CONFIG_EXAMPLE_NONBLOCK_CONNECT 1
[lwipopts.h]
#define ERRNO
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A socket nonblocking connect example thread will be started automatically when booting.

View file

@ -0,0 +1,32 @@
#include <ota_8195a.h>
#define PORT 8082
#define HOST "192.168.1.53" //"m-apps.oss-cn-shenzhen.aliyuncs.com"
#define RESOURCE "" //"051103061600.bin"
#ifdef HTTP_OTA_UPDATE
void http_update_ota_task(void *param){
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 1 minute to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
vTaskDelay(60*1000);
int ret = -1;
ret = http_update_ota(HOST, PORT, RESOURCE);
exit:
printf("\n\r[%s] Update task exit", __FUNCTION__);
if(!ret){
printf("\n\r[%s] Ready to reboot", __FUNCTION__);
ota_platform_reset();
}
vTaskDelete(NULL);
}
void example_ota_http(void){
if(xTaskCreate(http_update_ota_task, (char const *)"http_update_ota_task", 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS){
printf("\n\r[%s] Create update task failed", __FUNCTION__);
}
}
#endif

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_OTA_HTTP_H
#define EXAMPLE_OTA_HTTP_H
void example_ota_http(void);
#endif /* EXAMPLE_OTA_HTTP_H */

View file

@ -0,0 +1,23 @@
OTA HTTP UPDATING EXAMPLE
Description:
Download ota.bin from http download server(in tools\DownloadServer(HTTP))
Configuration:
[example_ota_http.c]
Modify PORT, HOST and RESOURCE based on your HTTP download server.
eg: SERVER: http://m-apps.oss-cn-shenzhen.aliyuncs.com/051103061600.bin
set: #define PORT 80
#define HOST "m-apps.oss-cn-shenzhen.aliyuncs.com"
#define RESOURCE "051103061600.bin"
[platform_opts.h]
#define CONFIG_EXAMPLE_OTA_HTTP 1
[ota_8195a.h]
#define HTTP_OTA_UPDATE
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A http download example thread will be started automatically when booting.
Using the example with the tool in tools\DownloadServer(HTTP)

View file

@ -0,0 +1,47 @@
#include "FreeRTOS.h"
#include "task.h"
#include <netif/etharp.h>
#include "wifi_conf.h"
#define RARP_THREAD_STACK_SIZE 200
const struct eth_addr macbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
extern struct netif xnetif[NET_IF_NUM];
void rarp_retrieve(uint8_t *rarp_ip, uint8_t *rarp_mac) {
printf("\n\rThe IP of device %02x:%02x:%02x:%02x:%02x:%02x is: %d.%d.%d.%d\r\n",
rarp_mac[0], rarp_mac[1], rarp_mac[2], rarp_mac[3], rarp_mac[4], rarp_mac[5],
rarp_ip[0], rarp_ip[1], rarp_ip[2], rarp_ip[3]);
}
static void rarp_thread(void *param)
{
printf("\r\n\r\n\r\n>>>>>>>>>>>>>>>rarp example<<<<<<<<<<<<<<<<<\r\n\r\n\r\n");
vTaskDelay(10000);
uint8_t *mac, *ip, *netmask, *gw;
err_t result;
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS){
printf("\r\n\r\n\r\n>>>>>>>>>>>>>>Wifi is disconnected!!Please connect!!<<<<<<<<<<<<<<<<<\r\n\r\n\r\n");
vTaskDelay(10000);
}
rarp_retrieve_hook_callback(rarp_retrieve);
for(int i = 0; i < 3; i ++){
printf("\n\r\n\retharp_raw: sending raw RARP packet.\n\r\n\r");
etharp_raw(&xnetif[0], (struct eth_addr *)xnetif[0].hwaddr, &macbroadcast,
(struct eth_addr *)xnetif[0].hwaddr, IP_ADDR_ANY,
(struct eth_addr *)xnetif[0].hwaddr, IP_ADDR_ANY, RARP_REQUEST);
vTaskDelay(1000);
}
vTaskDelete(NULL);
}
void example_rarp(void){
if(xTaskCreate(rarp_thread, ((const char*)"rarp_thread"), RARP_THREAD_STACK_SIZE, NULL, 1 , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(rarp_thread) failed\n\r", __FUNCTION__);
return;
}

View file

@ -0,0 +1,8 @@
#ifndef EXAMPLE_RARP_H
#define EXAMPLE_RARP_H
void example_rarp(void);
#endif /* EXAMPLE_RARP_H */

View file

@ -0,0 +1,20 @@
RARP EXAMPLE
Description:
In this example, it will send rarp request for 3 times. And the rarp reply callback will print the received reply IP address.
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_RARP 1
Execution:
You need to connect to WiFi manually by AT command. After connected the rarp request will be sent.
RARP server:
For Ubuntu, you can try to setup the RARP server as doing this:
• apt-get install rarpd
• touch /etc/ethers
• add “00:e0:4c:87:xx:xx(Amebas MAC) client” in /etc/ethers
• add”192.168.1.xx(Amebas ip) client” in /etc/hosts

View file

@ -0,0 +1,60 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <sntp/sntp.h>
#define TIME_MODE 1 //0: for UTC with microseconds, 1: for timezone with seconds
static void show_time(void)
{
#if (TIME_MODE == 0)
unsigned int update_tick = 0;
long update_sec = 0, update_usec = 0;
sntp_get_lasttime(&update_sec, &update_usec, &update_tick);
if(update_tick) {
long tick_diff_sec, tick_diff_ms, current_sec, current_usec;
unsigned int current_tick = xTaskGetTickCount();
tick_diff_sec = (current_tick - update_tick) / configTICK_RATE_HZ;
tick_diff_ms = (current_tick - update_tick) % configTICK_RATE_HZ / portTICK_RATE_MS;
update_sec += tick_diff_sec;
update_usec += (tick_diff_ms * 1000);
current_sec = update_sec + update_usec / 1000000;
current_usec = update_usec % 1000000;
printf("%s + %d usec\n", ctime(&current_sec), current_usec);
}
#elif (TIME_MODE == 1)
int timezone = 8; // use UTC+8 timezone for example
struct tm tm_now = sntp_gen_system_time(timezone);
printf("%d-%d-%d %d:%d:%d UTC%s%d\n",
tm_now.tm_year, tm_now.tm_mon, tm_now.tm_mday, tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec,
(timezone > 0) ? "+" : "", timezone);
#endif
}
static void example_sntp_showtime_thread(void *param)
{
int should_stop = 0;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SNTP show time\n");
sntp_init();
while(1) {
show_time();
vTaskDelay(1000);
if(should_stop)
break;
}
vTaskDelete(NULL);
}
void example_sntp_showtime(void)
{
if(xTaskCreate(example_sntp_showtime_thread, ((const char*)"example_sntp_showtime_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed\n", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_SNTP_SHOWTIME_H
#define EXAMPLE_SNTP_SHOWTIME_H
void example_sntp_showtime(void);
#endif /* EXAMPLE_SNTP_SHOWTIME_H */

View file

@ -0,0 +1,14 @@
LWIP SNTP SHOWTIME EXAMPLE
Description:
Show system time maintained by time from NTP server and system tick.
Configuration:
Can Modify SNTP_SERVER_ADDRESS and SNTP_UPDATE_DELAY in sntp.c for NTP time update
[platform_opts.h]
#define CONFIG_EXAMPLE_SNTP_SHOWTIME 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A lwip ntp showtime example thread will be started automatically when booting.

View file

@ -0,0 +1,150 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#define CONNECT_REMOTE 0
#if CONNECT_REMOTE
#define REMOTE_HOST "192.168.13.14"
#define REMOTE_PORT 5000
#endif
#define MAX_SOCKETS 10
#define SELECT_TIMEOUT 10
#define SERVER_PORT 5000
#define LISTEN_QLEN 2
static void example_socket_select_thread(void *param)
{
int max_socket_fd = -1;
#if CONNECT_REMOTE
struct sockaddr_in remote_addr;
int remote_fd = -1;
#endif
struct sockaddr_in server_addr;
int server_fd = -1;
int socket_used[MAX_SOCKETS];
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: socket select\n");
memset(socket_used, 0, sizeof(socket_used));
#if CONNECT_REMOTE
reconnect:
if((remote_fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(REMOTE_HOST);
remote_addr.sin_port = htons(REMOTE_PORT);
if(connect(remote_fd, (struct sockaddr *) &remote_addr, sizeof(remote_addr)) == 0) {
printf("connect socket fd(%d)\n", remote_fd);
socket_used[remote_fd] = 1;
if(remote_fd > max_socket_fd)
max_socket_fd = remote_fd;
}
else {
printf("connect error\n");
close(remote_fd);
goto reconnect;
}
}
else {
printf("socket error\n");
goto exit;
}
#endif
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("bind error\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("listen error\n");
goto exit;
}
socket_used[server_fd] = 1;
if(server_fd > max_socket_fd)
max_socket_fd = server_fd;
}
else {
printf("socket error\n");
goto exit;
}
while(1) {
int socket_fd;
unsigned char buf[512];
fd_set read_fds;
struct timeval timeout;
FD_ZERO(&read_fds);
timeout.tv_sec = SELECT_TIMEOUT;
timeout.tv_usec = 0;
for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++)
if(socket_used[socket_fd])
FD_SET(socket_fd, &read_fds);
if(select(max_socket_fd + 1, &read_fds, NULL, NULL, &timeout)) {
for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++) {
if(socket_used[socket_fd] && FD_ISSET(socket_fd, &read_fds)) {
if(socket_fd == server_fd) {
struct sockaddr_in client_addr;
unsigned int client_addr_size = sizeof(client_addr);
int fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(fd >= 0) {
printf("accept socket fd(%d)\n", fd);
socket_used[fd] = 1;
if(fd > max_socket_fd)
max_socket_fd = fd;
}
else {
printf("accept error\n");
}
}
else {
int read_size = read(socket_fd, buf, sizeof(buf));
if(read_size > 0) {
write(socket_fd, buf, read_size);
}
else {
printf("socket fd(%d) disconnected\n", socket_fd);
socket_used[socket_fd] = 0;
close(socket_fd);
}
}
}
}
}
else {
printf("TCP server: no data in %d seconds\n", SELECT_TIMEOUT);
}
vTaskDelay(10);
}
exit:
if(server_fd >= 0)
close(server_fd);
vTaskDelete(NULL);
}
void example_socket_select(void)
{
if(xTaskCreate(example_socket_select_thread, ((const char*)"example_socket_select_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_SOCKET_SELECT_H
#define EXAMPLE_SOCKET_SELECT_H
void example_socket_select(void);
#endif /* EXAMPLE_SOCKET_SELECT_H */

View file

@ -0,0 +1,17 @@
LWIP SOCKET SELECT EXAMPLE
Description:
Use socket select() to handle socket read from clients or remote server.
Configuration:
Modify SERVER_PORT definition for listen port of created TCP server.
Can enable CONNECT_REMOTE to include TCP connection to remote server in example. Modify REMOTE_HOST and REMOTE_PORT for remote server.
[platform_opts.h]
#define CONFIG_EXAMPLE_SOCKET_SELECT 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A socket select example thread will be started automatically when booting.
A local TCP server will be started to wait for connection. Can use a TCP client connecting to this server to send data.
If CONNECT_REMOTE is enabed in example. A remote TCP server is required and can send data to the created remote connection.

View file

@ -0,0 +1,7 @@
#ifndef EXAMPLE_SOCKET_TCP_TRX_H
#define EXAMPLE_SOCKET_TCP_TRX_H
void example_socket_tcp_trx_1(void);
void example_socket_tcp_trx_2(void);
#endif /* EXAMPLE_SOCKET_TCP_TRX_H */

View file

@ -0,0 +1,145 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
//#include <osdep_api.h>
#include <osdep_service.h>
#define SERVER_PORT 80
#define LISTEN_QLEN 2
static int tx_exit = 0, rx_exit = 0;
//static _Sema tcp_tx_rx_sema;
static _sema tcp_tx_rx_sema;
static void tx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
memset(buffer, 1, sizeof(buffer));
printf("\n%s start\n", __FUNCTION__);
while(1) {
int ret = 0;
//RtlDownSema(&tcp_tx_rx_sema);
rtw_down_sema(&tcp_tx_rx_sema);
ret = send(client_fd, buffer, sizeof(buffer), 0);
//RtlUpSema(&tcp_tx_rx_sema);
rtw_up_sema(&tcp_tx_rx_sema);
if(ret <= 0)
goto exit;
vTaskDelay(100);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
tx_exit = 1;
vTaskDelete(NULL);
}
static void rx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
printf("\n%s start\n", __FUNCTION__);
while(1) {
int ret = 0, sock_err = 0;
size_t err_len = sizeof(sock_err);
//RtlDownSema(&tcp_tx_rx_sema);
rtw_down_sema(&tcp_tx_rx_sema);
ret = recv(client_fd, buffer, sizeof(buffer), MSG_DONTWAIT);
getsockopt(client_fd, SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
//RtlUpSema(&tcp_tx_rx_sema);
rtw_up_sema(&tcp_tx_rx_sema);
// ret == -1 and socket error == EAGAIN when no data received for nonblocking
if((ret == -1) && (sock_err == EAGAIN))
continue;
else if(ret <= 0)
goto exit;
vTaskDelay(10);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
rx_exit = 1;
vTaskDelete(NULL);
}
static void example_socket_tcp_trx_thread(void *param)
{
int server_fd = -1, client_fd = -1;
struct sockaddr_in server_addr, client_addr;
size_t client_addr_size;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: socket tx/rx 1\n");
server_fd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("ERROR: bind\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("ERROR: listen\n");
goto exit;
}
while(1) {
client_addr_size = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(client_fd >= 0) {
tx_exit = 1;
rx_exit = 1;
//RtlInitSema(&tcp_tx_rx_sema, 1);
rtw_init_sema(&tcp_tx_rx_sema, 1);
if(xTaskCreate(tx_thread, ((const char*)"tx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(tx_thread) failed", __FUNCTION__);
else
tx_exit = 0;
vTaskDelay(10);
if(xTaskCreate(rx_thread, ((const char*)"rx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(rx_thread) failed", __FUNCTION__);
else
rx_exit = 0;
while(1) {
if(tx_exit && rx_exit) {
close(client_fd);
break;
}
else
vTaskDelay(1000);
}
//RtlFreeSema(&tcp_tx_rx_sema);
rtw_free_sema(&tcp_tx_rx_sema);
}
}
exit:
close(server_fd);
vTaskDelete(NULL);
}
void example_socket_tcp_trx_1(void)
{
if(xTaskCreate(example_socket_tcp_trx_thread, ((const char*)"example_socket_tcp_trx_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_socket_tcp_trx_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,125 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#define SERVER_PORT 80
#define LISTEN_QLEN 2
#define MAX_RETRY 5
static int tx_exit = 0, rx_exit = 0;
static void tx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
memset(buffer, 1, sizeof(buffer));
printf("\n%s start\n", __FUNCTION__);
while(1) {
int retry = 0;
// retry send if socket busy
for(retry = 0; retry < MAX_RETRY; retry ++) {
if(write(client_fd, buffer, sizeof(buffer)) == -1)
printf("\nwrite retry=%d\n", retry);
else
break;
}
// socket may be closed if max retry reached
if(retry == MAX_RETRY)
goto exit;
vTaskDelay(100);
}
exit:
printf("\n%s exit\n", __FUNCTION__);
tx_exit = 1;
vTaskDelete(NULL);
}
static void rx_thread(void *param)
{
int client_fd = * (int *) param;
unsigned char buffer[1024];
printf("\n%s start\n", __FUNCTION__);
while(1) {
if(read(client_fd, buffer, sizeof(buffer)) <= 0)
goto exit;
}
exit:
printf("\n%s exit\n", __FUNCTION__);
rx_exit = 1;
vTaskDelete(NULL);
}
static void example_socket_tcp_trx_thread(void *param)
{
int server_fd = -1, client_fd = -1;
struct sockaddr_in server_addr, client_addr;
size_t client_addr_size;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: socket tx/rx 2\n");
server_fd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("ERROR: bind\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("ERROR: listen\n");
goto exit;
}
while(1) {
client_addr_size = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(client_fd >= 0) {
tx_exit = 1;
rx_exit = 1;
if(xTaskCreate(tx_thread, ((const char*)"tx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(tx_thread) failed", __FUNCTION__);
else
tx_exit = 0;
vTaskDelay(10);
if(xTaskCreate(rx_thread, ((const char*)"rx_thread"), 512, &client_fd, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(rx_thread) failed", __FUNCTION__);
else
rx_exit = 0;
while(1) {
if(tx_exit && rx_exit) {
close(client_fd);
break;
}
else
vTaskDelay(1000);
}
}
}
exit:
close(server_fd);
vTaskDelete(NULL);
}
void example_socket_tcp_trx_2(void)
{
if(xTaskCreate(example_socket_tcp_trx_thread, ((const char*)"example_socket_tcp_trx_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_socket_tcp_trx_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,22 @@
LWIP SOCKET TCP TX/RX EXAMPLE
Description:
Example of TCP bidirectional transmission with use two threads for TCP tx/rx on one socket.
Example 1 uses non-blocking recv and semaphore for TCP send/recv mutex
Example 2 does not use any synchronization mechanism, but can only run correctly on lwip with TCPIP thread msg api patch
Configuration:
Modify SERVER_PORT in example_socket_tcp_trx.c for listen port
[platform_opts.h]
Run example 1 in example_socket_tcp_trx_1.c
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 1
Run example 2 in example_socket_tcp_trx_2.c
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 2
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A socket TCP trx example thread will be started automatically when booting.
A TCP server will be started to wait for connection.
Can use a TCP client connecting to this server to start a TCP bidirectional transmission

View file

@ -0,0 +1,274 @@
#include <platform_opts.h>
#if defined(CONFIG_EXAMPLE_SSL_DOWNLOAD) && (CONFIG_EXAMPLE_SSL_DOWNLOAD == 1)
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#if CONFIG_USE_POLARSSL
#include <lwip/sockets.h>
#include <polarssl/config.h>
#include <polarssl/memory.h>
#include <polarssl/ssl.h>
#define SERVER_HOST "176.34.62.248"
#define SERVER_PORT 443
#define RESOURCE "/repository/IOT/Project_Cloud_A.bin"
#define BUFFER_SIZE 2048
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
static void example_ssl_download_thread(void *param)
{
int server_fd = -1, ret;
struct sockaddr_in server_addr;
ssl_context ssl;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SSL download\n");
memory_set_own(pvPortMalloc, vPortFree);
memset(&ssl, 0, sizeof(ssl_context));
if((ret = net_connect(&server_fd, SERVER_HOST, SERVER_PORT)) != 0) {
printf("ERROR: net_connect ret(%d)\n", ret);
goto exit;
}
if((ret = ssl_init(&ssl)) != 0) {
printf("ERRPR: ssl_init ret(%d)\n", ret);
goto exit;
}
ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
ssl_set_rng(&ssl, my_random, NULL);
ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd);
if((ret = ssl_handshake(&ssl)) != 0) {
printf("ERROR: ssl_handshake ret(-0x%x)", -ret);
goto exit;
}
else {
unsigned char buf[BUFFER_SIZE + 1];
int pos = 0, read_size = 0, resource_size = 0, content_len = 0, header_removed = 0;
printf("SSL ciphersuite %s\n", ssl_get_ciphersuite(&ssl));
sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", RESOURCE, SERVER_HOST);
ssl_write(&ssl, buf, strlen(buf));
while((read_size = ssl_read(&ssl, buf + pos, BUFFER_SIZE - pos)) > 0) {
if(header_removed == 0) {
char *header = NULL;
pos += read_size;
buf[pos] = 0;
header = strstr(buf, "\r\n\r\n");
if(header) {
char *body, *content_len_pos;
body = header + strlen("\r\n\r\n");
*(body - 2) = 0;
header_removed = 1;
printf("\nHTTP Header: %s\n", buf);
// Remove header size to get first read size of data from body head
read_size = pos - ((unsigned char *) body - buf);
pos = 0;
content_len_pos = strstr(buf, "Content-Length: ");
if(content_len_pos) {
content_len_pos += strlen("Content-Length: ");
*(char*)(strstr(content_len_pos, "\r\n")) = 0;
content_len = atoi(content_len_pos);
}
}
else {
if(pos >= BUFFER_SIZE){
printf("ERROR: HTTP header\n");
goto exit;
}
continue;
}
}
printf("read resource %d bytes\n", read_size);
resource_size += read_size;
}
printf("exit read. ret = %d\n", read_size);
printf("http content-length = %d bytes, download resource size = %d bytes\n", content_len, resource_size);
}
exit:
if(server_fd >= 0)
net_close(server_fd);
ssl_free(&ssl);
vTaskDelete(NULL);
}
void example_ssl_download(void)
{
if(xTaskCreate(example_ssl_download_thread, ((const char*)"example_ssl_download_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}
#elif CONFIG_USE_MBEDTLS /* CONFIG_USE_POLARSSL */
#include <mbedTLS/config.h>
#include <mbedTLS/platform.h>
#include <mbedtls/net_sockets.h>
#include <mbedTLS/ssl.h>
#define SERVER_HOST "176.34.62.248"
#define SERVER_PORT "443"
#define RESOURCE "/repository/IOT/Project_Cloud_A.bin"
#define BUFFER_SIZE 2048
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
static void example_ssl_download_thread(void *param)
{
int ret;
mbedtls_net_context server_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SSL download\n");
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
mbedtls_net_init(&server_fd);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
if((ret = mbedtls_net_connect(&server_fd, SERVER_HOST, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
printf("ERROR: mbedtls_net_connect ret(%d)\n", ret);
goto exit;
}
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
if((ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf("ERRPR: mbedtls_ssl_config_defaults ret(%d)\n", ret);
goto exit;
}
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, my_random, NULL);
if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf("ERRPR: mbedtls_ssl_setup ret(%d)\n", ret);
goto exit;
}
if((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
printf("ERROR: mbedtls_ssl_handshake ret(-0x%x)", -ret);
goto exit;
}
else {
unsigned char buf[BUFFER_SIZE + 1];
int pos = 0, read_size = 0, resource_size = 0, content_len = 0, header_removed = 0;
printf("SSL ciphersuite %s\n", mbedtls_ssl_get_ciphersuite(&ssl));
sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", RESOURCE, SERVER_HOST);
mbedtls_ssl_write(&ssl, buf, strlen(buf));
while((read_size = mbedtls_ssl_read(&ssl, buf + pos, BUFFER_SIZE - pos)) > 0) {
if(header_removed == 0) {
char *header = NULL;
pos += read_size;
buf[pos] = 0;
header = strstr(buf, "\r\n\r\n");
if(header) {
char *body, *content_len_pos;
body = header + strlen("\r\n\r\n");
*(body - 2) = 0;
header_removed = 1;
printf("\nHTTP Header: %s\n", buf);
// Remove header size to get first read size of data from body head
read_size = pos - ((unsigned char *) body - buf);
pos = 0;
content_len_pos = strstr(buf, "Content-Length: ");
if(content_len_pos) {
content_len_pos += strlen("Content-Length: ");
*(strstr(content_len_pos, "\r\n")) = 0;
content_len = atoi(content_len_pos);
}
}
else {
if(pos >= BUFFER_SIZE){
printf("ERROR: HTTP header\n");
goto exit;
}
continue;
}
}
printf("read resource %d bytes\n", read_size);
resource_size += read_size;
}
printf("exit read. ret = %d\n", read_size);
printf("http content-length = %d bytes, download resource size = %d bytes\n", content_len, resource_size);
}
exit:
mbedtls_net_free(&server_fd);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
vTaskDelete(NULL);
}
void example_ssl_download(void)
{
if(xTaskCreate(example_ssl_download_thread, ((const char*)"example_ssl_download_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}
#endif /* CONFIG_USE_POLARSSL */
#endif /*CONFIG_EXAMPLE_SSL_DOWNLOAD*/

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_SSL_DOWNLOAD_H
#define EXAMPLE_SSL_DOWNLOAD_H
void example_ssl_download(void);
#endif /* EXAMPLE_SSL_DOWNLOAD_H */

View file

@ -0,0 +1,24 @@
SSL DOWNLOAD EXAMPLE
Description:
Download file from Web server via https.
Configuration:
Modify SERVER_HOST, SERVER_PORT and RESOURCE in example_ssl_download.c based on your SSL server.
Modify SSL_MAX_CONTENT_LEN in SSL config and configTOTAL_HEAP_SIZE in freertos config for large size file.
If the transmitted fils size is larger than 16kbytes, SSL_MAX_CONTENT_LEN should be set to 16384.
FreeRTOS heap may be increased for ssl buffer allocation.
(ex. If using 16kbytes * 2 for ssl input/output buffer, heap should be increased from 60kbytes to 80kbytes.)
[config_rsa.h]
#define SSL_MAX_CONTENT_LEN 16384
[FreeRTOSConfig.h]
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) )
[platform_opts.h]
#define CONFIG_EXAMPLE_SSL_DOWNLOAD 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A ssl download example thread will be started automatically when booting.

View file

@ -0,0 +1,394 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform_stdlib.h>
#include <lwip_netconf.h>
#include "platform_opts.h"
#if CONFIG_USE_POLARSSL
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/memory.h"
#include "polarssl/certs.h"
#include "polarssl/error.h"
#define SERVER_PORT 443
#define STACKSIZE 1150
extern struct netif xnetif[NET_IF_NUM];
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
static void example_ssl_server_thread(void *param){
#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_CERTS_C) || \
!defined(POLARSSL_SSL_TLS_C) || !defined(POLARSSL_SSL_SRV_C) || \
!defined(POLARSSL_RSA_C) || !defined(POLARSSL_NET_C) || \
!defined(POLARSSL_X509_CRT_PARSE_C)
printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or "
"POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
"POLARSSL_RSA_C and/or POLARSSL_NET_C and/or "
"POLARSSL_X509_CRT_PARSE_C not defined.\n");
#else
int ret, server_fd = -1, client_fd = -1;
x509_crt server_x509;
pk_context server_pk;
ssl_context ssl;
unsigned char buf[512];
uint8_t *ip;
char *response = "<HTML><BODY>SSL OK</BODY></HTML>";
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SSL server\n");
memory_set_own(pvPortMalloc, vPortFree);
memset(&server_x509, 0, sizeof(x509_crt));
memset(&server_pk, 0, sizeof(pk_context));
memset(&ssl, 0, sizeof(ssl_context));
/*
* 1. Prepare the certificate and key
*/
printf("\n\r . Preparing the certificate and key...");
x509_crt_init(&server_x509);
pk_init(&server_pk);
if((ret = x509_crt_parse(&server_x509, (const unsigned char *)test_srv_crt, strlen(test_srv_crt))) != 0) {
printf(" failed\n ! x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = x509_crt_parse(&server_x509, (const unsigned char *)test_ca_list, strlen(test_ca_list))) != 0) {
printf(" failed\n ! x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = pk_parse_key(&server_pk, test_srv_key, strlen(test_srv_key), NULL, 0)) != 0) {
printf(" failed\n ! pk_parse_key returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 2. Start the connection
*/
ip = LwIP_GetIP(&xnetif[0]);
printf("\n\r . Starting tcp server /%d.%d.%d.%d/%d...", ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
if((ret = net_bind(&server_fd, NULL, SERVER_PORT)) != 0) {
printf(" failed\n ! net_bind returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 3. Waiting for client to connect
*/
printf("\n\r . Waiting for client to connect...\n\r");
while((ret = net_accept(server_fd, &client_fd, NULL)) == 0) {
printf("\n\r . A client is connecting\n\r");
/*
* 4. Setup stuff
*/
printf("\n\r . Setting up the SSL/TLS structure...");
if((ret = ssl_init(&ssl)) != 0) {
printf(" failed\n ! ssl_init returned %d\n\n", ret);
goto close_client;
}
ssl_set_endpoint(&ssl, SSL_IS_SERVER);
ssl_set_ca_chain(&ssl, server_x509.next, NULL, NULL);
ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
ssl_set_rng(&ssl, my_random, NULL);
ssl_set_bio(&ssl, net_recv, &client_fd, net_send, &client_fd);
if((ret = ssl_set_own_cert(&ssl, &server_x509, &server_pk)) != 0) {
printf(" failed\n ! ssl_set_own_cert returned %d\n\n", ret);
goto close_client;
}
printf(" ok\n");
/*
* 5. Handshake
*/
printf("\n\r . Performing the SSL/TLS handshake...");
if((ret = ssl_handshake(&ssl)) != 0) {
printf(" failed\n ! ssl_handshake returned %d\n\n", ret);
goto close_client;
}
printf(" ok\n");
printf("\n\r . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl));
/*
* 6. Read the request from client
*/
printf("\n\r > Read request from client:");
memset(buf, 0, sizeof(buf));
if((ret = ssl_read(&ssl, buf, sizeof(buf))) <= 0) {
if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
printf(" failed\n\r ! ssl_read returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes read\n\r\n\r%s\n", ret, (char *) buf);
/*
* 7. Response the request
*/
printf("\n\r > Response to client:");
sprintf(buf, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", strlen(response), response);
if((ret = ssl_write(&ssl, buf, strlen(buf))) <= 0) {
if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) {
printf(" failed\n\r ! ssl_write returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes written\n\r\n\r%s\n", ret, (char *)buf);
close_client:
#ifdef POLARSSL_ERROR_C
if(ret != 0) {
char error_buf[100];
polarssl_strerror(ret, error_buf, 100);
printf("\n\rLast error was: %d - %s\n", ret, error_buf);
}
#endif
ssl_close_notify(&ssl);
net_close(client_fd);
ssl_free(&ssl);
}
net_close(server_fd);
exit:
x509_crt_free(&server_x509);
pk_free(&server_pk);
#endif
vTaskDelete(NULL);
}
void example_ssl_server(void)
{
if(xTaskCreate(example_ssl_server_thread, "example_ssl_server_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate example_ssl_server_thread failed", __FUNCTION__);
}
#elif CONFIG_USE_MBEDTLS /* CONFIG_USE_POLARSSL */
#include "mbedtls/config.h"
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/certs.h"
#define SERVER_PORT "443"
#define STACKSIZE 2048
extern struct netif xnetif[NET_IF_NUM];
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
static void example_ssl_server_thread(void *param)
{
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
"MBEDTLS_RSA_C and/or MBEDTLS_NET_C and/or "
"MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C not defined.\n");
#else
int ret;
unsigned char buf[512];
uint8_t *ip;
mbedtls_net_context server_fd, client_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt server_x509;
mbedtls_pk_context server_pk;
char *response = "<HTML><BODY>TLS OK</BODY></HTML>";
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SSL server\n");
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
/*
* 1. Prepare the certificate and key
*/
printf("\n\r . Preparing the certificate and key...");
mbedtls_x509_crt_init(&server_x509);
mbedtls_pk_init(&server_pk);
if((ret = mbedtls_x509_crt_parse(&server_x509, (const unsigned char *) mbedtls_test_srv_crt, mbedtls_test_srv_crt_len)) != 0) {
printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = mbedtls_x509_crt_parse(&server_x509, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len)) != 0) {
printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = mbedtls_pk_parse_key(&server_pk, (const unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0)) != 0) {
printf(" failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 2. Start the connection
*/
ip = LwIP_GetIP(&xnetif[0]);
printf("\n\r . Starting tcp server /%d.%d.%d.%d/%s...", ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
mbedtls_net_init(&server_fd);
if((ret = mbedtls_net_bind(&server_fd, NULL, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
printf(" failed\n ! mbedtls_net_bind returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 3. Waiting for client to connect
*/
printf("\n\r . Waiting for client to connect...\n\r");
mbedtls_net_init(&client_fd);
while((ret = mbedtls_net_accept(&server_fd, &client_fd, NULL, 0, NULL)) == 0) {
printf("\n\r . A client is connecting\n\r");
/*
* 4. Setup stuff
*/
printf("\n\r . Setting up the SSL/TLS structure...");
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
if((ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
goto close_client;
}
mbedtls_ssl_conf_ca_chain(&conf, server_x509.next, NULL);
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, my_random, NULL);
if((ret = mbedtls_ssl_conf_own_cert(&conf, &server_x509, &server_pk)) != 0) {
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
goto close_client;
}
if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret);
goto close_client;
}
mbedtls_ssl_set_bio(&ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
printf(" ok\n");
/*
* 5. Handshake
*/
printf("\n\r . Performing the SSL/TLS handshake...");
if((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
printf(" failed\n ! mbedtls_ssl_handshake returned %d\n\n", ret);
goto close_client;
}
printf(" ok\n");
printf("\n\r . Use ciphersuite %s\n", mbedtls_ssl_get_ciphersuite(&ssl));
/*
* 6. Read the request from client
*/
printf("\n\r > Read request from client:");
memset(buf, 0, sizeof(buf));
if((ret = mbedtls_ssl_read(&ssl, buf, sizeof(buf))) <= 0) {
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" failed\n\r ! mbedtls_ssl_read returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes read\n\r\n\r%s\n", ret, (char *) buf);
/*
* 7. Response the request
*/
printf("\n\r > Response to client:");
sprintf(buf, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", strlen(response), response);
if((ret = mbedtls_ssl_write(&ssl, buf, strlen(buf))) <= 0) {
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" failed\n\r ! mbedtls_ssl_write returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes written\n\r\n\r%s\n", ret, (char *)buf);
close_client:
mbedtls_ssl_close_notify(&ssl);
mbedtls_net_free(&client_fd);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
}
mbedtls_net_free(&server_fd);
exit:
mbedtls_x509_crt_free(&server_x509);
mbedtls_pk_free(&server_pk);
#endif
vTaskDelete(NULL);
}
void example_ssl_server(void)
{
if(xTaskCreate(example_ssl_server_thread, "example_ssl_server_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate example_ssl_server_thread failed", __FUNCTION__);
}
#endif /* CONFIG_USE_POLARSSL */

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_SSL_SERVER_H
#define EXAMPLE_SSL_SERVER_H
void example_ssl_server(void);
#endif /* EXAMPLE_SSL_SERVER_H */

View file

@ -0,0 +1,222 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform_stdlib.h>
#include <lwip_netconf.h>
#include "mbedtls/config.h"
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/certs.h"
#include "mbedtls/timing.h"
#define SERVER_PORT "4433"
#define STACKSIZE 2048
extern struct netif xnetif[NET_IF_NUM];
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
static void example_ssl_server_thread(void *param)
{
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
!defined(MBEDTLS_SSL_PROTO_DTLS) || !defined(MBEDTLS_TIMING_C) || \
!defined(MBEDTLS_TIMING_ALT)
printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
"MBEDTLS_RSA_C and/or MBEDTLS_NET_C and/or "
"MBEDTLS_PEM_PARSE_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
"MBEDTLS_SSL_PROTO_DTLS and/or MBEDTLS_TIMING_C and/or "
"MBEDTLS_TIMING_ALT not defined.\n");
#else
int ret;
unsigned char buf[512];
uint8_t *ip;
mbedtls_net_context server_fd, client_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt server_x509;
mbedtls_pk_context server_pk;
mbedtls_timing_delay_context timer;
char *response = "<HTML><BODY>DTLS OK</BODY></HTML>";
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: SSL server\n");
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
/*
* 1. Prepare the certificate and key
*/
printf("\n\r . Preparing the certificate and key...");
mbedtls_x509_crt_init(&server_x509);
mbedtls_pk_init(&server_pk);
if((ret = mbedtls_x509_crt_parse(&server_x509, (const unsigned char *) mbedtls_test_srv_crt, mbedtls_test_srv_crt_len)) != 0) {
printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = mbedtls_x509_crt_parse(&server_x509, (const unsigned char *) mbedtls_test_cas_pem, mbedtls_test_cas_pem_len)) != 0) {
printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
goto exit;
}
if((ret = mbedtls_pk_parse_key(&server_pk, (const unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0)) != 0) {
printf(" failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 2. Start the connection
*/
ip = LwIP_GetIP(&xnetif[0]);
printf("\n\r . Starting udp server /%d.%d.%d.%d/%s...", ip[0], ip[1], ip[2], ip[3], SERVER_PORT);
mbedtls_net_init(&server_fd);
if((ret = mbedtls_net_bind(&server_fd, NULL, SERVER_PORT, MBEDTLS_NET_PROTO_UDP)) != 0) {
printf(" failed\n ! mbedtls_net_bind returned %d\n\n", ret);
goto exit;
}
printf(" ok\n");
/*
* 3. Waiting for client to connect
*/
printf("\n\r . Waiting for client to connect...\n\r");
mbedtls_net_init(&client_fd);
while((ret = mbedtls_net_accept(&server_fd, &client_fd, NULL, 0, NULL)) == 0) {
printf("\n\r . A client is connecting\n\r");
/*
* 4. Setup stuff
*/
printf("\n\r . Setting up the SSL/TLS structure...");
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
if((ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_DATAGRAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
goto close_client;
}
mbedtls_ssl_conf_ca_chain(&conf, server_x509.next, NULL);
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(&conf, my_random, NULL);
if((ret = mbedtls_ssl_conf_own_cert(&conf, &server_x509, &server_pk)) != 0) {
printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
goto close_client;
}
if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret);
goto close_client;
}
mbedtls_ssl_set_bio(&ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay);
printf(" ok\n");
/*
* 5. Handshake
*/
printf("\n\r . Performing the SSL/TLS handshake...");
while((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
printf(" failed\n ! mbedtls_ssl_handshake returned %d\n\n", ret);
goto close_client;
}
}
printf(" ok\n");
printf("\n\r . Use ciphersuite %s\n", mbedtls_ssl_get_ciphersuite(&ssl));
/*
* 6. Read the request from client
*/
printf("\n\r > Read request from client:");
memset(buf, 0, sizeof(buf));
if((ret = mbedtls_ssl_read(&ssl, buf, sizeof(buf))) <= 0) {
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" failed\n\r ! mbedtls_ssl_read returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes read\n\r\n\r%s\n", ret, (char *) buf);
/*
* 7. Response the request
*/
printf("\n\r > Response to client:");
sprintf(buf, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n%s", strlen(response), response);
if((ret = mbedtls_ssl_write(&ssl, buf, strlen(buf))) <= 0) {
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf(" failed\n\r ! mbedtls_ssl_write returned %d\n", ret);
goto close_client;
}
}
printf(" %d bytes written\n\r\n\r%s\n", ret, (char *)buf);
close_client:
do {
mbedtls_ssl_close_notify(&ssl);
}
while(ret == MBEDTLS_ERR_SSL_WANT_WRITE);
mbedtls_net_free(&client_fd);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
}
mbedtls_net_free(&server_fd);
exit:
mbedtls_x509_crt_free(&server_x509);
mbedtls_pk_free(&server_pk);
#endif
vTaskDelete(NULL);
}
void example_ssl_server(void)
{
if(xTaskCreate(example_ssl_server_thread, "example_ssl_server_thread", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate example_ssl_server_thread failed", __FUNCTION__);
}

View file

@ -0,0 +1,20 @@
SSL SERVER EXAMPLE
Description:
A simple SSL server which can reply for the https request
Configuration:
Modify SERVER_PORT and response content in example_ssl_server.c based on your SSL server.
[config_rsa.h]
#define POLARSSL_CERTS_C
#define POLARSSL_SSL_SRV_C
[platform_opts.h]
#define CONFIG_EXAMPLE_SSL_SERVER 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A ssl server example thread will be started automatically when booting.

View file

@ -0,0 +1,170 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip_netconf.h>
#define TEST_MODE 0 // 0 to test client keepalive, 1 to test server keepalive
#define SERVER_IP 192.168.1.1
#define SERVER_PORT 80
#define LISTEN_QLEN 2
#define MAX_SOCKETS 10
#define SELECT_TIMEOUT 10
extern struct netif xnetif[];
static void example_tcp_keepalive_thread(void *param)
{
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: TCP Keepalive\n");
#if !LWIP_TCP_KEEPALIVE
printf("\nPlease enable LWIP_TCP_KEEPALIVE\n");
#else
#if (TEST_MODE == 0)
int server_socket, keepalive = 1, keepalive_idle = 3, keepalive_interval = 5, keepalive_count = 3;
struct sockaddr_in server_addr;
unsigned char *server_ip = LwIP_GetGW(&xnetif[0]);;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// enable socket keepalive with keepalive timeout = idle(3) + interval(5) * count(3) = 18 seconds
if(setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) != 0)
printf("ERROR: SO_KEEPALIVE\n");
if(setsockopt(server_socket, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_idle, sizeof(keepalive_idle)) != 0)
printf("ERROR: TCP_KEEPIDLE\n");
if(setsockopt(server_socket, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_interval, sizeof(keepalive_interval)) != 0)
printf("ERROR: TCP_KEEPINTVL\n");
if(setsockopt(server_socket, IPPROTO_TCP, TCP_KEEPCNT, &keepalive_count, sizeof(keepalive_count)) != 0)
printf("ERROR: TCP_KEEPCNT\n");
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = *((unsigned int *) server_ip);
server_addr.sin_port = htons(SERVER_PORT);
if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == 0) {
unsigned char response_buf[100];
int read_size;
printf("connect OK\n");
while((read_size = read(server_socket, response_buf, sizeof(response_buf))) > 0)
printf("read %d bytes\n", read_size);
printf("ERROR: read %d\n", read_size);
close(server_socket);
}
else {
printf("ERROR: connect\n");
close(server_socket);
}
#elif (TEST_MODE == 1)
int max_socket_fd = -1;
struct sockaddr_in server_addr;
int server_fd = -1;
int socket_used[MAX_SOCKETS];
memset(socket_used, 0, sizeof(socket_used));
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) {
printf("bind error\n");
goto exit;
}
if(listen(server_fd, LISTEN_QLEN) != 0) {
printf("listen error\n");
goto exit;
}
socket_used[server_fd] = 1;
if(server_fd > max_socket_fd)
max_socket_fd = server_fd;
}
else {
printf("socket error\n");
goto exit;
}
while(1) {
int socket_fd;
unsigned char buf[512];
fd_set read_fds;
struct timeval timeout;
FD_ZERO(&read_fds);
timeout.tv_sec = SELECT_TIMEOUT;
timeout.tv_usec = 0;
for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++)
if(socket_used[socket_fd])
FD_SET(socket_fd, &read_fds);
if(select(max_socket_fd + 1, &read_fds, NULL, NULL, &timeout)) {
for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++) {
if(socket_used[socket_fd] && FD_ISSET(socket_fd, &read_fds)) {
if(socket_fd == server_fd) {
struct sockaddr_in client_addr;
unsigned int client_addr_size = sizeof(client_addr);
int fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size);
if(fd >= 0) {
int keepalive = 1, keepalive_idle = 3, keepalive_interval = 5, keepalive_count = 3;
printf("accept socket fd(%d)\n", fd);
socket_used[fd] = 1;
// enable socket keepalive with keepalive timeout = idle(3) + interval(5) * count(3) = 18 seconds
if(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) != 0)
printf("ERROR: SO_KEEPALIVE\n");
if(setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_idle, sizeof(keepalive_idle)) != 0)
printf("ERROR: TCP_KEEPIDLE\n");
if(setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_interval, sizeof(keepalive_interval)) != 0)
printf("ERROR: TCP_KEEPINTVL\n");
if(setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepalive_count, sizeof(keepalive_count)) != 0)
printf("ERROR: TCP_KEEPCNT\n");
if(fd > max_socket_fd)
max_socket_fd = fd;
}
else {
printf("accept error\n");
}
}
else {
int read_size = read(socket_fd, buf, sizeof(buf));
if(read_size > 0) {
write(socket_fd, buf, read_size);
}
else {
printf("socket fd(%d) disconnected\n", socket_fd);
socket_used[socket_fd] = 0;
close(socket_fd);
}
}
}
}
}
vTaskDelay(10);
}
exit:
if(server_fd >= 0)
close(server_fd);
#endif /* TEST_MODE */
#endif /* LWIP_TCP_KEEPALIVE */
vTaskDelete(NULL);
}
void example_tcp_keepalive(void)
{
if(xTaskCreate(example_tcp_keepalive_thread, ((const char*)"example_tcp_keepalive_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_TCP_KEEPALIVE_H
#define EXAMPLE_TCP_KEEPALIVE_H
void example_tcp_keepalive(void);
#endif /* EXAMPLE_TCP_KEEPALIVE_H */

View file

@ -0,0 +1,26 @@
LWIP TCP KEEPALIVE EXAMPLE
Description:
Example for socket client and server implementation to break out of blocking read by TCP keepalive timeout.
Configuration:
[lwipopts.h]
#define LWIP_TCP_KEEPALIVE 1
[platform_opts.h]
#define CONFIG_EXAMPLE_TCP_KEEPALIVE 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A TCP keepalive example thread will be started automatically when booting.
Setup TEST_MODE in example_tcp_keepalive.c to verify client or server examples. Modify SERVER_IP and SERVER_PORT for client keepalive test. Modify SERVER_PORT for server keepalive test. Modify keepalive timeout by setting keepalive idle, interval and count value to socket options based on requirement.
1. For client TCP keepalive example, example thread connects to indicated server and continue to perform blocking read.
When using ATWD command to disconnect wifi, client thread will break out of blocking read after keepalive timeout
2. For server TCP keepalive example, example thread listens on indicated port and read data from the accepted connection.
Please use a client program to connect to server port of example thread
When using ATWD command to disconnect wifi, server thread will get select read event after keepalive timeout

View file

@ -0,0 +1,589 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include <platform_opts.h>
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "semphr.h"
#include "device.h"
#include "serial_api.h"
#include "at_cmd/log_service.h"
#include "uart_atcmd/example_uart_atcmd.h"
#include "flash_api.h"
#include "device_lock.h"
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
#include "freertos_pmu.h"
#endif
#include "osdep_service.h"
#include "serial_ex_api.h"
#include "at_cmd/atcmd_wifi.h"
#include "at_cmd/atcmd_lwip.h"
#include "pinmap.h"
#if CONFIG_EXAMPLE_UART_ATCMD
typedef int (*init_done_ptr)(void);
extern init_done_ptr p_wlan_init_done_callback;
extern char log_buf[LOG_SERVICE_BUFLEN];
extern xSemaphoreHandle log_rx_interrupt_sema;
extern void serial_rx_fifo_level(serial_t *obj, SerialFifoLevel FifoLv);
extern int atcmd_wifi_restore_from_flash(void);
extern int atcmd_lwip_restore_from_flash(void);
serial_t at_cmd_sobj;
char at_string[ATSTRING_LEN];
//_sema at_printf_sema;
_sema uart_at_dma_tx_sema;
unsigned char gAT_Echo = 1; // default echo on
#define UART_AT_MAX_DELAY_TIME_MS 20
#define UART_AT_DATA UART_SETTING_SECTOR
#define BACKUP_SECTOR FLASH_SYSTEM_DATA_ADDR-0x1000
#define UART_AT_USE_DMA_TX 0
void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len){
flash_t flash;
int size, offset, i;
u32 read_data;
switch(id){
case AT_PARTITION_UART:
size = UART_CONF_DATA_SIZE;
offset = UART_CONF_DATA_OFFSET;
break;
case AT_PARTITION_WIFI:
size = WIFI_CONF_DATA_SIZE;
offset = WIFI_CONF_DATA_OFFSET;
break;
case AT_PARTITION_LWIP:
size = LWIP_CONF_DATA_SIZE;
offset = LWIP_CONF_DATA_OFFSET;
break;
case AT_PARTITION_ALL:
size = 0x1000;
offset = 0;
break;
default:
printf("partition id is invalid!\r\n");
return;
}
device_mutex_lock(RT_DEV_LOCK_FLASH);
if(id == AT_PARTITION_ALL && ops == AT_PARTITION_ERASE){
flash_erase_sector(&flash, UART_SETTING_SECTOR);
goto exit;
}
if(ops == AT_PARTITION_READ){
flash_stream_read(&flash, UART_SETTING_SECTOR+offset, len, data);
goto exit;
}
//erase BACKUP_SECTOR
flash_erase_sector(&flash, UART_SETTING_BACKUP_SECTOR);
if(ops == AT_PARTITION_WRITE){
// backup new data
flash_stream_write(&flash, UART_SETTING_BACKUP_SECTOR+offset, len, data);
}
//backup front data to backup sector
for(i = 0; i < offset; i += sizeof(read_data)){
flash_read_word(&flash, UART_SETTING_SECTOR + i, &read_data);
flash_write_word(&flash, UART_SETTING_BACKUP_SECTOR + i,read_data);
}
//backup rear data
for(i = (offset + size); i < 0x1000; i += sizeof(read_data)){
flash_read_word(&flash, UART_SETTING_SECTOR + i, &read_data);
flash_write_word(&flash, UART_SETTING_BACKUP_SECTOR + i,read_data);
}
//erase UART_SETTING_SECTOR
flash_erase_sector(&flash, UART_SETTING_SECTOR);
//retore data to UART_SETTING_SECTOR from UART_SETTING_BACKUP_SECTOR
for(i = 0; i < 0x1000; i+= sizeof(read_data)){
flash_read_word(&flash, UART_SETTING_BACKUP_SECTOR + i, &read_data);
flash_write_word(&flash, UART_SETTING_SECTOR + i,read_data);
}
//erase BACKUP_SECTOR
flash_erase_sector(&flash, UART_SETTING_BACKUP_SECTOR);
exit:
device_mutex_unlock(RT_DEV_LOCK_FLASH);
return;
}
int read_uart_atcmd_setting_from_system_data(UART_LOG_CONF* uartconf)
{
// flash_t flash;
UART_LOG_CONF conf;
bool load_default = _TRUE;
// device_mutex_lock(RT_DEV_LOCK_FLASH);
// flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), (u8 *)&conf);
atcmd_update_partition_info(AT_PARTITION_UART, AT_PARTITION_READ, (u8 *)&conf, sizeof(UART_LOG_CONF));
do{
if(conf.FlowControl != DISABLE && conf.FlowControl != ENABLE)
break;
if(conf.DataBits != 5
&& conf.DataBits != 6
&& conf.DataBits != 7
&& conf.DataBits != 8) //5, 6, 7, 8
break;
if(conf.Parity != ParityNone && conf.Parity != ParityOdd && conf.Parity != ParityEven)
break;
if(conf.StopBits != 1 && conf.StopBits != 2)
break;
load_default = _FALSE;
}while(0);
if(load_default == _TRUE){
// load default setting
uartconf->BaudRate = 38400;
uartconf->DataBits = 8;
uartconf->Parity = ParityNone;
uartconf->StopBits = 1;
uartconf->FlowControl = DISABLE;
}
else{
uartconf->BaudRate = conf.BaudRate;
uartconf->DataBits = conf.DataBits;
uartconf->Parity = conf.Parity;
uartconf->StopBits = conf.StopBits;
uartconf->FlowControl = conf.FlowControl;
}
// device_mutex_unlock(RT_DEV_LOCK_FLASH);
printf("\r\nAT_UART_CONF: %d,%d,%d,%d,%d\r\n",
uartconf->BaudRate,
uartconf->DataBits,
uartconf->StopBits,
uartconf->Parity,
uartconf->FlowControl);
return 0;
}
int write_uart_atcmd_setting_to_system_data(UART_LOG_CONF* uartconf)
{
#if 0
flash_t flash;
u8 data1[sizeof(UART_LOG_CONF)];
u8 data2[sizeof(UART_LOG_CONF)];
u32 data,i;
rtw_memset(data2, 0xFF, sizeof(UART_LOG_CONF));
//Get upgraded image 2 addr from offset
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), data1);
if(rtw_memcmp(data1,data2,sizeof(UART_LOG_CONF)) == _TRUE){
flash_stream_write(&flash, UART_AT_DATA, sizeof(UART_LOG_CONF),(u8*)uartconf);
}else{
//erase backup sector
flash_erase_sector(&flash, BACKUP_SECTOR);
// backup log uart configuration
flash_stream_write(&flash, BACKUP_SECTOR, sizeof(UART_LOG_CONF),(u8*)uartconf);
//backup system data to backup sector
for(i = sizeof(UART_LOG_CONF); i < 0x1000; i+= 4){
flash_read_word(&flash, UART_AT_DATA + i, &data);
flash_write_word(&flash, BACKUP_SECTOR + i,data);
}
//erase system data
flash_erase_sector(&flash, UART_AT_DATA);
//write data back to system data
for(i = 0; i < 0x1000; i+= 4){
flash_read_word(&flash, BACKUP_SECTOR + i, &data);
flash_write_word(&flash, UART_AT_DATA + i,data);
}
//erase backup sector
flash_erase_sector(&flash, BACKUP_SECTOR);
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
#else
atcmd_update_partition_info(AT_PARTITION_UART, AT_PARTITION_WRITE, (u8 *)uartconf, sizeof(UART_LOG_CONF));
#endif
return 0;
}
int reset_uart_atcmd_setting(){
#if 0
flash_t flash;
u8 data1[sizeof(UART_LOG_CONF)];
u8 data2[sizeof(UART_LOG_CONF)];
u32 data,i;
rtw_memset(data2, 0xFF, sizeof(UART_LOG_CONF));
//Get upgraded image 2 addr from offset
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), data1);
if(rtw_memcmp(data1,data2,sizeof(UART_LOG_CONF)) == _TRUE){
;
}else{
//erase backup sector
flash_erase_sector(&flash, BACKUP_SECTOR);
// erase uart configuration
flash_stream_write(&flash, BACKUP_SECTOR, sizeof(UART_LOG_CONF),(u8*)data2);
//backup system data to backup sector
for(i = sizeof(UART_LOG_CONF); i < 0x1000; i+= 4){
flash_read_word(&flash, UART_AT_DATA + i, &data);
flash_write_word(&flash, BACKUP_SECTOR + i,data);
}
//erase system data
flash_erase_sector(&flash, UART_AT_DATA);
//write data back to system data
for(i = 0; i < 0x1000; i+= 4){
flash_read_word(&flash, BACKUP_SECTOR + i, &data);
flash_write_word(&flash, UART_AT_DATA + i,data);
}
//erase backup sector
flash_erase_sector(&flash, BACKUP_SECTOR);
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
#else
atcmd_update_partition_info(AT_PARTITION_ALL, AT_PARTITION_ERASE, NULL, 0);
#endif
return 0;
}
#if ATCMD_RX_GPIO_WAKEUP
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
#include "gpio_irq_api.h"
#define UART_AT_RX_WAKE UART_RX
void gpio_uart_at_rx_irq_callback (uint32_t id, gpio_irq_event event)
{
/* PMU_LOGUART_DEVICE is also handled in log service.
* It is release after a complete command is sent.
**/
//pmu_acquire_wakelock(BIT(PMU_LOGUART_DEVICE));
}
void uart_at_rx_wakeup()
{
gpio_irq_t gpio_rx_wake;
gpio_irq_init(&gpio_rx_wake, UART_AT_RX_WAKE, gpio_uart_at_rx_irq_callback, NULL);
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
gpio_irq_enable(&gpio_rx_wake);
}
#endif
#endif
void uart_atcmd_reinit(UART_LOG_CONF* uartconf){
serial_baud(&at_cmd_sobj,uartconf->BaudRate);
serial_format(&at_cmd_sobj, uartconf->DataBits, (SerialParity)uartconf->Parity, uartconf->StopBits);
// set flow control, only support RTS and CTS concurrent mode
// rxflow and tx flow is fixed by hardware
#define rxflow UART_RTS
#define txflow UART_CTS
if(uartconf->FlowControl){
pin_mode(txflow, PullDown); //init CTS in low
serial_set_flow_control(&at_cmd_sobj, FlowControlRTSCTS, rxflow, txflow);
}
else
serial_set_flow_control(&at_cmd_sobj, FlowControlNone, rxflow, txflow);
}
void uart_at_send_string(char *str)
{
unsigned int i=0;
while (str[i] != '\0') {
serial_putc(&at_cmd_sobj, str[i]);
i++;
}
}
#if UART_AT_USE_DMA_TX
static void uart_at_send_buf_done(uint32_t id)
{
//serial_t *sobj = (serial_t *)id;
rtw_up_sema_from_isr(&uart_at_dma_tx_sema);
}
#endif
void uart_at_send_buf(u8 *buf, u32 len)
{
unsigned char *st_p=buf;
if(!len || (!buf)){
return;
}
#if UART_AT_USE_DMA_TX
int ret;
while(rtw_down_sema(&uart_at_dma_tx_sema) == _TRUE){
ret = serial_send_stream_dma(&at_cmd_sobj, st_p, len);
if(ret != HAL_OK){
rtw_up_sema(&uart_at_dma_tx_sema);
return;
}else{
return;
}
}
#else
while(len){
serial_putc(&at_cmd_sobj, *st_p);
st_p++;
len--;
}
#endif
}
/*
void uart_at_lock(void)
{
rtw_down_sema(&at_printf_sema);
}
void uart_at_unlock(void)
{
rtw_up_sema(&at_printf_sema);
}
void uart_at_lock_init(){
rtw_init_sema(&at_printf_sema, 1);
}
*/
void uart_irq(uint32_t id, SerialIrq event)
{
serial_t *sobj = (serial_t *)id;
unsigned char rc=0;
static unsigned char temp_buf[LOG_SERVICE_BUFLEN] = "\0";
static unsigned int buf_count = 0;
static unsigned char combo_key = 0;
static u32 last_tickcnt = 0; //to check if any data lost
static bool is_data_cmd = _FALSE; // to mark if it's a data command
static u32 data_sz = 0, data_cmd_sz =0; // command will send to log handler until "data_cmd_sz" characters are received
if(event == RxIrq) {
rc = serial_getc(sobj);
if(atcmd_lwip_is_tt_mode()){
if(atcmd_lwip_tt_datasize < LOG_SERVICE_BUFLEN){
log_buf[atcmd_lwip_tt_datasize++] = rc;
atcmd_lwip_tt_lasttickcnt = xTaskGetTickCountFromISR();
}else{
//log_buf is overflow, the following data is drop here
}
if(atcmd_lwip_tt_datasize == 1)
rtw_up_sema_from_isr(&atcmd_lwip_tt_sema);
return;
}
if(buf_count == 4){
// if this is a data command with hex data, then '\n' should not be treated
// as the end of command
if(strncmp(temp_buf, "ATPT", C_NUM_AT_CMD)==0){
is_data_cmd = _TRUE;
}
}
if(buf_count > C_NUM_AT_CMD && is_data_cmd == _TRUE){
if(data_cmd_sz == 0){
if(data_sz == 0){
if(rc == ','){
//first delimeter, ATxx=[sz],....
char str[10]={0};
char size_pos = C_NUM_AT_CMD + C_NUM_AT_CMD_DLT;
memcpy(str, &temp_buf[size_pos], buf_count-size_pos);
data_sz = atoi(str); //get data size
}
}else{
if(rc == ':'){ //data will start after this delimeter ':'
strncpy(log_buf, (char *)temp_buf, buf_count);
rtw_memset(temp_buf,'\0',buf_count);
last_tickcnt = xTaskGetTickCountFromISR();
data_cmd_sz = buf_count + 1 + data_sz;
}
}
}
if(data_cmd_sz){
if((!gAT_Echo) && (rtw_systime_to_ms(xTaskGetTickCountFromISR() - last_tickcnt) > UART_AT_MAX_DELAY_TIME_MS)){
uart_at_send_string("\r\nERROR: data timeout\r\n\n# ");
memset(log_buf, 0, buf_count);
is_data_cmd = _FALSE;
data_sz = 0;
data_cmd_sz = 0;
buf_count=0;
last_tickcnt = 0;
return;
}
last_tickcnt = xTaskGetTickCountFromISR();
log_buf[buf_count++]=rc;
if(gAT_Echo == 1){
serial_putc(sobj, rc);
}
if(buf_count >= data_cmd_sz){
log_buf[data_cmd_sz - data_sz - 1] = '\0'; //for log service handler parse to get command parameter, replace ":" with "\0"
is_data_cmd = _FALSE;
data_sz = 0;
data_cmd_sz = 0;
buf_count=0;
last_tickcnt = 0;
rtw_up_sema_from_isr(&log_rx_interrupt_sema);
}
return;
}
}
if (rc == KEY_ESC) {
combo_key = 1;
}
else if (combo_key == 1){
if (rc == KEY_LBRKT) {
combo_key = 2;
}
else{
combo_key = 0;
}
}
else if (combo_key == 2){
//if ((rc=='A')|| rc=='B'){//up and down
//}
combo_key=0;
}
else if(rc == KEY_ENTER){
if(buf_count>0){
rtw_memset(log_buf,'\0',LOG_SERVICE_BUFLEN);
strncpy(log_buf,(char *)&temp_buf[0],buf_count);
rtw_up_sema_from_isr(&log_rx_interrupt_sema);
rtw_memset(temp_buf,'\0',buf_count);
is_data_cmd = _FALSE;
data_sz = 0;
data_cmd_sz = 0;
buf_count=0;
last_tickcnt = 0;
}else{
uart_at_send_string(STR_END_OF_ATCMD_RET);
}
}
else if(rc == KEY_BS){
if(buf_count>0){
buf_count--;
temp_buf[buf_count] = '\0';
if(gAT_Echo == 1){
serial_putc(sobj, rc);
serial_putc(sobj, ' ');
serial_putc(sobj, rc);
}
}
}
else{
// skip characters until "A"
if((buf_count == 0) && (rc != 'A')){
// some consoles send "\r\n" for enter,
//so skip '\n' here to prevent ERROR message each time it sends command
if(gAT_Echo == 1 && rc != KEY_NL){
uart_at_send_string("\r\nERROR:command should start with 'A'"STR_END_OF_ATCMD_RET);
}
return;
}
if(buf_count < (LOG_SERVICE_BUFLEN - 1)){
temp_buf[buf_count] = rc;
buf_count++;
if(gAT_Echo == 1){
serial_putc(sobj, rc);
}
}
else if(buf_count == (LOG_SERVICE_BUFLEN - 1)){
temp_buf[buf_count] = '\0';
if(gAT_Echo == 1){
uart_at_send_string("\r\nERROR:exceed size limit"STR_END_OF_ATCMD_RET);
}
}
}
}
}
void uart_atcmd_main(void)
{
UART_LOG_CONF uartconf;
read_uart_atcmd_setting_from_system_data(&uartconf);
serial_init(&at_cmd_sobj,UART_TX,UART_RX);
serial_baud(&at_cmd_sobj,uartconf.BaudRate);
serial_format(&at_cmd_sobj, uartconf.DataBits, (SerialParity)uartconf.Parity, uartconf.StopBits);
serial_rx_fifo_level(&at_cmd_sobj, FifoLvHalf);
// set flow control, only support RTS and CTS concurrent mode
// rxflow and tx flow is fixed by hardware
#define rxflow UART_RTS
#define txflow UART_CTS
if(uartconf.FlowControl){
pin_mode(txflow, PullDown); //init CTS in low
serial_set_flow_control(&at_cmd_sobj, FlowControlRTSCTS, rxflow, txflow);
}
else
serial_set_flow_control(&at_cmd_sobj, FlowControlNone, rxflow, txflow);
/*uart_at_lock_init();*/
#if UART_AT_USE_DMA_TX
rtw_init_sema(&uart_at_dma_tx_sema, 1);
#endif
#if UART_AT_USE_DMA_TX
serial_send_comp_handler(&at_cmd_sobj, (void*)uart_at_send_buf_done, (uint32_t)&at_cmd_sobj);
#endif
serial_irq_handler(&at_cmd_sobj, uart_irq, (uint32_t)&at_cmd_sobj);
serial_irq_set(&at_cmd_sobj, RxIrq, 1);
#if ATCMD_RX_GPIO_WAKEUP
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
uart_at_rx_wakeup();
#endif
#endif
}
static void uart_atcmd_thread(void *param)
{
p_wlan_init_done_callback = NULL;
atcmd_wifi_restore_from_flash();
atcmd_lwip_restore_from_flash();
rtw_msleep_os(20);
uart_atcmd_main();
at_printf("\r\nAT COMMAND READY");
if(atcmd_lwip_is_tt_mode())
at_printf(STR_END_OF_ATDATA_RET);
else
at_printf(STR_END_OF_ATCMD_RET);
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, STR_END_OF_ATCMD_RET);
vTaskDelete(NULL);
}
int uart_atcmd_module_init(void){
if(xTaskCreate(uart_atcmd_thread, ((const char*)"uart_atcmd_thread"), 1024, NULL, tskIDLE_PRIORITY+1 , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(uart_atcmd_thread) failed", __FUNCTION__);
return 0;
}
void example_uart_atcmd(void)
{
//if(xTaskCreate(uart_atcmd_thread, ((const char*)"uart_atcmd_thread"), 1024, NULL, tskIDLE_PRIORITY + 1 , NULL) != pdPASS)
// printf("\n\r%s xTaskCreate(uart_atcmd_thread) failed", __FUNCTION__);
p_wlan_init_done_callback = uart_atcmd_module_init;
return;
}
#endif

View file

@ -0,0 +1,77 @@
#ifndef __EXAMPLE_UART_ATCMD_H__
#define __EXAMPLE_UART_ATCMD_H__
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#if CONFIG_EXAMPLE_UART_ATCMD
#include "FreeRTOS.h"
#include "semphr.h"
/*UART Pinmux*/
#define CONFIG_AMEBA1 1
#if CONFIG_AMEBA1
#define UART_TX PA_4
#define UART_RX PA_0
#define UART_RTS PA_2
#define UART_CTS PA_1
#else
#define UART_TX PA_23
#define UART_RX PA_18
#define UART_RTS PA_22
#define UART_CTS PA_19
#endif
#define ATCMD_RX_GPIO_WAKEUP 0
#define KEY_NL 0xa // '\n'
#define KEY_ENTER 0xd // '\r'
#define KEY_BS 0x8
#define KEY_ESC 0x1B
#define KEY_LBRKT 0x5B
void uart_at_lock(void);
void uart_at_unlock(void);
void uart_at_send_string(char *str);
void uart_at_send_buf(u8 *buf, u32 len);
void example_uart_atcmd(void);
extern u8 key_2char2num(u8 hch, u8 lch);
static void at_hex2str(const u8 *start, u32 size, u8 *out, u32 out_size)
{
int index, index2;
u8 *buf, *line;
if(!start ||(size==0)||(!out)||(out_size==0))
return;
buf = (u8*)start;
line = (u8*)out;
for (index = 0, index2=0; (index < size)&&(index2<out_size); index++, index2+=2)
{
sprintf((char *)line+index2, "%02x", (u8) buf[index]);
}
return;
}
static void at_str2hex(const u8 *start, u32 size, u8 *out, u32 out_size)
{
int index, index2;
u8 *buf, *line;
if(!start ||(size==0))
return;
buf = (u8*)start;
line = (u8*)out;
for (index=0, index2=0; index<size; index+=2, index2++){
line[index2] = key_2char2num(buf[index], buf[index+1]);
}
return;
}
#endif //#if CONFIG_EXAMPLE_UART_ATCMD
#endif //#ifndef __EXAMPLE_UART_ATCMD_H__

View file

@ -0,0 +1,59 @@
#include "FreeRTOS.h"
#include "task.h"
#include "example_uart_update.h"
#include <platform/platform_stdlib.h>
#define XMODEM_UART_IDX 0
#define XMODEM_UART_MUX 2
#define XMODEM_UART_BAUDRATE 115200
extern void OTU_FW_Update(u8, u8, u32);
int is_update_image_enable(gpio_t *gpio_uart_update_eable)
{
GPIO_InitTypeDef GPIO_Pin;
u32 active_state;
// gpio_t gpio_uart_update_eable;
int ret = 0;
gpio_init(gpio_uart_update_eable, PIN_NAME);
gpio_dir(gpio_uart_update_eable, PIN_INPUT); // Direction: Input
gpio_mode(gpio_uart_update_eable, PullUp); // Pull-High
// ret = gpio_read(&gpio_uart_update_eable);
return ret;
}
void example_uart_update_thread(void *param)
{
int count = 0;
gpio_t gpio_uart_update_eable;
is_update_image_enable(&gpio_uart_update_eable);
//polling MAX_WAIT_TIME*50ms
while(count <= MAX_WAIT_TIME)
{
printf("waitting update enable\r\n");
if(gpio_read(&gpio_uart_update_eable) == 0){
printf("update image enabled with xmodem protocol!\r\n");
//uart_ymodem();
OTU_FW_Update(XMODEM_UART_IDX, XMODEM_UART_MUX, XMODEM_UART_BAUDRATE);
break;
}
else{
//RtlMsleepOS(50);
rtw_msleep_os(50);
count++;
}
}
vTaskDelete(NULL);
}
void example_uart_update(void)
{
if(xTaskCreate(example_uart_update_thread, ((const char*)"example_uart_update_thread"), 512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,84 @@
#ifndef UART_UPDATE_H
#define UART_UPDATE_H
#include "PinNames.h"
#include "gpio_api.h"
//#include "hal_gpio.h"
//#include "osdep_api.h"
#include "osdep_service.h"
#define MAX_WAIT_TIME 100
#if defined(CONFIG_PLATFORM_8711B)
#define PIN_NAME PA_5
#else
#define PIN_NAME PC_2
typedef enum
{
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
GPIO_Mode_INT = 0x02, /*!< GPIO Interrupt Mode */
GPIO_Mode_MAX = 0x03,
}GPIOMode_TypeDef;
/**
* @brief GPIO Configuration PullUp PullDown enumeration
*/
typedef enum
{
GPIO_PuPd_NOPULL = 0x00, /*!< GPIO Interrnal HIGHZ */
GPIO_PuPd_DOWN = 0x01, /*!< GPIO Interrnal Pull DOWN */
GPIO_PuPd_UP = 0x02, /*!< GPIO Interrnal Pull UP */
}GPIOPuPd_TypeDef;
/**
* @brief Setting interrupt's trigger type
*
* Setting interrupt's trigger type
*/
typedef enum
{
GPIO_INT_Trigger_LEVEL = 0x0, /**< This interrupt is level trigger */
GPIO_INT_Trigger_EDGE = 0x1, /**< This interrupt is edge trigger */
}GPIOIT_LevelType;
/**
* @brief Setting interrupt active mode
*
* Setting interrupt active mode
*/
typedef enum
{
GPIO_INT_POLARITY_ACTIVE_LOW = 0x0, /**< Setting interrupt to low active: falling edge or low level */
GPIO_INT_POLARITY_ACTIVE_HIGH = 0x1, /**< Setting interrupt to high active: rising edge or high level */
}GPIOIT_PolarityType;
/**
* @brief Enable/Disable interrupt debounce mode
*
* Enable/Disable interrupt debounce mode
*/
typedef enum
{
GPIO_INT_DEBOUNCE_DISABLE = 0x0, /**< Disable interrupt debounce */
GPIO_INT_DEBOUNCE_ENABLE = 0x1, /**< Enable interrupt debounce */
}GPIOIT_DebounceType;
typedef struct {
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. */
GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. */
GPIOIT_LevelType GPIO_ITTrigger; /**< Interrupt mode is level or edge trigger */
GPIOIT_PolarityType GPIO_ITPolarity; /**< Interrupt mode is high or low active trigger */
GPIOIT_DebounceType GPIO_ITDebounce; /**< Enable or disable de-bounce for interrupt */
u32 GPIO_Pin; // Pin: [7:5]: port number, [4:0]: pin number
}GPIO_InitTypeDef;
#endif
//======================================================
void example_uart_update();
int is_update_image_enable(gpio_t *gpio_uart_update_eable);
extern int uart_ymodem(void);
#endif

View file

@ -0,0 +1,64 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "websocket/libwsclient.h"
#include "websocket/wsclient_api.h"
#include <stdio.h>
#include "example_wsclient.h"
void handle_message(wsclient_context *wsclient, int data_len)
{
printf("\r\n>>>>>> Receiving: %s with length: %d\n", wsclient->receivedData, data_len);
if(strcmp(wsclient->receivedData, "hello") == 0)
ws_send("world", strlen("world"), 1, wsclient);
else if (strcmp(wsclient->receivedData, "world") == 0){
ws_close(wsclient);
wsclient = NULL;
}
}
static void example_wsclient_thread(void *param)
{
printf("\r\n\r\n\r\n>>>>>>>>>>>>>>>wsclient example<<<<<<<<<<<<<<<<<\r\n\r\n\r\n");
vTaskDelay(10000);
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS){
printf("\r\n\r\n\r\n>>>>>>>>>>>>>>Wifi is disconnected!!Please connect!!<<<<<<<<<<<<<<<<<\r\n\r\n\r\n");
vTaskDelay(10000);
}
int ret;
//wsclient_context *wsclient = create_wsclient("wss://echo.websocket.org", 0, NULL, NULL);
wsclient_context *wsclient = create_wsclient("wss://sandbox.kaazing.net", 0, "echo", NULL);
if(wsclient != NULL){
if(wsclient->use_ssl == 1){
#ifndef USING_SSL
printf("\r\nNot Support the wss server!\r\n");
vTaskDelete(NULL);
#endif
}
ret = ws_connect_url(wsclient);
if(ret >= 0){
ws_send("hello", strlen("hello"), 1, wsclient);
while (ws_getReadyState(wsclient) != CLOSED) {
ws_dispatch(handle_message);
ws_poll(0, wsclient);
}
}
else
printf("\r\nConnect to websocket server failed!\r\n");
}
else
printf("\r\nCreat websocket context failed!\r\n");
vTaskDelete(NULL);
}
void example_wsclient(void)
{
if(xTaskCreate(example_wsclient_thread, ((const char*)"example_wsclient_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef _EXAMPLE_WSCLIENT_H
#define _EXAMPLE_WSCLIENT_H
void example_wsclient(void);
#endif /* _EXAMPLE_WSCLIENT_H */

View file

@ -0,0 +1,48 @@
Websocket Client Example
Description:
A simple websocket client example which send "hello" and "world" to server.
The server will reply the message it received.
Once the client received "world", it will disconnect with server.
The SSL websocket server:
wss://echo.websocket.org
wss://sandbox.kaazing.net/echo
The websocket server without SSL:
ws://echo.websocket.org
ws://sandbox.kaazing.net/echo
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_WEBSOCKET 1
If using the WSS server:
[wsclient_api.h]
#define USING_SSL
[config_rsa.h]
#define SSL_MAX_CONTENT_LEN 5120
[example_wsclient.c]
wsclient_context *wsclient = create_wsclient("wss://sandbox.kaazing.net", 0, "echo", NULL);
or
wsclient_context *wsclient = create_wsclient("wss://echo.websocket.org", 0, NULL, NULL);
If using the WS server:
[example_wsclient.c]
wsclient_context *wsclient = create_wsclient("ws://sandbox.kaazing.net", 0, "echo", NULL);
or
wsclient_context *wsclient = create_wsclient("ws://echo.websocket.org", 0, NULL, NULL);
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A websocket client example thread will be started automatically when booting.
If using other websocekt server, modify the create_wsclient() API and the handle_message() function depending on the condition of the server.

View file

@ -0,0 +1,26 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include <platform_opts.h>
#include <wifi_mac_monitor/example_wifi_mac_monitor.h>
#include <platform/platform_stdlib.h>
typedef int (*mac_monitor_ptr)(unsigned char *phone_macaddr,char real_rssi);
extern mac_monitor_ptr mac_monitor_callback;
int get_station_mac(unsigned char *sta_mac,char rssi)
{
printf("\n\r%s: %02x:%02x:%02x:%02x:%02x:%02x, Rssi = %d\n",__func__,*(sta_mac)\
,*(sta_mac+1),*(sta_mac+2),*(sta_mac+3),*(sta_mac+4),*(sta_mac+5),rssi);
return 0;
}
void example_wifi_mac_monitor(void)
{
mac_monitor_callback = get_station_mac;
return;
}

View file

@ -0,0 +1,14 @@
#ifndef __EXAMPLE_WIFI_MAC_MONITOR_H__
#define __EXAMPLE_WIFI_MAC_MONITOR_H__
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
void example_wifi_mac_monitor(void);
int get_station_mac(unsigned char *sta_mac,char rssi);
#endif //#ifndef __EXAMPLE_WIFI_MAC_MONITOR_H__

View file

@ -0,0 +1,12 @@
WIFI MAC MONITOR EXAMPLE
Description:
Get station mac information in AP mode
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_WIFI_MAC_MONITOR 1
Execution:
When define CONFIG_EXAMPLE_WIFI_MAC_MONITOR, the callback function is automatically registered as get_station_mac().
It can collect the station mac address and rssi.

View file

@ -0,0 +1,185 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
/** @file
This example demonstrate how to implement wifi fast reconnection
**/
#include <platform_opts.h>
#include <wlan_fast_connect/example_wlan_fast_connect.h>
#include "task.h"
#include <platform/platform_stdlib.h>
#include <wifi/wifi_conf.h>
#include "flash_api.h"
#include "device_lock.h"
#include <lwip_netconf.h>
extern struct netif xnetif[NET_IF_NUM];
write_reconnect_ptr p_write_reconnect_ptr;
/*
* Usage:
* wifi connection indication trigger this function to save current
* wifi profile in flash
*
* Condition:
* CONFIG_EXAMPLE_WLAN_FAST_CONNECT flag is set
*/
int wlan_wrtie_reconnect_data_to_flash(u8 *data, uint32_t len)
{
flash_t flash;
struct wlan_fast_reconnect read_data = {0};
if(!data)
return -1;
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data);
#if ATCMD_VER == ATVER_2
struct wlan_fast_reconnect *copy_data = (struct wlan_fast_reconnect *) data;
copy_data->enable = read_data.enable;
#endif
//wirte it to flash if different content: SSID, Passphrase, Channel, Security type
if(memcmp(data, (u8 *) &read_data, sizeof(struct wlan_fast_reconnect)) != 0) {
printf("\r\n %s():not the same ssid/passphrase/channel, write new profile to flash", __func__);
flash_erase_sector(&flash, FAST_RECONNECT_DATA);
flash_stream_write(&flash, FAST_RECONNECT_DATA, len, (uint8_t *) data);
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
return 0;
}
/*
* Usage:
* After wifi init done, waln driver call this function to check whether
* auto-connect is required.
*
* This function read previous saved wlan profile in flash and execute connection.
*
* Condition:
* CONFIG_EXAMPLE_WLAN_FAST_CONNECT flag is set
*/
int wlan_init_done_callback()
{
flash_t flash;
struct wlan_fast_reconnect *data;
uint32_t channel;
uint32_t security_type;
uint8_t pscan_config;
char key_id[2] = {0};
int ret;
rtw_network_info_t wifi = {
{0}, // ssid
{0}, // bssid
0, // security
NULL, // password
0, // password len
-1 // key id
};
#if CONFIG_LWIP_LAYER
netif_set_up(&xnetif[0]);
#endif
#if CONFIG_AUTO_RECONNECT
//setup reconnection flag
if(wifi_set_autoreconnect(1) < 0){
return -1;
}
#endif
data = (struct wlan_fast_reconnect *)rtw_zmalloc(sizeof(struct wlan_fast_reconnect));
if(data){
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (uint8_t *)data);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
/* Check whether stored flash profile is empty */
struct wlan_fast_reconnect *empty_data;
empty_data = (struct wlan_fast_reconnect *)rtw_zmalloc(sizeof(struct wlan_fast_reconnect));
if(empty_data){
memset(empty_data, 0xff, sizeof(struct wlan_fast_reconnect));
if(memcmp(empty_data, data, sizeof(struct wlan_fast_reconnect)) == 0){
printf("[FAST_CONNECT] Fast connect profile is empty, abort fast connection\n");
rtw_mfree(data);
rtw_mfree(empty_data);
return 0;
}
rtw_mfree(empty_data);
}
memcpy(psk_essid, data->psk_essid, sizeof(data->psk_essid));
memcpy(psk_passphrase, data->psk_passphrase, sizeof(data->psk_passphrase));
memcpy(wpa_global_PSK, data->wpa_global_PSK, sizeof(data->wpa_global_PSK));
channel = data->channel;
sprintf(key_id,"%d",(char) (channel>>28));
channel &= 0xff;
security_type = data->security_type;
pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY;
//set partial scan for entering to listen beacon quickly
ret = wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1);
if(ret < 0){
rtw_mfree(data);
return -1;
}
wifi.security_type = security_type;
//SSID
strcpy((char *)wifi.ssid.val, (char*)psk_essid);
wifi.ssid.len = strlen((char*)psk_essid);
switch(security_type){
case RTW_SECURITY_WEP_PSK:
wifi.password = (unsigned char*) psk_passphrase;
wifi.password_len = strlen((char*)psk_passphrase);
wifi.key_id = atoi((const char *)key_id);
break;
case RTW_SECURITY_WPA_TKIP_PSK:
case RTW_SECURITY_WPA2_AES_PSK:
wifi.password = (unsigned char*) psk_passphrase;
wifi.password_len = strlen((char*)psk_passphrase);
break;
default:
break;
}
ret = wifi_connect((char*)wifi.ssid.val, wifi.security_type, (char*)wifi.password, wifi.ssid.len,
wifi.password_len, wifi.key_id, NULL);
if(ret == RTW_SUCCESS){
LwIP_DHCP(0, DHCP_START);
}
rtw_mfree(data);
}
return 0;
}
int Erase_Fastconnect_data(){
flash_t flash;
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_erase_sector(&flash, FAST_RECONNECT_DATA);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
return 0;
}
void example_wlan_fast_connect()
{
// Call back from wlan driver after wlan init done
p_wlan_init_done_callback = wlan_init_done_callback;
// Call back from application layer after wifi_connection success
p_write_reconnect_ptr = wlan_wrtie_reconnect_data_to_flash;
}

View file

@ -0,0 +1,50 @@
#ifndef __EXAMPLE_FAST_RECONNECTION_H__
#define __EXAMPLE_FAST_RECONNECTION_H__
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include "FreeRTOS.h"
#include <autoconf.h>
#include "main.h"
#define IW_PASSPHRASE_MAX_SIZE 64
//#define FAST_RECONNECT_DATA (0x80000 - 0x1000)
#define NDIS_802_11_LENGTH_SSID 32
#define A_SHA_DIGEST_LEN 20
struct wlan_fast_reconnect {
unsigned char psk_essid[NDIS_802_11_LENGTH_SSID + 4];
unsigned char psk_passphrase[IW_PASSPHRASE_MAX_SIZE + 1];
unsigned char wpa_global_PSK[A_SHA_DIGEST_LEN * 2];
uint32_t channel;
uint32_t security_type;
#if ATCMD_VER == ATVER_2
uint32_t enable;
#endif
};
typedef int (*wlan_init_done_ptr)(void);
typedef int (*write_reconnect_ptr)(uint8_t *data, uint32_t len);
//Variable
extern unsigned char psk_essid[NET_IF_NUM][NDIS_802_11_LENGTH_SSID+4];
extern unsigned char psk_passphrase[NET_IF_NUM][IW_PASSPHRASE_MAX_SIZE + 1];
extern unsigned char wpa_global_PSK[NET_IF_NUM][A_SHA_DIGEST_LEN * 2];
extern unsigned char psk_passphrase64[IW_PASSPHRASE_MAX_SIZE + 1];
//Function
extern wlan_init_done_ptr p_wlan_init_done_callback;
extern write_reconnect_ptr p_write_reconnect_ptr;
void example_wlan_fast_connect(void);
#endif //#ifndef __EXAMPLE_FAST_RECONNECTION_H__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
#ifndef EXAMPLE_WLAN_SCENARIO_H
#define EXAMPLE_WLAN_SCENARIO_H
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
void example_wlan_scenario(char* id);
#endif

View file

@ -0,0 +1,96 @@
WIFI API SCENARIOS EXAMPLE
Description:
Provide some Wi-Fi API scenarios for common usage.
Includes:
- Network Scan
- Authentication
- Mode switch about 7 cases
- Use scenario about 6 cases
Configuration:
Modify the argument of example_wlan_scenario() in example_entry.c to switch example cases.
[platform_opts.h]
#define CONFIG_ENABLE_WPS 1
#define CONFIG_ENABLE_P2P 1
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#define CONFIG_EXAMPLE_WLAN_SCENARIO 1
Execution:
The Wi-Fi example thread will be started automatically when booting.
Note:
The currently argument options are:
"S" for network scan:
- Scan nearby wlan routers and get info for each routers
"A" for Authentication:
- WPS-PBC
- WPS-PIN static PIN
- WPS-PIN dynamic PIN
- open
- WEP open (64 bit)
- WEP open (128 bit)
- WEP shared (64 bit)
- WEP shared (128 bit)
- WPA-PSK (TKIP)
- WPA-PSK (AES)
- WPA2-PSK (TKIP)
- WPA2-PSK (AES)
"M1" for mode switch case 1:
- Mode switch to infrastructure (AP mode)
"M2" for mode switch case 2:
- Mode switch to infrastructure (STA mode)
"M3" for mode switch case 3:
- Mode switch to infrastructure (P2P Autonomous GO)
"M4" for mode switch case 4:
- Mode switching time between AP and STA
"M5" for mode switch case 5:
- Mode switching time between P2P autonomous GO and STA
"M6" for mode switch case 6:
- Mode switch to infrastructure (AP mode with hidden SSID)
"M7" for mode switch case 7:
- Mode switching between concurrent mode and STA
"S1" for sequence scenario case 1:
Enable Wi-Fi with STA mode
-> Connect to AP by WPS enrollee static PIN mode (If failed, re-connect one time.)
-> Enable Wi-Fi Direct GO (It will re-enable WiFi, the original connection to AP would be broken.)
"S2" for sequence scenario case 2:
Enable Wi-Fi Direct GO
-> Disable Wi-Fi Direct GO, and enable Wi-Fi with STA mode (Disable Wi-Fi Direct GO must be done to release P2P resource.)
-> Connect to AP by WPS enrollee PBC mode (If failed, re-connect one time.)
"S3" for sequence scenario case 3:
Enable Wi-Fi with STA mode
-> Scan network
-> Connect to AP use STA mode (If failed, re-connect one time.)
-> Enable Wi-Fi Direct GO (It will re-enable WiFi, the original connection to AP would be broken.)
"S4" for sequence scenario case 4:
Enable Wi-Fi with STA mode
-> Connect to AP by WPS enrollee PBC mode (If failed, re-connect one time.)
-> Disconnect from AP
-> Enable Wi-Fi Direct GO
-> Disable Wi-Fi Direct GO, and enable Wi-Fi with STA mode (Disable Wi-Fi Direct GO must be done to release P2P resource.)
-> Connect to AP use STA mode (If failed, re-connect one time.)
-> Disconnect from AP
-> Disable Wi-Fi
"S5" for wlan scenario case 5: (Check connection result and RSSI value)
Enable Wi-Fi with STA mode
-> Connect to AP using STA mode, check the connection result based on error_flag
-> Show Wi-Fi information
-> Get AP's RSSI (also can refer ATWR)
"S6" for wlan scenario case 6: (Check scanned AP's RSSI, also can refer ATWS)
Enable Wi-Fi with STA mode
-> Scan network and handle the RSSI value (in dBm)

View file

@ -0,0 +1,111 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform_stdlib.h>
#include "xml.h"
static void example_xml_thread(void *param)
{
/* Create XML document
* <Home:Light xmlns:Home="http://www.home.com" xmlns="http://www.device.com" fw_ver="1.0.0">
* <Power>on</Power>
* <Color>
* <Red>255</Red>
* <Green>255</Green>
* <Blud>255</Blue>
* </Color>
* </Home:Light>
*/
struct xml_node *light_node, *power_node, *color_node, *red_node, *green_node, *blue_node;
// Creates element with (prefix, tag name, namespace uri), add element and text node as child
light_node = xml_new_element("Home", "Light", "http://www.home.com");
power_node = xml_new_element(NULL, "Power", NULL);
xml_add_child(power_node, xml_new_text("on"));
color_node = xml_new_element(NULL, "Color", NULL);
red_node = xml_new_element(NULL, "Red", NULL);
xml_add_child(red_node, xml_new_text("255"));
green_node = xml_new_element(NULL, "Green", NULL);
xml_add_child(green_node, xml_new_text("255"));
blue_node = xml_new_element(NULL, "Blue", NULL);
xml_add_child(blue_node, xml_new_text("255"));
xml_add_child(light_node, power_node);
xml_add_child(light_node, color_node);
xml_add_child(color_node, red_node);
xml_add_child(color_node, green_node);
xml_add_child(color_node, blue_node);
// Add or modify attributes
xml_set_attribute(light_node, "xmlns", "http://www.device.com");
xml_set_attribute(light_node, "fw_ver", "1.0.0");
// Dump XML document to memory buffer, equal to xml_dump_tree_ex(node, NULL, 0, 0);
char *dump_buf = xml_dump_tree(light_node);
printf("\n%s\n", dump_buf);
// Free dump buffer
xml_free(dump_buf);
// Dump XML document to memory buffer with prolog, new line, aligment
dump_buf = xml_dump_tree_ex(light_node, "<?xml version=\"1.0\"?>", 1, 4);
printf("\n%s\n", dump_buf);
xml_free(dump_buf);
// Delete XML tree to free memory
xml_delete_tree(light_node);
/* Parse XML document */
char *doc = "\
<?xml version=\"1.0\"?>\
<!--sensor example-->\
<Home:Sensor>\
<Thermostat>\
<Mode>auto</Mode>\
<Temperature unit=\"celsius\">25.5</Temperature>\
</Thermostat>\
</Home:Sensor>";
// Parse document buffer to XML tree. Prolog will be dropped
struct xml_node *root = xml_parse(doc, strlen(doc));
if(root) {
dump_buf = xml_dump_tree_ex(root, NULL, 1, 4);
printf("\n%s\n", dump_buf);
xml_free(dump_buf);
// Search by XPath, prefix and name in path should be matched
struct xml_node_set *set = xml_find_path(root, "/Home:Sensor/Thermostat/Temperature");
if(set->count) {
printf("\nFind %d element by %s\n", set->count, "/Home:Sensor/Thermostat/Temperature");
// Get XML tree search result 0
struct xml_node *temperature_node = set->node[0];
if(xml_is_text(temperature_node->child)) {
// Get text
printf("Temperature[0] is %s\n", temperature_node->child->text);
}
// Get attribute
char *unit = xml_get_attribute(temperature_node, "unit");
printf("Unit is \"%s\"\n", unit);
// Free attribute search result
xml_free(unit);
}
// Delete XML tree search result to free memory
xml_delete_set(set);
xml_delete_tree(root);
}
else {
printf("Xml parse failed\n");
}
vTaskDelete(NULL);
}
void example_xml(void)
{
if(xTaskCreate(example_xml_thread, ((const char*)"example_xml_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View file

@ -0,0 +1,6 @@
#ifndef EXAMPLE_XML_H
#define EXAMPLE_XML_H
void example_xml(void);
#endif /* EXAMPLE_XML_H */

View file

@ -0,0 +1,13 @@
XML EXAMPLE
Description:
The creation of a light XML document is used as the example of XML document generation.
The processing of a sensor XML document is used as the example of XML document parsing.
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_XML 1
Execution:
An XML example thread will be started automatically when booting.