initial commit
This commit is contained in:
@@ -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__);
|
||||
}
|
||||
@@ -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 */
|
||||
11
lib/amb1_sdk/common/example/alc_dsp_fw_upgrade/readme.txt
Normal file
11
lib/amb1_sdk/common/example/alc_dsp_fw_upgrade/readme.txt
Normal 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
|
||||
|
||||
@@ -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)
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_AMAZON_AWSIOT_H
|
||||
#define EXAMPLE_AMAZON_AWSIOT_H
|
||||
|
||||
void example_amazon_awsiot(void);
|
||||
|
||||
#endif /* EXAMPLE_AMAZON_AWSIOT_H */
|
||||
13
lib/amb1_sdk/common/example/amazon_awsiot/readme.txt
Normal file
13
lib/amb1_sdk/common/example/amazon_awsiot/readme.txt
Normal 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.
|
||||
|
||||
364
lib/amb1_sdk/common/example/audio/example_audio.c
Normal file
364
lib/amb1_sdk/common/example/audio/example_audio.c
Normal 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__);
|
||||
}
|
||||
|
||||
BIN
lib/amb1_sdk/common/example/audio_mp3/AudioSDTest.mp3
Normal file
BIN
lib/amb1_sdk/common/example/audio_mp3/AudioSDTest.mp3
Normal file
Binary file not shown.
15
lib/amb1_sdk/common/example/audio_mp3/README.txt
Normal file
15
lib/amb1_sdk/common/example/audio_mp3/README.txt
Normal 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
|
||||
246
lib/amb1_sdk/common/example/audio_mp3/example_audio_mp3.c
Normal file
246
lib/amb1_sdk/common/example/audio_mp3/example_audio_mp3.c
Normal 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__);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifdef _EXAMPLE_AUDIO_H_
|
||||
#define _EXAMPLE_AUDIO_H_
|
||||
|
||||
void example_audio_mp3(void);
|
||||
|
||||
#endif
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -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 */
|
||||
11
lib/amb1_sdk/common/example/audio_pcm_upload/readme.txt
Normal file
11
lib/amb1_sdk/common/example/audio_pcm_upload/readme.txt
Normal 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
|
||||
|
||||
81
lib/amb1_sdk/common/example/bcast/example_bcast.c
Normal file
81
lib/amb1_sdk/common/example/bcast/example_bcast.c
Normal 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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/bcast/example_bcast.h
Normal file
6
lib/amb1_sdk/common/example/bcast/example_bcast.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_BCAST_H
|
||||
#define EXAMPLE_BCAST_H
|
||||
|
||||
void example_bcast(void);
|
||||
|
||||
#endif /* EXAMPLE_BCAST_H */
|
||||
28
lib/amb1_sdk/common/example/bcast/readme.txt
Normal file
28
lib/amb1_sdk/common/example/bcast/readme.txt
Normal 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.
|
||||
86
lib/amb1_sdk/common/example/cJSON/cJSON_example.c
Normal file
86
lib/amb1_sdk/common/example/cJSON/cJSON_example.c
Normal 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);
|
||||
}
|
||||
}
|
||||
99
lib/amb1_sdk/common/example/coap/example_coap.c
Normal file
99
lib/amb1_sdk/common/example/coap/example_coap.c
Normal 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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/coap/example_coap.h
Normal file
6
lib/amb1_sdk/common/example/coap/example_coap.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_COAP_H
|
||||
#define EXAMPLE_COAP_H
|
||||
|
||||
void example_coap(void);
|
||||
|
||||
#endif /* EXAMPLE_COAP_H */
|
||||
6
lib/amb1_sdk/common/example/coap/readme.txt
Normal file
6
lib/amb1_sdk/common/example/coap/readme.txt
Normal 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.
|
||||
16
lib/amb1_sdk/common/example/dct/README.txt
Normal file
16
lib/amb1_sdk/common/example/dct/README.txt
Normal 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.
|
||||
82
lib/amb1_sdk/common/example/dct/example_dct.c
Normal file
82
lib/amb1_sdk/common/example/dct/example_dct.c
Normal 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
|
||||
7
lib/amb1_sdk/common/example/dct/example_dct.h
Normal file
7
lib/amb1_sdk/common/example/dct/example_dct.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef _EXAMPLE_DCT_H
|
||||
#define _EXAMPLE_DCT_H
|
||||
|
||||
void example_dct(void);
|
||||
|
||||
#endif /* _EXAMPLE_DCT_H */
|
||||
|
||||
164
lib/amb1_sdk/common/example/eap/example_eap.c
Normal file
164
lib/amb1_sdk/common/example/eap/example_eap.c
Normal 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 */
|
||||
9
lib/amb1_sdk/common/example/eap/example_eap.h
Normal file
9
lib/amb1_sdk/common/example/eap/example_eap.h
Normal 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
|
||||
34
lib/amb1_sdk/common/example/eap/readme.txt
Normal file
34
lib/amb1_sdk/common/example/eap/readme.txt
Normal 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.
|
||||
595
lib/amb1_sdk/common/example/example_entry.c
Normal file
595
lib/amb1_sdk/common/example/example_entry.c
Normal 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
|
||||
|
||||
}
|
||||
8
lib/amb1_sdk/common/example/example_entry.h
Normal file
8
lib/amb1_sdk/common/example/example_entry.h
Normal 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__
|
||||
171
lib/amb1_sdk/common/example/fatfs/example_fatfs.c
Normal file
171
lib/amb1_sdk/common/example/fatfs/example_fatfs.c
Normal 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
|
||||
7
lib/amb1_sdk/common/example/fatfs/example_fatfs.h
Normal file
7
lib/amb1_sdk/common/example/fatfs/example_fatfs.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef _EXAMPLE_FATFS_H
|
||||
#define _EXAMPLE_FATFS_H
|
||||
|
||||
void example_fatfs(void);
|
||||
|
||||
#endif /* _EXAMPLE_FATFS_H */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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__
|
||||
13
lib/amb1_sdk/common/example/get_beacon_frame/readme.txt
Normal file
13
lib/amb1_sdk/common/example/get_beacon_frame/readme.txt
Normal 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.
|
||||
|
||||
38
lib/amb1_sdk/common/example/googlenest/example.html
Normal file
38
lib/amb1_sdk/common/example/googlenest/example.html
Normal 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>
|
||||
240
lib/amb1_sdk/common/example/googlenest/example_google.c
Normal file
240
lib/amb1_sdk/common/example/googlenest/example_google.c
Normal 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__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
10
lib/amb1_sdk/common/example/googlenest/example_google.h
Normal file
10
lib/amb1_sdk/common/example/googlenest/example_google.h
Normal 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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
41
lib/amb1_sdk/common/example/high_load_memory_use/readme.txt
Normal file
41
lib/amb1_sdk/common/example/high_load_memory_use/readme.txt
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__
|
||||
13
lib/amb1_sdk/common/example/http_client/readme.txt
Normal file
13
lib/amb1_sdk/common/example/http_client/readme.txt
Normal 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.
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_HTTP_DOWNLOAD_H
|
||||
#define EXAMPLE_HTTP_DOWNLOAD_H
|
||||
|
||||
void example_http_download(void);
|
||||
|
||||
#endif /* EXAMPLE_HTTP_DOWNLOAD_H */
|
||||
15
lib/amb1_sdk/common/example/http_download/readme.txt
Normal file
15
lib/amb1_sdk/common/example/http_download/readme.txt
Normal 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.
|
||||
|
||||
137
lib/amb1_sdk/common/example/httpc/example_httpc.c
Normal file
137
lib/amb1_sdk/common/example/httpc/example_httpc.c
Normal 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¶m2=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¶m2=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¶m2=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¶m2=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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/httpc/example_httpc.h
Normal file
6
lib/amb1_sdk/common/example/httpc/example_httpc.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_HTTPC_H
|
||||
#define EXAMPLE_HTTPC_H
|
||||
|
||||
void example_httpc(void);
|
||||
|
||||
#endif /* EXAMPLE_HTTPC_H */
|
||||
15
lib/amb1_sdk/common/example/httpc/readme.txt
Normal file
15
lib/amb1_sdk/common/example/httpc/readme.txt
Normal 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.
|
||||
191
lib/amb1_sdk/common/example/httpd/example_httpd.c
Normal file
191
lib/amb1_sdk/common/example/httpd/example_httpd.c
Normal 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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/httpd/example_httpd.h
Normal file
6
lib/amb1_sdk/common/example/httpd/example_httpd.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_HTTPD_H
|
||||
#define EXAMPLE_HTTPD_H
|
||||
|
||||
void example_httpd(void);
|
||||
|
||||
#endif /* EXAMPLE_HTTPD_H */
|
||||
23
lib/amb1_sdk/common/example/httpd/readme.txt
Normal file
23
lib/amb1_sdk/common/example/httpd/readme.txt
Normal 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.
|
||||
|
||||
149
lib/amb1_sdk/common/example/inic_gspi/example_inic_gspi.c
Normal file
149
lib/amb1_sdk/common/example/inic_gspi/example_inic_gspi.c
Normal 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
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef _EXAMPLE_INIC_H
|
||||
#define _EXAMPLE_INIC_H
|
||||
|
||||
void example_inic(void);
|
||||
|
||||
#endif /* _EXAMPLE_INIC_H */
|
||||
|
||||
98
lib/amb1_sdk/common/example/mcast/example_mcast.c
Normal file
98
lib/amb1_sdk/common/example/mcast/example_mcast.c
Normal 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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/mcast/example_mcast.h
Normal file
6
lib/amb1_sdk/common/example/mcast/example_mcast.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_MCAST_H
|
||||
#define EXAMPLE_MCAST_H
|
||||
|
||||
void example_mcast(void);
|
||||
|
||||
#endif /* EXAMPLE_MCAST_H */
|
||||
17
lib/amb1_sdk/common/example/mcast/readme.txt
Normal file
17
lib/amb1_sdk/common/example/mcast/readme.txt
Normal 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.
|
||||
|
||||
55
lib/amb1_sdk/common/example/mdns/example_mdns.c
Normal file
55
lib/amb1_sdk/common/example/mdns/example_mdns.c
Normal 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__);
|
||||
}
|
||||
6
lib/amb1_sdk/common/example/mdns/example_mdns.h
Normal file
6
lib/amb1_sdk/common/example/mdns/example_mdns.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_MDNS_H
|
||||
#define EXAMPLE_MDNS_H
|
||||
|
||||
void example_mdns(void);
|
||||
|
||||
#endif /* EXAMPLE_MDNS_H */
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
13
lib/amb1_sdk/common/example/media_audio_from_rtp/readme.txt
Normal file
13
lib/amb1_sdk/common/example/media_audio_from_rtp/readme.txt
Normal 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)
|
||||
@@ -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************************************************/
|
||||
@@ -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 */
|
||||
@@ -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.
|
||||
188
lib/amb1_sdk/common/example/media_time_lapse/example_media_tl.c
Normal file
188
lib/amb1_sdk/common/example/media_time_lapse/example_media_tl.c
Normal 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************************************************/
|
||||
@@ -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 */
|
||||
3
lib/amb1_sdk/common/example/media_time_lapse/lapse.bat
Normal file
3
lib/amb1_sdk/common/example/media_time_lapse/lapse.bat
Normal 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
|
||||
6
lib/amb1_sdk/common/example/media_time_lapse/readme.txt
Normal file
6
lib/amb1_sdk/common/example/media_time_lapse/readme.txt
Normal 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.
|
||||
195
lib/amb1_sdk/common/example/mqtt/example_mqtt.c
Normal file
195
lib/amb1_sdk/common/example/mqtt/example_mqtt.c
Normal 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);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
6
lib/amb1_sdk/common/example/mqtt/example_mqtt.h
Normal file
6
lib/amb1_sdk/common/example/mqtt/example_mqtt.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_MQTT_H
|
||||
#define EXAMPLE_MQTT_H
|
||||
|
||||
void example_mqtt(void);
|
||||
|
||||
#endif /* EXAMPLE_MQTT_H */
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_NONBLOCK_CONNECT_H
|
||||
#define EXAMPLE_NONBLOCK_CONNECT_H
|
||||
|
||||
void example_nonblock_connect(void);
|
||||
|
||||
#endif /* EXAMPLE_NONBLOCK_CONNECT_H */
|
||||
16
lib/amb1_sdk/common/example/nonblock_connect/readme.txt
Normal file
16
lib/amb1_sdk/common/example/nonblock_connect/readme.txt
Normal 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.
|
||||
39
lib/amb1_sdk/common/example/ota_http/example_ota_http.c
Normal file
39
lib/amb1_sdk/common/example/ota_http/example_ota_http.c
Normal 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
|
||||
|
||||
6
lib/amb1_sdk/common/example/ota_http/example_ota_http.h
Normal file
6
lib/amb1_sdk/common/example/ota_http/example_ota_http.h
Normal 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 */
|
||||
23
lib/amb1_sdk/common/example/ota_http/readme.txt
Normal file
23
lib/amb1_sdk/common/example/ota_http/readme.txt
Normal 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)
|
||||
|
||||
77
lib/amb1_sdk/common/example/pppoe/example_pppoe.c
Normal file
77
lib/amb1_sdk/common/example/pppoe/example_pppoe.c
Normal 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 */
|
||||
6
lib/amb1_sdk/common/example/pppoe/example_pppoe.h
Normal file
6
lib/amb1_sdk/common/example/pppoe/example_pppoe.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_PPPOE_H
|
||||
#define EXAMPLE_PPPOE_H
|
||||
|
||||
void example_pppoe(void);
|
||||
|
||||
#endif /* EXAMPLE_PPPOE_H */
|
||||
21
lib/amb1_sdk/common/example/pppoe/readme.txt
Normal file
21
lib/amb1_sdk/common/example/pppoe/readme.txt
Normal 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
|
||||
47
lib/amb1_sdk/common/example/rarp/example_rarp.c
Normal file
47
lib/amb1_sdk/common/example/rarp/example_rarp.c
Normal 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;
|
||||
}
|
||||
8
lib/amb1_sdk/common/example/rarp/example_rarp.h
Normal file
8
lib/amb1_sdk/common/example/rarp/example_rarp.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef EXAMPLE_RARP_H
|
||||
#define EXAMPLE_RARP_H
|
||||
|
||||
void example_rarp(void);
|
||||
|
||||
|
||||
#endif /* EXAMPLE_RARP_H */
|
||||
|
||||
20
lib/amb1_sdk/common/example/rarp/readme.txt
Normal file
20
lib/amb1_sdk/common/example/rarp/readme.txt
Normal 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
|
||||
|
||||
|
||||
27
lib/amb1_sdk/common/example/s3_upload/User Guide.txt
Normal file
27
lib/amb1_sdk/common/example/s3_upload/User Guide.txt
Normal 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 PC’s (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 PC’s 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’
|
||||
851
lib/amb1_sdk/common/example/s3_upload/example_s3_upload.c
Normal file
851
lib/amb1_sdk/common/example/s3_upload/example_s3_upload.c
Normal 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(¤t_sec), strlen(ctime(¤t_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__);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_S3_UPLOAD_H
|
||||
#define EXAMPLE_S3_UPLOAD_H
|
||||
|
||||
void example_s3_upload(void);
|
||||
|
||||
#endif /* EXAMPLE_S3_UPLOAD_H */
|
||||
29
lib/amb1_sdk/common/example/s3_upload/readme.txt
Normal file
29
lib/amb1_sdk/common/example/s3_upload/readme.txt
Normal 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
|
||||
@@ -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(¤t_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__);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_SNTP_SHOWTIME_H
|
||||
#define EXAMPLE_SNTP_SHOWTIME_H
|
||||
|
||||
void example_sntp_showtime(void);
|
||||
|
||||
#endif /* EXAMPLE_SNTP_SHOWTIME_H */
|
||||
14
lib/amb1_sdk/common/example/sntp_showtime/readme.txt
Normal file
14
lib/amb1_sdk/common/example/sntp_showtime/readme.txt
Normal 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.
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef EXAMPLE_SOCKET_SELECT_H
|
||||
#define EXAMPLE_SOCKET_SELECT_H
|
||||
|
||||
void example_socket_select(void);
|
||||
|
||||
#endif /* EXAMPLE_SOCKET_SELECT_H */
|
||||
17
lib/amb1_sdk/common/example/socket_select/readme.txt
Normal file
17
lib/amb1_sdk/common/example/socket_select/readme.txt
Normal 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.
|
||||
@@ -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 */
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -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__);
|
||||
}
|
||||
22
lib/amb1_sdk/common/example/socket_tcp_trx/readme.txt
Normal file
22
lib/amb1_sdk/common/example/socket_tcp_trx/readme.txt
Normal 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
|
||||
651
lib/amb1_sdk/common/example/spi_atcmd/example_spi_atcmd.c
Normal file
651
lib/amb1_sdk/common/example/spi_atcmd/example_spi_atcmd.c
Normal 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
|
||||
26
lib/amb1_sdk/common/example/spi_atcmd/example_spi_atcmd.h
Normal file
26
lib/amb1_sdk/common/example/spi_atcmd/example_spi_atcmd.h
Normal 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__
|
||||
274
lib/amb1_sdk/common/example/ssl_download/example_ssl_download.c
Normal file
274
lib/amb1_sdk/common/example/ssl_download/example_ssl_download.c
Normal 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
Reference in New Issue
Block a user