feat(example): Restructure examples folder

This commit is contained in:
Wu Jian Gang
2018-04-12 11:45:59 +08:00
parent 441c17634b
commit 3f0f3f152a
71 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := mqtt_demo
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,168 @@
# ESP8266 MQTT Client Demo
## 1. Introduction
This MQTT demo is based on the Eclipse Paho MQTT library, and demonstrates a working MQTT client actions(subscribe, publish, ping). Using this MQTT demo, you can connect to the MQTT broker, subscribe to a topic and publish messages to the predefined topic.
Also, this demo will ping the MQTT broker in the defined interval if no sending or receiving action happens. And we add some APIs to realize the SSL functionality, these SSL APIs provide the one-way certification and two-way certification.
## 2. Configuration
Some basic configurations need to be done before starting this demo and are listed in the include/user_config.h.
* Wi-Fi SSID & Password
* MQTT Broker Address(can be a domain name) & MQTT Port
>Note: There is a publically accessible sandbox server for the Eclipse IoT projects available at iot.eclipse.org, please get some reference information from the website: https://iot.eclipse.org/getting-started
## 3. Description
### 3.1 MQTT-Normal
This section describes the mqtt informations and API for MQTT client without SSL functionality.
#### 3.1.1 MQTT Info
For this MQTT demo, mqtt-related informations are defined in the mqtt_client_thread(), and they are listed below.
* two buffers(i.e. sendbuf[80] & readbuf[80]) to store packets to be sent and received
* MQTTVersion, ClientID, KeepAliveInterval, etc are defined using **MQTTPacket_connectData_initializer**
* Command_timeout is defined as 30s, and you can use this value as default
* The subscribe topic is defined as "ESP8266/sample/sub"
* The subscribe message handler is "void messageArrived(MessageData* data)"
* The publish topic is defined as "ESP8266/sample/pub"
* The published message's QoS type is QoS2
These informarions are only defined as a demonstration, you can change them appropriately according to your own requirements.
#### 3.1.2 Major API
1.Platform-Related
* NetworkInit(): used to initialize **Network** structure, which includes read/write functions, etc.
* NetworkConnect(): used to create socket and connect to the MQTT broker
2.MQTT-Related
* MQTTClientInit(): used to initialize **MQTTClient** structure, which includes MQTT client information
* MQTTStartTask(): a task used to perform MQTT **keep alive**
* MQTTConnect(): used to perform MQTT connect
* MQTTSubscribe(): used to subscribe to a topic
* MQTTPublish(): used to publish messages to a topic
### 3.2 MQTT-SSL
This section describes the mqtt informations and API for MQTT client with SSL functionality enabled.
#### 3.2.1 MQTT Info
The aforementioned informations in the **MQTT Info** section of **MQTT-Normal** are also used for MQTT-SSL. As for SSL functionality, some more information will be needed and are listed below in the "Added-Info" section.
1.Existed-Info
This section is the same with the **MQTT Info** section of **MQTT-Normal**.
2.Added-Info
* May need header files of CA (and client certificate & key) included in the include/ directory
* May need length of the CA (and client certificate & key) files
* Need a **ssl_ca_crt_key_t** structure initialized using the CA (and client certificate & key) files
#### 3.2.2 Major API
When SSL is enabled, the Platform-related API are different with **MQTT-Normal** section.
1.Platform-related
* NetworkInitSSL(): used to initialize **Network** structure, which includes SSL read/write functions, etc.
* NetworkConnectSSL(): used to create socket and connect to the MQTT broker with SSL enabled
2.MQTT-Related
This section is the same with the "MQTT-Related" section of "MQTT-Normal".
#### 3.2.3 SSL Special
For SSL functionality, three certification ways may be used: no certification, one-way certification and two-way certification. The specific configurations for each of them are described below:
1.No Certification
* No CA file and client certificate & key files need to be included
* Define a **ssl_ca_crt_key_t** structure
* Set the **cacrt**, **cert** and **key** parameters within the structure to be **NULL**
* Recommend to set the **verify_mode** parameter to **SSL_VERIFY_NONE**
* Set the **method** parameter to **TLSv1_1_client_method()** or **TLSv1_2_client_method()**
* Set the **frag_len** parameter with a value between **2048** and **8192**
2.One-way Certification
* CA file shall be included, also length of the CA file shall be provided
* Define a **ssl_ca_crt_key_t** structure
* Set the **cacrt** parameter within the structure to the array in the CA file
* Set the **cacrt_len** parameter to length of the CA file
* Set the **verify_mode** parameter to **SSL_VERIFY_PEER**
* Set the **method** parameter to **TLSv1_1_client_method()** or **TLSv1_2_client_method()**
* Set the **frag_len** parameter with a value between **2048** and **8192**
3.Two-way Certification
* CA file and client certificate & key files shall be included
* Also length of the CA file and client certificate & key files shall be provided
* Define a **ssl_ca_crt_key_t** structure
* Set the **cacrt** parameter within the structure to the array in the CA file
* Set the **cacrt_len** parameter to length of the CA file
* Set the **cert** parameter within the structure to the array in the client certificate file
* Set the **cert_len** parameter to length of the client certificate file
* Set the **key** parameter within the structure to the array in the client key file
* Set the **key_len** parameter to length of the client key file
* Set the **verify_mode** parameter to **SSL_VERIFY_PEER**
* Set the **method** parameter to **TLSv1_1_client_method()** or **TLSv1_2_client_method()**
* Set the **frag_len** parameter with a value between **2048** and **8192**
>Note: two-way certification is decided by the SSL Server side, so on the client side we just provide all the files needed by the two-way certification.
#### 3.2.4 SSL Demo
The following shows a simple demo of the MQTT client SSL functionality, and only the different places compared with MQTT-Normal demo are displayed. The names of CA file, client certificate & key files are just a demonstration, changing these properly according to your own files.
```c
#include "openssl/ssl.h"
#include "CA.h"
#include "cert.h"
#include "key.h"
ssl_ca_crt_key_t ssl_cck;
#define SSL_CA_CERT_KEY_INIT(s,a,b,c,d,e,f) ((ssl_ca_crt_key_t *)s)->cacrt = a;\
((ssl_ca_crt_key_t *)s)->cacrt_len = b;\
((ssl_ca_crt_key_t *)s)->cert = c;\
((ssl_ca_crt_key_t *)s)->cert_len = d;\
((ssl_ca_crt_key_t *)s)->key = e;\
((ssl_ca_crt_key_t *)s)->key_len = f;
static void mqtt_client_thread(void *pvParameters)
{
......
NetworkInitSSL(&network);
......
SSL_CA_CERT_KEY_INIT(&ssl_cck, ca_crt, ca_crt_len, client_crt, client_crt_len, client_key, client_key_len);
if ((rc = NetworkConnectSSL(&network, address, MQTT_PORT, &ssl_cck, TLSv1_1_client_method(), SSL_VERIFY_NONE, 8192)) != 1) {
printf("Return code from network connect ssl is %d\n", rc);
}
......
}
```
## 4. Compiling & Execution
Once all the aforementioned works are done, we can compile and download the MQTT client (SSL) demo, and a few more steps will be needed.
* Export SDK_PATH & BIN_PATH, and run gen_misc.sh to compile and generate binary files
* Download the binary files to flash and run, also you can use UART console to watch the output log
All these being done, the MQTT client demo will:
* Connect to the MQTT Broker
* Subscribe to the topic "ESP8266/sample/sub"
* Publish messages to the topic "ESP8266/sample/pub" every 1 seconds
* MQTT keep alive interval is 60s, so if no sending and receiving actions happended during this interval, ping request will be sent and ping response is expected to be received.

View File

@ -0,0 +1,118 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include <stddef.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "mqtt/MQTTClient.h"
#include "user_config.h"
#define MQTT_CLIENT_THREAD_NAME "mqtt_client_thread"
#define MQTT_CLIENT_THREAD_STACK_WORDS 2048
#define MQTT_CLIENT_THREAD_PRIO 8
LOCAL xTaskHandle mqttc_client_handle;
static void messageArrived(MessageData* data)
{
printf("Message arrived: %s\n", data->message->payload);
}
static void mqtt_client_thread(void* pvParameters)
{
printf("mqtt client thread starts\n");
MQTTClient client;
Network network;
unsigned char sendbuf[80], readbuf[80] = {0};
int rc = 0, count = 0;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
pvParameters = 0;
NetworkInit(&network);
MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
char* address = MQTT_BROKER;
if ((rc = NetworkConnect(&network, address, MQTT_PORT)) != 0) {
printf("Return code from network connect is %d\n", rc);
}
#if defined(MQTT_TASK)
if ((rc = MQTTStartTask(&client)) != pdPASS) {
printf("Return code from start tasks is %d\n", rc);
} else {
printf("Use MQTTStartTask\n");
}
#endif
connectData.MQTTVersion = 3;
connectData.clientID.cstring = "ESP8266_sample";
if ((rc = MQTTConnect(&client, &connectData)) != 0) {
printf("Return code from MQTT connect is %d\n", rc);
} else {
printf("MQTT Connected\n");
}
if ((rc = MQTTSubscribe(&client, "ESP8266/sample/sub", 2, messageArrived)) != 0) {
printf("Return code from MQTT subscribe is %d\n", rc);
} else {
printf("MQTT subscribe to topic \"ESP8266/sample/sub\"\n");
}
while (++count) {
MQTTMessage message;
char payload[30];
message.qos = QOS2;
message.retained = 0;
message.payload = payload;
sprintf(payload, "message number %d", count);
message.payloadlen = strlen(payload);
if ((rc = MQTTPublish(&client, "ESP8266/sample/pub", &message)) != 0) {
printf("Return code from MQTT publish is %d\n", rc);
} else {
printf("MQTT publish topic \"ESP8266/sample/pub\", message number is %d\n", count);
}
vTaskDelay(1000 / portTICK_RATE_MS); //send every 1 seconds
}
printf("mqtt_client_thread going to be deleted\n");
vTaskDelete(NULL);
return;
}
void user_conn_init(void)
{
int ret;
ret = xTaskCreate(mqtt_client_thread,
MQTT_CLIENT_THREAD_NAME,
MQTT_CLIENT_THREAD_STACK_WORDS,
NULL,
MQTT_CLIENT_THREAD_PRIO,
&mqttc_client_handle);
if (ret != pdPASS) {
printf("mqtt create client thread %s failed\n", MQTT_CLIENT_THREAD_NAME);
}
}

View File

@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -0,0 +1,35 @@
/*
* ESPRESSIF MIT License
*
* Copyright (c) 2017 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __USER_CONFIG_H__
#define __USER_CONFIG_H__
#define SSID "espressif" /* Wi-Fi SSID */
#define PASSWORD "1234567890" /* Wi-Fi Password */
#define MQTT_BROKER "iot.eclipse.org" /* MQTT Broker Address*/
#define MQTT_PORT 1883 /* MQTT Port*/
#endif

View File

@ -0,0 +1,122 @@
/*
* ESPRESSIF MIT License
*
* Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "esp_common.h"
#include "user_config.h"
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void wifi_event_handler_cb(System_Event_t *event)
{
if (event == NULL) {
return;
}
switch (event->event_id) {
case EVENT_STAMODE_GOT_IP:
os_printf("sta got ip ,create task and free heap size is %d\n", system_get_free_heap_size());
user_conn_init();
break;
case EVENT_STAMODE_CONNECTED:
os_printf("sta connected\n");
break;
case EVENT_STAMODE_DISCONNECTED:
wifi_station_connect();
break;
default:
break;
}
}
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
os_printf("SDK version:%s %d\n", system_get_sdk_version(), system_get_free_heap_size());
wifi_set_opmode(STATION_MODE);
struct station_config config;
bzero(&config, sizeof(struct station_config));
sprintf(config.ssid, SSID);
sprintf(config.password, PASSWORD);
wifi_station_set_config(&config);
wifi_set_event_handler_cb(wifi_event_handler_cb);
wifi_station_connect();
}