initial commit

This commit is contained in:
2024-12-15 00:34:01 +06:00
commit 31efbc726f
1576 changed files with 657692 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
#include <FreeRTOS.h>
#include <task.h>
#include "device.h"
#include "gpio_api.h" // mbed
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#include "alc5680.h"
#include "wifi_conf.h"
#include "tftp/tftp.h"
#define GPIO_ALC_RESET_PIN PA_3
#define ALC_DSP_FIRMWARE_NAME "alc_fw_upgrade.bin"
#define TFTP_HOST_IP_ADDR "192.168.1.100"
#define TFTP_HOST_PORT 69
#define TFTP_MODE "octet"
#define ALC_5680_RESET 1
#define FORCE_UPGRADE 1
static void check_wifi_connection()
{
while(1){
vTaskDelay(1000);
if( wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS ){
printf("wifi is connected\r\n");
break;
}
}
}
static void example_alc_codec_fw_upgrade_thread(void *param)
{
tftp tftp_info;
unsigned int value = 0;
unsigned int test = 0;
gpio_t gpio_alc_reset;
memset(&tftp_info,0,sizeof(tftp));
check_wifi_connection();
// Init alc reset control pin
#if ALC_5680_RESET
printf("GPIO RESET\r\n");
gpio_init(&gpio_alc_reset, GPIO_ALC_RESET_PIN);
gpio_dir(&gpio_alc_reset, PIN_OUTPUT); // Direction: Output
gpio_mode(&gpio_alc_reset, PullNone); // No pull
gpio_write(&gpio_alc_reset, 1);
#endif
vTaskDelay(1000);//Wait for alc codec reset
printf("ALC568W_FW_UPGRADE\r\n");
alc5680_i2c_init();
alc5680_status();
alc5680_reg_read_16(0x1800C0CA,&value);
if(value == 0x1fc){
#if FORCE_UPGRADE
printf("The firmware already exist and force upgrade now...\r\n");
#else
printf("The firmware already exist\r\n");
goto EXIT;
#endif
}
alc5680_erase();
alc5680_reg_read_32(0x70000000,&value);
printf("addr 0x70000000 = %x\r\n",value);
alc5680_status();
tftp_info.recv_handle = alc5680_handler_function;
tftp_info.tftp_file_name=ALC_DSP_FIRMWARE_NAME;
printf("upgrade file name = %s\r\n",tftp_info.tftp_file_name);
tftp_info.tftp_mode = TFTP_MODE;
tftp_info.tftp_port = TFTP_HOST_PORT;
tftp_info.tftp_host = TFTP_HOST_IP_ADDR;
tftp_info.tftp_op = RRQ;//FOR READ OPERATION
tftp_info.tftp_retry_num = 5;
tftp_info.tftp_timeout = 5;//second
if(tftp_client_start(&tftp_info) == 0)
printf("Firmware upgrade successful\r\n");
else
printf("Firmware upgrade fail\r\n");
alc5680_reg_read_32(0x70000000,&value);
printf("addr 0x70000000 = %x\r\n",value);
alc5680_check_sum();
#if ALC_5680_RESET
printf("GPIO RESET\r\n");
gpio_write(&gpio_alc_reset, 1);
vTaskDelay(100);
gpio_write(&gpio_alc_reset, 0);
vTaskDelay(100);
gpio_write(&gpio_alc_reset, 1);
vTaskDelay(1000);
alc5680_status();
#endif
EXIT:
vTaskDelete(NULL);
}
void example_alc_dsp_fw_upgrade(void)
{
if(xTaskCreate(example_alc_codec_fw_upgrade_thread, ((const char*)"example_http_download_thread"), 4096, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View File

@@ -0,0 +1,6 @@
#ifndef EXAMPLE_ALC_DPS_FW_UPGRADE_H
#define EXAMPLE_ALC_DSP_FW_UPGRADE_H
void example_alc_dsp_fw_upgrade(void);
#endif /* EXAMPLE_ALC_CODEC_FW_UPGRADE_H */

View File

@@ -0,0 +1,11 @@
ALC CODEC FW UPGRADE
Description:
Get file from TFTP server and upgrade the audio dsp firmwatre.
Configuration:
Modify TFTP_HOST_IP_ADDR and ALC_DSP_FIRMWARE_NAME for your firmware in example_alc_dsp_fw_upgrade.c based on your TFTP server.
[platform_opts.h]
#define CONFIG_EXAMPLE_ALC_DSP_FW_UPGRADE 1

View File

@@ -0,0 +1,258 @@
#include <platform_opts.h>
#if (CONFIG_EXAMPLE_AMAZON_AWS_IOT)
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include <amazon_awsiot/example_amazon_awsiot.h>
#include "mqtt/MQTTClient/MQTTClient.h"
#include "wifi_conf.h"
#ifdef MQTT_TASK
#error "You need to undef MQTT_TASK in MQTTClient.h to enable WAIT_FOR_ACK features"
#endif
/* this example requires MQTT over SSL session */
#if (MQTT_OVER_SSL)
static unsigned char mqtt_sendbuf[1024], mqtt_readbuf[1024];
#define MQTT_BROKER_SERVER "a2zweh2b7yb784.iot.ap-southeast-1.amazonaws.com"
#define MQTT_CLIENT_ID "amebaClient"
#define THING_NAME "ameba"
char publishTopic[] = "$aws/things/" THING_NAME "/shadow/update";
char *subscribeTopic[5] = {
"$aws/things/" THING_NAME "/shadow/update/accepted",
"$aws/things/" THING_NAME "/shadow/update/rejected",
"$aws/things/" THING_NAME "/shadow/update/delta",
"$aws/things/" THING_NAME "/shadow/get/accepted",
"$aws/things/" THING_NAME "/shadow/get/rejected"
};
int led_state = 0;
/* root CA can be download here:
* https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem
**/
char* rootCABuff = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB\n" \
"yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\n" \
"ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp\n" \
"U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW\n" \
"ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0\n" \
"aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL\n" \
"MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\n" \
"ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln\n" \
"biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp\n" \
"U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y\n" \
"aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1\n" \
"nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex\n" \
"t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz\n" \
"SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG\n" \
"BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+\n" \
"rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/\n" \
"NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E\n" \
"BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH\n" \
"BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy\n" \
"aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv\n" \
"MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE\n" \
"p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y\n" \
"5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK\n" \
"WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ\n" \
"4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N\n" \
"hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq\n" \
"-----END CERTIFICATE-----\n";
/* Fill your certificate.pem.crt wiht LINE ENDING */
char* certificateBuff = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDWTCCAkGgAwIBAgIUE1UsPqN2mfvCGh2DLX2HWs3NOIYwDQYJKoZIhvcNAQEL\n" \
"BQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\n" \
"SW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTE2MDYyNzA2MzQ0\n" \
"NVoXDTQ5MTIzMTIzNTk1OVowHjEcMBoGA1UEAwwTQVdTIElvVCBDZXJ0aWZpY2F0\n" \
"ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANM8/fzFJeZoS2yIf0Yy\n" \
"seFqUlnwNwNsg0G4U+3mUPj47ogs3jLDFA208P85S3qnfDaUY553wYY3BcIlBzpp\n" \
"y7vstrgapTOxH2c/Nrk/QfDqg/gUBSZs24c12WvyqlfDnKcIsRxALbfO0yMWKATB\n" \
"fFfnnZRCOVO6eKcW2O3ptfYDH8tIhrzCAEAAAF6CYmlSzyw9KrWh7ypYCp3AcJ/Y\n" \
"Fp4+SsF6xxLRuLOk37NJL8HfuIappkUIN7seGU9Y6Bo2YgOj9yBXyW/dmV3IxKVW\n" \
"SUSMSdIP+pc/b8lFfnE14yFtfK7jKhdy4XOh9LpOMJYs0i74UVQKJs7NYL8MXHIu\n" \
"FlUCAwEAAaNgMF4wHwYDVR0jBBgwFoAUoTuxNa4LQJd07hfP4se/TevgQ0AwHQYD\n" \
"VR0OBBYEFAQ9fAKopGZ52+f+w0dJMAwTi/hVMAwGA1UdEwEB/wQCMAAwDgYDVR0P\n" \
"AQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQB6YQ+w6YTCZYWOlZfH09D8WhwV\n" \
"zSAzcEUdWH5T7bNK1N5r7/5zVIedseFxPUqtuC8j+C7CWDuLykpI8A2WAnayXOXn\n" \
"UPc/SNIet0nGts50cd4zzg7xMMqseGVdSMLAjFwqI8npJp9Ij8inrsf5f1hY0nhb\n" \
"Zb6FkVghlYhgmWv9p949kBQ6ODrtiyQqAYjzzZa957HwR7ajZfMIWm+HaV6f+NYq\n" \
"O43eQbt14xrRQNjAhSQaoVT64PH1TA6XiyoF25xlnrrxDXGAo5cxVDa1MmXu249X\n" \
"9z2+uzKgCYuugQk+w+8JmC6hR0EH4q4+ydsNkYTC0LK3MndHumA1Dj3OwUfA\n" \
"-----END CERTIFICATE-----\n";
/* Fill your private.pem.key wiht LINE ENDING */
char* privateKeyBuff = \
"-----BEGIN RSA PRIVATE KEY-----\n" \
"MIIEpAIBAAKCAQEA0zz9/MUl5mhLbIh/RjKx4WpSWfA3A2yDQbhT7eZQ+PjuiCze\n" \
"MsMUDbTw/zlLeqd8NpRjnnfBhjcFwiUHOmnLu+y2uBqlM7EfZz82uT9B8OqD+BQF\n" \
"JmzbhzXZa/KqV8OcpwixHEAtt87TIxYoBMF8V+edlEI5U7p4pxbY7em19gMfy0iG\n" \
"vMIAQAAAXoJiaVLPLD0qtaHvKlgKncBwn9gWnj5KwXrHEtG4s6Tfs0kvwd+4hqmm\n" \
"RQg3ux4ZT1joGjZiA6P3IFfJb92ZXcjEpVZJRIxJ0g/6lz9vyUV+cTXjIW18ruMq\n" \
"F3Lhc6H0uk4wlizSLvhRVAomzs1gvwxcci4WVQIDAQABAoIBAQCObSVjdRokzFVu\n" \
"jGokTrIZJrL36Ttul4+4lCwiz5PxCwbp0jbPSzEOPN3xeBQoUx0xP8QbaOuXLyo2\n" \
"yPiirgqsXuKkJ3MT820VFE41gS1Y3wa0EeuXCPbLp8c9PZUVL9ND3Fxui+dHc7Bw\n" \
"i9PXwQ2xx308JZq5lZUcNA93+oixohfoN4kgPfT3je7yPvn0j1rMHfjQPrSvpIvk\n" \
"P2XA66BZf8YS9k6lpJLzslntusHO4ZoqdQxaqa3a79qawUjkJ4G4qx3aDvzqdjXU\n" \
"DTFgTLI8sicWl4Icx3vqCgZfGWYuzRX5Ka5eUZYkwv4PgUOSynVvc6n3fjX/2F1X\n" \
"aPEqLuIBAoGBAO+Akr7F5LnRyLxLEeywjruGxvG5vHS41YvRcHSukrNLoK4mRMRA\n" \
"fTqJe8oZCRuOGsDBkRujgnSEUJhqt2+kGf9dvv5pCS35PFvTzawbpe8HX/JjitDb\n" \
"kKxAd3edsbOo3ZCOwYLFwMPMIMzemqFX67cXyQwOUhcGf6N7YBKhA6JhAoGBAOHK\n" \
"AarQJXo3C69SpWMvei3zmV8pUdVLPiiiNb1q/pustt+hykRhXNrngV3ncB7mJBET\n" \
"Q+36c5F04A6EBSp5Nr8EdiPnsFwk+ILKx7wQ6y0E29xIRLxryyu27rMAGpk8D1Oy\n" \
"8F2mX23qGWQAsMi2sxKk7o+2EGoUF1f/HKeDcOB1AoGBAM5johG8P2rSGYYJuxyY\n" \
"2adIcdCFGp4LWhrvFVW3yruvhHwOhlwIpuH28DIseOjCANPy+rUypoz6KOnvrLwM\n" \
"Ukr54kkjAsIXcahAUZDrEod1d31NwqZRT87gjxMJVcVY0/Zqzt9+wqr4EZv6iI5Z\n" \
"UcuqN5qoDJ3C/+NFwnjLQHKBAoGAQI5zX5VXwdPPQXeN1ggTFORba7vyq9txkEig\n" \
"uOHInlYJi3NE07xKwkQC1wh/JDaFBWTOvVIojOQv07ani3dQ0djCto1d/VqMu0ij\n" \
"RwBHXX3QJvF6xazEUGFjakaTVFC5ySKWWxBgpJqUW+VepmSmWqRRmUFi/BF2gzBr\n" \
"zvFj6qkCgYANcCc6wXqWNwmAnH/bfTRXunUgt3AAxmMXtkakhXAjElgFymgmXhTN\n" \
"Huu00WjTeZqOSl8bE0Ki/bcRojlx2QMMaEHGSVRL28uPJCJ4HeBAH3m22dtceFgF\n" \
"+ZHhF5b6NFe6EeLBcd/TGLtuKvc/jeru8tciNrPj9MTSJR9T0TYxhw==\n" \
"-----END RSA PRIVATE KEY-----\n";
#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);
if ((strstr(data->topicName->lenstring.data, "/shadow/get/accepted") != NULL) || (strstr(data->topicName->lenstring.data, "/shadow/update/accepted") != NULL)) {
char *pch;
// payload format: {"state":{"reported":{"led":1},"desired":{"led":0}},"metadata":{"reported":{"led":{"timestamp":1466996558}},"desired":{"led":{"timestamp":1466996558}}},"version":7,"timestamp":1466996558}
pch = strstr((char*)data->message->payload, "\"desired\":{\"led\":");
if (pch != NULL) {
pch += strlen("\"desired\":{\"led\":");
led_state = *pch - '0';
mqtt_printf(MQTT_INFO, "Update led state to %d", led_state);
}
}
}
int reconnect(MQTTClient* client, char *address, int port, MQTTPacket_connectData* connectData) {
int rc = 0;
while (1) {
do {
if (wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS) {
break;
}
mqtt_printf(MQTT_INFO, "Wi-Fi connected.");
if (client->isconnected == 0) {
if (NetworkConnect(client->ipstack, address, port) != 0) {
break;
}
mqtt_printf(MQTT_INFO, "\"%s\" Connected", address);
if (MQTTConnect(client, connectData) != 0) {
break;
}
mqtt_printf(MQTT_INFO, "MQTT Connected");
}
} while (0);
if (client->isconnected) {
break;
}
vTaskDelay(1000);
}
return rc;
}
//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 example_amazon_awsiot_thread(void *pvParameters)
{
/* connect to MQTT_BROKER_SERVER, subscribe to a topic, send and receive messages regularly every 5 sec */
MQTTClient client;
Network network;
int rc = 0, count = 0, i;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
char* address = MQTT_BROKER_SERVER;
char* pub_topic = publishTopic;
NetworkInit(&network);
network.rootCA = rootCABuff;
network.clientCA = certificateBuff;
network.private_key = privateKeyBuff;
network.use_ssl = 1;
MQTTClientInit(&client, &network, 30000, mqtt_sendbuf, sizeof(mqtt_sendbuf), mqtt_readbuf, sizeof(mqtt_readbuf));
connectData.MQTTVersion = 3;
connectData.clientID.cstring = MQTT_CLIENT_ID;
connectData.keepAliveInterval = 15 * 60;
reconnect(&client, address, 8883, &connectData);
for (i=0; i<5; i++) {
mqtt_printf(MQTT_INFO, "Subscribe to Topic: %s", subscribeTopic[i]);
if ((rc = MQTTSubscribe(&client, subscribeTopic[i], QOS1, messageArrived)) != 0) {
mqtt_printf(MQTT_INFO, "Return code from MQTT subscribe is %d\n", rc);
}
}
while (++count)
{
MQTTMessage message;
char payload[300];
message.qos = QOS1;
message.retained = 0;
message.payload = payload;
sprintf(payload, "{\"state\":{\"reported\":{\"led\":%d}},\"clientToken\":\"ameba\"}", led_state);
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, 10000)) != 0) {
mqtt_printf(MQTT_INFO,"Return code from yield is %d\n", rc);
}
if (client.isconnected == 0) {
reconnect(&client, address, 8883, &connectData);
for (i=0; i<5; i++) {
mqtt_printf(MQTT_INFO, "Subscribe to Topic: %s", subscribeTopic[i]);
if ((rc = MQTTSubscribe(&client, subscribeTopic[i], QOS1, messageArrived)) != 0) {
mqtt_printf(MQTT_INFO, "Return code from MQTT subscribe is %d\n", rc);
}
}
}
vTaskDelay(1000);
}
/* do not return */
}
void example_amazon_awsiot(void)
{
if(xTaskCreate(example_amazon_awsiot_thread, ((const char*)"example_amazon_awsiot_thread"), 4096, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}
#endif // #if (MQTT_OVER_SSL)
/*-----------------------------------------------------------*/
#endif // #if (CONFIG_EXAMPLE_AMAZON_AWS_IOT)

View File

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

View File

@@ -0,0 +1,13 @@
AMAZON AWS IOT EXAMPLE
Description:
Connect to Amazon AWS IoT. It requires MQTT protocol over SSL session. The original MQTT library client handler does
not support IP port for MQTT over SLL (8883). So we implement it without client handler. You need to undef MQTT_TASK
to enable related configuration.
Configuration:
Modify MQTT_BROKER_SERVER, THING_NAME, rootCABuff, certificateBuff, privateKeyBuff based on you account settings.
Execution:
You need to connect to WiFi manually by AT command. After connected the mqtt connection will preceed.

View File

@@ -0,0 +1,364 @@
#include "example_audio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "i2s_api.h"
#include "analogin_api.h"
#include <platform/platform_stdlib.h>
#if CONFIG_EXAMPLE_CODEC_SGTL5000
#include "sgtl5000.h"
#endif
#if CONFIG_EXAMPLE_CODEC_ALC5651
#include "alc5651.h"
#endif
#define CONFIG_PLAY_SD_WAV 0 // 1: play wav audio file store on SD card
//0: play audio file store on memory
#define CONFIG_TUNE_VOLUME 0 // tune volume by trimmer resistor and ADC
#define I2S_DMA_PAGE_SIZE 512 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
/* play wav file on SD card */
#if CONFIG_PLAY_SD_WAV
#include "ff.h"
#include <fatfs_ext/inc/ff_driver.h>
#include <disk_if/inc/sdcard.h>
#include "wav.h"
SRAM_BF_DATA_SECTION u8 WAV_Buf[I2S_DMA_PAGE_SIZE];
#define SAMPLE_BLOCKS (I2S_DMA_PAGE_SIZE/2)
#else
#include "birds_44100_2ch_16b.c"
#endif
u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#if defined(CONFIG_PLATFORM_8195A)
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_TX_PIN PC_2
#define I2S_SD_RX_PIN PC_4
#define I2S_MCK_PIN PC_3
#elif defined(CONFIG_PLATFORM_8711B)
#define I2S_SCLK_PIN PA_21
#define I2S_WS_PIN PA_22
#define I2S_SD_TX_PIN PA_19
#define I2S_SD_RX_PIN PA_20
#define I2S_MCK_PIN PA_18
#endif
i2s_t i2s_obj;
float volume_ratio = 0; // codec volume ration. 0.0 ~1.0
void i2s_tx_complete(void *data, char *pbuf)
{
//
}
void i2s_rx_complete(void *data, char* pbuf)
{
//
}
#if CONFIG_PLAY_SD_WAV
void print_wav_header(WavHeader *pwavHeader){
u8 buf[5];
printf("================wav header===============\n");
memcpy(buf, &pwavHeader->chunk_id[0], 4);
buf[4] = 0;
printf(" chunk_id: %s\n", buf);
printf(" chunk_size: 0x%08X\n",pwavHeader->chunk_size);
memcpy(buf, &pwavHeader->format[0], 4);
buf[4] = 0;
printf(" format: %s\n", buf);
memcpy(buf, &pwavHeader->fmtchunk_id[0], 4);
buf[4] = 0;
printf(" fmtchunk_id: %s\n", buf);
printf(" fmtchunk_size: 0x%08X\n",pwavHeader->fmtchunk_size);
printf(" audio_format: 0x%04X\n",pwavHeader->audio_format);
printf(" num_channels: 0x%04X\n",pwavHeader->num_channels);
printf(" sample_rate: 0x%08X\n",pwavHeader->sample_rate);
printf(" byte_rate: 0x%08X\n",pwavHeader->byte_rate);
printf(" block_align: 0x%04X\n",pwavHeader->block_align);
printf(" bps: 0x%04X\n",pwavHeader->bps);
memcpy(buf, &pwavHeader->datachunk_id[0], 4);
buf[4] = 0;
printf(" datachunk_id: %s\n", buf);
printf(" datachunk_size: 0x%08X\n",pwavHeader->datachunk_size);
printf("==================end====================\n");
}
void audio_play_sd_wav(u8* filename){
int drv_num = 0;
u32 read_length = 0;
FRESULT res;
FATFS m_fs;
FIL m_file;
char logical_drv[4]; /* root diretor */
char abs_path[64];
WavHeader pwavHeader;
u32 wav_length = 0;
u32 wav_offset = 0;
int *ptx_buf;
drv_num = FATFS_RegisterDiskDriver(&SD_disk_Driver);
if(drv_num < 0){
printf("Rigester disk driver to FATFS fail.\n");
return;
}else{
logical_drv[0] = drv_num + '0';
logical_drv[1] = ':';
logical_drv[2] = '/';
logical_drv[3] = 0;
}
if(f_mount(&m_fs, logical_drv, 1)!= FR_OK){
printf("FATFS mount logical drive fail, please format DISK to FAT16/32.\n");
goto unreg;
}
memset(abs_path, 0x00, sizeof(abs_path));
strcpy(abs_path, logical_drv);
sprintf(&abs_path[strlen(abs_path)],"%s", filename);
//Open source file
res = f_open(&m_file, abs_path, FA_OPEN_EXISTING | FA_READ); // open read only file
if(res != FR_OK){
printf("Open source file %(s) fail.\n", filename);
goto umount;
}
/* Read WAV header */
res = f_read(&m_file, WAV_Buf, sizeof(WavHeader),(UINT*)&read_length);
if((res != FR_OK) || (read_length == 0)){
printf("Read wav header fail!\n");
}
memcpy(&pwavHeader, WAV_Buf, sizeof(WavHeader));
print_wav_header(&pwavHeader);
if (strncmp(pwavHeader.chunk_id, "RIFF", 4) ||
strncmp(pwavHeader.format, "WAVE", 4)){
printf("Not a wav file\n");
goto exit;
}
/* only support PCM, 44.1K stereo wav file for this demo */
if (pwavHeader.audio_format != 1 ||
pwavHeader.sample_rate != 44100 ||
pwavHeader.num_channels != 2){
printf("Only PCM encoding 44.1K stereo wav file\n");
goto exit;
}
/* Read wav data length */
res = f_lseek(&m_file, m_file.fptr + pwavHeader.datachunk_size);
res = f_read(&m_file, WAV_Buf, 8,(UINT*)&read_length);
if((res != FR_OK) || (read_length == 0)){
printf("Read wav data info!\n");
}
if(strncmp(WAV_Buf, "data", 4)){
printf("Have not found invalid data chunk\n");
goto exit;
}
wav_length = *(u32*)&WAV_Buf[4];
printf("Audio data total length 0x%08X\n", wav_length);
do{
/* Read a block */
res = f_read(&m_file, WAV_Buf, I2S_DMA_PAGE_SIZE,(UINT*)&read_length);
if((res != FR_OK) || (read_length == 0)){
printf("Wav play done !\n");
break;
}
retry:
ptx_buf = i2s_get_tx_page(&i2s_obj);
if(ptx_buf){
if(read_length < I2S_DMA_PAGE_SIZE){
/* if valid audio data short than a page, make sure the rest of the page set to 0*/
memset((void*)ptx_buf, 0x00, I2S_DMA_PAGE_SIZE);
memcpy((void*)ptx_buf, (void*)&WAV_Buf[0], read_length);
}else
memcpy((void*)ptx_buf, (void*)&WAV_Buf[0], I2S_DMA_PAGE_SIZE);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
}else{
vTaskDelay(1);
goto retry;
}
wav_offset += read_length;
}while(1);
printf("I2S write data length 0x%08X\n", wav_offset);
exit:
// close source file
res = f_close(&m_file);
if(res){
printf("close file (%s) fail.\n", filename);
}
umount:
if(f_mount(NULL, logical_drv, 1) != FR_OK){
printf("FATFS unmount logical drive fail.\n");
}
unreg:
if(FATFS_UnRegisterDiskDriver(drv_num))
printf("Unregister disk driver from FATFS fail.\n");
}
#else
/* only for 16bit sampled audio data */
void audio_play_memory(void *audio, u32 length){
int *ptx_buf;
s16 *p = audio;
u32 offset = 0;
u32 sampleBlocks = length*2; // 2 channel
u32 MaxBlocksPerCycle = I2S_DMA_PAGE_SIZE/sizeof(short);
u32 dataLen = 0;
again:
ptx_buf = i2s_get_tx_page(&i2s_obj);
if (ptx_buf) {
if(sampleBlocks-offset >= MaxBlocksPerCycle)
dataLen = MaxBlocksPerCycle*sizeof(short);
else{
/* if valid audio data short than a page, make sure the rest of the page set to 0*/
memset((void*)ptx_buf, 0x00, I2S_DMA_PAGE_SIZE);
dataLen = (sampleBlocks-offset)*sizeof(short);
}
_memcpy((void*)ptx_buf, (void*)(p+offset), dataLen);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
offset += dataLen/sizeof(short);
if(offset >= sampleBlocks) {
offset = 0;
return;
}
goto again;
}else{
vTaskDelay(1);
goto again;
}
}
#endif
#if CONFIG_TUNE_VOLUME
#define MBED_ADC_PIN_3 AD_3 // HDK, A2
/*
* OFFSET: value of measuring at 0.000v, value(0.000v)
* GAIN_DIV: value(1.000v)-value(0.000v) or value(2.000v)-value(1.000v) or value(3.000v)-value(2.000v)
*
* MSB 12bit of value is valid, need to truncate LSB 4bit (0xABCD -> 0xABC). OFFSET and GAIN_DIV are truncated values.
*/
#define OFFSET 0x298
#define GAIN_DIV 0x34C
#define AD2MV(ad,offset,gain) (((ad/16)-offset)*1000/gain)
analogin_t adc2;
void audio_tune_volume_thread(void* param){
uint16_t offset, gain;
uint16_t adcdat2 = 0;
int32_t v_mv2;
float ratio = 0;
analogin_init(&adc2, MBED_ADC_PIN_3);
offset = OFFSET;
gain = GAIN_DIV;
while(1){
adcdat2 = analogin_read_u16(&adc2);
v_mv2 = AD2MV(adcdat2, offset, gain);
ratio = (float)v_mv2/(float)3300;
ratio = (float)((int)(ratio*10))/10.0;
if(ratio > 1.0)ratio = 1.0;
if(ratio < 0.0)ratio = 0.0;
if(ratio != volume_ratio){
volume_ratio = ratio;
#if CONFIG_EXAMPLE_CODEC_SGTL5000
sgtl5000_setVolume(volume_ratio);
#endif
}
vTaskDelay(100);
}
exit:
analogin_deinit(&adc2);
vTaskDelete(NULL);
}
#endif
void example_audio_thread(void* param){
printf("Audio codec demo begin......\n");
//Init I2S first, generate MCLK to drive SGTL5000
i2s_obj.channel_num = CH_STEREO;
i2s_obj.sampling_rate = SR_44p1KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_TXRX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_TX_PIN, I2S_SD_RX_PIN, I2S_MCK_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_rx_complete, (uint32_t)&i2s_obj);
// i2s_recv_page(&i2s_obj); // sumbit a page to receive
#if CONFIG_EXAMPLE_CODEC_SGTL5000
sgtl5000_enable();
#endif
#if CONFIG_EXAMPLE_CODEC_ALC5651
alc5651_init();
alc5651_init_interface2();
#endif
#if CONFIG_TUNE_VOLUME
/*Create a task to tune codec volume*/
if(xTaskCreate(audio_tune_volume_thread, ((const char*)"audio_tune_volume_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(audio_tune_volume_thread) failed", __FUNCTION__);
#endif
#if CONFIG_PLAY_SD_WAV
char wav[20] = "AudioSDTest.wav";
volume_ratio = 0.3;
#if CONFIG_EXAMPLE_CODEC_SGTL5000
sgtl5000_setVolume(volume_ratio);
#endif
printf("\nPlay %s on SD card.\n", wav);
audio_play_sd_wav(wav);
#else
volume_ratio = 0.7;
#if CONFIG_EXAMPLE_CODEC_SGTL5000
sgtl5000_setVolume(volume_ratio);
#endif
printf("\nPlay bird sing on memory.\n");
while(1){
audio_play_memory((void*)birds_sing, birds_sing_size);
wait_ms(1000);
}
#endif
exit:
vTaskDelete(NULL);
}
void example_audio(void)
{
if(xTaskCreate(example_audio_thread, ((const char*)"example_audio_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_audio_thread) failed", __FUNCTION__);
}

Binary file not shown.

View File

@@ -0,0 +1,15 @@
This mp3 example is used to play mp3 files from the SDCARD. In order to run the example the following steps must be followed.
1. Set the parameter CONFIG_EXAMPLE_AUDIO_MP3 to 1 in platform_opts.h file
2. In the example file "example_audio_mp3.c" set the config parameters in the start of the file
-->I2S_DMA_PAGE_SIZE :- Should be set to the value of decoded bytes depending upon the frequency of the mp3.
-->NUM_CHANNELS :- Should be set to CH_MONO if number of channels in mp3 file is 1 and CH_STEREO if its 2.
-->SAMPLING_FREQ:- Check the properties of the mp3 file to determine the sampling frequency and choose the appropriate macro.
The default values of the parameters are pre-set to the values of the sample audio file provided in the folder, in case you are using your own audio file please change the above parameters to the parameters for your audio file else the audio will not be played properly.
3. Build and flash the binary to test

View File

@@ -0,0 +1,246 @@
#include "mp3/mp3_codec.h"
#include "example_audio_mp3.h"
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "i2s_api.h"
#include "analogin_api.h"
#include <stdlib.h>
#include "platform_opts.h"
#include "ff.h"
#include <fatfs_ext/inc/ff_driver.h>
#include <disk_if/inc/sdcard.h>
#include "section_config.h"
#if CONFIG_EXAMPLE_MP3_STREAM_SGTL5000
#include "sgtl5000.h"
#else
#include "alc5651.h"
#endif
//-----------------Frequency Mapping Table--------------------//
/*+-------------+-------------------------+--------------------+
| Frequency(hz) | Number of Channels | Decoded Bytes |
|(CH_MONO:1 CH_STEREO:2) |(I2S_DMA_PAGE_SIZE) |
+---------------+-------------------------+--------------------+
| 8000 | 1 | 1152 |
| 8000 | 2 | 2304 |
| 16000 | 1 | 1152 |
| 16000 | 2 | 2304 |
| 22050 | 1 | 1152 |
| 22050 | 2 | 2304 |
| 24000 | 1 | 1152 |
| 24000 | 2 | 2304 |
| 32000 | 1 | 2304 |
| 32000 | 2 | 4608 |
| 44100 | 1 | 2304 |
| 44100 | 2 | 4608 |
| 48000 | 1 | 2304 |
| 48000 | 2 | 4608 |
+---------------+-------------------------+------------------+*/
//------------------------------------- ---CONFIG Parameters-----------------------------------------------//
#define I2S_DMA_PAGE_SIZE 4608 //Use frequency mapping table and set this value to number of decoded bytes
//Options:- 1152, 2304, 4608
#define NUM_CHANNELS CH_STEREO //Use mp3 file properties to determine number of channels
//Options:- CH_MONO, CH_STEREO
#define SAMPLING_FREQ SR_32KHZ //Use mp3 file properties to identify frequency and use appropriate macro
//Options:- SR_8KHZ =>8000hz - PASS
// SR_16KHZ =>16000hz - PASS
// SR_24KHZ =>24000hz - PASS
// SR_32KHZ =>32000hz - PASS
// SR_48KHZ =>48000hz - PASS
// SR_96KHZ =>96000hz ~ NOT SUPPORTED
// SR_7p35KHZ =>7350hz ~ NOT SUPPORTED
// SR_14p7KHZ =>14700hz ~ NOT SUPPORTED
// SR_22p05KHZ =>22050hz - PASS
// SR_29p4KHZ =>29400hz ~ NOT SUPPORTED
// SR_44p1KHZ =>44100hz - PASS
// SR_88p2KHZ =>88200hz ~ NOT SUPPORTED
#define FILE_NAME "AudioSDTest.mp3" //Specify the file name you wish to play that is present in the SDCARD
//------------------------------------- ---CONFIG Parameters-----------------------------------------------//
#define INPUT_FRAME_SIZE 1500
unsigned char MP3_Buf[INPUT_FRAME_SIZE];
signed short WAV_Buf[I2S_DMA_PAGE_SIZE];
#define I2S_DMA_PAGE_NUM 2 // Vaild number is 2~4
static u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
static u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
static i2s_t i2s_obj;
static void i2s_tx_complete(void *data, char *pbuf)
{
//
}
static void i2s_rx_complete(void *data, char* pbuf)
{
//
}
void audio_play_sd_mp3(u8* filename){
mp3_decoder_t mp3;
mp3_info_t info;
int drv_num = 0;
int frame_size = 0;
u32 read_length = 0;
FRESULT res;
FATFS m_fs;
FIL m_file[2];
char logical_drv[4]; //root diretor
char abs_path[32]; //Path to input file
DWORD bytes_left;
DWORD file_size;
int i = 0;
int bw = 0;
volatile u32 tim1 = 0;
volatile u32 tim2 = 0;
//WavHeader pwavHeader;
u32 wav_length = 0;
u32 wav_offset = 0;
int *ptx_buf;
drv_num = FATFS_RegisterDiskDriver(&SD_disk_Driver);
if(drv_num < 0){
printf("Rigester disk driver to FATFS fail.\n");
return;
}else{
logical_drv[0] = drv_num + '0';
logical_drv[1] = ':';
logical_drv[2] = '/';
logical_drv[3] = 0;
}
if(f_mount(&m_fs, logical_drv, 1)!= FR_OK){
printf("FATFS mount logical drive fail, please format DISK to FAT16/32.\n");
goto unreg;
}
memset(abs_path, 0x00, sizeof(abs_path));
strcpy(abs_path, logical_drv);
sprintf(&abs_path[strlen(abs_path)],"%s", filename);
//Open source file
res = f_open(&m_file[0], abs_path, FA_OPEN_EXISTING | FA_READ); // open read only file
if(res != FR_OK){
printf("Open source file %s fail.\n", filename);
goto umount;
}
file_size = (&m_file[0])->fsize;
bytes_left = file_size;
printf("File size is %d\n",file_size);
mp3 = mp3_create();
if(!mp3)
{
printf("mp3 context create fail\n");
goto exit;
}
tim1 = rtw_get_current_time();
do{
/* Read a block */
if(bytes_left >= INPUT_FRAME_SIZE)
res = f_read(&m_file[0], MP3_Buf, INPUT_FRAME_SIZE,(UINT*)&read_length);
else if(bytes_left > 0)
res = f_read(&m_file[0], MP3_Buf, bytes_left,(UINT*)&read_length);
if((res != FR_OK))
{
printf("Wav play done !\n");
break;
}
frame_size = mp3_decode(mp3, MP3_Buf, INPUT_FRAME_SIZE, WAV_Buf, &info);
bytes_left = bytes_left - frame_size;
f_lseek(&m_file[0], (file_size-bytes_left));
//printf("frame size [%d], Decoded bytes [%d]\n",frame_size,info.audio_bytes);
retry:
ptx_buf = i2s_get_tx_page(&i2s_obj);
if(ptx_buf){
if(info.audio_bytes < I2S_DMA_PAGE_SIZE){
/* if valid audio data short than a page, make sure the rest of the page set to 0*/
memset((void*)ptx_buf, 0x00, I2S_DMA_PAGE_SIZE);
memcpy((void*)ptx_buf, (void*)WAV_Buf, info.audio_bytes);
}else
memcpy((void*)ptx_buf, (void*)WAV_Buf, info.audio_bytes);
i2s_send_page(&i2s_obj, (uint32_t*)ptx_buf);
}else{
vTaskDelay(1);
goto retry;
}
}while(read_length > 0);
tim2 = rtw_get_current_time();
printf("Decode time = %dms\n",(tim2-tim1));
printf("PCM done\n");
exit:
// close source file
res = f_close(&m_file[0]);
if(res){
printf("close file (%s) fail.\n", filename);
}
umount:
if(f_mount(NULL, logical_drv, 1) != FR_OK){
printf("FATFS unmount logical drive fail.\n");
}
unreg:
if(FATFS_UnRegisterDiskDriver(drv_num))
printf("Unregister disk driver from FATFS fail.\n");
}
void example_audio_mp3_thread(void* param){
printf("Audio codec demo begin......\n");
i2s_obj.channel_num = NUM_CHANNELS;
i2s_obj.sampling_rate = SAMPLING_FREQ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_TXRX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)i2s_rx_complete, (uint32_t)&i2s_obj);
#if CONFIG_EXAMPLE_MP3_STREAM_SGTL5000
sgtl5000_enable();
sgtl5000_setVolume(0.5);
#else
alc5651_init();
alc5651_init_interface2();
#endif
char wav[16] = FILE_NAME;
audio_play_sd_mp3(wav);
exit:
vTaskDelete(NULL);
}
void example_audio_mp3(void)
{
if(xTaskCreate(example_audio_mp3_thread, ((const char*)"example_audio_mp3_thread"), 2000, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_audio_mp3_thread) failed", __FUNCTION__);
}

View File

@@ -0,0 +1,6 @@
#ifdef _EXAMPLE_AUDIO_H_
#define _EXAMPLE_AUDIO_H_
void example_audio_mp3(void);
#endif

View File

@@ -0,0 +1,301 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform_stdlib.h>
#include "device.h"
#include "diag.h"
#include "main.h"
#include "section_config.h"
#include "osdep_service.h"
#include "dma_api.h"
#include "wifi_conf.h"
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "main.h"
#include "i2s_api.h"
#include "tftp/tftp.h"
//gpio
#include "gpio_api.h" // mbed
#include "gpio_irq_api.h" // mbed
#define GPIO_IRQ_PIN PC_5
//
static i2s_t i2s_obj;
#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096
#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4
static u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
static u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM];
#define I2S_SCLK_PIN PC_1
#define I2S_WS_PIN PC_0
#define I2S_SD_PIN PC_2
typedef struct
{
char fccID[4];
unsigned long dwSize;
unsigned short wFormatTag;
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short uiBitsPerSample;
}WAVE_FMT; //Format Chunk
typedef struct
{
char fccID[4];
unsigned long dwSize;
}WAVE_DATA; //Data Chunk
typedef struct
{
char fccID[4];
unsigned long dwSize;
char fccType[4];
}WAVE_HEAD; //RIFF WAVE Chunk
typedef struct{
WAVE_HEAD w_header;
WAVE_FMT w_fmt;
WAVE_DATA w_data;
}WAVE_HEADER;
#define SDRAM_BSS_SECTION \
SECTION(".sdram.bss")
#define RECORD_LEN (1024*1024) //for record
//#define RECORD_LEN (1024*200)//for check data
unsigned int record_length = 0;
//SDRAM_DATA_SECTION unsigned char record_data[RECORD_LEN]={0};
SDRAM_BSS_SECTION unsigned char record_data[RECORD_LEN];
#define WRITE_FREE 0
#define WRITE_LOCK 1
static unsigned char audio_status = 0;
static unsigned char write_status = 0;
static unsigned char wifi_state = 0;
static unsigned char audio_start = 0;
#define RECORD_WAV_NAME "AMEBA"
#define TFTP_HOST_IP_ADDR "192.168.1.100"
#define TFTP_HOST_PORT 69
#define TFTP_MODE "octet"
_sema VOICE_TRIGGER_SEMA;//INFORM I2S TO RECORD DATA
_sema VOICE_UPLOAD_SEMA;//INFORM TFTP TO UPLOAD DATA
#define INTERNAL_TEST 0
#if INTERNAL_TEST
extern char upgrade_ip[64];
#endif
static void check_wifi_connection()
{
while(1){
vTaskDelay(1000);
#if INTERNAL_TEST
if( wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS && upgrade_ip[0]!=0) {
printf("wifi is connected ip = %s\r\n",upgrade_ip);
wifi_state = 1;
break;
}
#else
if( wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS ){
printf("wifi is connected\r\n");
wifi_state = 1;
break;
}
#endif
}
}
void voice_demo_irq_handler (uint32_t id, gpio_irq_event event)
{
if(wifi_state == 1 && write_status == WRITE_FREE){
audio_start = 1;
rtw_up_sema_from_isr(&VOICE_TRIGGER_SEMA);
}
printf("voice irq = %d\n",audio_start);
}
static void test_tx_complete(void *data, char *pbuf)
{
return ;
}
static void test_rx_complete(void *data, char* pbuf)
{
i2s_t *obj = (i2s_t *)data;
int *ptx_buf;
if((audio_start) == 1 && (write_status == WRITE_FREE)){
if((record_length+I2S_DMA_PAGE_SIZE)<RECORD_LEN){
if(record_length == 0){
_memcpy((void*)(record_data+record_length+sizeof(WAVE_HEADER)),(void*)pbuf,I2S_DMA_PAGE_SIZE);
record_length+=(I2S_DMA_PAGE_SIZE+sizeof(WAVE_HEADER));
}else{
_memcpy((void*)(record_data+record_length),(void*)pbuf,I2S_DMA_PAGE_SIZE);
record_length+=I2S_DMA_PAGE_SIZE;
}
i2s_recv_page(obj);
}else{
write_status = WRITE_LOCK;
printf("write length = %x\r\n",record_length);
rtw_up_sema_from_isr(&VOICE_UPLOAD_SEMA);
}
}
}
void example_audio_init()
{
printf("I2S initial\r\n");
i2s_obj.channel_num = I2S_CH_MONO;
i2s_obj.sampling_rate = SR_48KHZ;
i2s_obj.word_length = WL_16b;
i2s_obj.direction = I2S_DIR_TXRX;
i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN);
i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \
I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE);
i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj);
i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj);
printf("i2s init finish\r\n");
/* rx need clock, let tx out first */
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));
//i2s_recv_page(&i2s_obj);
}
void tftp_audio_send_handler(unsigned char *buffer,int *len,unsigned int index)
{
//static unsigned int total_size = record_length;
int remain_len = record_length -(512*(index-1));
if(remain_len/512){
//memset(buffer,index,512);
memcpy(buffer,record_data+512*(index-1),512);
*len = 512;
}else{
//memset(buffer,index,(total_size%512));
memcpy(buffer,record_data+512*(index-1),remain_len%512);
*len = (record_length%512);
}
//printf("handler = %d size = %d\r\n",total_size,(*len));
}
void tftp_init_audio(tftp *tftp_info)
{
tftp_info->send_handle = tftp_audio_send_handler;
tftp_info->tftp_file_name=RECORD_WAV_NAME;
printf("send file name = %s\r\n",tftp_info->tftp_file_name);
tftp_info->tftp_mode = TFTP_MODE;
tftp_info->tftp_port = TFTP_HOST_PORT;
#if INTERNAL_TEST
tftp_info->tftp_host = upgrade_ip;
#else
tftp_info->tftp_host = TFTP_HOST_IP_ADDR;
#endif
tftp_info->tftp_op = WRQ;//FOR READ OPERATION
tftp_info->tftp_retry_num = 5;
tftp_info->tftp_timeout = 2;//second
printf("tftp retry time = %d timeout = %d seconds\r\n",tftp_info->tftp_retry_num,tftp_info->tftp_timeout);
}
void example_audio_transfer_thread(void* param){
while(1){
rtw_down_sema(&VOICE_TRIGGER_SEMA);
i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj));
i2s_recv_page(&i2s_obj);
printf("start_record_data\r\n");
}
}
void example_audio_pcm_upload_thread(void* param){
WAVE_HEADER w_header;
tftp tftp_info;
static int tftp_count = 0;
memset(&tftp_info,0,sizeof(tftp));
char tftp_filename[64]={0};
strcpy(w_header.w_header.fccID, "RIFF");
strcpy(w_header.w_header.fccType, "WAVE");
strcpy(w_header.w_fmt.fccID, "fmt ");
w_header.w_fmt.dwSize=16;
w_header.w_fmt.wFormatTag=1;
w_header.w_fmt.wChannels=1;
w_header.w_fmt.dwSamplesPerSec=48000;
w_header.w_fmt.dwAvgBytesPerSec=w_header.w_fmt.dwSamplesPerSec*2;
w_header.w_fmt.wBlockAlign=2;
w_header.w_fmt.uiBitsPerSample=16;
strcpy(w_header.w_data.fccID, "data");
rtw_init_sema(&VOICE_TRIGGER_SEMA,0);
rtw_init_sema(&VOICE_UPLOAD_SEMA,0);
//gpio
gpio_irq_t voice_irq;
gpio_t voice_pinr;
printf("GPIO_IRQ\r\n");
check_wifi_connection();
// Initial Push Button pin as interrupt source
gpio_irq_init(&voice_irq, GPIO_IRQ_PIN, voice_demo_irq_handler, (uint32_t)(&voice_pinr));
gpio_irq_set(&voice_irq, IRQ_RISE, 1); // Falling Edge Trigger
gpio_irq_enable(&voice_irq);
//
//tftp
tftp_init_audio(&tftp_info);
//tftp
example_audio_init();
if(xTaskCreate(example_audio_transfer_thread, ((const char*)"example_audio_transfer_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
while(1){
//vTaskDelay(1000);
rtw_down_sema(&VOICE_UPLOAD_SEMA);
if( wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS ) {
wifi_state = 1;
if((write_status == WRITE_LOCK) && audio_start){
printf("wifi connect\r\n");
w_header.w_data.dwSize=36+record_length-sizeof(WAVE_HEADER);
memcpy(record_data,&w_header,sizeof(WAVE_HEADER));
memset(tftp_filename,0,sizeof(tftp_filename));
sprintf(tftp_filename,"%s_%d.wav",RECORD_WAV_NAME,tftp_count);
//sprintf(tftp_filename,"%s_%d.wav",tftp_info.tftp_file_name,tftp_count);
tftp_info.tftp_file_name = tftp_filename;
printf("File name = %s\r\n",tftp_info.tftp_file_name);
if(tftp_client_start(&tftp_info) == 0)
printf("Send file successful\r\n");
else
printf("Send file fail\r\n");
audio_start = 0;
record_length = 0;
write_status = WRITE_FREE;
tftp_count++;
}
}else{
wifi_state = 0;
}
}
}
void example_audio_pcm_upload(void)
{
if(xTaskCreate(example_audio_pcm_upload_thread, ((const char*)"example_audio_pcm_upload_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View File

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

View File

@@ -0,0 +1,11 @@
Audio pcm data upload
Description:
Upload pcm file to TFTP server.
Configuration:
Modify TFTP_HOST_IP_ADDR and RECORD_WAV_NAME in example_audio_pcm_upload.c based on your TFTP server.
[platform_opts.h]
#define CONFIG_EXAMPLE_AUDIO_PCM_UPLOAD 1

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_BROADCAST;
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,86 @@
#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);
if(NULL != iot_json)
free(iot_json);
}
}
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,99 @@
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "platform_stdlib.h"
#include "wifi_constants.h"
#include "wifi_conf.h"
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#include "sn_coap_protocol.h"
#include "sn_coap_ameba_port.h"
#define SERVER_HOST "coap.me"
#define URI_PATH "/hello"
#define SERVER_PORT 5683
#define BUF_LEN 1280 // Suggested is to keep packet size under 1280 bytes
struct coap_s* coapHandle;
coap_version_e coapVersion = COAP_VERSION_1;
uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) {
printf("coap tx cb\n");
return 0;
}
int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) {
printf("coap rx cb\n");
return 0;
}
static void example_coap_thread(void *para){
printf("\nCoAP Client Example\n");
while(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) != RTW_SUCCESS){
printf("Wait for WIFI connection ...\n");
vTaskDelay(1000);
}
// Initialize the CoAP protocol handle, pointing to local implementations on malloc/free/tx/rx functions
coapHandle = coap_protocol_init(&coap_tx_cb, &coap_rx_cb);
// See ns_coap_header.h
sn_coap_hdr_s *coap_res_ptr = (sn_coap_hdr_s*)coap_calloc(1*sizeof(sn_coap_hdr_s));
coap_res_ptr->token_len = 0;
coap_res_ptr->coap_status = COAP_STATUS_OK;
coap_res_ptr->msg_code = COAP_MSG_CODE_REQUEST_GET;
coap_res_ptr->msg_type = COAP_MSG_TYPE_CONFIRMABLE;
coap_res_ptr->content_format = COAP_CT_TEXT_PLAIN;
coap_res_ptr->msg_id = 7;
coap_res_ptr->uri_path_len = strlen(URI_PATH);
coap_res_ptr->payload_len = 0;
coap_res_ptr->token_ptr = NULL;
coap_res_ptr->uri_path_ptr = (uint8_t*)URI_PATH;
coap_res_ptr->payload_ptr = NULL;
coap_res_ptr->options_list_ptr = NULL;
int socket = coap_sock_open();
//send CoAP message
coap_send(SERVER_HOST, SERVER_PORT, socket, coap_res_ptr);
coap_free(coap_res_ptr);
//receive CoAP message
struct sockaddr_in from_address;
uint8_t* recv_buffer = (uint8_t*)coap_calloc(BUF_LEN);
int ret;
while((ret = coap_recv(socket, &from_address, recv_buffer, BUF_LEN)) >= 0)
{
uint32_t ip = from_address.sin_addr.s_addr;
uint8_t bytes[4];
bytes[0] = ip & 0xFF;
bytes[1] = (ip >> 8) & 0xFF;
bytes[2] = (ip >> 16) & 0xFF;
bytes[3] = (ip >> 24) & 0xFF;
printf("\nReceived %d bytes from '%d.%d.%d.%d:%d'\n", ret, bytes[0], bytes[1], bytes[2], bytes[3], from_address.sin_port);
sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion);
coap_print_hdr(parsed);
}
coap_free(recv_buffer);
coap_sock_close(socket);
vTaskDelete(NULL);
}
void example_coap(void)
{
if(xTaskCreate(example_coap_thread, ((const char*)"example_coap_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_COAP_H
#define EXAMPLE_COAP_H
void example_coap(void);
#endif /* EXAMPLE_COAP_H */

View File

@@ -0,0 +1,6 @@
This example demonstrates how to use mbed-CoAP C library to build and parse a CoAP message.
In the example, a confirmable GET request is send to test server "coap.me" to retrieve the resource under path "/hello". The expected return is an ACK message with payload "world".
Note:
Company Firewall may block CoAP message. You can use copper (https://addons.mozilla.org/en-US/firefox/addon/copper-270430/) to test the server's reachability.

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,82 @@
#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
#define DCT_BEGIN_ADDR 0x100000 /*!< DCT begin address of flash, ex: 0x100000 = 1M */
#define MODULE_NUM 6 /*!< max number of module */
#define VARIABLE_NAME_SIZE 32 /*!< max size of the variable name */
#define VARIABLE_VALUE_SIZE 64 /*!< 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];
// initial DCT
ret = dct_init(DCT_BEGIN_ADDR, MODULE_NUM, VARIABLE_NAME_SIZE, VARIABLE_VALUE_SIZE, 1);
// 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,595 @@
/******************************************************************************
*
* 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 defined(CONFIG_EXAMPLE_HTTP2_CLIENT) && CONFIG_EXAMPLE_HTTP2_CLIENT
#include <http2_client/example_http2_client.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_CLIENT
#include <websocket_client/example_wsclient.h>
#endif
#if CONFIG_EXAMPLE_WEBSOCKET_SERVER
#include <websocket_server/example_ws_server.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
#if CONFIG_EXAMPLE_BT_BEACON
#include <bt_beacon/example_bt_beacon.h>
#endif
#if CONFIG_EXAMPLE_BT_CONFIG
#include <bt_config/example_bt_config.h>
#endif
#if CONFIG_EXAMPLE_BT_GATT_CLIENT
#include <bt_gatt_client/example_bt_gatt_client.h>
#endif
#if CONFIG_EXAMPLE_BT_GATT_SERVER
#include <bt_gatt_server/example_bt_gatt_server.h>
#endif
#if CONFIG_EXAMPLE_BT_SPP
#include <bt_spp/example_bt_spp.h>
#endif
#if CONFIG_EXAMPLE_WIFI_ROAMING
#include <wifi_roaming/example_wifi_roaming.h>
#endif
#if CONFIG_EXAMPLE_ALC_DSP_FW_UPGRADE
#include <alc_dsp_fw_upgrade/example_alc_dsp_fw_upgrade.h>
#endif
#if CONFIG_EXAMPLE_AUDIO_PCM_UPLOAD
#include <audio_pcm_upload/example_audio_pcm_upload.h>
#endif
#if CONFIG_EXAMPLE_HTTP_MP3
#include <http_mp3/example_http_mp3.h>
#endif
#if (CONFIG_EXAMPLE_AMAZON_FREERTOS)
#include <amazon_freertos/example_amazon_freertos.h>
#endif
#if (CONFIG_EXAMPLE_AMAZON_AFQP_TESTS)
#include <amazon_afqp_tests/example_amazon_afqp_tests.h>
#endif
#if defined(CONFIG_WIFI_MESH) && CONFIG_WIFI_MESH
#include <rmesh_test.h>
#endif
/*
Preprocessor of example
*/
void pre_example_entry(void)
{
#if CONFIG_EXAMPLE_CM_BACKTRACE
cm_backtrace_init("application", "HW v1.0", "SW v1.0");
#endif
#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 defined(CONFIG_EXAMPLE_HTTP2_CLIENT) && CONFIG_EXAMPLE_HTTP2_CLIENT
example_http2_client();
#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_USB_VENDOR_SPECIFIC
example_vendor_specific();
#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_CLIENT
example_wsclient();
#endif
#if CONFIG_EXAMPLE_WEBSOCKET_SERVER
example_wsserver();
#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
#if CONFIG_EXAMPLE_BT_BEACON
example_bt_beacon();
#endif
#if CONFIG_EXAMPLE_BT_CONFIG
example_bt_config();
#endif
#if CONFIG_EXAMPLE_BT_GATT_CLIENT
example_bt_gatt_client();
#endif
#if CONFIG_EXAMPLE_BT_GATT_SERVER
example_bt_gatt_server();
#endif
#if CONFIG_EXAMPLE_BT_SPP
example_bt_spp();
#endif
#if CONFIG_EXAMPLE_WIFI_ROAMING
example_wifi_roaming();
#endif
#if CONFIG_EXAMPLE_TICKLESS_WIFI_ROAMING
example_tickless_wifi_roaming();
#endif
#if CONFIG_EXAMPLE_ALC_DSP_FW_UPGRADE
example_alc_dsp_fw_upgrade();
#endif
#if CONFIG_EXAMPLE_AUDIO_PCM_UPLOAD
example_audio_pcm_upload();
#endif
#if CONFIG_EXAMPLE_HTTP_MP3
example_http_mp3();
#endif
#if CONFIG_GREE
example_gree();
#endif
#if (CONFIG_EXAMPLE_AMAZON_FREERTOS)
example_amazon_freertos();
#endif
#if (CONFIG_EXAMPLE_AMAZON_AFQP_TESTS)
example_amazon_afqp_tests();
#endif
#if CONFIG_EXAMPLE_ANDLINK
example_andlink();
#endif
#if CONFIG_EXAMPLE_BT8752
example_wifi_over_8752();
#endif
#if CONFIG_EXAMPLE_S3_UPLOAD
example_s3_upload();
#endif
#if defined(CONFIG_RIC) && (CONFIG_RIC == 1)
extern void example_ric(void);
example_ric();
#endif
#if defined(CONFIG_WIFI_MESH) && CONFIG_WIFI_MESH
// example_rmesh();
rmesh_enter_net_config_test();
#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,171 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "basic_types.h"
#include "platform_opts.h"
#include "section_config.h"
#if CONFIG_FATFS_EN
#include "ff.h"
#include <fatfs_ext/inc/ff_driver.h>
#if FATFS_DISK_USB
#include "usb.h"
#include <disk_if/inc/usbdisk.h>
#elif FATFS_DISK_SD
#include "sdio_host.h"
#include <disk_if/inc/sdcard.h>
#endif
#define TEST_SIZE (512)
u8 test_info[]="\"Ameba memory card test information: Hello world.\"";
SRAM_BF_DATA_SECTION u8 WRBuf[TEST_SIZE];
SRAM_BF_DATA_SECTION u8 RDBuf[TEST_SIZE];
void example_fatfs_thread(void* param){
int drv_num = 0;
int Fatfs_ok = 0;
FRESULT res;
FATFS m_fs;
FIL m_file;
char logical_drv[4]; /* root diretor */
char path[64];
char filename[64] = "TEST.TXT";
int br,bw;
int test_result = 1;
int ret = 0;
//1 init disk drive
printf("Init Disk driver.\n");
#if FATFS_DISK_USB
_usb_init();
ret = wait_usb_ready();
if(ret != USB_INIT_OK){
if(ret == USB_NOT_ATTACHED)
printf("\r\n NO USB device attached\n");
else
printf("\r\n USB init fail\n");
goto exit;
}
#elif FATFS_DISK_SD
// Set sdio debug level
DBG_INFO_MSG_OFF(_DBG_SDIO_);
DBG_WARN_MSG_OFF(_DBG_SDIO_);
DBG_ERR_MSG_ON(_DBG_SDIO_);
if(sdio_init_host()!=0){
printf("SDIO host init fail.\n");
goto exit;
}
#endif
//1 register disk driver to fatfs
printf("Register disk driver to Fatfs.\n");
#if FATFS_DISK_USB
drv_num = FATFS_RegisterDiskDriver(&USB_disk_Driver);
#elif FATFS_DISK_SD
drv_num = FATFS_RegisterDiskDriver(&SD_disk_Driver);
#endif
if(drv_num < 0){
printf("Rigester disk driver to FATFS fail.\n");
}else{
Fatfs_ok = 1;
logical_drv[0] = drv_num + '0';
logical_drv[1] = ':';
logical_drv[2] = '/';
logical_drv[3] = 0;
}
//1 Fatfs write and read test
if(Fatfs_ok){
printf("FatFS Write/Read test begin......\n\n");
if(f_mount(&m_fs, logical_drv, 1)!= FR_OK){
printf("FATFS mount logical drive fail.\n");
goto fail;
}
// write and read test
strcpy(path, logical_drv);
sprintf(&path[strlen(path)],"%s",filename);
//Open source file
res = f_open(&m_file, path, FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res){
printf("open file (%s) fail.\n", filename);
goto fail;
}
printf("Test file name:%s\n\n",filename);
// clean write and read buffer
memset(&WRBuf[0], 0x00, TEST_SIZE);
memset(&RDBuf[0], 0x00, TEST_SIZE);
strcpy(&WRBuf[0], &test_info[0]);
do{
res = f_write(&m_file, WRBuf, strlen(WRBuf), (u32*)&bw);
if(res){
f_lseek(&m_file, 0);
printf("Write error.\n");
}
printf("Write %d bytes.\n", bw);
} while (bw < strlen(WRBuf));
printf("Write content:\n%s\n", WRBuf);
printf("\n");
/* move the file pointer to the file head*/
res = f_lseek(&m_file, 0);
do{
res = f_read(&m_file, RDBuf, strlen(WRBuf), (u32*)&br);
if(res){
f_lseek(&m_file, 0);
printf("Read error.\n");
}
printf("Read %d bytes.\n", br);
}while(br < strlen(WRBuf));
printf("Read content:\n%s\n", RDBuf);
// close source file
res = f_close(&m_file);
if(res){
printf("close file (%s) fail.\n", filename);
}
//
if(f_mount(NULL, logical_drv, 1) != FR_OK){
printf("FATFS unmount logical drive fail.\n");
}
if(FATFS_UnRegisterDiskDriver(drv_num))
printf("Unregister disk driver from FATFS fail.\n");
}
fail:
#if FATFS_DISK_USB
// deinit usb driver
#elif FATFS_DISK_SD
sdio_deinit_host();
#endif
exit:
vTaskDelete(NULL);
}
void example_fatfs(void)
{
if(xTaskCreate(example_fatfs_thread, ((const char*)"example_fatfs_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_fatfs_thread) failed", __FUNCTION__);
}
#endif

View File

@@ -0,0 +1,7 @@
#ifndef _EXAMPLE_FATFS_H
#define _EXAMPLE_FATFS_H
void example_fatfs(void);
#endif /* _EXAMPLE_FATFS_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,38 @@
<html>
<head>
<script src="https://cdn.firebase.com/js/client/2.1.1/firebase.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<h1>Realtek Google Nest API example</h1>
<hr />
<h3 style="text-align:center;margin-left:auto;margin-right:auto;">Data To Device</h3>
<h4>Input the value of RGB to change the state of light:</h4>
<p>Red <input type="text" id="redInput" placeholder="Red" />
Green <input type="text" id="greenInput" placeholder="Green" />
Blue <input type="text" id="blueInput" placeholder="Blue" />
<input type="button" value="submit" name="submit" onClick="submit()" />
</p>
<script>
var myDataRef = new Firebase('https://your_firebase_address.firebaseio.com/light');
function submit()
{
var red = $('#redInput').val();
var green = $('#greenInput').val();
var blue = $('#blueInput').val();
myDataRef.set({
Red: red,
Green: green,
Blue: blue
});
};
</script>
</body>
</html>

View File

@@ -0,0 +1,240 @@
#include "cmsis_os.h"
#include "diag.h"
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "google/google_nest.h"
#include <googlenest/example_google.h>
#include "cJSON.h"
osThreadId google_thread_id;
#define malloc pvPortMalloc
#define free vPortFree
void google_data_retrieve(char *response_buf);
void google_data_retrieve(char *response_buf) {
//printf("\r\n\r\n\r\nResponse_buf:\r\n%s\r\n", response_buf);
char *event = NULL;
char *delims = "\n";
char *data = NULL, *backup = NULL;
char *info = NULL;
cJSON_Hooks memoryHook;
event = strtok_r(response_buf, delims, &backup);
data = strtok_r( NULL, delims, &backup );
if (!strncmp(data, "data: ", strlen("data: "))){
info = data + strlen("data: ");
if(info != NULL){
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
cJSON *infoJSObject, *pathJSObject, *dataJSObject;
cJSON *redJSObject, *greenJSObject, *blueJSObject;
char *red, *green, *blue;
if((infoJSObject = cJSON_Parse(info)) != NULL) {
pathJSObject = cJSON_GetObjectItem(infoJSObject, "path");
dataJSObject = cJSON_GetObjectItem(infoJSObject, "data");
if(dataJSObject != NULL) {
redJSObject = cJSON_GetObjectItem(dataJSObject, "Red");
greenJSObject = cJSON_GetObjectItem(dataJSObject, "Green");
blueJSObject = cJSON_GetObjectItem(dataJSObject, "Blue");
if(redJSObject)
red = redJSObject->valuestring;
if(greenJSObject)
green = greenJSObject->valuestring;
if(blueJSObject)
blue = blueJSObject->valuestring;
printf("\n\rThe latest RGB information: RGB(%s, %s, %s)\n\r", red, green, blue);
cJSON_Delete(dataJSObject);
}
cJSON_Delete(infoJSObject);
}
else
printf("\r\nCannot parse the message to JSON!\r\n");
}
else
printf("\r\n This is the keep alive message or cannot get the information!\r\n");
}
else
printf("\r\nData structure may wrong!\r\n");
}
void gn_todevice_start(void) {
googlenest_context googlenest;
char *googlenest_host = HOST_ADDR;
char *googlenest_uri = "light.json";
printf("\r\nStart connecting to Google Nest Server...\r\n");
memset(&googlenest, 0, sizeof(googlenest_context));
reconnect:
if(gn_connect(&googlenest, googlenest_host, GN_PORT) == 0) {
printf("\r\n Connection is OK!\r\n");
google_retrieve_data_hook_callback(google_data_retrieve);
if(gn_stream(&googlenest, googlenest_uri) != 0){
printf("\r\n Connection is fail! \r\n Start Reconnecting...\r\n");
goto reconnect;
}
gn_close(&googlenest);
}
else{
printf("\r\n Connection is fail! \r\n\r\n\r\n\r\nStart Reconnecting...\r\n");
goto reconnect;
}
}
void gn_fromdevice_start(int type) {
googlenest_context googlenest;
char *googlenest_uri_1 = "MotionSensor.json";
char *googlenest_uri_2 = ".json";
cJSON_Hooks memoryHook;
int j = 0;
char a[3],b[3],c[3];
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
printf("\r\nStart connecting to Google Nest Server to update data!\r\n");
while(1) {
memset(&googlenest, 0, sizeof(googlenest_context));
if(gn_connect(&googlenest, HOST_ADDR, GN_PORT) == 0) {
char *data;
//For the example "From Device"
if(type == 1){
cJSON *MSJSObject;
if((MSJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(MSJSObject, "MotionSensor", cJSON_CreateNumber(j++));
data = cJSON_Print(MSJSObject);
cJSON_Delete(MSJSObject);
}
if(gn_put(&googlenest, googlenest_uri_1, data) == 0)
printf("\n\rUpdate the Motion Sensor's data to %d\n\r", (j-1));
}
//For the example "BOTH"
else if(type == 2){
cJSON *dataJSObject, *lightJSObject, *MSJSObject;
if((j+4)>256)
j = 0;
sprintf(a,"%d", j);
sprintf(b,"%d", (j+2));
sprintf(c,"%d", (j+4));
if((dataJSObject = cJSON_CreateObject()) != NULL) {
if((lightJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(dataJSObject, "light", lightJSObject);
cJSON_AddItemToObject(lightJSObject, "Red", cJSON_CreateString(a));
cJSON_AddItemToObject(lightJSObject, "Green", cJSON_CreateString(b));
cJSON_AddItemToObject(lightJSObject, "Blue", cJSON_CreateString(c));
}
if((MSJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(dataJSObject, "MotionSensor", MSJSObject);
cJSON_AddItemToObject(MSJSObject, "MotionSensor", cJSON_CreateNumber(j++));
}
data = cJSON_Print(dataJSObject);
cJSON_Delete(dataJSObject);
}
if(gn_put(&googlenest, googlenest_uri_2, data) == 0)
printf("\n\rUpdate data OK\r\n");
}
free(data);
gn_close(&googlenest);
}
else{
printf("\n\rConnection failed!\n\r");
break;
}
vTaskDelay(5 * configTICK_RATE_HZ);
}
}
void gn_fromdevice_task(void *arg) {
int i, j = 1;
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 2 mins to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
for (i = 0; i<120; i++)
vTaskDelay(1000 / portTICK_PERIOD_MS);
gn_fromdevice_start(j);
}
void gn_todevice_task(void *arg) {
int i;
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 2 mins to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
for (i = 0; i<120; i++)
vTaskDelay(1000 / portTICK_PERIOD_MS);
gn_todevice_start();
}
void gn_both_fromdevice_task(void *arg) {
int i, j = 2;
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 2 mins to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
for (i = 0; i<120; i++)
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("\n\r\n\r\n\r\n\r<<<<<<Starting update data to Google Nest Server>>>>>>>\n\r\n\r\n\r\n\r");
gn_fromdevice_start(j);
}
void gn_both_todevice_task(void *arg) {
int i;
for (i = 0; i<150; i++)
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("\n\r\n\r\n\r\n\r<<<<<<Starting retrieving data from Google Nest Server>>>>>>>\n\r\n\r\n\r\n\r");
gn_todevice_start();
}
void example_google(char *type) {
if(strcmp(type, "FromDevice") == 0){
if(xTaskCreate(gn_fromdevice_task, ((const char*)"gn_fromdevice_task"), 768, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
else if(strcmp(type, "ToDevice") == 0){
if(xTaskCreate(gn_todevice_task, ((const char*)"gn_todevice_task"), 1000, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
else if(strcmp(type, "BOTH") == 0){
if(xTaskCreate(gn_both_fromdevice_task, ((const char*)"gn_both_fromdevice_task"), 768, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
if(xTaskCreate(gn_both_todevice_task, ((const char*)"gn_both_todevice_task"), 1000, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
}

View File

@@ -0,0 +1,10 @@
#ifndef GOOGLE_THREAD_H
#define GOOGLE_THREAD_H
#define HOST_ADDR "your_firebase_address.firebaseio.com"
#define GN_PORT 443
void example_google(char *type);
#endif

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 "176.34.62.248"
#define SERVER_PORT 80
#define RESOURCE "/repository/IOT/Project_Cloud_A.bin"
#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,149 @@
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "basic_types.h"
#include "platform_opts.h"
#if CONFIG_EXAMPLE_INIC_GSPI_HOST
#include "src/include/autoconf.h"
#include "lwip_netconf.h"
#include "freertos/inic_intf.h"
#include "spi_api.h"
#include "spi_ex_api.h"
#ifdef CONFIG_RTL8711B
#define SPI0_MOSI PA_23
#define SPI0_MISO PA_22
#define SPI0_SCLK PA_18
#define SPI0_CS PA_19 // This pin is redundant
#define GPIO_CS PA_19
#else
// SPI0
#define SPI0_MOSI PC_2
#define SPI0_MISO PC_3
#define SPI0_SCLK PC_1
#define SPI0_CS PC_0 // This pin is redundant
#define GPIO_CS PB_2
#endif
#define SPI0_FREQUENCY 20000000
// SPI master configuration
#define SPI_BITS 8 // Ameba SPI support 8bits and 16bits mode
static spi_t spi0_master;
static gpio_t gpio_cs;
volatile bool txDone = FALSE;
volatile bool rxDone = FALSE;
volatile bool txbusIdle = FALSE;
#define SLAVE_SELECT() gpio_write(&gpio_cs, 0)
#define SLAVE_DESELECT() gpio_write(&gpio_cs, 1)
int spi_transfer(uint8_t* buf, uint32_t buf_len)
{
int i = 0;
int ret = 0;
SLAVE_SELECT();
txbusIdle = FALSE; // ensure TX done
rxDone = FALSE; // ensure RX done
if(spi_master_write_read_stream(&spi0_master, buf, buf, buf_len)!=0x00){
ret = -1;
}else{
while((!txbusIdle) || (!rxDone)){
wait_ms(1);
if (++i > 2000) {
printf("SPI write and read Timeout...\r\n");
break;
}
}
}
/* Chip Select Pull High */
SLAVE_DESELECT();
return ret;
}
// SPI master interrupt callback if use interrupt mode
void spi_tx_rx_intr_callback(void *pdata, SpiIrq event){
switch(event){
case SpiRxIrq:
rxDone = TRUE;
break;
case SpiTxIrq:
txDone = TRUE;
break;
default:
printf("unknown interrput evnent!\n");
}
}
void spi_tx_bus_idle_callback(void *pdata, SpiIrq event){
txbusIdle = TRUE;
}
void spi_init_master(){
// init spi master
#ifdef CONFIG_RTL8711B
spi0_master.spi_idx=MBED_SPI1;
#endif
spi_init(&spi0_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
spi_format(&spi0_master, SPI_BITS, 0, 0);
spi_frequency(&spi0_master, SPI0_FREQUENCY);
printf("spi master frequency %d Hz\n",SPI0_FREQUENCY);
// init spi master tx/rx done interrupt
spi_irq_hook(&spi0_master, (spi_irq_handler)spi_tx_rx_intr_callback, NULL);
// init spi master tx bus idle interrupt
spi_bus_tx_done_irq_hook(&spi0_master, (spi_irq_handler)spi_tx_bus_idle_callback, NULL);
gpio_init(&gpio_cs, GPIO_CS);
gpio_mode(&gpio_cs, PullDown);
gpio_dir(&gpio_cs, PIN_OUTPUT);
SLAVE_DESELECT(); // deselect slave
}
void example_inic_gspi_thread(void* param){
int ret;
char pbuf_SSID[] = "ATW0=bonjour"; // set your own SSID
char pbuf_PASS[] = "****"; // set password
char pbuf_CONN[] = "ATWC";
printf("iNIC master example start...\n");
/* init host spi contorller */
spi_init_master();
/* init inic driver */
ret = rltk_inic_init();
if(ret == 0){// inic init successfully
rltk_inic_start();
}
/* start io control test*/
// set SSID
atcmd_ctl(pbuf_SSID, sizeof(pbuf_SSID));
// set password
//atcmd_ctl(pbuf_PASS, sizeof(pbuf_PASS));
// start connecttion
atcmd_ctl(pbuf_CONN, sizeof(pbuf_CONN));
fail:
vTaskDelete(NULL);
}
void example_inic_gspi(void)
{
if(xTaskCreate(example_inic_gspi_thread, ((const char*)"example_inic_gspi_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_inic_gspi_thread) failed", __FUNCTION__);
}
#endif

View File

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

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,65 @@
#include "FreeRTOS.h"
#include "task.h"
#include "example_media_audio_from_rtp.h"
#include "mmf_source.h"
#include "mmf_sink.h"
void example_media_audio_from_rtp_main(void* param)
{
int con = 1;
msink_context *msink_ctx;
msrc_context *msrc_ctx;
xQueueHandle src2sink_qid;
xQueueHandle sink2src_qid;
src2sink_qid = xQueueCreate(3, sizeof(exch_buf_t));
sink2src_qid = xQueueCreate(3, sizeof(exch_buf_t));
// open and setup stream
#if CONFIG_EXAMPLE_MP3_STREAM_RTP
if( (msink_ctx = mmf_sink_open(&mp3_sink_module))==NULL)
goto fail;
mmf_sink_ctrl(msink_ctx, CMD_SET_INPUT_QUEUE, (int)src2sink_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_OUTPUT_QUEUE, (int)sink2src_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_STREAMMING, ON);
mmf_sink_ctrl(msink_ctx, CMD_SET_TASK_ON, 512);
#else
if( (msink_ctx = mmf_sink_open(&i2s_sink_module))==NULL)
goto fail;
mmf_sink_ctrl(msink_ctx, CMD_SET_INPUT_QUEUE, (int)src2sink_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_OUTPUT_QUEUE, (int)sink2src_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_STREAMMING, ON);
mmf_sink_ctrl(msink_ctx, CMD_SET_TASK_ON, 0);
#endif
if((msrc_ctx = mmf_source_open(&rtp_src_module))==NULL)
goto fail;
mmf_source_ctrl(msrc_ctx, CMD_SET_PRIV_BUF, 1);
mmf_source_ctrl(msrc_ctx, CMD_SET_INPUT_QUEUE, (int)sink2src_qid);
mmf_source_ctrl(msrc_ctx, CMD_SET_OUTPUT_QUEUE, (int)src2sink_qid);
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, ON);
mmf_source_ctrl(msrc_ctx, CMD_SET_TASK_ON, 0);
while(con)
{
vTaskDelay(100);
}
mmf_sink_ctrl(msink_ctx, CMD_SET_STREAMMING, OFF);
mmf_source_ctrl(msrc_ctx, CMD_SET_PRIV_BUF, 0);
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, OFF);
fail:
mmf_sink_close(msink_ctx);
mmf_source_close(msrc_ctx);
vTaskDelete(NULL);
}
void example_media_audio_from_rtp(void)
{
/*user can start their own task here*/
if(xTaskCreate(example_media_audio_from_rtp_main, ((const char*)"example_media_audio_from_rtp_main"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) {
printf("\r\n example_media_audio_from_rtp_main: Create Task Error\n");
}
}

View File

@@ -0,0 +1,8 @@
#ifndef EXAMPLE_MEDIA_AUDIO_FROM_RTP_H
#define EXAMPLE_MEDIA_AUDIO_FROM_RTP_H
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "osdep_api.h"
void example_media_geo_rtp(void);
#endif

View File

@@ -0,0 +1,13 @@
--This example is contributed by Ian--
In order to test this example, you can utilize vlc rtp streaming feature to feed pcmu data for ameba to play audio.
For better wlan performance please make the following modification before compiling this example:
in lwipopts.h,
PBUF_POOL_SIZE 20 => 40 (just an example)
PBUF_POOL_BUFSIZE 500 => 250
DEFAULT_UDP_RECVMBOX_SIZE 6 => 24 (just an example)
in opt.h,
MEMP_NUM_NETBUF 2 => 24 (just an example)
TCPIP_MBOX_SIZE 6 => 6 (just an example)

View File

@@ -0,0 +1,161 @@
/*
* uvc video capture example
*/
#include "FreeRTOS.h"
#include "task.h"
#include "example_media_ss.h"
#include "mmf_source.h"
#include "mmf_sink.h"
// select source
#define SRC_UVC 1
#define SRC_MJPG_FILE 0
#define SRC_H264_FILE 0
#define SRC_H264_UNIT 0
#define SRC_AAC_FILE 0
#define SRC_PCMU_FILE 0
#define SRC_I2S 0
//---------------------------------------------------------------------------------------
void example_media_ss_main(void *param)
{
rtw_mdelay_os(1000);
int con = 100;
msink_context *msink_ctx;
msrc_context *msrc_ctx;
xQueueHandle src2sink_qid;
xQueueHandle sink2src_qid;
src2sink_qid = xQueueCreate(2, sizeof(exch_buf_t));
sink2src_qid = xQueueCreate(2, sizeof(exch_buf_t));
// open and setup stream
if( (msink_ctx = mmf_sink_open(&rtsp_module))==NULL)
goto fail;
//audio will ignore these settings
mmf_sink_ctrl(msink_ctx, CMD_SET_FRAMERATE, 30);
mmf_sink_ctrl(msink_ctx, CMD_SET_BITRATE, 0);
#if SRC_UVC==1 || SRC_MJPG_FILE==1
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_V_MJPG);
#elif SRC_H264_FILE==1
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_V_H264);
mmf_sink_ctrl(msink_ctx, CMD_SET_SPS,(int)"Z0LADZp0BsHvN4CIAAADAAgAAAMBlHihVQ==");
mmf_sink_ctrl(msink_ctx, CMD_SET_PPS,(int)"aM48gA==");
mmf_sink_ctrl(msink_ctx, CMD_SET_LEVEL,(int)"42c00d");
#elif SRC_H264_UNIT==1
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_V_H264);
mmf_sink_ctrl(msink_ctx, CMD_SET_SPS,(int)"Z0LADZp0BsHvN4CIAAADAAgAAAMBlHihVQ==");
mmf_sink_ctrl(msink_ctx, CMD_SET_PPS,(int)"aM48gA==");
mmf_sink_ctrl(msink_ctx, CMD_SET_LEVEL,(int)"42c00d");
#elif SRC_AAC_FILE==1
mmf_sink_ctrl(msink_ctx, CMD_SET_SAMPLERATE, 44100);
mmf_sink_ctrl(msink_ctx, CMD_SET_CHANNEL, 2);
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_A_MP4A_LATM);
#elif SRC_PCMU_FILE==1
mmf_sink_ctrl(msink_ctx, CMD_SET_SAMPLERATE, 8000);
mmf_sink_ctrl(msink_ctx, CMD_SET_CHANNEL, 1);
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_A_PCMU);
#elif SRC_I2S==1
mmf_sink_ctrl(msink_ctx, CMD_SET_SAMPLERATE, 8000);
mmf_sink_ctrl(msink_ctx, CMD_SET_CHANNEL, 1);
mmf_sink_ctrl(msink_ctx, CMD_SET_CODEC, FMT_A_PCMA);
#else
#error NO SINK FORMAT
#endif
//apply all above setting
mmf_sink_ctrl(msink_ctx, CMD_SET_APPLY, 0);
mmf_sink_ctrl(msink_ctx, CMD_SET_INPUT_QUEUE, (int)src2sink_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_OUTPUT_QUEUE, (int)sink2src_qid);
mmf_sink_ctrl(msink_ctx, CMD_SET_STREAMMING, ON);
mmf_sink_ctrl(msink_ctx, CMD_SET_TASK_ON, 0);
// open and setup media
#if SRC_UVC==1
if((msrc_ctx = mmf_source_open(&uvc_module))==NULL)
#elif SRC_MJPG_FILE==1
if((msrc_ctx = mmf_source_open(&mjpgf_module))==NULL)
#elif SRC_H264_FILE==1
if((msrc_ctx = mmf_source_open(&h264f_module))==NULL)
#elif SRC_H264_UNIT==1
if((msrc_ctx = mmf_source_open(&h264_unit_module))==NULL)
#elif SRC_AAC_FILE==1
if((msrc_ctx = mmf_source_open(&aacf_module))==NULL)
#elif SRC_PCMU_FILE==1
if((msrc_ctx = mmf_source_open(&pcmuf_module))==NULL)
#elif SRC_I2S==1
if((msrc_ctx = mmf_source_open(&i2s_module))==NULL)
#else
#error NO SOURCE SELECTED
if(1)
#endif
goto fail;
mmf_source_ctrl(msrc_ctx, CMD_SET_FRAMETYPE, FMT_V_MJPG);
mmf_source_ctrl(msrc_ctx, CMD_SET_HEIGHT, 480);
mmf_source_ctrl(msrc_ctx, CMD_SET_WIDTH, 640);
mmf_source_ctrl(msrc_ctx, CMD_SET_FRAMERATE, 30);
mmf_source_ctrl(msrc_ctx, CMD_SET_CPZRATIO, 0);
mmf_source_ctrl(msrc_ctx, CMD_SET_APPLY, 0);
mmf_source_ctrl(msrc_ctx, CMD_SET_INPUT_QUEUE, (int)sink2src_qid);
mmf_source_ctrl(msrc_ctx, CMD_SET_OUTPUT_QUEUE, (int)src2sink_qid);
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, ON);
mmf_source_ctrl(msrc_ctx, CMD_SET_TASK_ON, 0);
//disable wifi power save
wifi_disable_powersave();
#if 0
while(1){
mmf_source_get_frame(msrc_ctx, &exbuf[0]);
mmf_sink_put_frame(msink_ctx, &exbuf[0]);
vTaskDelay(33);
}
#endif
// int toggle = 1;
// TODO: exit condition or signal
while(con)
{
vTaskDelay(1000);
#if 0
con--;
if(con == 1)
{
con = 100;
if(toggle>0)
{
mmf_sink_ctrl(msink_ctx, CMD_SET_TASK_FROZEN, 0);
mmf_source_ctrl(msrc_ctx, CMD_SET_TASK_FROZEN, 0);
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, OFF);
}else{
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, ON);
mmf_source_ctrl(msrc_ctx, CMD_SET_TASK_ON, 0);
mmf_sink_ctrl(msink_ctx, CMD_SET_TASK_ON, 0);
}
toggle *= -1;
}
#endif
//if(con <= 0)
// break;
}
mmf_sink_ctrl(msink_ctx, CMD_SET_STREAMMING, OFF);
mmf_source_ctrl(msrc_ctx, CMD_SET_STREAMMING, OFF);
fail:
mmf_sink_close(msink_ctx);
mmf_source_close(msrc_ctx);
vTaskDelete(NULL);
}
void example_media_ss(void)
{
/*user can start their own task here*/
if(xTaskCreate(example_media_ss_main, ((const char*)"example_media_ss"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) {
printf("\r\n example_media_ss_main: Create Task Error\n");
}
}
/************************************************************end of rtsp/rtp with motion-jpeg************************************************/

View File

@@ -0,0 +1,10 @@
#ifndef EXAMPLE_MEDIA_SS_H
#define EXAMPLE_MEDIA_SS_H
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "osdep_api.h"
void example_media_ss(void);
#endif /* EXAMPLE_MEDIA_SS_H */

View File

@@ -0,0 +1,6 @@
THis is an example for USB Video Capture specifically for motion-jpeg capturing.
Please MAKE SURE to reserve enough heap size for UVC by raising configTOTAL_HEAP_SIZE in freeRTOSconfig.h & turning off some functions (e.g. WPS, JDSMART, ATcmd for internal and system) since image frame storing could consume quite large memory space.
You may switch to UVC workspace to run the example for all settings has been made for you to run example well.

View File

@@ -0,0 +1,188 @@
/*
* uvc video capture example
*/
#include "example_media_tl.h"
#include "mjpeg2jpeg.h"
#include "ff.h"
#include <fatfs_ext/inc/ff_driver.h>
#include "sdio_host.h"
#include <disk_if/inc/sdcard.h>
void example_tl_fatfs_thread(unsigned char* write_buf, const int write_buf_len, const int iter){
u8 *tl_WRBuf;
const int sizeof_write_buf = ( write_buf_len*(sizeof(u8)) );
tl_WRBuf = (u8*)malloc(sizeof_write_buf);
int drv_num = 0;
int Fatfs_ok = 0;
FRESULT res;
FATFS m_fs;
FIL m_file;
char logical_drv[4]; /* root diretor */
char f_num[15];
sprintf(f_num, "%d", iter);
char filename[64] = "img";
strcat(filename,f_num);
strcat(filename,".jpeg");
char path[64];
int bw;
int test_result = 1;
// Set sdio debug level
DBG_INFO_MSG_OFF(_DBG_SDIO_);
DBG_WARN_MSG_OFF(_DBG_SDIO_);
DBG_ERR_MSG_ON(_DBG_SDIO_);
if(sdio_init_host()!=0){
printf("SDIO host init fail.\n");
exit(NULL);
}
//1 register disk driver to fatfs
drv_num = FATFS_RegisterDiskDriver(&SD_disk_Driver);
if(drv_num < 0)
printf("Rigester disk driver to FATFS fail.\n");
else{
Fatfs_ok = 1;
logical_drv[0] = drv_num + '0';
logical_drv[1] = ':';
logical_drv[2] = '/';
logical_drv[3] = 0;
}
//1 Fatfs write
if(Fatfs_ok){
if(f_mount(&m_fs, logical_drv, 1)!= FR_OK){
printf("FATFS mount logical drive fail.\n");
goto fail;
}
// write and read test
strcpy(path, logical_drv);
sprintf(&path[strlen(path)],"%s",filename);
//Open source file
res = f_open(&m_file, path, FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res){
printf("open file (%s) fail.\n", filename);
goto fail;
}
printf("Test file name:%s\n\n",filename);
DWORD size;
size = (&m_file)->fsize;
res = f_lseek(&m_file,size);
if(res){
f_lseek(&m_file, 0);
printf("file Seek error.\n");
}
// clean write and read buffer
memset(tl_WRBuf, 0x00, write_buf_len);
memcpy(tl_WRBuf, write_buf, write_buf_len);
do{
res = f_write(&m_file, tl_WRBuf, sizeof_write_buf, (u32*)&bw);
if(res){
f_lseek(&m_file, 0);
printf("Write error.\n");
}
printf("Write %d bytes.\n", bw);
} while (bw < strlen(tl_WRBuf));
// close source file
res = f_close(&m_file);
if(res)
printf("close file (%s) fail.\n", filename);
if(f_mount(NULL, logical_drv, 1) != FR_OK)
printf("FATFS unmount logical drive fail.\n");
if(FATFS_UnRegisterDiskDriver(drv_num))
printf("Unregister disk driver from FATFS fail.\n");
}
fail:
sdio_deinit_host();
free(tl_WRBuf);
}
void example_media_tl_main(void *param)
{
printf("\r\n Enter Timelapse Example\n");
int err = 0;
/*init usb driver prior to init uvc driver*/
_usb_init();
if(wait_usb_ready() < 0){
printf("\n USB Not Ready \n");
exit(NULL);
}
/*init uvc driver*/
if(uvc_stream_init() < 0){
printf("\n Unable to initialize UVC Stream \n");
exit(NULL);
}
struct uvc_context *uvc_ctx = malloc(sizeof(struct uvc_context)); //Creation of UVC Context
if(!uvc_ctx){
printf("\n UVC Context Creation Failed \n");
exit(NULL);
}
/* Set UVC Parameters */
uvc_ctx->fmt_type = UVC_FORMAT_MJPEG;
uvc_ctx->width = 640;
uvc_ctx->height = 480;
uvc_ctx->frame_rate = 30;
uvc_ctx->compression_ratio = 50;
if(uvc_set_param(uvc_ctx->fmt_type, &uvc_ctx->width, &uvc_ctx->height, &uvc_ctx->frame_rate, &uvc_ctx->compression_ratio) < 0){
printf("\n UVC Set Parameters Failed \n");
exit(NULL);
}
if(uvc_stream_on() < 0){
printf("\n Unable to turn on UVC Stream\n");
exit(NULL);
}
err = -EAGAIN;
register int iter = 0;
int ret = 0;
struct uvc_buf_context buf; /* Global, need to change*/
/*Creating AV Packet for conversion*/
AVFrame in_Frame;
do{
ret = uvc_dqbuf(&buf);
if(buf.index < 0){
printf("\r\n dequeue fail\n");
err = -EAGAIN;
}
if((uvc_buf_check(&buf)<0)||(ret < 0)){
printf("\n\rbuffer error!");
uvc_stream_off();
err = -EIO; // should return error
}
in_Frame.FrameData = (char*)buf.data;
in_Frame.FrameLength = buf.len;
mjpeg2jpeg(&in_Frame);
example_tl_fatfs_thread(in_Frame.FrameData, in_Frame.FrameLength, iter);
ret = uvc_qbuf(&buf);
++iter;
vTaskDelay(2000);
}while( (err == -EAGAIN) );
/*Close UVC Stream */
uvc_stream_free();
/* Free UVC Context */
free((struct uvc_context *)uvc_ctx);
/* De-initialize USB */
_usb_deinit();
/*Delete Task */
vTaskDelete(NULL);
}
void example_media_tl(void)
{
/*user can start their own task here*/
if(xTaskCreate(example_media_tl_main, ((const char*)"example_media_tl"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) {
printf("\r\n example_media_tl_main: Create Task Error\n");
}
}
/************************************************************end of rtsp/rtp with motion-jpeg************************************************/

View File

@@ -0,0 +1,27 @@
#ifndef EXAMPLE_MEDIA_TL_H
#define EXAMPLE_MEDIA_TL_H
#include "mmf_source.h"
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "osdep_api.h"
#include "basic_types.h"
#include "section_config.h"
#include "videodev2.h"
#include "uvcvideo.h"
#include "v4l2_driver.h"
#include "uvc_intf.h"
void example_media_tl(void);
void example_media_tl_main(void *param);
int uvc_tl_mod_handle(int);
int uvc_tl_mod_set_param(void* ctx, int cmd, int arg);
void uvc_tl_mod_close(void* ctx);
void* uvc_tl_mod_open(void);
#endif /* EXAMPLE_MEDIA_SS_H */

View File

@@ -0,0 +1,3 @@
c:\ffmpeg.exe -i img%%d.JPEG -f image2 final%%d.png
c:\ffmpeg.exe -framerate 30 -i final%%d.png -vf fps=30 -pix_fmt yuv420p output.mp4
del /s *.png

View File

@@ -0,0 +1,6 @@
THis is an example for USB Video Capture specifically for motion-jpeg capturing.
Please MAKE SURE to reserve enough heap size for UVC by raising configTOTAL_HEAP_SIZE in freeRTOSconfig.h & turning off some functions (e.g. WPS, JDSMART, ATcmd for internal and system) since image frame storing could consume quite large memory space.
You may switch to UVC workspace to run the example for all settings has been made for you to run example well.

View File

@@ -0,0 +1,195 @@
/* 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
static 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";
int port = 1883;
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, port, 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,39 @@
#if defined(CONFIG_PLATFORM_8711B)
#include "rtl8710b_ota.h"
#include <FreeRTOS.h>
#include <task.h>
#else
#include <ota_8195a.h>
#endif
#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 for Ameba1, rtl8710b_ota.h for AmebaZ]
#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,77 @@
#include <platform_opts.h>
#if CONFIG_EXAMPLE_PPPOE
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include <lwip_netconf.h>
#include <../netif/ppp/ppp_impl.h>
#include <netif/ppp_oe.h>
#define PPPOE_USER "user"
#define PPPOE_PASSWD "passwd"
extern struct netif xnetif[];
void pppLinkStatusCallback(void *ctx, int errCode, void *arg)
{
switch(errCode) {
case PPPERR_NONE: {
struct ppp_addrs *ppp_addrs = arg;
printf("pppLinkStatusCallback: PPPERR_NONE\n");
printf(" our_ipaddr=%s\n", ip_ntoa(&ppp_addrs->our_ipaddr));
printf(" his_ipaddr=%s\n", ip_ntoa(&ppp_addrs->his_ipaddr));
printf(" netmask =%s\n", ip_ntoa(&ppp_addrs->netmask));
printf(" dns1 =%s\n", ip_ntoa(&ppp_addrs->dns1));
printf(" dns2 =%s\n", ip_ntoa(&ppp_addrs->dns2));
dns_setserver(0, &ppp_addrs->dns1);
dns_setserver(1, &ppp_addrs->dns2);
break;
}
default:
printf("pppLinkStatusCallback: errCode(%d)\n", errCode);
break;
}
}
static void example_pppoe_thread(void *param)
{
int ppp_desc = -1;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: PPPOE\n");
xnetif[0].flags &= ~(NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP); /* no ARP */
xnetif[0].flags |= NETIF_FLAG_ETHERNET; /* pure ethernet */
pppInit();
pppSetAuth(PPPAUTHTYPE_ANY, PPPOE_USER, PPPOE_PASSWD);
ppp_desc = pppOverEthernetOpen(&xnetif[0], NULL, NULL, pppLinkStatusCallback, NULL);
if(ppp_desc >= 0) {
while(1) {
int if_up = 0;
pppIOCtl(ppp_desc, PPPCTLG_UPSTATUS, &if_up);
if(if_up)
break;
else
vTaskDelay(1000);
}
printf("Close PPPOE after 10 seconds\n");
vTaskDelay(10000);
pppClose(ppp_desc);
}
exit:
vTaskDelete(NULL);
}
void example_pppoe(void)
{
if(xTaskCreate(example_pppoe_thread, ((const char*)"example_pppoe_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}
#endif /* CONFIG_EXAMPLE_PPPOE */

View File

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

View File

@@ -0,0 +1,21 @@
LWIP PPPOE EXAMPLE
Description:
Example for lwip pppoe connection.
Configuration:
[lwipopts.h]
#define PPP_SUPPORT 1
#define PPPOE_SUPPORT 1
#define PPPOS_SUPPORT 0
#define PAP_SUPPORT 1
#define CHAP_SUPPORT 1
#define MD5_SUPPORT 1
[platform_opts.h]
#define CONFIG_EXAMPLE_PPPOE 1
Execution:
Can make automatical Wi-Fi connection when booting by using wlan fast connect example.
A PPPOE example thread will be started automatically when booting.
Setup PPPOE_USER and PPPOE_PASSWD in example_pppoe.c for authentication. PPP addresses will be shown after PPP is connected

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:
<EFBFBD> apt-get install rarpd
<EFBFBD> touch /etc/ethers
<EFBFBD> add <20>00:e0:4c:87:xx:xx(Ameba<62>s MAC) client<6E> in /etc/ethers
<EFBFBD> add<64>192.168.1.xx(Ameba<62>s ip) client<6E> in /etc/hosts

View File

@@ -0,0 +1,27 @@
This user guide helps you to setup download server and session token
In this version of the example code, a local download server is used to demonstrate how to upload a large file by multiple parts to the AWS S3 server. Also, session token option is added for testing purpose.
To run the demonstration, you need to setup local download server.
To test the session token, you need to control the related macros to add the x-amz-security-token in different positions and test all the possible combinations
Setup download server (use PC as local download server)
1) Make sure PC and Ameba-1 are in the same network (eg. connect to the same wifi)
2) Place test file in the download server by adding the test file under tools\DownloadServer(HTTP)
3) Open “tools\DownloadServer(HTTP)\start.bat” in notepad
4) Change file path with the name of the test file (eg. image.jpg)
5) Run “tools\DownloadServer(HTTP)\start.bat” and wait for download request
6) In cmd, enter ipconfig to see the PCs (download server) IP address (IPv4 Address)
7) Open example_s3_upload.c
8) Set DL_File_TYPE to the format of test file
9) Set DL_SERVER_HOST to the PCs IP address
10) Set DL_RESOURCE to the name of test file
11) Set S3_RESOURCE to the name to be shown in S3 server
12) Compile and run example_s3_upload.c
13) Connect Ameba-1 to the same network as download server connected
Setup SESSION_TOKEN (temporary security credentials)
1) When use session token as the credentials, set SESSION_TOKEN as 1 in example_s3_upload.c
2) Fill in S3_KEY_ID, S3_KEY_SECRET and S3_SESSION_TOKEN to the temporary security credentials that obtained from AWS STS
3) Edit ADD_IN_FORM_FIELD, ADD_IN_POLICY and ADD_IN_REQUEST_HEADER to control where to add the x-amz-security-token to.
4) Edit the rest of S3 server parameters (see component\common\example\s3_upload\readme.txt)
5) Compile and run example_s3_upload.c

View File

@@ -0,0 +1,851 @@
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include <httpc/httpc.h>
#include <string.h>
#include <stdlib.h>
#include <device_lock.h>
#include <sntp/sntp.h>
#include <hal_crypto.h>
#include <cjson.h>
#include <osdep_service.h>
#include <stdio.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#define TEXT_TXT 1
#define IMAGE_JPG 2
/* Set download server parameters */
#define DL_File_TYPE IMAGE_JPG //download file format (TEXT_TXT , IMAGE_JPG)
#define DL_SERVER_HOST "192.168.0.101" //download server host address
#define DL_SERVER_PORT 8082 //download server port number
#define BUFFER_SIZE 2048 //download buffer size
#define RECV_TO 5000 //receive timeout in ms
/* Show information for debugging */
#define SHOW_INFO 1
#define SHOW_PROGRESS 1
/* Set file to be downloaded and saved as */
#define DL_RESOURCE "test_image.jpg" //file in download server
#define S3_RESOURCE "S3_image.jpg" //file name and format that will be shown in S3 server
/* Set Security Credentials */
#define SESSION_TOKEN 0
#if SESSION_TOKEN
//temporary security credentials
#define S3_KEY_ID "AFIA3AVW256YUEXAMPLE"
#define S3_KEY_SECRET "trwieEhsWFqauERw4BkNg13Z9RJ0S1qSoEXAMPLE"
#define S3_SESSION_TOKEN "FQoGZXIvYEXAMPLE//////////wEaDBcEXAMPLEhozDHTCLwARX2vPunHUXXUv9OXsS+EXAMPLEWBDglFSpxLaf7eY6ywzgIsxYTcq09mXeWtwSYfbvc8BHEXAMPLEdq9F3udTY8dxBfvA1BzJj50P59pRabkkLZzBvrs8yjmpbiXcBOJM9C+EXAMPLE8/XpO4E6AAjLBsZOeUPfYDZ9tbkWyV9+TYV/xohD1dDKI555Mrd7y7t/mwLOD79w7EXAMPLEhZXO8LmpE8hDw+zrOc2QZmgIeVqbCF0MCQv8IGe03RdGwlBb+Y1zBnmA0vlEXAMPLEZaK8cmEzrGsR/+DeW2Fsm/EmvFS2SKikq2GGEXAMPLEQ=="
#define ADD_IN_FORM_FIELD 1
#define ADD_IN_POLICY 1
#define ADD_IN_REQUEST_HEADER 1
#else
//long-term credentials
#define S3_KEY_ID "AKIAJWHJCGO5OEXAMPLE"
#define S3_KEY_SECRET "PBVQIwZVy3kDjZPcnLeemnYJ2MPgtV9FOEXAMPLE"
#define ADD_IN_FORM_FIELD 0
#define ADD_IN_POLICY 0
#define ADD_IN_REQUEST_HEADER 0
#endif
/* Set S3 server parameters */
#define UPLOAD_METHOD "POST"
#define S3_BUCKET "bucket_name"
#define S3_KEY "AWS "
#define S3_REGION "ap-southeast-1"
#define S3_SERVICE "s3"
#define S3_SERVER_HOST S3_BUCKET"."S3_SERVICE"-"S3_REGION".amazonaws.com"
#define S3_PORT "443"
#define S3_POLICY_EXPIRATION "2020-07-30T12:00:00.000Z" //policy expriation time
#define S3_ALGORITHM "AWS4-HMAC-SHA256"
#define S3_ACL "public-read-write"
#define HTTP_CRLF "\r\n"
#if (DL_File_TYPE == 1)
#define CONTENT_TYPE "text/txt"
#elif (DL_File_TYPE == 2)
#define CONTENT_TYPE "image/jpeg"
#endif
typedef struct {
u8 *s3_expiration;
u8 *bucket;
u8 *s3_key;
u8 *s3_acl;
u8 *content_type;
u8 *x_amz_meta_tag;
u8 *x_amz_crd;
u8 *x_amz_alg;
u8 *x_amz_date;
#if ADD_IN_POLICY
u8 *x_amz_security_token;
#endif
}policy;
/* Generate random number for 'boundary' */
extern int rtw_get_random_bytes(void* dst, u32 size);
/* Generate post policy */
char * generate_s3_policy(policy policy_element)
{
cJSON_Hooks memoryHook;
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
char *policy = NULL;
cJSON *object = NULL;
cJSON *s3_conditions = NULL;
cJSON *try_conditions = NULL;
cJSON *s3_bucket = NULL;
cJSON *key_sw = NULL;
cJSON *s3_acl_obj = NULL;
cJSON *cont_type_sw = NULL;
cJSON *meta_tag_sw = NULL;
cJSON *amz_crd = NULL;
cJSON *amz_alg = NULL;
cJSON *amz_date = NULL;
#if ADD_IN_POLICY
cJSON *amz_security_token = NULL;
#endif
if((object = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(object, "expiration", cJSON_CreateString(policy_element.s3_expiration));
cJSON_AddItemToObject(object, "conditions", s3_conditions = cJSON_CreateArray());
cJSON_AddItemToArray(s3_conditions, s3_bucket = cJSON_CreateObject());
cJSON_AddItemToObject(s3_bucket, "bucket", cJSON_CreateString(policy_element.bucket));
cJSON_AddItemToArray(s3_conditions, key_sw = cJSON_CreateArray());
cJSON_AddItemToArray(key_sw, cJSON_CreateString("starts-with"));
cJSON_AddItemToArray(key_sw, cJSON_CreateString(policy_element.s3_key));
cJSON_AddItemToArray(key_sw, cJSON_CreateString(""));
cJSON_AddItemToArray(s3_conditions, s3_acl_obj = cJSON_CreateObject());
cJSON_AddItemToObject(s3_acl_obj , "acl", cJSON_CreateString(policy_element.s3_acl));
cJSON_AddItemToArray(s3_conditions, cont_type_sw = cJSON_CreateArray());
cJSON_AddItemToArray(cont_type_sw, cJSON_CreateString("starts-with"));
cJSON_AddItemToArray(cont_type_sw, cJSON_CreateString(policy_element.content_type));
#if (DL_File_TYPE == 1)
cJSON_AddItemToArray(cont_type_sw, cJSON_CreateString("text/"));
#elif (DL_File_TYPE == 2)
cJSON_AddItemToArray(cont_type_sw, cJSON_CreateString("image/"));
#endif
cJSON_AddItemToArray(s3_conditions, meta_tag_sw = cJSON_CreateArray());
cJSON_AddItemToArray(meta_tag_sw, cJSON_CreateString("starts-with"));
cJSON_AddItemToArray(meta_tag_sw, cJSON_CreateString(policy_element.x_amz_meta_tag));
cJSON_AddItemToArray(meta_tag_sw, cJSON_CreateString(""));
cJSON_AddItemToArray(s3_conditions, amz_crd = cJSON_CreateObject());
cJSON_AddItemToObject(amz_crd, "x-amz-credential", cJSON_CreateString(policy_element.x_amz_crd));
cJSON_AddItemToArray(s3_conditions, amz_alg = cJSON_CreateObject());
cJSON_AddItemToObject(amz_alg, "x-amz-algorithm", cJSON_CreateString(policy_element.x_amz_alg));
cJSON_AddItemToArray(s3_conditions, amz_date = cJSON_CreateObject());
cJSON_AddItemToObject(amz_date, "x-amz-date", cJSON_CreateString(policy_element.x_amz_date));
#if ADD_IN_POLICY
cJSON_AddItemToArray(s3_conditions, amz_security_token = cJSON_CreateObject());
cJSON_AddItemToObject(amz_security_token, "x-amz-security-token", cJSON_CreateString(policy_element.x_amz_security_token));
#endif
policy = cJSON_Print(object);
cJSON_Delete(object);
}
return policy;
}
/* Generate html form */
int create_form (u8 *form_content, u8 *boundary, char *form_name, char *form_value, int file_upload)
{
int strLength=0;
unsigned int content_disposition_length = 256 + strlen(boundary) + strlen(form_name) + strlen(form_value);
char *content_disposition = malloc(content_disposition_length);
if(!content_disposition) {
printf("malloc failed for content_disposition\r\n");
return -1;
}
strLength = 0;
memset(content_disposition, 0, content_disposition_length);
memcpy(content_disposition, boundary, strlen(boundary));
strLength = strlen(boundary);
memcpy(content_disposition+strLength, HTTP_CRLF, 2);
strLength += 2;
memcpy(content_disposition+strLength, "Content-Disposition: form-data; name=\"", 38);
strLength += 38;
memcpy(content_disposition+strLength, form_name, strlen(form_name));
strLength += strlen(form_name);
if(file_upload!=0) {
memcpy(content_disposition+strLength, "\"; filename=\"", 13);
strLength += 13;
memcpy(content_disposition+strLength, form_value, strlen(form_value));
strLength += strlen(form_value);
memcpy(content_disposition+strLength, "\"", 1);
strLength += 1;
memcpy(content_disposition+strLength, HTTP_CRLF, 2);
strLength += 2;
memcpy(content_disposition+strLength, "Content-Type: ", 14);
strLength += 14;
memcpy(content_disposition+strLength, CONTENT_TYPE, strlen(CONTENT_TYPE));
strLength += strlen(CONTENT_TYPE);
}
else {
memcpy(content_disposition+strLength, "\"", 1);
strLength += 1;
}
memcpy(content_disposition+strLength, HTTP_CRLF, 2);
strLength += 2;
memcpy(content_disposition+strLength, HTTP_CRLF, 2);
strLength += 2;
if(file_upload == 0) {
memcpy(content_disposition+strLength, form_value, strlen(form_value));
strLength += strlen(form_value);
memcpy(content_disposition+strLength, HTTP_CRLF, 2);
strLength += 2;
}
memcpy(form_content,content_disposition,strLength);
free (content_disposition);
return strLength;
}
static void example_s3_upload_thread(void *param)
{
/* To avoid gcc warnings */
( void ) param;
struct httpc_conn *conn = NULL;
int ret;
int str_len = 0;
int form_len = 0;
int end_b_len = 0;
u8 *date = NULL;
u8 *canonical_URI = NULL;
u8 *stringtosign = NULL;
u8 *authorization_header = NULL;
u8* content = NULL;
u8 file_content_digest[32]={0};
u8 canonical_request_digest[32]={0};
u8 datekey_digest[32]={0};
u8 dateregionkey_digest[32]={0};
u8 dateregionservicekey_digest[32]={0};
u8 signingkey_digest[32]={0};
u8 sha256_signature[32]={0};
u8 *ISO_hour = NULL;
u8 *ISO_min = NULL;
u8 *ISO_sec = NULL;
u8 *ISO_year = NULL;
u8 *ISO_mth = NULL;
u8 *ISO_day = NULL;
u8 *day_space = NULL;
u8 *day_num = NULL;
u8 *s3_daystamp = NULL;
u8 *s3_timestamp = NULL;
u8 *s3_credential = NULL;
u8 *s3_scope = NULL;
u8 *hex_sha256_file_content = NULL;
u8 *hex_sha256_canonical_request = NULL;
u8 *host_header = NULL;
u8 *content_type_header = NULL;
u8 *canonical_headers = NULL;
u8 *x_amz_content_sha256 = NULL;
u8 *x_amz_date = NULL;
#if SESSION_TOKEN
u8 *x_amz_security_token = NULL;
#endif
u8 *canonical_request = NULL;
u8 *datekey_str = NULL;
u8 *signature = NULL;
u8 *payload_content = NULL;
u8 *boundary = NULL;
u8 *multipart_datatype = NULL;
u8 *form_boundary = NULL;
u8 *end_boundary = NULL;
char *form_content = NULL;
char *s3_policy = NULL;
u8 base64_len = 128;
u8 base64_hmac_len = 128;
u8 md5_digest[16] = {0};
u8 hmac_digest[20] = {0};
u8 base64_buffer[128] = {0};
u8 base64_hmac_buffer[128] = {0};
u8 boundary_buffer[16] = {0};
#if SHOW_PROGRESS
int progress = 0;
int current_work = 0;
int dividend = 0;
int last_rs = 0;
#endif
int server_fd = -1;
struct sockaddr_in server_addr;
struct hostent *server_host;
// Delay to wait for IP by DHCP
vTaskDelay(10000);
printf("\nExample: S3 file upload using HTTP POST (Sig_V4)\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(DL_SERVER_PORT);
// Support DL_SERVER_HOST in IP or domain name
server_host = gethostbyname(DL_SERVER_HOST);
memcpy((void *) &server_addr.sin_addr, (void *) server_host->h_addr, 4);
/* Connect Download Server */
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;
/* Connect S3 Server */
conn = httpc_conn_new(HTTPC_SECURE_TLS, NULL, NULL, NULL);
if(conn) {
if(httpc_conn_connect(conn, S3_SERVER_HOST, 443, 0) == 0) {
/* Get Date */
int should_stop = 0;
sntp_init();
date=malloc(50);
if(!date) {
printf("malloc failed for date\r\n");
goto exit;
}
while(1) {
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;
memset(date, 0, 50);
memcpy(date, ctime(&current_sec), strlen(ctime(&current_sec))-1);
vTaskDelay(1000);
break;
}
}
/* Re-format date to ISO8601 format */
ISO_hour = malloc(10);
if(!ISO_hour) {
printf("malloc failed for ISO_hour\r\n");
goto exit;
}
ISO_min = malloc(10);
if(!ISO_min) {
printf("malloc failed for ISO_min\r\n");
goto exit;
}
ISO_sec = malloc(10);
if(!ISO_sec) {
printf("malloc failed for ISO_sec\r\n");
goto exit;
}
ISO_year = malloc(10);
if(!ISO_year) {
printf("malloc failed for ISO_year\r\n");
goto exit;
}
ISO_mth = malloc(10);
if(!ISO_mth) {
printf("malloc failed for ISO_mth\r\n");
goto exit;
}
ISO_day = malloc(10);
if(!ISO_day) {
printf("malloc failed for ISO_day\r\n");
goto exit;
}
day_space = malloc(10);
if(!day_space) {
printf("malloc failed for day_space\r\n");
goto exit;
}
day_num = malloc(10);
if(!day_num) {
printf("malloc failed for day_num\r\n");
goto exit;
}
memset(ISO_hour, 0, 10);
memset(ISO_min, 0, 10);
memset(ISO_sec, 0, 10);
memset(ISO_year, 0, 10);
memset(ISO_mth, 0, 10);
memset(ISO_day, 0, 10);
memcpy(ISO_hour, date+11, 2);
memcpy(ISO_min, date+14, 2);
memcpy(ISO_sec, date+17, 2);
memcpy(ISO_year, date+20, 4);
memcpy(ISO_mth, date+4, 3);
memcpy(ISO_day, date+8, 2);
if(strcmp(ISO_mth, "Jan") == 0) {
memcpy(ISO_mth, "01", 2);
}
else if(strcmp(ISO_mth, "Feb") == 0) {
memcpy(ISO_mth, "02", 2);
}
else if(strcmp(ISO_mth, "Mar") == 0) {
memcpy(ISO_mth, "03", 2);
}
else if(strcmp(ISO_mth, "Apr") == 0) {
memcpy(ISO_mth, "04", 2);
}
else if(strcmp(ISO_mth, "May") == 0) {
memcpy(ISO_mth, "05", 2);
}
else if(strcmp(ISO_mth, "Jun") == 0) {
memcpy(ISO_mth, "06", 2);
}
else if(strcmp(ISO_mth, "Jul") == 0) {
memcpy(ISO_mth, "07", 2);
}
else if(strcmp(ISO_mth, "Aug") == 0) {
memcpy(ISO_mth, "08", 2);
}
else if(strcmp(ISO_mth, "Sep") == 0) {
memcpy(ISO_mth, "09", 2);
}
else if(strcmp(ISO_mth, "Oct") == 0) {
memcpy(ISO_mth, "10", 2);
}
else if(strcmp(ISO_mth, "Nov") == 0) {
memcpy(ISO_mth, "11", 2);
}
else if(strcmp(ISO_mth, "Dec") == 0) {
memcpy(ISO_mth, "12", 2);
}
memset(day_space, 0, 10);
memcpy(day_space, ISO_day, 1);
if(strcmp(day_space, " ") == 0) {
memset(day_num, 0, 10);
memcpy(day_num, ISO_day+1, 1);
str_len = 0;
memset(ISO_day, 0, 10);
memcpy(ISO_day, "0", 1);
str_len = 1;
memcpy(ISO_day+str_len, day_num, 1);
str_len += 1;
}
s3_daystamp = malloc(50);
if(!s3_daystamp) {
printf("malloc failed for s3_daystamp\r\n");
goto exit;
}
str_len = 0;
memset(s3_daystamp, 0, 50);
memcpy(s3_daystamp, ISO_year, 4);
str_len = 4;
memcpy(s3_daystamp+str_len, ISO_mth, 2);
str_len += 2;
memcpy(s3_daystamp+str_len, ISO_day, 2);
str_len += 2;
s3_timestamp = malloc(50);
if(!s3_timestamp) {
printf("malloc failed for s3_timestamp\r\n");
goto exit;
}
str_len = 0;
memset(s3_timestamp, 0, 50);
memcpy(s3_timestamp, s3_daystamp, 8);
str_len = 8;
memcpy(s3_timestamp+str_len, "T", 1);
str_len += 1;
memcpy(s3_timestamp+str_len, ISO_hour, 2);
str_len += 2;
memcpy(s3_timestamp+str_len, ISO_min, 2);
str_len += 2;
memcpy(s3_timestamp+str_len, ISO_sec, 2);
str_len += 2;
memcpy(s3_timestamp+str_len, "Z", 1);
str_len += 1;
/* Get x-amz-credential */
s3_credential = malloc(128);
if(!s3_credential) {
printf("malloc failed for s3_credential\r\n");
goto exit;
}
str_len = 0;
memset(s3_credential, 0, 128);
memcpy(s3_credential, S3_KEY_ID, strlen(S3_KEY_ID));
str_len = strlen(S3_KEY_ID);
memcpy(s3_credential+str_len, "/", 1);
str_len += 1;
memcpy(s3_credential+str_len, s3_daystamp, 8);
str_len += 8;
memcpy(s3_credential+str_len, "/", 1);
str_len += 1;
memcpy(s3_credential+str_len, S3_REGION, strlen(S3_REGION));
str_len += strlen(S3_REGION);
memcpy(s3_credential+str_len, "/", 1);
str_len += 1;
memcpy(s3_credential+str_len, S3_SERVICE, strlen(S3_SERVICE));
str_len += strlen(S3_SERVICE);
memcpy(s3_credential+str_len, "/", 1);
str_len += 1;
memcpy(s3_credential+str_len, "aws4_request", strlen("aws4_request"));
str_len += strlen("aws4_request");
/* Constuct Policy */
policy policy_element;
policy_element.s3_expiration = S3_POLICY_EXPIRATION;
policy_element.bucket = S3_BUCKET;
policy_element.s3_key = "$key";
policy_element.s3_acl = S3_ACL;
policy_element.content_type = "$Content-Type";
policy_element.x_amz_meta_tag = "$x-amz-meta-tag";
policy_element.x_amz_crd = s3_credential;
policy_element.x_amz_alg = S3_ALGORITHM;
policy_element.x_amz_date = s3_timestamp;
#if ADD_IN_POLICY
policy_element.x_amz_security_token = S3_SESSION_TOKEN;
#endif
s3_policy = generate_s3_policy(policy_element);
#if SHOW_INFO
printf(" ---------------\r\n");
printf("| POST Policy |\r\n");
printf(" ---------------\r\n%s",s3_policy);
#endif
/* Build StringToSign */
stringtosign = malloc(2048);
if(!stringtosign) {
printf("malloc failed for stringtosign\r\n");
goto exit;
}
memset(stringtosign, 0, 2048);
if((ret = httpc_base64_encode(s3_policy, strlen(s3_policy), stringtosign, 2048)) != 0) {
printf("base64 encode failed for s3_policy\r\n");
goto exit;
}
/* Construct SigningKey */
datekey_str = malloc(128);
if(!datekey_str) {
printf("malloc failed for datekey_str\r\n");
goto exit;
}
memset(datekey_str, 0, 128);
str_len = 0;
memcpy(datekey_str, "AWS4", 4);
str_len = 4;
memcpy(datekey_str+str_len, S3_KEY_SECRET, strlen(S3_KEY_SECRET));
str_len += strlen(S3_KEY_SECRET);
/* SHA-256 Encryption */
device_mutex_lock(RT_DEV_LOCK_CRYPTO);
ret = rtl_crypto_hmac_sha2(SHA2_256, s3_daystamp, strlen(s3_daystamp), datekey_str, strlen(datekey_str), datekey_digest);
ret += rtl_crypto_hmac_sha2(SHA2_256, S3_REGION, strlen(S3_REGION), datekey_digest, 32, dateregionkey_digest);
ret += rtl_crypto_hmac_sha2(SHA2_256, S3_SERVICE, strlen(S3_SERVICE), dateregionkey_digest, 32, dateregionservicekey_digest);
ret += rtl_crypto_hmac_sha2(SHA2_256, "aws4_request", 12, dateregionservicekey_digest, 32, signingkey_digest);
ret += rtl_crypto_hmac_sha2(SHA2_256, stringtosign, strlen(stringtosign), signingkey_digest, 32, sha256_signature); //sha256 signature
device_mutex_unlock(RT_DEV_LOCK_CRYPTO);
if(ret != 0 ) {
printf("sha256 failed %d\r\n", ret);
goto exit;
}
/* Construct Signature */
signature = malloc(1024);
if(!signature) {
printf("malloc failed for signature\r\n");
goto exit;
}
memset(signature, 0, 1024);
/* Represent in Hex form */
for(int i=0;i<32;i++) {
sprintf(signature+2*i, "%02x", sha256_signature[i]);
}
/* Construct Multipart form-data */
boundary = malloc(64);
if(!boundary) {
printf("malloc failed for boundary\r\n");
goto exit;
}
memset(boundary, 0, 64);
rtw_get_random_bytes(boundary_buffer, 16);
for(int i=0;i<16;i++) {
sprintf(boundary+2*i, "%02x", boundary_buffer[i]);
}
multipart_datatype = malloc(100);
if(!multipart_datatype) {
printf("malloc failed for multipart_datatype\r\n");
goto exit;
}
str_len = 0;
memset(multipart_datatype, 0, 100);
memcpy(multipart_datatype+str_len, "multipart/form-data; boundary=", 30);
str_len = 30;
memcpy(multipart_datatype+str_len, boundary, strlen(boundary));
str_len += strlen(boundary);
form_boundary=malloc(64);
if(!form_boundary) {
printf("malloc failed for form_boundary\r\n");
goto exit;
}
str_len = 0;
memset(form_boundary, 0, 64);
memcpy(form_boundary+str_len, "--", 2);
str_len = 2;
memcpy(form_boundary+str_len, boundary, strlen(boundary));
str_len += strlen(boundary);
end_boundary=malloc(64);
if(!end_boundary) {
printf("malloc failed for end_boundary\r\n");
goto exit;
}
end_b_len = 0;
memset(end_boundary, 0, 64);
memcpy(end_boundary+end_b_len, HTTP_CRLF, 2);
end_b_len += 2;
memcpy(end_boundary+end_b_len, form_boundary, strlen(form_boundary));
end_b_len += strlen(form_boundary);
memcpy(end_boundary+end_b_len, "--", 2);
end_b_len += 2;
payload_content=malloc(4096);
if(!payload_content) {
printf("malloc failed for payload_content\r\n");
goto exit;
}
memset(payload_content, 0, 4096);
form_len = 0;
form_len += create_form(payload_content + form_len, form_boundary, "key", S3_RESOURCE, 0);
form_len += create_form(payload_content + form_len, form_boundary, "acl", S3_ACL, 0);
form_len += create_form(payload_content + form_len, form_boundary, "Content-Type", CONTENT_TYPE, 0);
form_len += create_form(payload_content + form_len, form_boundary, "X-Amz-Credential", s3_credential, 0);
form_len += create_form(payload_content + form_len, form_boundary, "X-Amz-Algorithm", S3_ALGORITHM, 0);
form_len += create_form(payload_content + form_len, form_boundary, "X-Amz-Date", s3_timestamp, 0);
#if ADD_IN_FORM_FIELD
form_len += create_form(payload_content + form_len, form_boundary, "x-amz-security-token", S3_SESSION_TOKEN, 0);
#endif
form_len += create_form(payload_content + form_len, form_boundary, "X-Amz-Meta-Tag", "", 0);
form_len += create_form(payload_content + form_len, form_boundary, "Policy", stringtosign, 0);
form_len += create_form(payload_content + form_len, form_boundary, "X-Amz-Signature", signature, 0);
form_len += create_form(payload_content + form_len, form_boundary, "file", S3_RESOURCE, 1);
/* Send GET request to download server */
content = malloc(BUFFER_SIZE);
if(!content) {
printf("malloc failed for content\r\n");
goto exit;
}
memset(content, 0, BUFFER_SIZE);
sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", DL_RESOURCE, DL_SERVER_HOST);
write(server_fd, buf, strlen(buf));
/* Start receiving data from download server*/
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("\n-- Download Server --\r\n");
printf("HTTP 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("\n-- S3 Server --\r\n");
/* Start building request header */
httpc_request_write_header_start(conn, UPLOAD_METHOD, "/", multipart_datatype, (form_len+content_len+end_b_len));
#if ADD_IN_REQUEST_HEADER
httpc_request_write_header(conn, "x-amz-security-token", S3_SESSION_TOKEN);
#endif
httpc_request_write_header(conn, "Accept", "*/*");
httpc_request_write_header(conn, "Expect", "100 Continue");
/* Send request header */
httpc_request_write_header_finish(conn);
/* Send request body */
httpc_request_write_data(conn, (uint8_t*)payload_content, strlen(payload_content));
#if SHOW_INFO
printf(" ---------------\r\n");
printf("| HTML Form |\r\n");
printf(" ---------------\r\n%s",payload_content);
#endif
printf("Uploading (%s) ...\r\n",DL_RESOURCE);
#if SHOW_PROGRESS
dividend = content_len/50;
printf("0%%--------------------------------------------100%%\r\n");
#endif
}
#if SHOW_PROGRESS
last_rs += read_size;
current_work = last_rs/dividend - progress;
for(int i=0;i<current_work;i++)
printf(">");
progress += current_work;
#endif
memcpy(content, buf, read_size);
resource_size += read_size;
/* Send data to S3 server */
httpc_request_write_data(conn, (uint8_t*)content, read_size);
}
/* Send end boundary to end the form */
httpc_request_write_data(conn, (uint8_t*)end_boundary, strlen(end_boundary));
#if SHOW_INFO
printf("\nSaved as (%s) in server.\r\n",S3_RESOURCE);
printf("%s\r\n",end_boundary);
#endif
// 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 rd_size = 0;
uint32_t total_size = 0;
while(1) {
memset(buf, 0, sizeof(buf));
rd_size = httpc_response_read_data(conn, buf, sizeof(buf) - 1);
if(rd_size > 0) {
total_size += rd_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");
}
printf("\nEnd of S3 upload example\n");
httpc_conn_close(conn);
httpc_conn_free(conn);
}
else {
printf("ERROR: connect\n");
}
exit:
if(server_fd >= 0)
close(server_fd);
if(content)
free(content);
if(date)
free(date);
if(canonical_URI)
free(canonical_URI);
if(stringtosign)
free(stringtosign);
if(authorization_header)
free(authorization_header);
if(ISO_hour)
free(ISO_hour);
if(ISO_min)
free(ISO_min);
if(ISO_sec)
free(ISO_sec);
if(ISO_year)
free(ISO_year);
if(ISO_mth)
free(ISO_mth);
if(ISO_day)
free(ISO_day);
if(day_space)
free(day_space);
if(day_num)
free(day_num);
if(s3_daystamp)
free(s3_daystamp);
if(s3_timestamp)
free(s3_timestamp);
if(s3_credential)
free(s3_credential);
if(s3_scope)
free(s3_scope);
if(hex_sha256_file_content)
free(hex_sha256_file_content);
if(hex_sha256_canonical_request)
free(hex_sha256_canonical_request);
if(host_header)
free(host_header);
if(content_type_header)
free(content_type_header);
if(canonical_headers)
free(canonical_headers);
if(x_amz_content_sha256)
free(x_amz_content_sha256);
if(x_amz_date)
free(x_amz_date);
if(canonical_request)
free(canonical_request);
if(datekey_str)
free(datekey_str);
if(signature)
free(signature);
if(payload_content)
free(payload_content);
if(boundary)
free(boundary);
if(multipart_datatype)
free(multipart_datatype);
if(form_boundary)
free(form_boundary);
if(end_boundary)
free(end_boundary);
if(form_content)
free(form_content);
if(s3_policy)
free(s3_policy);
printf("Exit\r\n");
vTaskDelete(NULL);
}
void example_s3_upload(void)
{
if(xTaskCreate(example_s3_upload_thread, ((const char*)"example_s3_upload_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(example_s3_upload_thread) failed", __FUNCTION__);
}

View File

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

View File

@@ -0,0 +1,29 @@
S3 UPLOAD EXAMPLE
Description:
This example is to upload a file to AWS S3 server.
Configuration:
[platform_opts.h]
#define CONFIG_EXAMPLE_S3_UPLOAD 1
Execution:
Please provide and set below macros correctly
#define DL_File_TYPE // The format of file to be downloaded
#define DL_SERVER_HOST // Download server host address (cmd->ipconfig->IPv4 Address)
#define DL_SERVER_PORT // Download server port number (set same as in start.bat)
#define SHOW_INFO // Set to 1 to see the POST policy and HTML form
#define SHOW_PROGRESS // Set to 1 to see the upload progress bar
#define DL_RESOURCE // Name of file to be downloaded
#define S3_RESOURCE // Name of file to be uploaded
#define SESSION_TOKEN // Set to 1 to use Security Credentials
#define S3_KEY_ID
#define S3_KEY_SECRET
#define S3_SESSION_TOKEN
#define ADD_IN_FORM_FIELD // Set to 1 to add "x-amz-security-token" in HTML form
#define ADD_IN_POLICY // Set to 1 to add "x-amz-security-token" in POST policy
#define ADD_IN_REQUEST_HEADER // Set to 1 to add "x-amz-security-token" in request header
#define S3_BUCKET
#define S3_REGION
#define S3_POLICY_EXPIRATION

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,651 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#include <platform_opts.h>
#if CONFIG_EXAMPLE_SPI_ATCMD
#include "FreeRTOS.h"
#include "task.h"
#include <platform/platform_stdlib.h>
#include "semphr.h"
#include "device.h"
#include "osdep_api.h"
#include "osdep_service.h"
#include "device_lock.h"
#include "spi_atcmd/example_spi_atcmd.h"
#include "at_cmd/log_service.h"
#include "at_cmd/atcmd_wifi.h"
#include "at_cmd/atcmd_lwip.h"
#include "flash_api.h"
#include "spi_api.h"
#include "spi_ex_api.h"
#include "gpio_irq_api.h"
#include "gpio_irq_ex_api.h"
/**** SPI FUNCTIONS ****/
spi_t spi_obj;
gpio_t gpio_cs;
#define SPI_RX_BUFFER_SIZE ATSTRING_LEN/2
#define SPI_TX_BUFFER_SIZE ATSTRING_LEN/2
uint16_t spi_chunk_buffer[ATSTRING_LEN/2];
_Sema master_rx_done_sema;
_Sema master_tx_done_sema;
#define SPI_USE_STREAM (0)
#define SPI_USE_DMA (1)
/**** SLAVE HARDWARE READY ****/
gpio_t gpio_hrdy;
#define SPI_SLAVE_BUSY 0
#define SPI_SLAVE_READY 1
volatile int spi_slave_status = SPI_SLAVE_BUSY;
_Sema spi_check_hrdy_sema;
#define BLOCKING 1
#define NONBLOCKING 0
volatile int hrdy_pull_down_counter = 0;
/**** SLAVE SYNC ****/
gpio_irq_t gpio_sync;
#define SPI_STATE_MISO 0
#define SPI_STATE_MOSI 1
int spi_state = SPI_STATE_MISO;
/**** TASK THREAD ****/
_Sema spi_check_trx_sema;
/**** LOG SERVICE ****/
char at_string[ATSTRING_LEN];
extern char log_buf[LOG_SERVICE_BUFLEN];
extern xSemaphoreHandle log_rx_interrupt_sema;
#define LOG_TX_BUFFER_SIZE 48*1024
char log_tx_buffer[LOG_TX_BUFFER_SIZE];
uint32_t log_tx_idx = 0;
uint32_t log_rx_idx = 0;
/**** DATA FORMAT ****/
#define PREAMBLE_COMMAND 0x6000
#define PREAMBLE_DATA_READ 0x1000
#define PREAMBLE_DATA_WRITE 0x0000
#define COMMAND_DUMMY 0x0000
#define COMMAND_BEGIN 0x0304
#define COMMAND_END 0x0305
#define COMMAND_READ_BEGIN 0x0012
#define COMMAND_READ_RAW 0x0013
#define COMMAND_WRITE_BEGIN 0x0014
#define COMMAND_READ_WRITE_END 0x0015
#define REGISTER_ADDR 0x2000
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_SPI:
size = SPI_CONF_DATA_SIZE;
offset = SPI_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, SPI_SETTING_SECTOR);
goto exit;
}
if(ops == AT_PARTITION_READ){
flash_stream_read(&flash, SPI_SETTING_SECTOR+offset, len, data);
goto exit;
}
//erase BACKUP_SECTOR
flash_erase_sector(&flash, SPI_SETTING_BACKUP_SECTOR);
if(ops == AT_PARTITION_WRITE){
// backup new data
flash_stream_write(&flash, SPI_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, SPI_SETTING_SECTOR + i, &read_data);
flash_write_word(&flash, SPI_SETTING_BACKUP_SECTOR + i,read_data);
}
//backup rear data
for(i = (offset + size); i < 0x1000; i += sizeof(read_data)){
flash_read_word(&flash, SPI_SETTING_SECTOR + i, &read_data);
flash_write_word(&flash, SPI_SETTING_BACKUP_SECTOR + i,read_data);
}
//erase UART_SETTING_SECTOR
flash_erase_sector(&flash, SPI_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, SPI_SETTING_BACKUP_SECTOR + i, &read_data);
flash_write_word(&flash, SPI_SETTING_SECTOR + i,read_data);
}
//erase BACKUP_SECTOR
flash_erase_sector(&flash, SPI_SETTING_BACKUP_SECTOR);
exit:
device_mutex_unlock(RT_DEV_LOCK_FLASH);
return;
}
/* AT cmd V2 API */
void spi_at_send_string(char *str) {
spi_at_send_buf(str, strlen(str));
}
/* AT cmd V2 API */
void spi_at_send_buf(u8 *buf, u32 len) {
int i;
int spi_tx_tail_next;
if( !len || (!buf) ){
return;
}
if (buf == log_tx_buffer) {
log_tx_idx = len;
} else {
for (i=0; i<len; i++) {
if (log_tx_idx == LOG_TX_BUFFER_SIZE) {
// overflow!
break;
}
log_tx_buffer[log_tx_idx++] = buf[i];
}
}
if (__get_IPSR() != 0) {
RtlUpSema(&spi_check_trx_sema);
} else {
RtlUpSemaFromISR(&spi_check_trx_sema);
}
}
/* IRQ handler called when SPI TX/RX finish */
void master_trx_done_callback(void *pdata, SpiIrq event) {
switch(event){
case SpiRxIrq:
RtlUpSemaFromISR(&master_rx_done_sema);
//DBG_8195A("Master RX done!\n");
break;
case SpiTxIrq:
//DBG_8195A("Master TX done!\n");
break;
default:
DBG_8195A("unknown interrput evnent!\n");
}
}
/* IRQ handler called when SPI TX finish */
static void master_tx_done_callback(uint32_t id) {
RtlUpSemaFromISR(&master_tx_done_sema);
}
/* IRQ handler as gpio hrdy hit rising edge */
void slave_hrdy_change_callback(uint32_t id) {
gpio_irq_disable(&gpio_hrdy);
if (spi_slave_status == SPI_SLAVE_BUSY) {
// Transition from LOW to HIGH. Change to listen IRQ_LOW
spi_slave_status = SPI_SLAVE_READY;
hrdy_pull_down_counter++;
gpio_irq_set(&gpio_hrdy, IRQ_LOW, 1);
gpio_irq_enable(&gpio_hrdy);
} else {
// Transition from HIGH to LOW. Change to listen IRQ_HIGH
spi_slave_status = SPI_SLAVE_BUSY;
gpio_irq_set(&gpio_hrdy, IRQ_HIGH, 1);
gpio_irq_enable(&gpio_hrdy);
}
RtlUpSemaFromISR(&spi_check_hrdy_sema);
}
/* IRQ Handler as gpio sync state change */
void slave_sync_chagne_callback(uint32_t id)
{
gpio_irq_disable(&gpio_sync);
if (spi_state == SPI_STATE_MISO) {
// Transition from LOW to HIGH. Change to listen IRQ_LOW
spi_state = SPI_STATE_MOSI;
gpio_irq_set(&gpio_sync, IRQ_LOW, 1);
gpio_irq_enable(&gpio_sync);
} else {
// Transition from HIGH to LOW. Change to listen IRQ_HIGH
spi_state = SPI_STATE_MISO;
gpio_irq_set(&gpio_sync, IRQ_HIGH, 1);
gpio_irq_enable(&gpio_sync);
}
RtlUpSemaFromISR(&spi_check_trx_sema);
}
void spi_atcmd_main(void)
{
wifi_disable_powersave();
// read settings
SPI_LOG_CONF spiconf;
spiconf.bits = 16;
spiconf.frequency = 20000000;
spiconf.mode = (SPI_SCLK_IDLE_LOW|SPI_SCLK_TOGGLE_MIDDLE);
// init spi
spi_init(&spi_obj, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS);
spi_frequency(&spi_obj, spiconf.frequency);
spi_format(&spi_obj, spiconf.bits, spiconf.mode, 0);
spi_bus_tx_done_irq_hook(&spi_obj, master_tx_done_callback, (uint32_t)&spi_obj);
spi_irq_hook(&spi_obj, master_trx_done_callback, (uint32_t)&spi_obj);
// init simulated spi cs
gpio_init(&gpio_cs, GPIO_CS);
gpio_dir(&gpio_cs, PIN_OUTPUT);
gpio_mode(&gpio_cs, PullNone);
gpio_write(&gpio_cs, 1);
// init gpio for check if spi slave hw ready
gpio_init(&gpio_hrdy, GPIO_HRDY);
gpio_dir(&gpio_hrdy, PIN_INPUT);
gpio_mode(&gpio_hrdy, PullDown);
gpio_irq_init(&gpio_hrdy, GPIO_HRDY, slave_hrdy_change_callback, (uint32_t)&gpio_hrdy);
gpio_irq_set(&gpio_hrdy, IRQ_HIGH, 1);
gpio_irq_enable(&gpio_hrdy);
// init gpio for check if spi slave want to send data
gpio_irq_init(&gpio_sync, GPIO_SYNC, slave_sync_chagne_callback,(uint32_t)&gpio_sync);
gpio_irq_set(&gpio_sync, IRQ_HIGH, 1);
gpio_irq_enable(&gpio_sync);
// init semaphore for check hardware ready
RtlInitSema(&spi_check_hrdy_sema, 1);
RtlDownSema(&spi_check_hrdy_sema);
// init semaphore that makes spi tx/rx thread to check something
RtlInitSema(&spi_check_trx_sema, 1);
RtlDownSema(&spi_check_trx_sema);
// init semaphore for master tx
RtlInitSema(&master_tx_done_sema, 1);
RtlDownSema(&master_tx_done_sema);
// init semaphore for master rx
RtlInitSema(&master_rx_done_sema, 1);
RtlDownSema(&master_rx_done_sema);
}
int32_t spi_master_send(spi_t *obj, char *tx_buffer, uint32_t length) {
hrdy_pull_down_counter = 0;
spi_master_write_stream_dma(obj, tx_buffer, length);
RtlDownSema(&master_tx_done_sema);
if (spi_slave_status == SPI_SLAVE_BUSY) {
while (hrdy_pull_down_counter == 0);
hrdy_pull_down_counter = 0;
}
}
int32_t spi_master_recv(spi_t *obj, char *rx_buffer, uint32_t length) {
hrdy_pull_down_counter = 0;
spi_flush_rx_fifo(obj);
spi_master_read_stream_dma(obj, rx_buffer, length);
RtlDownSema(&master_rx_done_sema);
RtlDownSema(&master_tx_done_sema);
if (spi_slave_status == SPI_SLAVE_BUSY) {
while (hrdy_pull_down_counter == 0);
hrdy_pull_down_counter = 0;
}
}
void atcmd_check_special_case(char *buf) {
int i;
if (strlen(buf) > 4) {
if (strncmp(buf, "ATPT", 4) == 0) {
for (i=0; i<strlen(buf); i++) {
if (buf[i] == ':') {
buf[i] = '\0';
break;
}
}
}
}
}
static void spi_trx_thread(void *param)
{
uint32_t i;
uint32_t rxlen, txlen;
uint32_t recv_len, recv_remain, send_len;
uint16_t dummy, L_address, H_address, L_size, H_size;
int slave_ready = 0;
do {
slave_ready = gpio_read(&gpio_hrdy);
rtw_msleep_os(1000);
} while(slave_ready == 0);
while(1) {
RtlDownSema(&spi_check_trx_sema);
if (spi_state == SPI_STATE_MOSI) {
if (log_tx_idx > 0) {
/* Slave hw is ready, and Master has something to send. */
// stage A, read target address
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_BEGIN;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
gpio_write(&gpio_cs, 0);
spi_chunk_buffer[0] = PREAMBLE_DATA_READ;
spi_master_send(&spi_obj, spi_chunk_buffer, 1 * 2);
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
dummy = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
L_address = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
H_address = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
L_size = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
H_size = spi_chunk_buffer[0];
gpio_write(&gpio_cs, 1);
// stage B, write data
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_WRITE_BEGIN;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
if (log_tx_idx % 2 != 0) {
log_tx_buffer[log_tx_idx++] = 0;
}
send_len = log_tx_idx / 2;
L_size = send_len & 0x0000FFFF;
H_size = (send_len & 0xFFFF0000) >> 16;
gpio_write(&gpio_cs, 0);
txlen = 1;
spi_chunk_buffer[0] = PREAMBLE_DATA_WRITE;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = L_address;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = H_address;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = L_size;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = H_size;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
gpio_write(&gpio_cs, 0);
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_WRITE;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
txlen = log_tx_idx/2;
spi_master_send(&spi_obj, log_tx_buffer, txlen * 2); // sending raw data
gpio_write(&gpio_cs, 1);
// stage C, write data end
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_READ_WRITE_END;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
// stage final
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_END;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
L_size = log_tx_idx & 0x0000FFFF;
H_size = (log_tx_idx & 0xFFFF0000) >> 16;
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_WRITE;
spi_chunk_buffer[txlen++] = L_size;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_WRITE;
spi_chunk_buffer[txlen++] = H_size;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
// finalize
log_tx_idx = 0;
}
} else if (spi_state == SPI_STATE_MISO) {
/* Slave hw is ready, and Slave want to send something. */
do {
// stage A, read target address
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_BEGIN;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_READ;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
dummy = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
L_address = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
H_address = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
L_size = spi_chunk_buffer[0];
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2);
H_size = spi_chunk_buffer[0];
gpio_write(&gpio_cs, 1);
recv_len = ((H_size << 16) | L_size);
if (recv_len == 0) {
break;
}
// Stage B, confirm addr & len
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_READ_BEGIN;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
gpio_write(&gpio_cs, 0);
txlen = 1;
spi_chunk_buffer[0] = PREAMBLE_DATA_WRITE;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = L_address;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = H_address;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = L_size;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_chunk_buffer[0] = H_size;
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
// Stage C, begin to read
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_READ_RAW;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_READ;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
spi_master_recv(&spi_obj, spi_chunk_buffer, 1 * 2); // recv dummy
rxlen = recv_len;
spi_master_recv(&spi_obj, log_buf, rxlen * 2);
log_buf[rxlen*2]= '\0';
gpio_write(&gpio_cs, 1);
// Stage D, read end
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_READ_WRITE_END;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
// stage final
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_COMMAND;
spi_chunk_buffer[txlen++] = COMMAND_END;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
L_size = (recv_len) & 0x0000FFFF;
H_size = ((recv_len) & 0xFFFF0000) >> 16;
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_WRITE;
spi_chunk_buffer[txlen++] = L_size;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
txlen = 0;
spi_chunk_buffer[txlen++] = PREAMBLE_DATA_WRITE;
spi_chunk_buffer[txlen++] = H_size;
gpio_write(&gpio_cs, 0);
spi_master_send(&spi_obj, spi_chunk_buffer, txlen * 2);
gpio_write(&gpio_cs, 1);
// finalize
//printf("%s", log_buf);
atcmd_check_special_case(log_buf);
RtlUpSema(&log_rx_interrupt_sema);
taskYIELD();
} while (0);
}
}
vTaskDelete(NULL);
}
static void spi_atcmd_thread(void *param)
{
p_wlan_init_done_callback = NULL;
atcmd_wifi_restore_from_flash();
atcmd_lwip_restore_from_flash();
rtw_msleep_os(20);
spi_atcmd_main();
// the rx_buffer of atcmd is to receive and sending out to log_tx
atcmd_lwip_set_rx_buffer(log_tx_buffer, sizeof(log_tx_buffer));
at_set_debug_mask(0x0);
if(xTaskCreate(spi_trx_thread, ((const char*)"spi_trx_thread"), 4096, NULL, tskIDLE_PRIORITY+1 , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(spi_trx_thread) failed", __FUNCTION__);
vTaskDelete(NULL);
}
int spi_atcmd_module_init(void){
if(xTaskCreate(spi_atcmd_thread, ((const char*)"spi_atcmd_thread"), 1024, NULL, tskIDLE_PRIORITY+1 , NULL) != pdPASS)
printf("\n\r%s xTaskCreate(spi_atcmd_thread) failed", __FUNCTION__);
return 0;
}
void example_spi_atcmd(void)
{
p_wlan_init_done_callback = spi_atcmd_module_init;
return;
}
#endif // #if CONFIG_EXAMPLE_SPI_ATCMD

View File

@@ -0,0 +1,26 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#ifndef __EXAMPLE_SPI_ATCMD_H__
#define __EXAMPLE_SPI_ATCMD_H__
#if CONFIG_EXAMPLE_SPI_ATCMD
#define SPI0_MOSI PC_2
#define SPI0_MISO PC_3
#define SPI0_SCLK PC_1
#define SPI0_CS PC_0
#define GPIO_CS PA_3
#define GPIO_HRDY PA_1
#define GPIO_SYNC PB_3
void example_spi_atcmd(void);
#endif // #if CONFIG_EXAMPLE_SPI_ATCMD
#endif // #ifndef __EXAMPLE_SPI_ATCMD_H__

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*/

Some files were not shown because too many files have changed in this diff Show More