├── image ├── dma.jpg ├── web.png ├── cube1.jpg ├── cube2.jpg ├── main.png ├── device.jpg └── framework.png ├── .gitignore ├── Src ├── ESP8266Client │ └── src │ │ ├── wifi_credentials.h │ │ ├── ESP8266Client.h │ │ ├── networkwrapper.h │ │ └── networkwrapper.c ├── bh1750_i2c_drv.c ├── MQTTPacket │ ├── CMakeLists.txt │ └── src │ │ ├── CMakeLists.txt │ │ ├── MQTTUnsubscribe.h │ │ ├── MQTTSubscribe.h │ │ ├── MQTTPublish.h │ │ ├── MQTTFormat.h │ │ ├── StackTrace.h │ │ ├── MQTTUnsubscribeServer.c │ │ ├── transport.h │ │ ├── MQTTUnsubscribeClient.c │ │ ├── MQTTSubscribeServer.c │ │ ├── MQTTDeserializePublish.c │ │ ├── MQTTPacket.h │ │ ├── MQTTSubscribeClient.c │ │ ├── transport.c │ │ ├── MQTTConnectServer.c │ │ ├── MQTTConnect.h │ │ ├── MQTTSerializePublish.c │ │ ├── MQTTConnectClient.c │ │ ├── MQTTFormat.c │ │ └── MQTTPacket.c ├── sys.c ├── dma.c ├── gpio.c ├── stm32f1xx_hal_msp.c ├── sysmem.c ├── tim.c ├── i2c.c ├── fifo.c ├── syscalls.c ├── usart.c ├── stm32f1xx_it.c └── system_stm32f1xx.c ├── Inc ├── bh1750_i2c_drv.h ├── topic_name_helper.h ├── fifo.h ├── sys.h ├── gpio.h ├── i2c.h ├── tim.h ├── dma.h ├── usart.h ├── stm32f1xx_it.h └── main.h ├── platformio.ini ├── Final_pro.elf.cfg ├── LICENSE ├── .project ├── Final_pro.elf.launch ├── .mxproject ├── README.md └── Final_pro.ioc /image/dma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/dma.jpg -------------------------------------------------------------------------------- /image/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/web.png -------------------------------------------------------------------------------- /image/cube1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/cube1.jpg -------------------------------------------------------------------------------- /image/cube2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/cube2.jpg -------------------------------------------------------------------------------- /image/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/main.png -------------------------------------------------------------------------------- /image/device.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/device.jpg -------------------------------------------------------------------------------- /image/framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TsingWei/stm32_iot_light_sensor/HEAD/image/framework.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/ 3 | .settings/ 4 | *.elf 5 | Drivers/ 6 | Debug/ 7 | Release/ 8 | Startup/ 9 | report/ 10 | *.ld -------------------------------------------------------------------------------- /Src/ESP8266Client/src/wifi_credentials.h: -------------------------------------------------------------------------------- 1 | #ifndef _WIFI_CREDENTIALS_H 2 | #define _WIFI_CREDENTIALS_H 3 | 4 | #define WIFI_AP_SSID "SUSTC-Wifi" 5 | #define WIFI_AP_PASS "12345678" 6 | #define SERVER_ADDR ("10.21.100.203") 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Src/bh1750_i2c_drv.c: -------------------------------------------------------------------------------- 1 | #include "bh1750_i2c_drv.h" 2 | #include "i2c.h" 3 | 4 | uint8_t BH1750_Send_Cmd(BH1750_MODE cmd) 5 | { 6 | return HAL_I2C_Master_Transmit(&hi2c2, BH1750_ADDR_WRITE, (uint8_t*)&cmd, 1, 0xFFFF); 7 | } 8 | 9 | uint8_t BH1750_Read_Dat(uint8_t* dat) 10 | { 11 | return HAL_I2C_Master_Receive(&hi2c2, BH1750_ADDR_READ, dat, 2, 0xFFFF); 12 | } 13 | 14 | uint16_t BH1750_Dat_To_Lux(uint8_t* dat) 15 | { 16 | uint16_t lux = 0; 17 | lux = dat[0]; 18 | lux <<= 8; 19 | lux += dat[1]; 20 | lux = (int)(lux / 1.2); 21 | 22 | return lux; 23 | } 24 | -------------------------------------------------------------------------------- /Inc/bh1750_i2c_drv.h: -------------------------------------------------------------------------------- 1 | #include 2 | #define BH1750_ADDR_WRITE 0x46 //01000110 3 | #define BH1750_ADDR_READ 0x47 //01000111 4 | 5 | typedef enum 6 | { 7 | POWER_OFF_CMD = 0x00, //断电:无激活状态 8 | POWER_ON_CMD = 0x01, //通电:等待测量指令 9 | RESET_REGISTER = 0x07, //重置数字寄存器(在断电状态下不起作用) 10 | CONT_H_MODE = 0x10, //连续H分辨率模式:在11x分辨率下开始测量,测量时间120ms 11 | CONT_H_MODE2 = 0x11, //连续H分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms 12 | CONT_L_MODE = 0x13, //连续L分辨率模式:在411分辨率下开始测量,测量时间16ms 13 | ONCE_H_MODE = 0x20, //一次高分辨率模式:在11x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 14 | ONCE_H_MODE2 = 0x21, //一次高分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 15 | ONCE_L_MODE = 0x23 //一次低分辨率模式:在411x分辨率下开始测量,测量时间16ms,测量后自动设置为断电模式 16 | } BH1750_MODE; 17 | 18 | uint8_t BH1750_Send_Cmd(BH1750_MODE cmd); 19 | uint16_t BH1750_Dat_To_Lux(uint8_t* dat); 20 | 21 | -------------------------------------------------------------------------------- /Inc/topic_name_helper.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEDS_TOPIC 1 4 | #define LEDH_TOPIC 2 5 | #define LIGHT_TOPIC 3 6 | #define MODE_TOPIC 4 7 | 8 | const char* leds_topic_name = "leds"; 9 | const char* ledh_topic_name = "ledh"; 10 | const char* light_topic_name = "light"; 11 | const char* mode_topic_name = "mode"; 12 | 13 | int getTopicCode(const char* topic_name){ 14 | if(!strcmp(topic_name,leds_topic_name)) 15 | return LEDS_TOPIC; 16 | if(!strcmp(topic_name,ledh_topic_name)) 17 | return LEDH_TOPIC; 18 | if(!strcmp(topic_name,light_topic_name)) 19 | return LIGHT_TOPIC; 20 | if(!strcmp(topic_name,mode_topic_name)) 21 | return MODE_TOPIC; 22 | } 23 | 24 | // Only parse the first one char to unsigned int. 25 | int getPayLoadValue(const char* payload){ 26 | return payload[0]-48; 27 | } 28 | -------------------------------------------------------------------------------- /Src/MQTTPacket/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Copyright (c) 2017 IBM Corp. 3 | # 4 | # All rights reserved. This program and the accompanying materials 5 | # are made available under the terms of the Eclipse Public License v1.0 6 | # and Eclipse Distribution License v1.0 which accompany this distribution. 7 | # 8 | # The Eclipse Public License is available at 9 | # http://www.eclipse.org/legal/epl-v10.html 10 | # and the Eclipse Distribution License is available at 11 | # http://www.eclipse.org/org/documents/edl-v10.php. 12 | # 13 | # Contributors: 14 | # Ian Craggs - initial version 15 | #*******************************************************************************/ 16 | 17 | project("paho-mqttpacket" C) 18 | 19 | ADD_SUBDIRECTORY(src) 20 | ADD_SUBDIRECTORY(samples) 21 | ADD_SUBDIRECTORY(test) 22 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ;PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | include_dir=Inc 13 | src_dir=Src 14 | ; lib_deps=FreeRTOS 15 | ; lib_dir=Middlewares/Third_Party 16 | lib_dir=Lib 17 | 18 | [common] 19 | build_flags = -std=gnu99 -Wl,-u,_printf_float 20 | -ISrc/MQTTPacket/src 21 | -ISrc/ESP8266Client/src 22 | -DconfigUSE_STATS_FORMATTING_FUNCTIONS=2 23 | 24 | 25 | [env:genericSTM32F103RC] 26 | platform = ststm32 27 | board = genericSTM32F103RC 28 | framework = stm32cube 29 | monitor_speed = 115200 30 | build_flags = ${common.build_flags} 31 | upload_protocol = stlink 32 | debug_tool = stlink 33 | 34 | -------------------------------------------------------------------------------- /Final_pro.elf.cfg: -------------------------------------------------------------------------------- 1 | # This is an genericBoard board with a single STM32F103RCTx chip 2 | # 3 | # Generated by STM32CubeIDE 4 | # Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s) 5 | 6 | source [find interface/stlink.cfg] 7 | 8 | set WORKAREASIZE 0x8000 9 | 10 | transport select "hla_swd" 11 | 12 | set CHIPNAME STM32F103RCTx 13 | set BOARDNAME genericBoard 14 | 15 | # Enable debug when in low power modes 16 | set ENABLE_LOW_POWER 1 17 | 18 | # Stop Watchdog counters when halt 19 | set STOP_WATCHDOG 1 20 | 21 | # STlink Debug clock frequency 22 | set CLOCK_FREQ 8000 23 | 24 | # Reset configuration 25 | # use hardware reset, connect under reset 26 | # connect_assert_srst needed if low power mode application running (WFI...) 27 | reset_config srst_only srst_nogate connect_assert_srst 28 | set CONNECT_UNDER_RESET 1 29 | set CORE_RESET 0 30 | 31 | 32 | 33 | # BCTM CPU variables 34 | 35 | 36 | 37 | source [find target/stm32f1x.cfg] 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 TsingWei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Final_pro 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | com.st.stm32cube.ide.mcu.MCUProjectNature 23 | org.eclipse.cdt.core.cnature 24 | com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAProjectNature 25 | com.st.stm32cube.ide.mcu.MCUCubeProjectNature 26 | com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature 27 | com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature 28 | com.st.stm32cube.ide.mcu.MCURootProjectNature 29 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 30 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 31 | 32 | 33 | -------------------------------------------------------------------------------- /Inc/fifo.h: -------------------------------------------------------------------------------- 1 | /* Define to prevent recursive inclusion -------------------------------------*/ 2 | #ifndef _FIFO_H 3 | #define _FIFO_H 4 | 5 | // #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /* Includes ------------------------------------------------------------------*/ 12 | /* Define --------------------------------------------------------------------*/ 13 | #ifndef min 14 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 15 | #endif 16 | 17 | #define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) 18 | 19 | /* Private typedef -----------------------------------------------------------*/ 20 | struct fifo { 21 | unsigned int in; 22 | unsigned int out; 23 | unsigned int mask; 24 | unsigned char *data; 25 | }; 26 | 27 | /* Function prototypes -------------------------------------------------------*/ 28 | extern unsigned int fifo_used(struct fifo *fifo); 29 | extern signed int fifo_alloc(struct fifo *fifo, unsigned int size); 30 | extern void fifo_free(struct fifo *fifo); 31 | extern int fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size); 32 | extern unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len); 33 | extern unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /Src/sys.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : SYS.c 4 | * Description : This file provides code for the configuration 5 | * of the SYS instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "sys.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | /* SYS init function */ 28 | void MX_SYS_Init(void) 29 | { 30 | 31 | /** NOJTAG: JTAG-DP Disabled and SW-DP Enabled 32 | */ 33 | __HAL_AFIO_REMAP_SWJ_NOJTAG(); 34 | 35 | } 36 | 37 | /* USER CODE BEGIN 1 */ 38 | 39 | /* USER CODE END 1 */ 40 | 41 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 42 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #******************************************************************************* 2 | # Copyright (c) 2017 IBM Corp. 3 | # 4 | # All rights reserved. This program and the accompanying materials 5 | # are made available under the terms of the Eclipse Public License v1.0 6 | # and Eclipse Distribution License v1.0 which accompany this distribution. 7 | # 8 | # The Eclipse Public License is available at 9 | # http://www.eclipse.org/legal/epl-v10.html 10 | # and the Eclipse Distribution License is available at 11 | # http://www.eclipse.org/org/documents/edl-v10.php. 12 | # 13 | # Contributors: 14 | # Ian Craggs - initial version 15 | #*******************************************************************************/ 16 | 17 | # MQTTPacket Library 18 | file(GLOB SOURCES "*.c") 19 | add_library(paho-embed-mqtt3c SHARED ${SOURCES}) 20 | install(TARGETS paho-embed-mqtt3c DESTINATION /usr/lib) 21 | target_compile_definitions(paho-embed-mqtt3c PRIVATE MQTT_SERVER MQTT_CLIENT) 22 | 23 | add_library(MQTTPacketClient SHARED MQTTFormat MQTTPacket 24 | MQTTSerializePublish MQTTDeserializePublish 25 | MQTTConnectClient MQTTSubscribeClient MQTTUnsubscribeClient) 26 | target_compile_definitions(MQTTPacketClient PRIVATE MQTT_CLIENT) 27 | 28 | add_library(MQTTPacketServer SHARED MQTTFormat MQTTPacket 29 | MQTTSerializePublish MQTTDeserializePublish 30 | MQTTConnectServer MQTTSubscribeServer MQTTUnsubscribeServer) 31 | target_compile_definitions(MQTTPacketServer PRIVATE MQTT_SERVER) 32 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTUnsubscribe.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTUNSUBSCRIBE_H_ 19 | #define MQTTUNSUBSCRIBE_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 29 | int count, MQTTString topicFilters[]); 30 | 31 | DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[], 32 | unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid); 35 | 36 | DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len); 37 | 38 | #endif /* MQTTUNSUBSCRIBE_H_ */ 39 | -------------------------------------------------------------------------------- /Inc/sys.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : SYS.h 4 | * Description : This file provides code for the configuration 5 | * of the SYS instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __sys_H 21 | #define __sys_H 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | #include "main.h" 28 | 29 | /* USER CODE BEGIN Includes */ 30 | 31 | /* USER CODE END Includes */ 32 | 33 | /* USER CODE BEGIN Private defines */ 34 | 35 | /* USER CODE END Private defines */ 36 | 37 | void MX_SYS_Init(void); 38 | 39 | /* USER CODE BEGIN Prototypes */ 40 | 41 | /* USER CODE END Prototypes */ 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | #endif /*__ sys_H */ 47 | 48 | /** 49 | * @} 50 | */ 51 | 52 | /** 53 | * @} 54 | */ 55 | 56 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 57 | -------------------------------------------------------------------------------- /Inc/gpio.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : gpio.h 4 | * Description : This file contains all the functions prototypes for 5 | * the gpio 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __gpio_H 22 | #define __gpio_H 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "main.h" 29 | 30 | /* USER CODE BEGIN Includes */ 31 | 32 | /* USER CODE END Includes */ 33 | 34 | /* USER CODE BEGIN Private defines */ 35 | 36 | /* USER CODE END Private defines */ 37 | 38 | void MX_GPIO_Init(void); 39 | 40 | /* USER CODE BEGIN Prototypes */ 41 | 42 | /* USER CODE END Prototypes */ 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | #endif /*__ pinoutConfig_H */ 48 | 49 | /** 50 | * @} 51 | */ 52 | 53 | /** 54 | * @} 55 | */ 56 | 57 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 58 | -------------------------------------------------------------------------------- /Inc/i2c.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : I2C.h 4 | * Description : This file provides code for the configuration 5 | * of the I2C instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __i2c_H 21 | #define __i2c_H 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | #include "main.h" 28 | 29 | /* USER CODE BEGIN Includes */ 30 | 31 | /* USER CODE END Includes */ 32 | 33 | extern I2C_HandleTypeDef hi2c2; 34 | 35 | /* USER CODE BEGIN Private defines */ 36 | 37 | /* USER CODE END Private defines */ 38 | 39 | void MX_I2C2_Init(void); 40 | 41 | /* USER CODE BEGIN Prototypes */ 42 | 43 | /* USER CODE END Prototypes */ 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif /*__ i2c_H */ 49 | 50 | /** 51 | * @} 52 | */ 53 | 54 | /** 55 | * @} 56 | */ 57 | 58 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 59 | -------------------------------------------------------------------------------- /Inc/tim.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : TIM.h 4 | * Description : This file provides code for the configuration 5 | * of the TIM instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __tim_H 21 | #define __tim_H 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | #include "main.h" 28 | 29 | /* USER CODE BEGIN Includes */ 30 | 31 | /* USER CODE END Includes */ 32 | 33 | extern TIM_HandleTypeDef htim2; 34 | 35 | /* USER CODE BEGIN Private defines */ 36 | 37 | /* USER CODE END Private defines */ 38 | 39 | void MX_TIM2_Init(void); 40 | 41 | /* USER CODE BEGIN Prototypes */ 42 | 43 | /* USER CODE END Prototypes */ 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif /*__ tim_H */ 49 | 50 | /** 51 | * @} 52 | */ 53 | 54 | /** 55 | * @} 56 | */ 57 | 58 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 59 | -------------------------------------------------------------------------------- /Inc/dma.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : dma.h 4 | * Description : This file contains all the function prototypes for 5 | * the dma.c file 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __dma_H 21 | #define __dma_H 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /* Includes ------------------------------------------------------------------*/ 28 | #include "main.h" 29 | 30 | /* DMA memory to memory transfer handles -------------------------------------*/ 31 | 32 | /* USER CODE BEGIN Includes */ 33 | 34 | /* USER CODE END Includes */ 35 | 36 | /* USER CODE BEGIN Private defines */ 37 | 38 | /* USER CODE END Private defines */ 39 | 40 | void MX_DMA_Init(void); 41 | 42 | /* USER CODE BEGIN Prototypes */ 43 | 44 | /* USER CODE END Prototypes */ 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* __dma_H */ 51 | 52 | /** 53 | * @} 54 | */ 55 | 56 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 57 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTSubscribe.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTSUBSCRIBE_H_ 19 | #define MQTTSUBSCRIBE_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 29 | int count, MQTTString topicFilters[], int requestedQoSs[]); 30 | 31 | DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, 32 | int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs); 35 | 36 | DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len); 37 | 38 | 39 | #endif /* MQTTSUBSCRIBE_H_ */ 40 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTPublish.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTPUBLISH_H_ 19 | #define MQTTPUBLISH_H_ 20 | 21 | #if !defined(DLLImport) 22 | #define DLLImport 23 | #endif 24 | #if !defined(DLLExport) 25 | #define DLLExport 26 | #endif 27 | 28 | DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, 29 | MQTTString topicName, unsigned char* payload, int payloadlen); 30 | 31 | DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, 32 | unsigned char** payload, int* payloadlen, unsigned char* buf, int len); 33 | 34 | DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid); 35 | DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid); 36 | DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid); 37 | 38 | #endif /* MQTTPUBLISH_H_ */ 39 | -------------------------------------------------------------------------------- /Inc/usart.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : USART.h 4 | * Description : This file provides code for the configuration 5 | * of the USART instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __usart_H 21 | #define __usart_H 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | #include "main.h" 28 | 29 | /* USER CODE BEGIN Includes */ 30 | 31 | /* USER CODE END Includes */ 32 | 33 | extern UART_HandleTypeDef huart1; 34 | extern UART_HandleTypeDef huart2; 35 | 36 | /* USER CODE BEGIN Private defines */ 37 | 38 | /* USER CODE END Private defines */ 39 | 40 | void MX_USART1_UART_Init(void); 41 | void MX_USART2_UART_Init(void); 42 | 43 | /* USER CODE BEGIN Prototypes */ 44 | void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart); 45 | /* USER CODE END Prototypes */ 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | #endif /*__ usart_H */ 51 | 52 | /** 53 | * @} 54 | */ 55 | 56 | /** 57 | * @} 58 | */ 59 | 60 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 61 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTFormat.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #if !defined(MQTTFORMAT_H) 18 | #define MQTTFORMAT_H 19 | 20 | #include "StackTrace.h" 21 | #include "MQTTPacket.h" 22 | 23 | const char* MQTTPacket_getName(unsigned short packetid); 24 | int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data); 25 | int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent); 26 | int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, 27 | unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen); 28 | int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid); 29 | int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, 30 | MQTTString topicFilters[], int requestedQoSs[]); 31 | int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs); 32 | int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, 33 | int count, MQTTString topicFilters[]); 34 | char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); 35 | char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Src/dma.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : dma.c 4 | * Description : This file provides code for the configuration 5 | * of all the requested memory to memory DMA transfers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "dma.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | /*----------------------------------------------------------------------------*/ 28 | /* Configure DMA */ 29 | /*----------------------------------------------------------------------------*/ 30 | 31 | /* USER CODE BEGIN 1 */ 32 | 33 | /* USER CODE END 1 */ 34 | 35 | /** 36 | * Enable DMA controller clock 37 | */ 38 | void MX_DMA_Init(void) 39 | { 40 | 41 | /* DMA controller clock enable */ 42 | __HAL_RCC_DMA1_CLK_ENABLE(); 43 | 44 | /* DMA interrupt init */ 45 | /* DMA1_Channel4_IRQn interrupt configuration */ 46 | HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0); 47 | HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); 48 | /* DMA1_Channel5_IRQn interrupt configuration */ 49 | HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); 50 | HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); 51 | /* DMA1_Channel6_IRQn interrupt configuration */ 52 | HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 1, 0); 53 | HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); 54 | /* DMA1_Channel7_IRQn interrupt configuration */ 55 | HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0); 56 | HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn); 57 | 58 | } 59 | 60 | /* USER CODE BEGIN 2 */ 61 | 62 | /* USER CODE END 2 */ 63 | 64 | /** 65 | * @} 66 | */ 67 | 68 | /** 69 | * @} 70 | */ 71 | 72 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 73 | -------------------------------------------------------------------------------- /Src/ESP8266Client/src/ESP8266Client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file esp8266client.c 3 | * @author Atakan S. 4 | * @date 01/01/2019 5 | * @version 1.0 6 | * @brief ESP8266 Client Mode Driver. 7 | * 8 | * @copyright Copyright (c) 2018 Atakan SARIOGLU ~ www.atakansarioglu.com 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a 11 | * copy of this software and associated documentation files (the "Software"), 12 | * to deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #ifndef _ESP8266CLIENT_H_ 30 | #define _ESP8266CLIENT_H_ 31 | 32 | // Includes. 33 | #include 34 | #include 35 | #include 36 | 37 | // Type definitions. 38 | typedef int32_t ESP82_Result_t; 39 | #define ESP82_ERROR (-1) 40 | #define ESP82_INPROGRESS (0) 41 | #define ESP82_SUCCESS (1) 42 | #define ESP82_RECEIVE_NOTHING (-2) 43 | 44 | // Prototypes. 45 | void ESP82_Init(const uint32_t baud, const uint8_t parity, uint32_t (* const getTime_ms_functionHandler)(void)); 46 | ESP82_Result_t ESP82_CheckPresence(void); 47 | ESP82_Result_t ESP82_ConnectWifi(const bool resetToDefault, const char * ssid, const char * pass); 48 | ESP82_Result_t ESP82_IsConnectedWifi(void); 49 | ESP82_Result_t ESP82_StartTCP(const char * host, const uint16_t port, const uint16_t keepalive, const bool ssl); 50 | ESP82_Result_t ESP82_CloseTCP(void); 51 | ESP82_Result_t ESP82_Send(const char * const data, const uint8_t dataLength); 52 | ESP82_Result_t ESP82_Receive(char * const data, const uint8_t dataLengthMax); 53 | ESP82_Result_t ESP82_Delay(const uint16_t delay_ms); 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /Inc/stm32f1xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f1xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F1xx_IT_H 23 | #define __STM32F1xx_IT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* Private includes ----------------------------------------------------------*/ 30 | /* USER CODE BEGIN Includes */ 31 | 32 | /* USER CODE END Includes */ 33 | 34 | /* Exported types ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN ET */ 36 | 37 | /* USER CODE END ET */ 38 | 39 | /* Exported constants --------------------------------------------------------*/ 40 | /* USER CODE BEGIN EC */ 41 | 42 | /* USER CODE END EC */ 43 | 44 | /* Exported macro ------------------------------------------------------------*/ 45 | /* USER CODE BEGIN EM */ 46 | 47 | /* USER CODE END EM */ 48 | 49 | /* Exported functions prototypes ---------------------------------------------*/ 50 | void NMI_Handler(void); 51 | void HardFault_Handler(void); 52 | void MemManage_Handler(void); 53 | void BusFault_Handler(void); 54 | void UsageFault_Handler(void); 55 | void SVC_Handler(void); 56 | void DebugMon_Handler(void); 57 | void PendSV_Handler(void); 58 | void SysTick_Handler(void); 59 | void DMA1_Channel4_IRQHandler(void); 60 | void DMA1_Channel5_IRQHandler(void); 61 | void DMA1_Channel6_IRQHandler(void); 62 | void DMA1_Channel7_IRQHandler(void); 63 | void TIM2_IRQHandler(void); 64 | void USART1_IRQHandler(void); 65 | void USART2_IRQHandler(void); 66 | /* USER CODE BEGIN EFP */ 67 | 68 | /* USER CODE END EFP */ 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* __STM32F1xx_IT_H */ 75 | 76 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 77 | -------------------------------------------------------------------------------- /Src/gpio.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : gpio.c 4 | * Description : This file provides code for the configuration 5 | * of all used GPIO pins. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "gpio.h" 22 | /* USER CODE BEGIN 0 */ 23 | 24 | /* USER CODE END 0 */ 25 | 26 | /*----------------------------------------------------------------------------*/ 27 | /* Configure GPIO */ 28 | /*----------------------------------------------------------------------------*/ 29 | /* USER CODE BEGIN 1 */ 30 | 31 | /* USER CODE END 1 */ 32 | 33 | /** Configure pins as 34 | * Analog 35 | * Input 36 | * Output 37 | * EVENT_OUT 38 | * EXTI 39 | */ 40 | void MX_GPIO_Init(void) 41 | { 42 | 43 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 44 | 45 | /* GPIO Ports Clock Enable */ 46 | __HAL_RCC_GPIOD_CLK_ENABLE(); 47 | __HAL_RCC_GPIOA_CLK_ENABLE(); 48 | __HAL_RCC_GPIOB_CLK_ENABLE(); 49 | 50 | /*Configure GPIO pin Output Level */ 51 | HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET); 52 | 53 | /*Configure GPIO pin Output Level */ 54 | HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); 55 | 56 | /*Configure GPIO pin : PtPin */ 57 | GPIO_InitStruct.Pin = LED0_Pin; 58 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 59 | GPIO_InitStruct.Pull = GPIO_NOPULL; 60 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 61 | HAL_GPIO_Init(LED0_GPIO_Port, &GPIO_InitStruct); 62 | 63 | /*Configure GPIO pin : PtPin */ 64 | GPIO_InitStruct.Pin = LED1_Pin; 65 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 66 | GPIO_InitStruct.Pull = GPIO_NOPULL; 67 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 68 | HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct); 69 | 70 | } 71 | 72 | /* USER CODE BEGIN 2 */ 73 | 74 | /* USER CODE END 2 */ 75 | 76 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 77 | -------------------------------------------------------------------------------- /Inc/main.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.h 5 | * @brief : Header for main.c file. 6 | * This file contains the common defines of the application. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2019 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __MAIN_H 24 | #define __MAIN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "stm32f1xx_hal.h" 32 | 33 | /* Private includes ----------------------------------------------------------*/ 34 | /* USER CODE BEGIN Includes */ 35 | 36 | /* USER CODE END Includes */ 37 | 38 | /* Exported types ------------------------------------------------------------*/ 39 | /* USER CODE BEGIN ET */ 40 | 41 | /* USER CODE END ET */ 42 | 43 | /* Exported constants --------------------------------------------------------*/ 44 | /* USER CODE BEGIN EC */ 45 | 46 | /* USER CODE END EC */ 47 | 48 | /* Exported macro ------------------------------------------------------------*/ 49 | /* USER CODE BEGIN EM */ 50 | 51 | /* USER CODE END EM */ 52 | 53 | /* Exported functions prototypes ---------------------------------------------*/ 54 | void Error_Handler(void); 55 | 56 | /* USER CODE BEGIN EFP */ 57 | #ifdef __GNUC__ 58 | #define PUTCHAR_PROTO int __io_putchar(int ch) 59 | #else 60 | #define PUTCHAR_PROTO int fputc(int ch, FILE *f) 61 | #endif /* __GNUC__ */ 62 | /* USER CODE END EFP */ 63 | 64 | /* Private defines -----------------------------------------------------------*/ 65 | #define LED0_Pin GPIO_PIN_8 66 | #define LED0_GPIO_Port GPIOA 67 | #define LED1_Pin GPIO_PIN_2 68 | #define LED1_GPIO_Port GPIOD 69 | /* USER CODE BEGIN Private defines */ 70 | #define RX_BUFFER_SIZE 256 71 | #define FIFO_BUFFER_SIZE 1024 72 | /* USER CODE END Private defines */ 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif /* __MAIN_H */ 79 | 80 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 81 | -------------------------------------------------------------------------------- /Src/stm32f1xx_hal_msp.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * File Name : stm32f1xx_hal_msp.c 5 | * Description : This file provides code for the MSP Initialization 6 | * and de-Initialization codes. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2019 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Includes ------------------------------------------------------------------*/ 23 | #include "main.h" 24 | /* USER CODE BEGIN Includes */ 25 | 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN Define */ 35 | 36 | /* USER CODE END Define */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN Macro */ 40 | 41 | /* USER CODE END Macro */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* External functions --------------------------------------------------------*/ 54 | /* USER CODE BEGIN ExternalFunctions */ 55 | 56 | /* USER CODE END ExternalFunctions */ 57 | 58 | /* USER CODE BEGIN 0 */ 59 | 60 | /* USER CODE END 0 */ 61 | /** 62 | * Initializes the Global MSP. 63 | */ 64 | void HAL_MspInit(void) 65 | { 66 | /* USER CODE BEGIN MspInit 0 */ 67 | 68 | /* USER CODE END MspInit 0 */ 69 | 70 | __HAL_RCC_AFIO_CLK_ENABLE(); 71 | __HAL_RCC_PWR_CLK_ENABLE(); 72 | 73 | /* System interrupt init*/ 74 | 75 | /** NOJTAG: JTAG-DP Disabled and SW-DP Enabled 76 | */ 77 | __HAL_AFIO_REMAP_SWJ_NOJTAG(); 78 | 79 | /* USER CODE BEGIN MspInit 1 */ 80 | 81 | /* USER CODE END MspInit 1 */ 82 | } 83 | 84 | /* USER CODE BEGIN 1 */ 85 | 86 | /* USER CODE END 1 */ 87 | 88 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 89 | -------------------------------------------------------------------------------- /Src/ESP8266Client/src/networkwrapper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file networkwrapper.h 3 | * @author Atakan S. 4 | * @date 01/01/2019 5 | * @version 1.0 6 | * @brief Network wrapper for PAHO MQTT project based on ESP8266. 7 | * 8 | * @copyright Copyright (c) 2018 Atakan SARIOGLU ~ www.atakansarioglu.com 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a 11 | * copy of this software and associated documentation files (the "Software"), 12 | * to deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #ifndef _NETWORKWRAPPER_H 30 | #define _NETWORKWRAPPER_H 31 | 32 | // Socket data type. 33 | #ifndef network_socket_t 34 | #define network_socket_t void* 35 | #endif 36 | 37 | /* 38 | * @brief Initialize network subsystem. 39 | */ 40 | void network_init(void); 41 | 42 | /* 43 | * @brief Close network connection. 44 | */ 45 | void network_close(void); 46 | 47 | /* 48 | * @brief Starts the connection or saves the parameters and defers the connection to the send/recv methods. 49 | * @param host Host name. 50 | * @param port Remote port number. 51 | * @param keepalive Seconds for keepalive function. 52 | * @param ssl If true, SSL connection type will be used, otherwise TCP. 53 | * @return Returns 0 on success and negative on error. 54 | */ 55 | int network_connect(const char * host, const unsigned short int port, const unsigned short int keepalive, const char ssl); 56 | 57 | /* 58 | * @brief NON-BLOCKING Sends data and mimics transparency. 59 | * @param address Pointer to the data to be sent. 60 | * @param bytes Number of bytes to be sent. 61 | * @return Returns the number of actual data bytes sent or negative on error. 62 | */ 63 | int network_send(unsigned char *address, unsigned int bytes); 64 | 65 | /* 66 | * @brief NON-BLOCKING Receives data and mimics transparency. 67 | * @param address Pointer to the memory into that the received data is stored. 68 | * @param maxbytes Number of maximum bytes to be received. 69 | * @return Returns the number of actual data bytes received or negative on error. 70 | */ 71 | int network_recv(unsigned char *address, unsigned int maxbytes); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /Src/sysmem.c: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | ** 4 | ** File : sysmem.c 5 | ** 6 | ** Author : Auto-generated by STM32CubeIDE 7 | ** 8 | ** Abstract : STM32CubeIDE Minimal System Memory calls file 9 | ** 10 | ** For more information about which c-functions 11 | ** need which of these lowlevel functions 12 | ** please consult the Newlib libc-manual 13 | ** 14 | ** Environment : STM32CubeIDE MCU 15 | ** 16 | ** Distribution: The file is distributed as is, without any warranty 17 | ** of any kind. 18 | ** 19 | ***************************************************************************** 20 | ** 21 | **

© COPYRIGHT(c) 2018 STMicroelectronics

22 | ** 23 | ** Redistribution and use in source and binary forms, with or without modification, 24 | ** are permitted provided that the following conditions are met: 25 | ** 1. Redistributions of source code must retain the above copyright notice, 26 | ** this list of conditions and the following disclaimer. 27 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 28 | ** this list of conditions and the following disclaimer in the documentation 29 | ** and/or other materials provided with the distribution. 30 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 31 | ** may be used to endorse or promote products derived from this software 32 | ** without specific prior written permission. 33 | ** 34 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 38 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 41 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 42 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | ** 45 | ** 46 | ***************************************************************************** 47 | */ 48 | 49 | /* Includes */ 50 | #include 51 | #include 52 | 53 | /* Variables */ 54 | extern int errno; 55 | register char * stack_ptr asm("sp"); 56 | 57 | /* Functions */ 58 | 59 | /** 60 | _sbrk 61 | Increase program data space. Malloc and related functions depend on this 62 | **/ 63 | caddr_t _sbrk(int incr) 64 | { 65 | extern char end asm("end"); 66 | static char *heap_end; 67 | char *prev_heap_end; 68 | 69 | if (heap_end == 0) 70 | heap_end = &end; 71 | 72 | prev_heap_end = heap_end; 73 | if (heap_end + incr > stack_ptr) 74 | { 75 | errno = ENOMEM; 76 | return (caddr_t) -1; 77 | } 78 | 79 | heap_end += incr; 80 | 81 | return (caddr_t) prev_heap_end; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /Src/tim.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : TIM.c 4 | * Description : This file provides code for the configuration 5 | * of the TIM instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "tim.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | TIM_HandleTypeDef htim2; 28 | 29 | /* TIM2 init function */ 30 | void MX_TIM2_Init(void) 31 | { 32 | TIM_ClockConfigTypeDef sClockSourceConfig = {0}; 33 | TIM_MasterConfigTypeDef sMasterConfig = {0}; 34 | 35 | htim2.Instance = TIM2; 36 | htim2.Init.Prescaler = 7199; 37 | htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 38 | htim2.Init.Period = 4999; 39 | htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 40 | htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 41 | if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 42 | { 43 | Error_Handler(); 44 | } 45 | sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 46 | if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) 47 | { 48 | Error_Handler(); 49 | } 50 | sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 51 | sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 52 | if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) 53 | { 54 | Error_Handler(); 55 | } 56 | 57 | } 58 | 59 | void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) 60 | { 61 | 62 | if(tim_baseHandle->Instance==TIM2) 63 | { 64 | /* USER CODE BEGIN TIM2_MspInit 0 */ 65 | 66 | /* USER CODE END TIM2_MspInit 0 */ 67 | /* TIM2 clock enable */ 68 | __HAL_RCC_TIM2_CLK_ENABLE(); 69 | 70 | /* TIM2 interrupt Init */ 71 | HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); 72 | HAL_NVIC_EnableIRQ(TIM2_IRQn); 73 | /* USER CODE BEGIN TIM2_MspInit 1 */ 74 | 75 | /* USER CODE END TIM2_MspInit 1 */ 76 | } 77 | } 78 | 79 | void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) 80 | { 81 | 82 | if(tim_baseHandle->Instance==TIM2) 83 | { 84 | /* USER CODE BEGIN TIM2_MspDeInit 0 */ 85 | 86 | /* USER CODE END TIM2_MspDeInit 0 */ 87 | /* Peripheral clock disable */ 88 | __HAL_RCC_TIM2_CLK_DISABLE(); 89 | 90 | /* TIM2 interrupt Deinit */ 91 | HAL_NVIC_DisableIRQ(TIM2_IRQn); 92 | /* USER CODE BEGIN TIM2_MspDeInit 1 */ 93 | 94 | /* USER CODE END TIM2_MspDeInit 1 */ 95 | } 96 | } 97 | 98 | /* USER CODE BEGIN 1 */ 99 | 100 | /* USER CODE END 1 */ 101 | 102 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 103 | -------------------------------------------------------------------------------- /Src/i2c.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : I2C.c 4 | * Description : This file provides code for the configuration 5 | * of the I2C instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "i2c.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | I2C_HandleTypeDef hi2c2; 28 | 29 | /* I2C2 init function */ 30 | void MX_I2C2_Init(void) 31 | { 32 | 33 | hi2c2.Instance = I2C2; 34 | hi2c2.Init.ClockSpeed = 100000; 35 | hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; 36 | hi2c2.Init.OwnAddress1 = 0; 37 | hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 38 | hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 39 | hi2c2.Init.OwnAddress2 = 0; 40 | hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 41 | hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 42 | if (HAL_I2C_Init(&hi2c2) != HAL_OK) 43 | { 44 | Error_Handler(); 45 | } 46 | 47 | } 48 | 49 | void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) 50 | { 51 | 52 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 53 | if(i2cHandle->Instance==I2C2) 54 | { 55 | /* USER CODE BEGIN I2C2_MspInit 0 */ 56 | __HAL_RCC_I2C2_CLK_ENABLE(); 57 | /* USER CODE END I2C2_MspInit 0 */ 58 | 59 | __HAL_RCC_GPIOB_CLK_ENABLE(); 60 | /**I2C2 GPIO Configuration 61 | PB10 ------> I2C2_SCL 62 | PB11 ------> I2C2_SDA 63 | */ 64 | GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; 65 | GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; 66 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 67 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 68 | 69 | /* I2C2 clock enable */ 70 | __HAL_RCC_I2C2_CLK_ENABLE(); 71 | /* USER CODE BEGIN I2C2_MspInit 1 */ 72 | 73 | /* USER CODE END I2C2_MspInit 1 */ 74 | } 75 | } 76 | 77 | void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) 78 | { 79 | 80 | if(i2cHandle->Instance==I2C2) 81 | { 82 | /* USER CODE BEGIN I2C2_MspDeInit 0 */ 83 | 84 | /* USER CODE END I2C2_MspDeInit 0 */ 85 | /* Peripheral clock disable */ 86 | __HAL_RCC_I2C2_CLK_DISABLE(); 87 | 88 | /**I2C2 GPIO Configuration 89 | PB10 ------> I2C2_SCL 90 | PB11 ------> I2C2_SDA 91 | */ 92 | HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11); 93 | 94 | /* USER CODE BEGIN I2C2_MspDeInit 1 */ 95 | 96 | /* USER CODE END I2C2_MspDeInit 1 */ 97 | } 98 | } 99 | 100 | /* USER CODE BEGIN 1 */ 101 | 102 | /* USER CODE END 1 */ 103 | 104 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 105 | -------------------------------------------------------------------------------- /Src/fifo.c: -------------------------------------------------------------------------------- 1 | /* Includes -----------------------------------------------------------------*/ 2 | #include "fifo.h" 3 | #include "stdlib.h" 4 | #include "string.h" 5 | // #include "includes.h" 6 | 7 | /* Variables -----------------------------------------------------------------*/ 8 | /* Private functions ---------------------------------------------------------*/ 9 | /******************************************************************************/ 10 | 11 | /* 12 | * internal helper to calculate the unused elements in a fifo 13 | */ 14 | static __inline unsigned int fifo_unused(struct fifo *fifo) 15 | { 16 | return (fifo->mask + 1) - (fifo->in - fifo->out); 17 | } 18 | 19 | unsigned int fifo_used(struct fifo *fifo) 20 | { 21 | return (fifo->in - fifo->out); 22 | } 23 | 24 | signed int fifo_alloc(struct fifo *fifo, unsigned int size) 25 | { 26 | /* 27 | * round down to the next power of 2, since our 'let the indices 28 | * wrap' technique works only in this case. 29 | */ 30 | if (!is_power_of_2(size)) 31 | return -1; 32 | 33 | fifo->in = 1; 34 | fifo->out = 1; 35 | 36 | if (size < 2){ 37 | fifo->data = NULL; 38 | fifo->mask = 0; 39 | return -1; 40 | } 41 | fifo->data = malloc(size); 42 | 43 | if (!fifo->data){ 44 | fifo->mask = 0; 45 | return -1; 46 | } 47 | fifo->mask = size - 1; 48 | 49 | return 0; 50 | } 51 | 52 | void fifo_free(struct fifo *fifo) 53 | { 54 | free(fifo->data); 55 | fifo->in = 0; 56 | fifo->out = 0; 57 | fifo->data = NULL; 58 | fifo->mask = 0; 59 | } 60 | 61 | int fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size) 62 | { 63 | if (!is_power_of_2(size)) 64 | return -1; 65 | 66 | fifo->in = 0; 67 | fifo->out = 0; 68 | fifo->data = buffer; 69 | 70 | if (size < 2) { 71 | fifo->mask = 0; 72 | return -1; 73 | } 74 | fifo->mask = size - 1; 75 | 76 | return 0; 77 | } 78 | 79 | static void fifo_copy_in(struct fifo *fifo, unsigned char *src, unsigned int len, unsigned int off) 80 | { 81 | unsigned int size = fifo->mask + 1; 82 | unsigned int l; 83 | 84 | off &= fifo->mask; 85 | 86 | l = min(len, size - off); 87 | 88 | memcpy(fifo->data + off, src, l); 89 | memcpy(fifo->data, src + l, len - l); 90 | } 91 | 92 | unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len) 93 | { 94 | unsigned int l; 95 | 96 | l = fifo_unused(fifo); 97 | if (len > l) 98 | len = l; 99 | 100 | fifo_copy_in(fifo, buf, len, fifo->in); 101 | fifo->in += len; 102 | 103 | return len; 104 | } 105 | 106 | static void fifo_copy_out(struct fifo *fifo, unsigned char *dst, unsigned int len, unsigned int off) 107 | { 108 | unsigned int size = fifo->mask + 1; 109 | unsigned int l; 110 | 111 | off &= fifo->mask; 112 | l = min(len, size - off); 113 | 114 | memcpy(dst, fifo->data + off, l); 115 | memcpy(dst + l, fifo->data, len - l); 116 | } 117 | 118 | unsigned int fifo_out_peek(struct fifo *fifo, unsigned char *buf, unsigned int len) 119 | { 120 | unsigned int l; 121 | 122 | l = fifo->in - fifo->out; 123 | if (len > l) 124 | len = l; 125 | 126 | fifo_copy_out(fifo, buf, len, fifo->out); 127 | return len; 128 | } 129 | 130 | unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len) 131 | { 132 | len = fifo_out_peek(fifo, buf, len); 133 | fifo->out += len; 134 | return len; 135 | } 136 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/StackTrace.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - fix for bug #434081 16 | *******************************************************************************/ 17 | 18 | #ifndef STACKTRACE_H_ 19 | #define STACKTRACE_H_ 20 | 21 | #include 22 | #define NOSTACKTRACE 1 23 | 24 | #if defined(NOSTACKTRACE) 25 | #define FUNC_ENTRY 26 | #define FUNC_ENTRY_NOLOG 27 | #define FUNC_ENTRY_MED 28 | #define FUNC_ENTRY_MAX 29 | #define FUNC_EXIT 30 | #define FUNC_EXIT_NOLOG 31 | #define FUNC_EXIT_MED 32 | #define FUNC_EXIT_MAX 33 | #define FUNC_EXIT_RC(x) 34 | #define FUNC_EXIT_MED_RC(x) 35 | #define FUNC_EXIT_MAX_RC(x) 36 | 37 | #else 38 | 39 | #if defined(WIN32) 40 | #define inline __inline 41 | #define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM) 42 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1) 43 | #define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM) 44 | #define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM) 45 | #define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM) 46 | #define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1) 47 | #define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM) 48 | #define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM) 49 | #define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM) 50 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM) 51 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM) 52 | #else 53 | #define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM) 54 | #define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1) 55 | #define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM) 56 | #define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM) 57 | #define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM) 58 | #define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1) 59 | #define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM) 60 | #define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM) 61 | #define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM) 62 | #define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM) 63 | #define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM) 64 | 65 | void StackTrace_entry(const char* name, int line, int trace); 66 | void StackTrace_exit(const char* name, int line, void* return_value, int trace); 67 | 68 | void StackTrace_printStack(FILE* dest); 69 | char* StackTrace_get(unsigned long); 70 | 71 | #endif 72 | 73 | #endif 74 | 75 | 76 | 77 | 78 | #endif /* STACKTRACE_H_ */ 79 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTUnsubscribeServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into unsubscribe data 25 | * @param dup integer returned - the MQTT dup flag 26 | * @param packetid integer returned - the MQTT packet identifier 27 | * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays 28 | * @param count - number of members in the topicFilters and requestedQoSs arrays 29 | * @param topicFilters - array of topic filter names 30 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 31 | * @param buflen the length in bytes of the data in the supplied buffer 32 | * @return the length of the serialized data. <= 0 indicates error 33 | */ 34 | int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], 35 | unsigned char* buf, int len) 36 | { 37 | MQTTHeader header = {0}; 38 | unsigned char* curdata = buf; 39 | unsigned char* enddata = NULL; 40 | int rc = 0; 41 | int mylen = 0; 42 | 43 | FUNC_ENTRY; 44 | header.byte = readChar(&curdata); 45 | if (header.bits.type != UNSUBSCRIBE) 46 | goto exit; 47 | *dup = header.bits.dup; 48 | 49 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 50 | enddata = curdata + mylen; 51 | 52 | *packetid = readInt(&curdata); 53 | 54 | *count = 0; 55 | while (curdata < enddata) 56 | { 57 | if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) 58 | goto exit; 59 | (*count)++; 60 | } 61 | 62 | rc = 1; 63 | exit: 64 | FUNC_EXIT_RC(rc); 65 | return rc; 66 | } 67 | 68 | 69 | /** 70 | * Serializes the supplied unsuback data into the supplied buffer, ready for sending 71 | * @param buf the buffer into which the packet will be serialized 72 | * @param buflen the length in bytes of the supplied buffer 73 | * @param packetid integer - the MQTT packet identifier 74 | * @return the length of the serialized data. <= 0 indicates error 75 | */ 76 | int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid) 77 | { 78 | MQTTHeader header = {0}; 79 | int rc = 0; 80 | unsigned char *ptr = buf; 81 | 82 | FUNC_ENTRY; 83 | if (buflen < 2) 84 | { 85 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 86 | goto exit; 87 | } 88 | header.byte = 0; 89 | header.bits.type = UNSUBACK; 90 | writeChar(&ptr, header.byte); /* write header */ 91 | 92 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 93 | 94 | writeInt(&ptr, packetid); 95 | 96 | rc = ptr - buf; 97 | exit: 98 | FUNC_EXIT_RC(rc); 99 | return rc; 100 | } 101 | 102 | 103 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/transport.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - media specifics, nice api doc :^) 16 | *******************************************************************************/ 17 | 18 | typedef struct { 19 | int (*send)(unsigned char *address, unsigned int bytes); ///< pointer to function to send 'bytes' bytes, returns the actual number of bytes sent 20 | int (*recv)(unsigned char *address, unsigned int maxbytes); ///< pointer to function to receive upto 'maxbytes' bytes, returns the actual number of bytes copied 21 | } transport_iofunctions_t; 22 | 23 | #define TRANSPORT_DONE 1 24 | #define TRANSPORT_AGAIN 0 25 | #define TRANSPORT_ERROR -1 26 | /** 27 | @note Blocks until requested buflen is sent 28 | */ 29 | int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen); 30 | /** 31 | @note Blocks until requested count is received, as MQTTPacket_read() expects 32 | @warning This function is not supported (not implemented) 33 | @warning unless you provide a timeout, this function can block forever. Socket based systems do have 34 | a built in timeout, if your system can provide this, do modify this function, otherwise use getdatanb() instead 35 | @returns number of bytes read 36 | */ 37 | int transport_getdata(unsigned char* buf, int count); 38 | 39 | /** 40 | This is a bare metal implementation, so we must have non-blocking functions, 41 | the process of pumping to serial lines can result a bit slow and we don't want to busy wait. 42 | This function starts the process, you will call sendPacketBuffernb() until it reports success (or error) 43 | */ 44 | void transport_sendPacketBuffernb_start(int sock, unsigned char* buf, int buflen); 45 | /** 46 | This is a bare metal implementation, so we must have non-blocking functions, 47 | the process of pumping to serial lines can result a bit slow and we don't want to busy wait 48 | @returns TRANSPORT_DONE if finished, TRANSPORT_AGAIN for call again, or TRANSPORT_ERROR on error 49 | @note you will call again until it finishes (this is stream) 50 | */ 51 | int transport_sendPacketBuffernb(int sock); 52 | 53 | /** 54 | This is a bare metal implementation, so we must have non-blocking functions, 55 | the process of sucking from serial lines can result a bit slow and we don't want to busy wait 56 | @return the actual number of bytes read, 0 for none, or TRANSPORT_ERROR on error 57 | @note you will call again until total number of expected bytes is read (this is stream) 58 | */ 59 | int transport_getdatanb(void *sck, unsigned char* buf, int count); 60 | 61 | /** 62 | We assume whatever connection needs to be done, it is externally established by the specifics of the hardware 63 | E.g.: 64 | A cell modem: you will call AT+whatever and put the modem in transparent mode, OR, you will embed 65 | the AT+xSENDx / AT+xRECVx commands into the former sendPacketBuffer() and getdatanb() functions 66 | @param thisio pointer to a structure containing all necessary stuff to handle direct serial I/O 67 | @returns whatever indicator the system assigns to this link, if any. (a.k.a. : 'sock'), or TRANSPORT_ERROR for error 68 | */ 69 | int transport_open(transport_iofunctions_t *thisio); 70 | int transport_close(int sock); 71 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTUnsubscribeClient.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | /** 23 | * Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters 24 | * @param count the number of topic filter strings in topicFilters 25 | * @param topicFilters the array of topic filter strings to be used in the publish 26 | * @return the length of buffer needed to contain the serialized version of the packet 27 | */ 28 | int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[]) 29 | { 30 | int i; 31 | int len = 2; /* packetid */ 32 | 33 | for (i = 0; i < count; ++i) 34 | len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/ 35 | return len; 36 | } 37 | 38 | 39 | /** 40 | * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending 41 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 42 | * @param buflen the length in bytes of the data in the supplied buffer 43 | * @param dup integer - the MQTT dup flag 44 | * @param packetid integer - the MQTT packet identifier 45 | * @param count - number of members in the topicFilters array 46 | * @param topicFilters - array of topic filter names 47 | * @return the length of the serialized data. <= 0 indicates error 48 | */ 49 | int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, 50 | int count, MQTTString topicFilters[]) 51 | { 52 | unsigned char *ptr = buf; 53 | MQTTHeader header = {0}; 54 | int rem_len = 0; 55 | int rc = -1; 56 | int i = 0; 57 | 58 | FUNC_ENTRY; 59 | if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen) 60 | { 61 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 62 | goto exit; 63 | } 64 | 65 | header.byte = 0; 66 | header.bits.type = UNSUBSCRIBE; 67 | header.bits.dup = dup; 68 | header.bits.qos = 1; 69 | writeChar(&ptr, header.byte); /* write header */ 70 | 71 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 72 | 73 | writeInt(&ptr, packetid); 74 | 75 | for (i = 0; i < count; ++i) 76 | writeMQTTString(&ptr, topicFilters[i]); 77 | 78 | rc = ptr - buf; 79 | exit: 80 | FUNC_EXIT_RC(rc); 81 | return rc; 82 | } 83 | 84 | 85 | /** 86 | * Deserializes the supplied (wire) buffer into unsuback data 87 | * @param packetid returned integer - the MQTT packet identifier 88 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 89 | * @param buflen the length in bytes of the data in the supplied buffer 90 | * @return error code. 1 is success, 0 is failure 91 | */ 92 | int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen) 93 | { 94 | unsigned char type = 0; 95 | unsigned char dup = 0; 96 | int rc = 0; 97 | 98 | FUNC_ENTRY; 99 | rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen); 100 | if (type == UNSUBACK) 101 | rc = 1; 102 | FUNC_EXIT_RC(rc); 103 | return rc; 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTSubscribeServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into subscribe data 25 | * @param dup integer returned - the MQTT dup flag 26 | * @param packetid integer returned - the MQTT packet identifier 27 | * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays 28 | * @param count - number of members in the topicFilters and requestedQoSs arrays 29 | * @param topicFilters - array of topic filter names 30 | * @param requestedQoSs - array of requested QoS 31 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 32 | * @param buflen the length in bytes of the data in the supplied buffer 33 | * @return the length of the serialized data. <= 0 indicates error 34 | */ 35 | int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[], 36 | int requestedQoSs[], unsigned char* buf, int buflen) 37 | { 38 | MQTTHeader header = {0}; 39 | unsigned char* curdata = buf; 40 | unsigned char* enddata = NULL; 41 | int rc = -1; 42 | int mylen = 0; 43 | 44 | FUNC_ENTRY; 45 | header.byte = readChar(&curdata); 46 | if (header.bits.type != SUBSCRIBE) 47 | goto exit; 48 | *dup = header.bits.dup; 49 | 50 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 51 | enddata = curdata + mylen; 52 | 53 | *packetid = readInt(&curdata); 54 | 55 | *count = 0; 56 | while (curdata < enddata) 57 | { 58 | if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata)) 59 | goto exit; 60 | if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */ 61 | goto exit; 62 | requestedQoSs[*count] = readChar(&curdata); 63 | (*count)++; 64 | } 65 | 66 | rc = 1; 67 | exit: 68 | FUNC_EXIT_RC(rc); 69 | return rc; 70 | } 71 | 72 | 73 | /** 74 | * Serializes the supplied suback data into the supplied buffer, ready for sending 75 | * @param buf the buffer into which the packet will be serialized 76 | * @param buflen the length in bytes of the supplied buffer 77 | * @param packetid integer - the MQTT packet identifier 78 | * @param count - number of members in the grantedQoSs array 79 | * @param grantedQoSs - array of granted QoS 80 | * @return the length of the serialized data. <= 0 indicates error 81 | */ 82 | int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs) 83 | { 84 | MQTTHeader header = {0}; 85 | int rc = -1; 86 | unsigned char *ptr = buf; 87 | int i; 88 | 89 | FUNC_ENTRY; 90 | if (buflen < 2 + count) 91 | { 92 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 93 | goto exit; 94 | } 95 | header.byte = 0; 96 | header.bits.type = SUBACK; 97 | writeChar(&ptr, header.byte); /* write header */ 98 | 99 | ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */ 100 | 101 | writeInt(&ptr, packetid); 102 | 103 | for (i = 0; i < count; ++i) 104 | writeChar(&ptr, grantedQoSs[i]); 105 | 106 | rc = ptr - buf; 107 | exit: 108 | FUNC_EXIT_RC(rc); 109 | return rc; 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTDeserializePublish.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "StackTrace.h" 18 | #include "MQTTPacket.h" 19 | #include 20 | 21 | #define min(a, b) ((a < b) ? 1 : 0) 22 | 23 | /** 24 | * Deserializes the supplied (wire) buffer into publish data 25 | * @param dup returned integer - the MQTT dup flag 26 | * @param qos returned integer - the MQTT QoS value 27 | * @param retained returned integer - the MQTT retained flag 28 | * @param packetid returned integer - the MQTT packet identifier 29 | * @param topicName returned MQTTString - the MQTT topic in the publish 30 | * @param payload returned byte buffer - the MQTT publish payload 31 | * @param payloadlen returned integer - the length of the MQTT payload 32 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 33 | * @param buflen the length in bytes of the data in the supplied buffer 34 | * @return error code. 1 is success 35 | */ 36 | int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName, 37 | unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen) 38 | { 39 | MQTTHeader header = {0}; 40 | unsigned char* curdata = buf; 41 | unsigned char* enddata = NULL; 42 | int rc = 0; 43 | int mylen = 0; 44 | 45 | FUNC_ENTRY; 46 | header.byte = readChar(&curdata); 47 | if (header.bits.type != PUBLISH) 48 | goto exit; 49 | *dup = header.bits.dup; 50 | *qos = header.bits.qos; 51 | *retained = header.bits.retain; 52 | 53 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 54 | enddata = curdata + mylen; 55 | 56 | if (!readMQTTLenString(topicName, &curdata, enddata) || 57 | enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ 58 | goto exit; 59 | 60 | if (*qos > 0) 61 | *packetid = readInt(&curdata); 62 | 63 | *payloadlen = enddata - curdata; 64 | *payload = curdata; 65 | rc = 1; 66 | exit: 67 | FUNC_EXIT_RC(rc); 68 | return rc; 69 | } 70 | 71 | 72 | 73 | /** 74 | * Deserializes the supplied (wire) buffer into an ack 75 | * @param packettype returned integer - the MQTT packet type 76 | * @param dup returned integer - the MQTT dup flag 77 | * @param packetid returned integer - the MQTT packet identifier 78 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 79 | * @param buflen the length in bytes of the data in the supplied buffer 80 | * @return error code. 1 is success, 0 is failure 81 | */ 82 | int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen) 83 | { 84 | MQTTHeader header = {0}; 85 | unsigned char* curdata = buf; 86 | unsigned char* enddata = NULL; 87 | int rc = 0; 88 | int mylen; 89 | 90 | FUNC_ENTRY; 91 | header.byte = readChar(&curdata); 92 | *dup = header.bits.dup; 93 | *packettype = header.bits.type; 94 | 95 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 96 | enddata = curdata + mylen; 97 | 98 | if (enddata - curdata < 2) 99 | goto exit; 100 | *packetid = readInt(&curdata); 101 | 102 | rc = 1; 103 | exit: 104 | FUNC_EXIT_RC(rc); 105 | return rc; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTPacket.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Xiang Rong - 442039 Add makefile to Embedded C client 16 | *******************************************************************************/ 17 | 18 | #ifndef MQTTPACKET_H_ 19 | #define MQTTPACKET_H_ 20 | 21 | #if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */ 22 | extern "C" { 23 | #endif 24 | 25 | #if defined(WIN32_DLL) || defined(WIN64_DLL) 26 | #define DLLImport __declspec(dllimport) 27 | #define DLLExport __declspec(dllexport) 28 | #elif defined(LINUX_SO) 29 | #define DLLImport extern 30 | #define DLLExport __attribute__ ((visibility ("default"))) 31 | #else 32 | #define DLLImport 33 | #define DLLExport 34 | #endif 35 | 36 | enum errors 37 | { 38 | MQTTPACKET_BUFFER_TOO_SHORT = -2, 39 | MQTTPACKET_READ_ERROR = -1, 40 | MQTTPACKET_READ_COMPLETE 41 | }; 42 | 43 | enum msgTypes 44 | { 45 | CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, 46 | PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK, 47 | PINGREQ, PINGRESP, DISCONNECT 48 | }; 49 | 50 | /** 51 | * Bitfields for the MQTT header byte. 52 | */ 53 | typedef union 54 | { 55 | unsigned char byte; /**< the whole byte */ 56 | #if defined(REVERSED) 57 | struct 58 | { 59 | unsigned int type : 4; /**< message type nibble */ 60 | unsigned int dup : 1; /**< DUP flag bit */ 61 | unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 62 | unsigned int retain : 1; /**< retained flag bit */ 63 | } bits; 64 | #else 65 | struct 66 | { 67 | unsigned int retain : 1; /**< retained flag bit */ 68 | unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */ 69 | unsigned int dup : 1; /**< DUP flag bit */ 70 | unsigned int type : 4; /**< message type nibble */ 71 | } bits; 72 | #endif 73 | } MQTTHeader; 74 | 75 | typedef struct 76 | { 77 | int len; 78 | char* data; 79 | } MQTTLenString; 80 | 81 | typedef struct 82 | { 83 | char* cstring; 84 | MQTTLenString lenstring; 85 | } MQTTString; 86 | 87 | #define MQTTString_initializer {NULL, {0, NULL}} 88 | 89 | int MQTTstrlen(MQTTString mqttstring); 90 | 91 | #include "MQTTConnect.h" 92 | #include "MQTTPublish.h" 93 | #include "MQTTSubscribe.h" 94 | #include "MQTTUnsubscribe.h" 95 | #include "MQTTFormat.h" 96 | 97 | DLLExport int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid); 98 | DLLExport int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen); 99 | 100 | int MQTTPacket_len(int rem_len); 101 | DLLExport int MQTTPacket_equals(MQTTString* a, char* b); 102 | 103 | DLLExport int MQTTPacket_encode(unsigned char* buf, int length); 104 | int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value); 105 | int MQTTPacket_decodeBuf(unsigned char* buf, int* value); 106 | 107 | int readInt(unsigned char** pptr); 108 | char readChar(unsigned char** pptr); 109 | void writeChar(unsigned char** pptr, char c); 110 | void writeInt(unsigned char** pptr, int anInt); 111 | int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata); 112 | void writeCString(unsigned char** pptr, const char* string); 113 | void writeMQTTString(unsigned char** pptr, MQTTString mqttstring); 114 | 115 | DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)); 116 | 117 | typedef struct { 118 | int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */ 119 | void *sck; /* pointer to whatever the system may use to identify the transport */ 120 | int multiplier; 121 | int rem_len; 122 | int len; 123 | char state; 124 | }MQTTTransport; 125 | 126 | int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp); 127 | 128 | #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ 129 | } 130 | #endif 131 | 132 | 133 | #endif /* MQTTPACKET_H_ */ 134 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTSubscribeClient.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | /** 23 | * Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters 24 | * @param count the number of topic filter strings in topicFilters 25 | * @param topicFilters the array of topic filter strings to be used in the publish 26 | * @return the length of buffer needed to contain the serialized version of the packet 27 | */ 28 | int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[]) 29 | { 30 | int i; 31 | int len = 2; /* packetid */ 32 | 33 | for (i = 0; i < count; ++i) 34 | len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */ 35 | return len; 36 | } 37 | 38 | 39 | /** 40 | * Serializes the supplied subscribe data into the supplied buffer, ready for sending 41 | * @param buf the buffer into which the packet will be serialized 42 | * @param buflen the length in bytes of the supplied bufferr 43 | * @param dup integer - the MQTT dup flag 44 | * @param packetid integer - the MQTT packet identifier 45 | * @param count - number of members in the topicFilters and reqQos arrays 46 | * @param topicFilters - array of topic filter names 47 | * @param requestedQoSs - array of requested QoS 48 | * @return the length of the serialized data. <= 0 indicates error 49 | */ 50 | int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count, 51 | MQTTString topicFilters[], int requestedQoSs[]) 52 | { 53 | unsigned char *ptr = buf; 54 | MQTTHeader header = {0}; 55 | int rem_len = 0; 56 | int rc = 0; 57 | int i = 0; 58 | 59 | FUNC_ENTRY; 60 | if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen) 61 | { 62 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 63 | goto exit; 64 | } 65 | 66 | header.byte = 0; 67 | header.bits.type = SUBSCRIBE; 68 | header.bits.dup = dup; 69 | header.bits.qos = 1; 70 | writeChar(&ptr, header.byte); /* write header */ 71 | 72 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 73 | 74 | writeInt(&ptr, packetid); 75 | 76 | for (i = 0; i < count; ++i) 77 | { 78 | writeMQTTString(&ptr, topicFilters[i]); 79 | writeChar(&ptr, requestedQoSs[i]); 80 | } 81 | 82 | rc = ptr - buf; 83 | exit: 84 | FUNC_EXIT_RC(rc); 85 | return rc; 86 | } 87 | 88 | 89 | 90 | /** 91 | * Deserializes the supplied (wire) buffer into suback data 92 | * @param packetid returned integer - the MQTT packet identifier 93 | * @param maxcount - the maximum number of members allowed in the grantedQoSs array 94 | * @param count returned integer - number of members in the grantedQoSs array 95 | * @param grantedQoSs returned array of integers - the granted qualities of service 96 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 97 | * @param buflen the length in bytes of the data in the supplied buffer 98 | * @return error code. 1 is success, 0 is failure 99 | */ 100 | int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen) 101 | { 102 | MQTTHeader header = {0}; 103 | unsigned char* curdata = buf; 104 | unsigned char* enddata = NULL; 105 | int rc = 0; 106 | int mylen; 107 | 108 | FUNC_ENTRY; 109 | header.byte = readChar(&curdata); 110 | if (header.bits.type != SUBACK) 111 | goto exit; 112 | 113 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 114 | enddata = curdata + mylen; 115 | if (enddata - curdata < 2) 116 | goto exit; 117 | 118 | *packetid = readInt(&curdata); 119 | 120 | *count = 0; 121 | while (curdata < enddata) 122 | { 123 | if (*count > maxcount) 124 | { 125 | rc = -1; 126 | goto exit; 127 | } 128 | grantedQoSs[(*count)++] = readChar(&curdata); 129 | } 130 | 131 | rc = 1; 132 | exit: 133 | FUNC_EXIT_RC(rc); 134 | return rc; 135 | } 136 | 137 | 138 | -------------------------------------------------------------------------------- /Src/syscalls.c: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | ** 4 | ** File : syscalls.c 5 | ** 6 | ** Author : Auto-generated by STM32CubeIDE 7 | ** 8 | ** Abstract : STM32CubeIDE Minimal System calls file 9 | ** 10 | ** For more information about which c-functions 11 | ** need which of these lowlevel functions 12 | ** please consult the Newlib libc-manual 13 | ** 14 | ** Environment : STM32CubeIDE MCU 15 | ** 16 | ** Distribution: The file is distributed as is, without any warranty 17 | ** of any kind. 18 | ** 19 | ***************************************************************************** 20 | ** 21 | **

© COPYRIGHT(c) 2018 STMicroelectronics

22 | ** 23 | ** Redistribution and use in source and binary forms, with or without modification, 24 | ** are permitted provided that the following conditions are met: 25 | ** 1. Redistributions of source code must retain the above copyright notice, 26 | ** this list of conditions and the following disclaimer. 27 | ** 2. Redistributions in binary form must reproduce the above copyright notice, 28 | ** this list of conditions and the following disclaimer in the documentation 29 | ** and/or other materials provided with the distribution. 30 | ** 3. Neither the name of STMicroelectronics nor the names of its contributors 31 | ** may be used to endorse or promote products derived from this software 32 | ** without specific prior written permission. 33 | ** 34 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 35 | ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 38 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 40 | ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 41 | ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 42 | ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | ** 45 | ** 46 | ***************************************************************************** 47 | */ 48 | 49 | /* Includes */ 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | 60 | /* Variables */ 61 | //#undef errno 62 | extern int errno; 63 | extern int __io_putchar(int ch) __attribute__((weak)); 64 | extern int __io_getchar(void) __attribute__((weak)); 65 | 66 | register char * stack_ptr asm("sp"); 67 | 68 | char *__env[1] = { 0 }; 69 | char **environ = __env; 70 | 71 | 72 | /* Functions */ 73 | void initialise_monitor_handles() 74 | { 75 | } 76 | 77 | int _getpid(void) 78 | { 79 | return 1; 80 | } 81 | 82 | int _kill(int pid, int sig) 83 | { 84 | errno = EINVAL; 85 | return -1; 86 | } 87 | 88 | void _exit (int status) 89 | { 90 | _kill(status, -1); 91 | while (1) {} /* Make sure we hang here */ 92 | } 93 | 94 | __attribute__((weak)) int _read(int file, char *ptr, int len) 95 | { 96 | int DataIdx; 97 | 98 | for (DataIdx = 0; DataIdx < len; DataIdx++) 99 | { 100 | *ptr++ = __io_getchar(); 101 | } 102 | 103 | return len; 104 | } 105 | 106 | __attribute__((weak)) int _write(int file, char *ptr, int len) 107 | { 108 | int DataIdx; 109 | 110 | for (DataIdx = 0; DataIdx < len; DataIdx++) 111 | { 112 | __io_putchar(*ptr++); 113 | } 114 | return len; 115 | } 116 | 117 | int _close(int file) 118 | { 119 | return -1; 120 | } 121 | 122 | 123 | int _fstat(int file, struct stat *st) 124 | { 125 | st->st_mode = S_IFCHR; 126 | return 0; 127 | } 128 | 129 | int _isatty(int file) 130 | { 131 | return 1; 132 | } 133 | 134 | int _lseek(int file, int ptr, int dir) 135 | { 136 | return 0; 137 | } 138 | 139 | int _open(char *path, int flags, ...) 140 | { 141 | /* Pretend like we always fail */ 142 | return -1; 143 | } 144 | 145 | int _wait(int *status) 146 | { 147 | errno = ECHILD; 148 | return -1; 149 | } 150 | 151 | int _unlink(char *name) 152 | { 153 | errno = ENOENT; 154 | return -1; 155 | } 156 | 157 | int _times(struct tms *buf) 158 | { 159 | return -1; 160 | } 161 | 162 | int _stat(char *file, struct stat *st) 163 | { 164 | st->st_mode = S_IFCHR; 165 | return 0; 166 | } 167 | 168 | int _link(char *old, char *new) 169 | { 170 | errno = EMLINK; 171 | return -1; 172 | } 173 | 174 | int _fork(void) 175 | { 176 | errno = EAGAIN; 177 | return -1; 178 | } 179 | 180 | int _execve(char *name, char **argv, char **env) 181 | { 182 | errno = ENOMEM; 183 | return -1; 184 | } 185 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/transport.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - port to the bare metal environment and serial media specifics 16 | *******************************************************************************/ 17 | 18 | /** By the way, this is a nice bare bones example, easier to expand to whatever non-OS 19 | media you might have */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "transport.h" 27 | 28 | /** 29 | This simple low-level implementation assumes a single connection for a single thread. Thus, single static 30 | variables are used for that connection. 31 | On other scenarios, you might want to put all these variables into a structure and index via the 'sock' 32 | parameter, as some functions show in the comments 33 | The blocking rx function is not supported. 34 | If you plan on writing one, take into account that the current implementation of 35 | MQTTPacket_read() has a function pointer for a function call to get the data to a buffer, but no provisions 36 | to know the caller or other indicator (the socket id): int (*getfn)(unsigned char*, int) 37 | */ 38 | static transport_iofunctions_t *io = NULL; 39 | static unsigned char *from = NULL; // to keep track of data sending 40 | static int howmany; // ditto 41 | 42 | 43 | void transport_sendPacketBuffernb_start(int sock, unsigned char* buf, int buflen) 44 | { 45 | from = buf; // from[sock] or mystruct[sock].from 46 | howmany = buflen; // myhowmany[sock] or mystruct[sock].howmany 47 | } 48 | 49 | int transport_sendPacketBuffernb(int sock) 50 | { 51 | transport_iofunctions_t *myio = io; // io[sock] or mystruct[sock].io 52 | int len; 53 | 54 | /* you should have called open() with a valid pointer to a valid struct and 55 | called sendPacketBuffernb_start with a valid buffer, before calling this */ 56 | assert((myio != NULL) && (myio->send != NULL) && (from != NULL)); 57 | if((len = myio->send(from, howmany)) > 0){ 58 | from += len; 59 | if((howmany -= len) <= 0){ 60 | return TRANSPORT_DONE; 61 | } 62 | } else if(len < 0){ 63 | return TRANSPORT_ERROR; 64 | } 65 | return TRANSPORT_AGAIN; 66 | } 67 | 68 | int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen) 69 | { 70 | int rc; 71 | 72 | transport_sendPacketBuffernb_start(sock, buf, buflen); 73 | while((rc=transport_sendPacketBuffernb(sock)) == TRANSPORT_AGAIN){ 74 | /* this is unlikely to loop forever unless there is a hardware problem */ 75 | } 76 | if(rc == TRANSPORT_DONE){ 77 | return buflen; 78 | } 79 | return TRANSPORT_ERROR; 80 | } 81 | 82 | 83 | int transport_getdata(unsigned char* buf, int count) 84 | { 85 | // int rc; 86 | assert(0); /* This function is NOT supported, it is just here to tease you */ 87 | // transport_sendPacketBuffernb_start(sock, buf, count); 88 | // while((rc=transport_sendPacketBuffernb(sock)) == TRANSPORT_AGAIN){ 89 | // /* this is unlikely to loop forever unless there is a hardware problem */ 90 | // } 91 | // if(rc == TRANSPORT_DONE){ 92 | // return count; 93 | // } 94 | return TRANSPORT_ERROR; /* nah, it is here for similarity with other transport examples */ 95 | } 96 | 97 | int transport_getdatanb(void *sck, unsigned char* buf, int count) 98 | { 99 | //int sock = *((int *)sck); /* sck: pointer to whatever the system may use to identify the transport */ 100 | transport_iofunctions_t *myio = io; // io[sock] or mystruct[sock].io 101 | int len; 102 | 103 | /* you should have called open() with a valid pointer to a valid struct before calling this */ 104 | assert((myio != NULL) && (myio->recv != NULL)); 105 | /* this call will return immediately if no bytes, or return whatever outstanding bytes we have, 106 | upto count */ 107 | while((len = myio->recv(buf, count)) == 0); 108 | if (len >0 ) 109 | return len; 110 | if (len==-2) 111 | return 0; 112 | if(len == -1) 113 | return TRANSPORT_ERROR; 114 | } 115 | 116 | /** 117 | return >=0 for a connection descriptor, <0 for an error code 118 | */ 119 | int transport_open(transport_iofunctions_t *thisio) 120 | { 121 | int idx=0; // for multiple connections, you might, basically turn myio into myio[MAX_CONNECTIONS], 122 | 123 | //if((idx=assignidx()) >= MAX_CONNECTIONS) // somehow assign an index, 124 | // return TRANSPORT_ERROR; 125 | io = thisio; // store myio[idx] = thisio, or mystruct[idx].io = thisio, 126 | return idx; // and return the index used 127 | } 128 | 129 | int transport_close(int sock) 130 | { 131 | int rc=TRANSPORT_DONE; 132 | 133 | return rc; 134 | } 135 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTConnectServer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "StackTrace.h" 18 | #include "MQTTPacket.h" 19 | #include 20 | 21 | #define min(a, b) ((a < b) ? a : b) 22 | 23 | 24 | /** 25 | * Validates MQTT protocol name and version combinations 26 | * @param protocol the MQTT protocol name as an MQTTString 27 | * @param version the MQTT protocol version number, as in the connect packet 28 | * @return correct MQTT combination? 1 is true, 0 is false 29 | */ 30 | int MQTTPacket_checkVersion(MQTTString* protocol, int version) 31 | { 32 | int rc = 0; 33 | 34 | if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp", 35 | min(6, protocol->lenstring.len)) == 0) 36 | rc = 1; 37 | else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT", 38 | min(4, protocol->lenstring.len)) == 0) 39 | rc = 1; 40 | return rc; 41 | } 42 | 43 | 44 | /** 45 | * Deserializes the supplied (wire) buffer into connect data structure 46 | * @param data the connect data structure to be filled out 47 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 48 | * @param len the length in bytes of the data in the supplied buffer 49 | * @return error code. 1 is success, 0 is failure 50 | */ 51 | int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len) 52 | { 53 | MQTTHeader header = {0}; 54 | MQTTConnectFlags flags = {0}; 55 | unsigned char* curdata = buf; 56 | unsigned char* enddata = &buf[len]; 57 | int rc = 0; 58 | MQTTString Protocol; 59 | int version; 60 | int mylen = 0; 61 | 62 | FUNC_ENTRY; 63 | header.byte = readChar(&curdata); 64 | if (header.bits.type != CONNECT) 65 | goto exit; 66 | 67 | curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */ 68 | 69 | if (!readMQTTLenString(&Protocol, &curdata, enddata) || 70 | enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */ 71 | goto exit; 72 | 73 | version = (int)readChar(&curdata); /* Protocol version */ 74 | /* If we don't recognize the protocol version, we don't parse the connect packet on the 75 | * basis that we don't know what the format will be. 76 | */ 77 | if (MQTTPacket_checkVersion(&Protocol, version)) 78 | { 79 | flags.all = readChar(&curdata); 80 | data->cleansession = flags.bits.cleansession; 81 | data->keepAliveInterval = readInt(&curdata); 82 | if (!readMQTTLenString(&data->clientID, &curdata, enddata)) 83 | goto exit; 84 | data->willFlag = flags.bits.will; 85 | if (flags.bits.will) 86 | { 87 | data->will.qos = flags.bits.willQoS; 88 | data->will.retained = flags.bits.willRetain; 89 | if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) || 90 | !readMQTTLenString(&data->will.message, &curdata, enddata)) 91 | goto exit; 92 | } 93 | if (flags.bits.username) 94 | { 95 | if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata)) 96 | goto exit; /* username flag set, but no username supplied - invalid */ 97 | if (flags.bits.password && 98 | (enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata))) 99 | goto exit; /* password flag set, but no password supplied - invalid */ 100 | } 101 | else if (flags.bits.password) 102 | goto exit; /* password flag set without username - invalid */ 103 | rc = 1; 104 | } 105 | exit: 106 | FUNC_EXIT_RC(rc); 107 | return rc; 108 | } 109 | 110 | 111 | /** 112 | * Serializes the connack packet into the supplied buffer. 113 | * @param buf the buffer into which the packet will be serialized 114 | * @param buflen the length in bytes of the supplied buffer 115 | * @param connack_rc the integer connack return code to be used 116 | * @param sessionPresent the MQTT 3.1.1 sessionPresent flag 117 | * @return serialized length, or error if 0 118 | */ 119 | int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent) 120 | { 121 | MQTTHeader header = {0}; 122 | int rc = 0; 123 | unsigned char *ptr = buf; 124 | MQTTConnackFlags flags = {0}; 125 | 126 | FUNC_ENTRY; 127 | if (buflen < 2) 128 | { 129 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 130 | goto exit; 131 | } 132 | header.byte = 0; 133 | header.bits.type = CONNACK; 134 | writeChar(&ptr, header.byte); /* write header */ 135 | 136 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 137 | 138 | flags.all = 0; 139 | flags.bits.sessionpresent = sessionPresent; 140 | writeChar(&ptr, flags.all); 141 | writeChar(&ptr, connack_rc); 142 | 143 | rc = ptr - buf; 144 | exit: 145 | FUNC_EXIT_RC(rc); 146 | return rc; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTConnect.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014, 2017 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - add connack return code definitions 16 | * Xiang Rong - 442039 Add makefile to Embedded C client 17 | * Ian Craggs - fix for issue #64, bit order in connack response 18 | *******************************************************************************/ 19 | 20 | #ifndef MQTTCONNECT_H_ 21 | #define MQTTCONNECT_H_ 22 | 23 | enum connack_return_codes 24 | { 25 | MQTT_CONNECTION_ACCEPTED = 0, 26 | MQTT_UNNACCEPTABLE_PROTOCOL = 1, 27 | MQTT_CLIENTID_REJECTED = 2, 28 | MQTT_SERVER_UNAVAILABLE = 3, 29 | MQTT_BAD_USERNAME_OR_PASSWORD = 4, 30 | MQTT_NOT_AUTHORIZED = 5, 31 | }; 32 | 33 | #if !defined(DLLImport) 34 | #define DLLImport 35 | #endif 36 | #if !defined(DLLExport) 37 | #define DLLExport 38 | #endif 39 | 40 | 41 | typedef union 42 | { 43 | unsigned char all; /**< all connect flags */ 44 | #if defined(REVERSED) 45 | struct 46 | { 47 | unsigned int username : 1; /**< 3.1 user name */ 48 | unsigned int password : 1; /**< 3.1 password */ 49 | unsigned int willRetain : 1; /**< will retain setting */ 50 | unsigned int willQoS : 2; /**< will QoS value */ 51 | unsigned int will : 1; /**< will flag */ 52 | unsigned int cleansession : 1; /**< clean session flag */ 53 | unsigned int : 1; /**< unused */ 54 | } bits; 55 | #else 56 | struct 57 | { 58 | unsigned int : 1; /**< unused */ 59 | unsigned int cleansession : 1; /**< cleansession flag */ 60 | unsigned int will : 1; /**< will flag */ 61 | unsigned int willQoS : 2; /**< will QoS value */ 62 | unsigned int willRetain : 1; /**< will retain setting */ 63 | unsigned int password : 1; /**< 3.1 password */ 64 | unsigned int username : 1; /**< 3.1 user name */ 65 | } bits; 66 | #endif 67 | } MQTTConnectFlags; /**< connect flags byte */ 68 | 69 | 70 | 71 | /** 72 | * Defines the MQTT "Last Will and Testament" (LWT) settings for 73 | * the connect packet. 74 | */ 75 | typedef struct 76 | { 77 | /** The eyecatcher for this structure. must be MQTW. */ 78 | char struct_id[4]; 79 | /** The version number of this structure. Must be 0 */ 80 | int struct_version; 81 | /** The LWT topic to which the LWT message will be published. */ 82 | MQTTString topicName; 83 | /** The LWT payload. */ 84 | MQTTString message; 85 | /** 86 | * The retained flag for the LWT message (see MQTTAsync_message.retained). 87 | */ 88 | unsigned char retained; 89 | /** 90 | * The quality of service setting for the LWT message (see 91 | * MQTTAsync_message.qos and @ref qos). 92 | */ 93 | char qos; 94 | } MQTTPacket_willOptions; 95 | 96 | 97 | #define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 } 98 | 99 | 100 | typedef struct 101 | { 102 | /** The eyecatcher for this structure. must be MQTC. */ 103 | char struct_id[4]; 104 | /** The version number of this structure. Must be 0 */ 105 | int struct_version; 106 | /** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1 107 | */ 108 | unsigned char MQTTVersion; 109 | MQTTString clientID; 110 | unsigned short keepAliveInterval; 111 | unsigned char cleansession; 112 | unsigned char willFlag; 113 | MQTTPacket_willOptions will; 114 | MQTTString username; 115 | MQTTString password; 116 | } MQTTPacket_connectData; 117 | 118 | typedef union 119 | { 120 | unsigned char all; /**< all connack flags */ 121 | #if defined(REVERSED) 122 | struct 123 | { 124 | unsigned int reserved : 7; /**< unused */ 125 | unsigned int sessionpresent : 1; /**< session present flag */ 126 | } bits; 127 | #else 128 | struct 129 | { 130 | unsigned int sessionpresent : 1; /**< session present flag */ 131 | unsigned int reserved: 7; /**< unused */ 132 | } bits; 133 | #endif 134 | } MQTTConnackFlags; /**< connack flags byte */ 135 | 136 | #define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \ 137 | MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} } 138 | 139 | DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options); 140 | DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len); 141 | 142 | DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent); 143 | DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen); 144 | 145 | DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen); 146 | DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen); 147 | 148 | #endif /* MQTTCONNECT_H_ */ 149 | -------------------------------------------------------------------------------- /Final_pro.elf.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /.mxproject: -------------------------------------------------------------------------------- 1 | [PreviousGenFiles] 2 | HeaderPath=C:/Users/User/Desktop/Final_pro/Inc 3 | HeaderFiles=gpio.h;i2c.h;sys.h;usart.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;main.h;dma.h;tim.h; 4 | SourcePath=C:/Users/User/Desktop/Final_pro/Src 5 | SourceFiles=gpio.c;i2c.c;sys.c;usart.c;stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c;dma.c;tim.c; 6 | 7 | [PreviousLibFiles] 8 | LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; 9 | 10 | [PreviousUsedCubeIDEFiles] 11 | SourceFiles=Src\main.c;Src\gpio.c;Src\dma.c;Src\i2c.c;Src\sys.c;Src\tim.c;Src\usart.c;Src\stm32f1xx_it.c;Src\stm32f1xx_hal_msp.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Src/system_stm32f1xx.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Src/system_stm32f1xx.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;; 12 | HeaderPath=Drivers\STM32F1xx_HAL_Driver\Inc;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32F1xx\Include;Drivers\CMSIS\Include;Inc; 13 | CDefines=USE_HAL_DRIVER;STM32F103xE;USE_HAL_DRIVER;USE_HAL_DRIVER; 14 | 15 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTSerializePublish.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144 16 | *******************************************************************************/ 17 | 18 | #include "MQTTPacket.h" 19 | #include "StackTrace.h" 20 | 21 | #include 22 | 23 | 24 | /** 25 | * Determines the length of the MQTT publish packet that would be produced using the supplied parameters 26 | * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0) 27 | * @param topicName the topic name to be used in the publish 28 | * @param payloadlen the length of the payload to be sent 29 | * @return the length of buffer needed to contain the serialized version of the packet 30 | */ 31 | int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen) 32 | { 33 | int len = 0; 34 | 35 | len += 2 + MQTTstrlen(topicName) + payloadlen; 36 | if (qos > 0) 37 | len += 2; /* packetid */ 38 | return len; 39 | } 40 | 41 | 42 | /** 43 | * Serializes the supplied publish data into the supplied buffer, ready for sending 44 | * @param buf the buffer into which the packet will be serialized 45 | * @param buflen the length in bytes of the supplied buffer 46 | * @param dup integer - the MQTT dup flag 47 | * @param qos integer - the MQTT QoS value 48 | * @param retained integer - the MQTT retained flag 49 | * @param packetid integer - the MQTT packet identifier 50 | * @param topicName MQTTString - the MQTT topic in the publish 51 | * @param payload byte buffer - the MQTT publish payload 52 | * @param payloadlen integer - the length of the MQTT payload 53 | * @return the length of the serialized data. <= 0 indicates error 54 | */ 55 | int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid, 56 | MQTTString topicName, unsigned char* payload, int payloadlen) 57 | { 58 | unsigned char *ptr = buf; 59 | MQTTHeader header = {0}; 60 | int rem_len = 0; 61 | int rc = 0; 62 | 63 | FUNC_ENTRY; 64 | if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen) 65 | { 66 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 67 | goto exit; 68 | } 69 | 70 | header.bits.type = PUBLISH; 71 | header.bits.dup = dup; 72 | header.bits.qos = qos; 73 | header.bits.retain = retained; 74 | writeChar(&ptr, header.byte); /* write header */ 75 | 76 | ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */; 77 | 78 | writeMQTTString(&ptr, topicName); 79 | 80 | if (qos > 0) 81 | writeInt(&ptr, packetid); 82 | 83 | memcpy(ptr, payload, payloadlen); 84 | ptr += payloadlen; 85 | 86 | rc = ptr - buf; 87 | 88 | exit: 89 | FUNC_EXIT_RC(rc); 90 | return rc; 91 | } 92 | 93 | 94 | 95 | /** 96 | * Serializes the ack packet into the supplied buffer. 97 | * @param buf the buffer into which the packet will be serialized 98 | * @param buflen the length in bytes of the supplied buffer 99 | * @param type the MQTT packet type 100 | * @param dup the MQTT dup flag 101 | * @param packetid the MQTT packet identifier 102 | * @return serialized length, or error if 0 103 | */ 104 | int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid) 105 | { 106 | MQTTHeader header = {0}; 107 | int rc = 0; 108 | unsigned char *ptr = buf; 109 | 110 | FUNC_ENTRY; 111 | if (buflen < 4) 112 | { 113 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 114 | goto exit; 115 | } 116 | header.bits.type = packettype; 117 | header.bits.dup = dup; 118 | header.bits.qos = (packettype == PUBREL) ? 1 : 0; 119 | writeChar(&ptr, header.byte); /* write header */ 120 | 121 | ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */ 122 | writeInt(&ptr, packetid); 123 | rc = ptr - buf; 124 | exit: 125 | FUNC_EXIT_RC(rc); 126 | return rc; 127 | } 128 | 129 | 130 | /** 131 | * Serializes a puback packet into the supplied buffer. 132 | * @param buf the buffer into which the packet will be serialized 133 | * @param buflen the length in bytes of the supplied buffer 134 | * @param packetid integer - the MQTT packet identifier 135 | * @return serialized length, or error if 0 136 | */ 137 | int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid) 138 | { 139 | return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid); 140 | } 141 | 142 | 143 | /** 144 | * Serializes a pubrel packet into the supplied buffer. 145 | * @param buf the buffer into which the packet will be serialized 146 | * @param buflen the length in bytes of the supplied buffer 147 | * @param dup integer - the MQTT dup flag 148 | * @param packetid integer - the MQTT packet identifier 149 | * @return serialized length, or error if 0 150 | */ 151 | int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid) 152 | { 153 | return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid); 154 | } 155 | 156 | 157 | /** 158 | * Serializes a pubrel packet into the supplied buffer. 159 | * @param buf the buffer into which the packet will be serialized 160 | * @param buflen the length in bytes of the supplied buffer 161 | * @param packetid integer - the MQTT packet identifier 162 | * @return serialized length, or error if 0 163 | */ 164 | int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid) 165 | { 166 | return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid); 167 | } 168 | 169 | 170 | -------------------------------------------------------------------------------- /Src/ESP8266Client/src/networkwrapper.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file networkwrapper.c 3 | * @author Atakan S. 4 | * @date 01/01/2019 5 | * @version 1.0 6 | * @brief Network wrapper for PAHO MQTT project based on ESP8266. 7 | * 8 | * @copyright Copyright (c) 2018 Atakan SARIOGLU ~ www.atakansarioglu.com 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a 11 | * copy of this software and associated documentation files (the "Software"), 12 | * to deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in 18 | * all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | // Includes. 30 | #include "networkwrapper.h" 31 | #include "ESP8266Client.h" 32 | #include 33 | 34 | // Variables. 35 | static char network_host[32] = "10.21.100.103";///< HostName i.e. "test.mosquitto.org" 36 | static unsigned short int network_port = 1883;///< Remote port number. 37 | static unsigned short int network_keepalive = 20;///< Default keepalive time in seconds. 38 | static char network_ssl = false;///< SSL is disabled by default. 39 | static int network_send_state = 0;///< Internal state of send. 40 | static int network_recv_state = 0;///< Internal state of recv. 41 | 42 | // Global time provider. 43 | extern long unsigned int network_gettime_ms(void);///< Returns 32bit ms time value. 44 | 45 | void network_init(void){ } 46 | 47 | void network_close(void){ } 48 | 49 | int network_connect(const char * host, const unsigned short int port, const unsigned short int keepalive, const char ssl){ 50 | // Get connection info. 51 | strcpy(network_host, host); 52 | network_port = port; 53 | network_keepalive = keepalive; 54 | network_ssl = ssl; 55 | 56 | // Reset the internal states. 57 | network_send_state = 0; 58 | network_recv_state = 0; 59 | 60 | // Success. 61 | return 0; 62 | } 63 | 64 | int network_send(unsigned char *address, unsigned int bytes){ 65 | // State Machine. 66 | ESP82_Result_t espResult = ESP82_SUCCESS; 67 | switch(network_send_state) { 68 | case 0: 69 | // Init ESP8266 driver. 70 | ESP82_Init(115200, false, network_gettime_ms); 71 | 72 | // To the next state. 73 | network_send_state++; 74 | 75 | break; 76 | case 1: 77 | // Connect to wifi (restore to default first). 78 | #include "wifi_credentials.h"// Has the below 2 definitions only. 79 | espResult = ESP82_ConnectWifi(true, WIFI_AP_SSID, WIFI_AP_PASS); 80 | if(espResult == ESP82_SUCCESS){ 81 | // To the next state. 82 | network_send_state++; 83 | } 84 | break; 85 | case 2: 86 | // Wait 1sec. 87 | espResult = ESP82_Delay(1000); 88 | if(espResult == ESP82_SUCCESS){ 89 | // To the next state. 90 | network_send_state++; 91 | } 92 | break; 93 | case 3: 94 | // Check the wifi connection status. 95 | espResult = ESP82_IsConnectedWifi(); 96 | if(espResult == ESP82_SUCCESS){ 97 | // To the next state. 98 | network_send_state++; 99 | } 100 | break; 101 | case 4: 102 | // Start TCP connection. 103 | espResult = ESP82_StartTCP(network_host, network_port, network_keepalive, network_ssl); 104 | if(espResult == ESP82_SUCCESS){ 105 | // To the next state. 106 | network_send_state++; 107 | } 108 | break; 109 | case 5: 110 | // Send the data. 111 | espResult = ESP82_Send(address, bytes); 112 | if(espResult == ESP82_SUCCESS){ 113 | // Return the actual number of bytes. Stay in this state unless error occurs. 114 | return bytes; 115 | } 116 | break; 117 | default: 118 | // Reset the state machine. 119 | network_send_state = 0; 120 | } 121 | 122 | // Fall-back on error. 123 | if(espResult == ESP82_ERROR){ 124 | if(network_send_state < 4){ 125 | // If error occured before wifi connection, start over. 126 | network_send_state = 0; 127 | }else{ 128 | // Check wifi connection and try to send again. 129 | network_send_state = 3; 130 | } 131 | 132 | // Error. 133 | return -1; 134 | } 135 | 136 | // In progress. 137 | return 0; 138 | } 139 | 140 | int network_recv(unsigned char *address, unsigned int maxbytes){ 141 | static char receiveBuffer[128]; 142 | static int receiveBufferBack = 0; 143 | static int receiveBufferFront = 0; 144 | int actualLength; 145 | 146 | // State Machine. 147 | ESP82_Result_t espResult; 148 | switch(network_recv_state) { 149 | case 0: 150 | espResult = ESP82_Receive(receiveBuffer, 128); 151 | if(espResult > 0){ 152 | // Set the buffer pointers. 153 | receiveBufferBack = espResult; 154 | receiveBufferFront = 0; 155 | 156 | // To the next state. 157 | network_recv_state++; 158 | } 159 | break; 160 | case 1: 161 | // Extract to the out buffer. 162 | if(receiveBufferFront < receiveBufferBack) { 163 | // Get actual length. 164 | actualLength = (receiveBufferBack - receiveBufferFront); 165 | if(actualLength > maxbytes){ 166 | actualLength = maxbytes; 167 | } 168 | 169 | // Extract the actual bytes. 170 | memcpy(address, &receiveBuffer[receiveBufferFront], actualLength); 171 | receiveBufferFront += actualLength; 172 | 173 | // Buffer is empty. 174 | if(receiveBufferBack == receiveBufferFront) { 175 | network_recv_state = 0; 176 | } 177 | 178 | // Return the count. 179 | return actualLength; 180 | } 181 | break; 182 | default: 183 | // Reset the state machine. 184 | network_recv_state = 0; 185 | } 186 | 187 | // Fall-back on error. 188 | if(espResult == ESP82_ERROR){ 189 | // Reset the state machine. 190 | network_recv_state = 0; 191 | 192 | // Error. 193 | return -1; 194 | } 195 | // Recv nothing. 196 | if(espResult == ESP82_RECEIVE_NOTHING){ 197 | // Reset the state machine. 198 | network_recv_state = 0; 199 | 200 | return -2; 201 | } 202 | 203 | 204 | // In progress. 205 | return 0; 206 | } 207 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTConnectClient.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "MQTTPacket.h" 18 | #include "StackTrace.h" 19 | 20 | #include 21 | 22 | /** 23 | * Determines the length of the MQTT connect packet that would be produced using the supplied connect options. 24 | * @param options the options to be used to build the connect packet 25 | * @return the length of buffer needed to contain the serialized version of the packet 26 | */ 27 | int MQTTSerialize_connectLength(MQTTPacket_connectData* options) 28 | { 29 | int len = 0; 30 | 31 | FUNC_ENTRY; 32 | 33 | if (options->MQTTVersion == 3) 34 | len = 12; /* variable depending on MQTT or MQIsdp */ 35 | else if (options->MQTTVersion == 4) 36 | len = 10; 37 | 38 | len += MQTTstrlen(options->clientID)+2; 39 | if (options->willFlag) 40 | len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2; 41 | if (options->username.cstring || options->username.lenstring.data) 42 | len += MQTTstrlen(options->username)+2; 43 | if (options->password.cstring || options->password.lenstring.data) 44 | len += MQTTstrlen(options->password)+2; 45 | 46 | FUNC_EXIT_RC(len); 47 | return len; 48 | } 49 | 50 | 51 | /** 52 | * Serializes the connect options into the buffer. 53 | * @param buf the buffer into which the packet will be serialized 54 | * @param len the length in bytes of the supplied buffer 55 | * @param options the options to be used to build the connect packet 56 | * @return serialized length, or error if 0 57 | */ 58 | int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options) 59 | { 60 | unsigned char *ptr = buf; 61 | MQTTHeader header = {0}; 62 | MQTTConnectFlags flags = {0}; 63 | int len = 0; 64 | int rc = -1; 65 | 66 | FUNC_ENTRY; 67 | if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen) 68 | { 69 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 70 | goto exit; 71 | } 72 | 73 | header.byte = 0; 74 | header.bits.type = CONNECT; 75 | writeChar(&ptr, header.byte); /* write header */ 76 | 77 | ptr += MQTTPacket_encode(ptr, len); /* write remaining length */ 78 | 79 | if (options->MQTTVersion == 4) 80 | { 81 | writeCString(&ptr, "MQTT"); 82 | writeChar(&ptr, (char) 4); 83 | } 84 | else 85 | { 86 | writeCString(&ptr, "MQIsdp"); 87 | writeChar(&ptr, (char) 3); 88 | } 89 | 90 | flags.all = 0; 91 | flags.bits.cleansession = options->cleansession; 92 | flags.bits.will = (options->willFlag) ? 1 : 0; 93 | if (flags.bits.will) 94 | { 95 | flags.bits.willQoS = options->will.qos; 96 | flags.bits.willRetain = options->will.retained; 97 | } 98 | 99 | if (options->username.cstring || options->username.lenstring.data) 100 | flags.bits.username = 1; 101 | if (options->password.cstring || options->password.lenstring.data) 102 | flags.bits.password = 1; 103 | 104 | writeChar(&ptr, flags.all); 105 | writeInt(&ptr, options->keepAliveInterval); 106 | writeMQTTString(&ptr, options->clientID); 107 | if (options->willFlag) 108 | { 109 | writeMQTTString(&ptr, options->will.topicName); 110 | writeMQTTString(&ptr, options->will.message); 111 | } 112 | if (flags.bits.username) 113 | writeMQTTString(&ptr, options->username); 114 | if (flags.bits.password) 115 | writeMQTTString(&ptr, options->password); 116 | 117 | rc = ptr - buf; 118 | 119 | exit: FUNC_EXIT_RC(rc); 120 | return rc; 121 | } 122 | 123 | 124 | /** 125 | * Deserializes the supplied (wire) buffer into connack data - return code 126 | * @param sessionPresent the session present flag returned (only for MQTT 3.1.1) 127 | * @param connack_rc returned integer value of the connack return code 128 | * @param buf the raw buffer data, of the correct length determined by the remaining length field 129 | * @param len the length in bytes of the data in the supplied buffer 130 | * @return error code. 1 is success, 0 is failure 131 | */ 132 | int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen) 133 | { 134 | MQTTHeader header = {0}; 135 | unsigned char* curdata = buf; 136 | unsigned char* enddata = NULL; 137 | int rc = 0; 138 | int mylen; 139 | MQTTConnackFlags flags = {0}; 140 | 141 | FUNC_ENTRY; 142 | header.byte = readChar(&curdata); 143 | if (header.bits.type != CONNACK) 144 | goto exit; 145 | 146 | curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */ 147 | enddata = curdata + mylen; 148 | if (enddata - curdata < 2) 149 | goto exit; 150 | 151 | flags.all = readChar(&curdata); 152 | *sessionPresent = flags.bits.sessionpresent; 153 | *connack_rc = readChar(&curdata); 154 | 155 | rc = 1; 156 | exit: 157 | FUNC_EXIT_RC(rc); 158 | return rc; 159 | } 160 | 161 | 162 | /** 163 | * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket 164 | * @param buf the buffer into which the packet will be serialized 165 | * @param buflen the length in bytes of the supplied buffer, to avoid overruns 166 | * @param packettype the message type 167 | * @return serialized length, or error if 0 168 | */ 169 | int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype) 170 | { 171 | MQTTHeader header = {0}; 172 | int rc = -1; 173 | unsigned char *ptr = buf; 174 | 175 | FUNC_ENTRY; 176 | if (buflen < 2) 177 | { 178 | rc = MQTTPACKET_BUFFER_TOO_SHORT; 179 | goto exit; 180 | } 181 | header.byte = 0; 182 | header.bits.type = packettype; 183 | writeChar(&ptr, header.byte); /* write header */ 184 | 185 | ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */ 186 | rc = ptr - buf; 187 | exit: 188 | FUNC_EXIT_RC(rc); 189 | return rc; 190 | } 191 | 192 | 193 | /** 194 | * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 195 | * @param buf the buffer into which the packet will be serialized 196 | * @param buflen the length in bytes of the supplied buffer, to avoid overruns 197 | * @return serialized length, or error if 0 198 | */ 199 | int MQTTSerialize_disconnect(unsigned char* buf, int buflen) 200 | { 201 | return MQTTSerialize_zero(buf, buflen, DISCONNECT); 202 | } 203 | 204 | 205 | /** 206 | * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket 207 | * @param buf the buffer into which the packet will be serialized 208 | * @param buflen the length in bytes of the supplied buffer, to avoid overruns 209 | * @return serialized length, or error if 0 210 | */ 211 | int MQTTSerialize_pingreq(unsigned char* buf, int buflen) 212 | { 213 | return MQTTSerialize_zero(buf, buflen, PINGREQ); 214 | } 215 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 基于HAL(CubeMX)库和MQTT协议的STM32模拟智能街灯 4 | ## 项目要求 5 | - 收集并上传环境光传感器的测量数据到服务器 6 | - 收集并上传开发板(开/关)上的LED状态到服务器 7 | - 实现一个web页面/移动应用程序/微信迷你程序,要求如下: 8 | 9 | 1. 可视化环境光传感器的测量 10 | 2. 控制LED有两种模式: 在远程应用程序上切换这两种模式 11 | 12 | - 手动模式:在远程应用上手动控制LED的开关 13 | - 自动模式:根据环境测量值控制LED的开关光传感器。当测量值低于50勒克斯时打开LED,当测量值低于50勒克斯时关闭LED 14 | 15 | ## 架构 16 | 17 | ![架构](./image/framework.png) 18 | 1. MQTT Broker使用emqx 19 | 2. 前端使用mqtt.js通过Websocket连接Broker 20 | 3. 设备通过MQTT协议连接Broker 21 | 22 | ### 23 | 前端界面使用highchart画图,并使用了mdbootsrap来制作按钮卡片 24 | ![web](./image/web.png) 25 | 26 | ## 设备端 27 | 28 | ### 设备总览 29 | ![all](./image/device.jpg) 30 | ### 业务逻辑 31 | MQTT各主题: 32 | 33 | - light:硬件往这个topic发布环境中的灯光信息,直接传int值 34 | - ledh:硬件往这个topic发布led灯的暗灭信息,0为关灯,1为开灯 35 | - ledmode: 硬件往这个topic发布led灯的暗灭信息,1为手动模式,2为自动模式。 36 | - mode:服务器往这个topic发布指令,1为手动模式,2为自动模式。 37 | - leds:服务器往这个topic发布指令,如果硬件为手动模式,0为关灯,1为开灯。 38 | 39 | ![main](./image/main.png) 40 | esp8266驱动来自于[atakansarioglu/esp8266-iot-driver](https://github.com/atakansarioglu/esp8266-iot-driver),但无法直接应用于HAL开发,需要做如下移植适配. 41 | ### 1. ESP8266的串口封装 42 | 借助cubeMX的HAL库的便利性, 这里直接在cubeMX上将uart2串口DMA控制器打开. 并同时在代码中手动配置UART2的空闲中断. 43 | 1. 当串口有消息进来时,DMA控制器会直接将消息往指定内存地址中写入. 44 | 2. 当一次串口消息接收完成时,会触发空闲中断,通知CPU处理Buffer. 45 | 3. CPU从BUFFER中取数据,放入ESP8266驱动层的FIFO中,等待下一次空闲中断 46 | 47 | ![cube](./image/cube1.jpg) 48 | ![DMA](./image/dma.jpg) 49 | 50 | `main.c`中开启空闲中断, 开启DMA控制器, 并初始化FIFO: 51 | ```c 52 | ... 53 | fifo_alloc(&rxFifo, FIFO_BUFFER_SIZE); 54 | HAL_UART_Receive_DMA(&huart2, rxBuffer, RX_BUFFER_SIZE); 55 | __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); 56 | ... 57 | ``` 58 | 59 | `stm32f1xx_it.c`中对于USART2的空闲中断的处理: 60 | ```c 61 | ... 62 | void USART2_IRQHandler(void) 63 | { 64 | /* USER CODE BEGIN USART2_IRQn 0 */ 65 | uint32_t tmp_flag = 0; 66 | uint32_t temp; 67 | tmp_flag = __HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); 68 | if((tmp_flag != RESET)) 69 | { 70 | __HAL_UART_CLEAR_IDLEFLAG(&huart2); 71 | temp = huart2.Instance->SR; // read as clear 72 | temp = huart2.Instance->DR; 73 | HAL_UART_DMAStop(&huart2); 74 | temp = hdma_usart2_rx.Instance->CNDTR; 75 | rx_len = RX_BUFFER_SIZE - temp; 76 | recv_end_flag = 1; 77 | HAL_UART_IdleCpltCallback(&huart2); 78 | } 79 | 80 | /* USER CODE END USART2_IRQn 0 */ 81 | HAL_UART_IRQHandler(&huart2); 82 | /* USER CODE BEGIN USART2_IRQn 1 */ 83 | 84 | /* USER CODE END USART2_IRQn 1 */ 85 | } 86 | ... 87 | ``` 88 | 上面的对Idle Interrupt的处理中,仿照了HAL库原有的中断处理方式,在重新设置各寄存器和标志位后调用 89 | `HAL_UART_IdleCpltCallback(&huart2)`这个回调函数,该函数在`ESP8266Client\src\ESP8266Client.c`中实现: 90 | ```c 91 | ... 92 | void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart){ 93 | if(huart == &huart2 && recv_end_flag == 1){ 94 | fifo_in(&rxFifo, rxBuffer, rx_len); 95 | memset(rxBuffer+rx_len,0,RX_BUFFER_SIZE-rx_len); 96 | HAL_UART_Receive_DMA(&huart2, rxBuffer, RX_BUFFER_SIZE); 97 | } 98 | } 99 | ... 100 | ``` 101 | 然后每次 102 | 1. 向ESP8266发送命令后后的检查response 103 | 2. 非阻塞接收检查是否受到数据 104 | 时,都需要从FIFO中取出数据. 105 | `Src\ESP8266Client\src\ESP8266Client.c`: 106 | ```c 107 | ... 108 | ESP82_Result_t ESP82_Receive(char * const data, const uint8_t dataLengthMax) { 109 | ... 110 | int popLength = fifo_out(&rxFifo, &ESP82_resBuffer[ESP82_resBufferBack], ESP82_BUFFERSIZE_RESPONSE - 1 - ESP82_resBufferBack); 111 | ESP82_resBufferBack += popLength; 112 | uint8_t availableLength = (ESP82_resBufferBack - ESP82_resBufferFront); 113 | recv_end_flag == 0; 114 | ... 115 | } 116 | 117 | ... 118 | 119 | static ESP82_Result_t ESP82_checkResponse(const uint32_t expectedFlags, const uint16_t timeout_ms, char * const responseOut, const uint8_t responseLengthMax){ 120 | ... 121 | // Get response data and terminate as a string. 122 | ESP82_resBufferBack += fifo_out(&rxFifo, &ESP82_resBuffer[ESP82_resBufferBack], ESP82_BUFFERSIZE_RESPONSE - 1 - ESP82_resBufferBack); 123 | ESP82_resBuffer[ESP82_resBufferBack] = 0; 124 | recv_end_flag == 0; 125 | ... 126 | } 127 | ... 128 | 129 | ``` 130 | ### 2.收到空数据时返回空标志(-2)以区分`IN_PROGRESS`状态 131 | 原本的代码中使用`IN_PROGRESS`(0)来表示ESP8266驱动层正在解析命令. 132 | 且原代码使用有限状态机,必须上层任务必须多次循环才能驱动一次底层解析完成. 133 | 但是,如果没有收到数据,底层驱动也会返回0表示其没有收到. 134 | 135 | 也就是说,上层函数无法区分底层到底是正在解析还是没收到数据. 136 | 于是修改原有代码, 定义`ESP82_RECEIVE_NOTHING`(-2)状态码来特别区分没有收到数据的情况. 137 | 138 | 首先还是在`ESP8266Client.c`中修改`ESP82_Receive()`函数,使其增加一个状态: 139 | ```c 140 | ... 141 | ESP82_Result_t ESP82_Receive(char * const data, const uint8_t dataLengthMax) { 142 | ... 143 | case ESP82_State1: 144 | // Get the incoming data header. 145 | if(availableLength >= 7){ 146 | ... 147 | } 148 | else if(availableLength == 0){ 149 | ESP82_inProgress = false; 150 | return ESP82_RECEIVE_NOTHING; 151 | // recv nothing; 152 | } 153 | ... 154 | } 155 | ... 156 | ``` 157 | 158 | 然后在高一层的`networkwrapper.c`的`network_recv()`函数中, 检测`ESP82_RECEIVE_NOTHING`状态: 159 | ```c 160 | ... 161 | int network_recv(unsigned char *address, unsigned int maxbytes){ 162 | ... 163 | // Recv nothing. 164 | if(espResult == ESP82_RECEIVE_NOTHING){ 165 | // Reset the state machine. 166 | network_recv_state = 0; 167 | return -2; 168 | } 169 | 170 | // In progress. 171 | return 0; 172 | } 173 | ... 174 | ``` 175 | 176 | 在更高一层的`transport.c`中,也要修改其非阻塞接收函数`transport_getdatanb()`,原本只调用底层函数一次,将推动状态机的任务交给了上层函数. 177 | 这里直接改为循环调用底层函数, 在该层完成状态机的推动. 修改后再返回0是没有歧义的,就是表示没有收到数据: 178 | ```c 179 | ... 180 | int transport_getdatanb(void *sck, unsigned char* buf, int count) 181 | { 182 | //int sock = *((int *)sck); /* sck: pointer to whatever the system may use to identify the transport */ 183 | transport_iofunctions_t *myio = io; // io[sock] or mystruct[sock].io 184 | int len; 185 | 186 | /* you should have called open() with a valid pointer to a valid struct before calling this */ 187 | assert((myio != NULL) && (myio->recv != NULL)); 188 | /* this call will return immediately if no bytes, or return whatever outstanding bytes we have, 189 | upto count */ 190 | while((len = myio->recv(buf, count)) == 0); 191 | if (len >0 ) 192 | return len; 193 | if (len==-2) 194 | return 0; 195 | if(len == -1) 196 | return TRANSPORT_ERROR; 197 | } 198 | ... 199 | ``` 200 | ### 3.使用定时器中断来更新硬件信息 201 | ![cube](./image/cube2.jpg) 202 | 203 | 这里用了TIM2作为时钟源. 在定时器周期到达回调函数中,更新硬件信息, 并且用闪灯表示连接上了MQTT Broker: 204 | `main.c`: 205 | ```c 206 | ... 207 | void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 208 | { 209 | if (htim->Instance == TIM2) 210 | { 211 | updateDeviceInfo(); 212 | if(MQTT_connected){ 213 | HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); 214 | } 215 | else{ 216 | HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, SET); 217 | } 218 | } 219 | } 220 | ... 221 | void updateDeviceInfo() 222 | { 223 | ledStatus = HAL_GPIO_ReadPin(LED0_GPIO_Port, LED0_Pin); 224 | ledStatus = !ledStatus; 225 | lightSensorValue = lightSensorLux(); 226 | if (ledMode == 2)// Auto mode 227 | { 228 | HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, lightSensorValue >= 50); 229 | } 230 | else if(ledMode == 1){// Manual mode 231 | HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, !ledSwitch); 232 | } 233 | } 234 | ... 235 | ``` 236 | 237 | ### 4.What To Do Next 238 | 1. 目前运行的版本是直接基于HAL库, 不带os, 日后可以将其移植到freeRTOS上, 不同的任务用不同的os task进行, 可以提高程序可读性. 239 | 240 | ### 5.参考 241 | 1. 参考的项目地址:[atakansarioglu/mqtt_temperature_logger_esp8266](https://github.com/atakansarioglu/mqtt_temperature_logger_esp8266),主要使用了它的,ESP8266驱动 242 | 2. FIFO的实现来自于: [linux内核的队列实现移植](https://blog.csdn.net/u013401853/article/details/53063434) 243 | 3. MQTT驱动来自Paho MQTT, 用于解析MQTT数据包和将数据序列化到MQTT包中. 244 | 245 | 246 | -------------------------------------------------------------------------------- /Final_pro.ioc: -------------------------------------------------------------------------------- 1 | #MicroXplorer Configuration settings - do not modify 2 | Dma.Request0=USART2_RX 3 | Dma.Request1=USART2_TX 4 | Dma.Request2=USART1_TX 5 | Dma.Request3=USART1_RX 6 | Dma.RequestsNb=4 7 | Dma.USART1_RX.3.Direction=DMA_PERIPH_TO_MEMORY 8 | Dma.USART1_RX.3.Instance=DMA1_Channel5 9 | Dma.USART1_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE 10 | Dma.USART1_RX.3.MemInc=DMA_MINC_ENABLE 11 | Dma.USART1_RX.3.Mode=DMA_NORMAL 12 | Dma.USART1_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 13 | Dma.USART1_RX.3.PeriphInc=DMA_PINC_DISABLE 14 | Dma.USART1_RX.3.Priority=DMA_PRIORITY_LOW 15 | Dma.USART1_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 16 | Dma.USART1_TX.2.Direction=DMA_MEMORY_TO_PERIPH 17 | Dma.USART1_TX.2.Instance=DMA1_Channel4 18 | Dma.USART1_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE 19 | Dma.USART1_TX.2.MemInc=DMA_MINC_ENABLE 20 | Dma.USART1_TX.2.Mode=DMA_NORMAL 21 | Dma.USART1_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 22 | Dma.USART1_TX.2.PeriphInc=DMA_PINC_DISABLE 23 | Dma.USART1_TX.2.Priority=DMA_PRIORITY_LOW 24 | Dma.USART1_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 25 | Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY 26 | Dma.USART2_RX.0.Instance=DMA1_Channel6 27 | Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE 28 | Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE 29 | Dma.USART2_RX.0.Mode=DMA_NORMAL 30 | Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 31 | Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE 32 | Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW 33 | Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 34 | Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH 35 | Dma.USART2_TX.1.Instance=DMA1_Channel7 36 | Dma.USART2_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE 37 | Dma.USART2_TX.1.MemInc=DMA_MINC_ENABLE 38 | Dma.USART2_TX.1.Mode=DMA_NORMAL 39 | Dma.USART2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE 40 | Dma.USART2_TX.1.PeriphInc=DMA_PINC_DISABLE 41 | Dma.USART2_TX.1.Priority=DMA_PRIORITY_LOW 42 | Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority 43 | File.Version=6 44 | KeepUserPlacement=false 45 | Mcu.Family=STM32F1 46 | Mcu.IP0=DMA 47 | Mcu.IP1=I2C2 48 | Mcu.IP2=NVIC 49 | Mcu.IP3=RCC 50 | Mcu.IP4=SYS 51 | Mcu.IP5=TIM2 52 | Mcu.IP6=USART1 53 | Mcu.IP7=USART2 54 | Mcu.IPNb=8 55 | Mcu.Name=STM32F103R(C-D-E)Tx 56 | Mcu.Package=LQFP64 57 | Mcu.Pin0=PD0-OSC_IN 58 | Mcu.Pin1=PD1-OSC_OUT 59 | Mcu.Pin10=PA14 60 | Mcu.Pin11=PD2 61 | Mcu.Pin12=VP_SYS_VS_Systick 62 | Mcu.Pin13=VP_TIM2_VS_ClockSourceINT 63 | Mcu.Pin2=PA2 64 | Mcu.Pin3=PA3 65 | Mcu.Pin4=PB10 66 | Mcu.Pin5=PB11 67 | Mcu.Pin6=PA8 68 | Mcu.Pin7=PA9 69 | Mcu.Pin8=PA10 70 | Mcu.Pin9=PA13 71 | Mcu.PinsNb=14 72 | Mcu.ThirdPartyNb=0 73 | Mcu.UserConstants= 74 | Mcu.UserName=STM32F103RCTx 75 | MxCube.Version=5.4.0 76 | MxDb.Version=DB.5.0.40 77 | NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false 78 | NVIC.DMA1_Channel4_IRQn=true\:0\:0\:false\:false\:true\:false\:true 79 | NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true 80 | NVIC.DMA1_Channel6_IRQn=true\:1\:0\:true\:false\:true\:false\:true 81 | NVIC.DMA1_Channel7_IRQn=true\:0\:0\:false\:false\:true\:false\:true 82 | NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false 83 | NVIC.ForceEnableDMAVector=true 84 | NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false 85 | NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false 86 | NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false 87 | NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false 88 | NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 89 | NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false 90 | NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true 91 | NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true 92 | NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true 93 | NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true 94 | NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false 95 | PA10.Mode=Asynchronous 96 | PA10.Signal=USART1_RX 97 | PA13.Mode=Serial_Wire 98 | PA13.Signal=SYS_JTMS-SWDIO 99 | PA14.Mode=Serial_Wire 100 | PA14.Signal=SYS_JTCK-SWCLK 101 | PA2.Mode=Asynchronous 102 | PA2.Signal=USART2_TX 103 | PA3.Mode=Asynchronous 104 | PA3.Signal=USART2_RX 105 | PA8.GPIOParameters=GPIO_Label 106 | PA8.GPIO_Label=LED0 107 | PA8.Locked=true 108 | PA8.Signal=GPIO_Output 109 | PA9.Mode=Asynchronous 110 | PA9.Signal=USART1_TX 111 | PB10.Mode=I2C 112 | PB10.Signal=I2C2_SCL 113 | PB11.Mode=I2C 114 | PB11.Signal=I2C2_SDA 115 | PCC.Checker=false 116 | PCC.Line=STM32F103 117 | PCC.MCU=STM32F103R(C-D-E)Tx 118 | PCC.PartNumber=STM32F103RCTx 119 | PCC.Seq0=0 120 | PCC.Series=STM32F1 121 | PCC.Temperature=25 122 | PCC.Vdd=3.3 123 | PD0-OSC_IN.Mode=HSE-External-Oscillator 124 | PD0-OSC_IN.Signal=RCC_OSC_IN 125 | PD1-OSC_OUT.Mode=HSE-External-Oscillator 126 | PD1-OSC_OUT.Signal=RCC_OSC_OUT 127 | PD2.GPIOParameters=GPIO_Label 128 | PD2.GPIO_Label=LED1 129 | PD2.Locked=true 130 | PD2.Signal=GPIO_Output 131 | PinOutPanel.RotationAngle=0 132 | ProjectManager.AskForMigrate=true 133 | ProjectManager.BackupPrevious=false 134 | ProjectManager.CompilerOptimize=6 135 | ProjectManager.ComputerToolchain=false 136 | ProjectManager.CoupleFile=true 137 | ProjectManager.CustomerFirmwarePackage= 138 | ProjectManager.DefaultFWLocation=true 139 | ProjectManager.DeletePrevious=true 140 | ProjectManager.DeviceId=STM32F103RCTx 141 | ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.0 142 | ProjectManager.FreePins=false 143 | ProjectManager.HalAssertFull=false 144 | ProjectManager.HeapSize=0x200 145 | ProjectManager.KeepUserCode=true 146 | ProjectManager.LastFirmware=true 147 | ProjectManager.LibraryCopy=1 148 | ProjectManager.MainLocation=Src 149 | ProjectManager.NoMain=false 150 | ProjectManager.PreviousToolchain=STM32CubeIDE 151 | ProjectManager.ProjectBuild=false 152 | ProjectManager.ProjectFileName=Final_pro.ioc 153 | ProjectManager.ProjectName=Final_pro 154 | ProjectManager.StackSize=0x400 155 | ProjectManager.TargetToolchain=STM32CubeIDE 156 | ProjectManager.ToolChainLocation= 157 | ProjectManager.UnderRoot=true 158 | ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_I2C2_Init-I2C2-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_DMA_Init-DMA-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true 159 | RCC.ADCFreqValue=36000000 160 | RCC.AHBFreq_Value=72000000 161 | RCC.APB1CLKDivider=RCC_HCLK_DIV2 162 | RCC.APB1Freq_Value=36000000 163 | RCC.APB1TimFreq_Value=72000000 164 | RCC.APB2Freq_Value=72000000 165 | RCC.APB2TimFreq_Value=72000000 166 | RCC.FCLKCortexFreq_Value=72000000 167 | RCC.FamilyName=M 168 | RCC.HCLKFreq_Value=72000000 169 | RCC.I2S2Freq_Value=72000000 170 | RCC.I2S3Freq_Value=72000000 171 | RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,I2S2Freq_Value,I2S3Freq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,PLLSourceVirtual,SDIOFreq_Value,SDIOHCLKDiv2FreqValue,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,VCOOutput2Freq_Value 172 | RCC.MCOFreq_Value=72000000 173 | RCC.PLLCLKFreq_Value=72000000 174 | RCC.PLLMCOFreq_Value=36000000 175 | RCC.PLLMUL=RCC_PLL_MUL9 176 | RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE 177 | RCC.SDIOFreq_Value=72000000 178 | RCC.SDIOHCLKDiv2FreqValue=36000000 179 | RCC.SYSCLKFreq_VALUE=72000000 180 | RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK 181 | RCC.TimSysFreq_Value=72000000 182 | RCC.USBFreq_Value=72000000 183 | RCC.VCOOutput2Freq_Value=8000000 184 | TIM2.IPParameters=Prescaler,Period 185 | TIM2.Period=4999 186 | TIM2.Prescaler=7199 187 | USART1.IPParameters=VirtualMode 188 | USART1.VirtualMode=VM_ASYNC 189 | USART2.IPParameters=VirtualMode 190 | USART2.VirtualMode=VM_ASYNC 191 | VP_SYS_VS_Systick.Mode=SysTick 192 | VP_SYS_VS_Systick.Signal=SYS_VS_Systick 193 | VP_TIM2_VS_ClockSourceINT.Mode=Internal 194 | VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT 195 | board=custom 196 | isbadioc=false 197 | -------------------------------------------------------------------------------- /Src/usart.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * File Name : USART.c 4 | * Description : This file provides code for the configuration 5 | * of the USART instances. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "usart.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | UART_HandleTypeDef huart1; 28 | UART_HandleTypeDef huart2; 29 | DMA_HandleTypeDef hdma_usart1_tx; 30 | DMA_HandleTypeDef hdma_usart1_rx; 31 | DMA_HandleTypeDef hdma_usart2_rx; 32 | DMA_HandleTypeDef hdma_usart2_tx; 33 | 34 | /* USART1 init function */ 35 | 36 | void MX_USART1_UART_Init(void) 37 | { 38 | 39 | huart1.Instance = USART1; 40 | huart1.Init.BaudRate = 115200; 41 | huart1.Init.WordLength = UART_WORDLENGTH_8B; 42 | huart1.Init.StopBits = UART_STOPBITS_1; 43 | huart1.Init.Parity = UART_PARITY_NONE; 44 | huart1.Init.Mode = UART_MODE_TX_RX; 45 | huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; 46 | huart1.Init.OverSampling = UART_OVERSAMPLING_16; 47 | if (HAL_UART_Init(&huart1) != HAL_OK) 48 | { 49 | Error_Handler(); 50 | } 51 | 52 | } 53 | /* USART2 init function */ 54 | 55 | void MX_USART2_UART_Init(void) 56 | { 57 | 58 | huart2.Instance = USART2; 59 | huart2.Init.BaudRate = 115200; 60 | huart2.Init.WordLength = UART_WORDLENGTH_8B; 61 | huart2.Init.StopBits = UART_STOPBITS_1; 62 | huart2.Init.Parity = UART_PARITY_NONE; 63 | huart2.Init.Mode = UART_MODE_TX_RX; 64 | huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; 65 | huart2.Init.OverSampling = UART_OVERSAMPLING_16; 66 | if (HAL_UART_Init(&huart2) != HAL_OK) 67 | { 68 | Error_Handler(); 69 | } 70 | 71 | } 72 | 73 | void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) 74 | { 75 | 76 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 77 | if(uartHandle->Instance==USART1) 78 | { 79 | /* USER CODE BEGIN USART1_MspInit 0 */ 80 | 81 | /* USER CODE END USART1_MspInit 0 */ 82 | /* USART1 clock enable */ 83 | __HAL_RCC_USART1_CLK_ENABLE(); 84 | 85 | __HAL_RCC_GPIOA_CLK_ENABLE(); 86 | /**USART1 GPIO Configuration 87 | PA9 ------> USART1_TX 88 | PA10 ------> USART1_RX 89 | */ 90 | GPIO_InitStruct.Pin = GPIO_PIN_9; 91 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 92 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 93 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 94 | 95 | GPIO_InitStruct.Pin = GPIO_PIN_10; 96 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 97 | GPIO_InitStruct.Pull = GPIO_NOPULL; 98 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 99 | 100 | /* USART1 DMA Init */ 101 | /* USART1_TX Init */ 102 | hdma_usart1_tx.Instance = DMA1_Channel4; 103 | hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; 104 | hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; 105 | hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; 106 | hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 107 | hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 108 | hdma_usart1_tx.Init.Mode = DMA_NORMAL; 109 | hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; 110 | if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) 111 | { 112 | Error_Handler(); 113 | } 114 | 115 | __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx); 116 | 117 | /* USART1_RX Init */ 118 | hdma_usart1_rx.Instance = DMA1_Channel5; 119 | hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; 120 | hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; 121 | hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; 122 | hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 123 | hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 124 | hdma_usart1_rx.Init.Mode = DMA_NORMAL; 125 | hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; 126 | if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK) 127 | { 128 | Error_Handler(); 129 | } 130 | 131 | __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx); 132 | 133 | /* USART1 interrupt Init */ 134 | HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); 135 | HAL_NVIC_EnableIRQ(USART1_IRQn); 136 | /* USER CODE BEGIN USART1_MspInit 1 */ 137 | 138 | /* USER CODE END USART1_MspInit 1 */ 139 | } 140 | else if(uartHandle->Instance==USART2) 141 | { 142 | /* USER CODE BEGIN USART2_MspInit 0 */ 143 | 144 | /* USER CODE END USART2_MspInit 0 */ 145 | /* USART2 clock enable */ 146 | __HAL_RCC_USART2_CLK_ENABLE(); 147 | 148 | __HAL_RCC_GPIOA_CLK_ENABLE(); 149 | /**USART2 GPIO Configuration 150 | PA2 ------> USART2_TX 151 | PA3 ------> USART2_RX 152 | */ 153 | GPIO_InitStruct.Pin = GPIO_PIN_2; 154 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 155 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 156 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 157 | 158 | GPIO_InitStruct.Pin = GPIO_PIN_3; 159 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 160 | GPIO_InitStruct.Pull = GPIO_NOPULL; 161 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 162 | 163 | /* USART2 DMA Init */ 164 | /* USART2_RX Init */ 165 | hdma_usart2_rx.Instance = DMA1_Channel6; 166 | hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; 167 | hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; 168 | hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; 169 | hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 170 | hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 171 | hdma_usart2_rx.Init.Mode = DMA_NORMAL; 172 | hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW; 173 | if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) 174 | { 175 | Error_Handler(); 176 | } 177 | 178 | __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx); 179 | 180 | /* USART2_TX Init */ 181 | hdma_usart2_tx.Instance = DMA1_Channel7; 182 | hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; 183 | hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; 184 | hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE; 185 | hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 186 | hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 187 | hdma_usart2_tx.Init.Mode = DMA_NORMAL; 188 | hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; 189 | if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK) 190 | { 191 | Error_Handler(); 192 | } 193 | 194 | __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx); 195 | 196 | /* USART2 interrupt Init */ 197 | HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); 198 | HAL_NVIC_EnableIRQ(USART2_IRQn); 199 | /* USER CODE BEGIN USART2_MspInit 1 */ 200 | 201 | /* USER CODE END USART2_MspInit 1 */ 202 | } 203 | } 204 | 205 | void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) 206 | { 207 | 208 | if(uartHandle->Instance==USART1) 209 | { 210 | /* USER CODE BEGIN USART1_MspDeInit 0 */ 211 | 212 | /* USER CODE END USART1_MspDeInit 0 */ 213 | /* Peripheral clock disable */ 214 | __HAL_RCC_USART1_CLK_DISABLE(); 215 | 216 | /**USART1 GPIO Configuration 217 | PA9 ------> USART1_TX 218 | PA10 ------> USART1_RX 219 | */ 220 | HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); 221 | 222 | /* USART1 DMA DeInit */ 223 | HAL_DMA_DeInit(uartHandle->hdmatx); 224 | HAL_DMA_DeInit(uartHandle->hdmarx); 225 | 226 | /* USART1 interrupt Deinit */ 227 | HAL_NVIC_DisableIRQ(USART1_IRQn); 228 | /* USER CODE BEGIN USART1_MspDeInit 1 */ 229 | 230 | /* USER CODE END USART1_MspDeInit 1 */ 231 | } 232 | else if(uartHandle->Instance==USART2) 233 | { 234 | /* USER CODE BEGIN USART2_MspDeInit 0 */ 235 | 236 | /* USER CODE END USART2_MspDeInit 0 */ 237 | /* Peripheral clock disable */ 238 | __HAL_RCC_USART2_CLK_DISABLE(); 239 | 240 | /**USART2 GPIO Configuration 241 | PA2 ------> USART2_TX 242 | PA3 ------> USART2_RX 243 | */ 244 | HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); 245 | 246 | /* USART2 DMA DeInit */ 247 | HAL_DMA_DeInit(uartHandle->hdmarx); 248 | HAL_DMA_DeInit(uartHandle->hdmatx); 249 | 250 | /* USART2 interrupt Deinit */ 251 | HAL_NVIC_DisableIRQ(USART2_IRQn); 252 | /* USER CODE BEGIN USART2_MspDeInit 1 */ 253 | 254 | /* USER CODE END USART2_MspDeInit 1 */ 255 | } 256 | } 257 | 258 | /* USER CODE BEGIN 1 */ 259 | 260 | /* USER CODE END 1 */ 261 | 262 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 263 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTFormat.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | *******************************************************************************/ 16 | 17 | #include "StackTrace.h" 18 | #include "MQTTPacket.h" 19 | 20 | #include 21 | 22 | 23 | const char* MQTTPacket_names[] = 24 | { 25 | "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL", 26 | "PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK", 27 | "PINGREQ", "PINGRESP", "DISCONNECT" 28 | }; 29 | 30 | 31 | const char* MQTTPacket_getName(unsigned short packetid) 32 | { 33 | return MQTTPacket_names[packetid]; 34 | } 35 | 36 | 37 | int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data) 38 | { 39 | int strindex = 0; 40 | 41 | strindex = snprintf(strbuf, strbuflen, 42 | "CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d", 43 | (int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data, 44 | (int)data->cleansession, data->keepAliveInterval); 45 | if (data->willFlag) 46 | strindex += snprintf(&strbuf[strindex], strbuflen - strindex, 47 | ", will QoS %d, will retain %d, will topic %.*s, will message %.*s", 48 | data->will.qos, data->will.retained, 49 | data->will.topicName.lenstring.len, data->will.topicName.lenstring.data, 50 | data->will.message.lenstring.len, data->will.message.lenstring.data); 51 | if (data->username.lenstring.data && data->username.lenstring.len > 0) 52 | strindex += snprintf(&strbuf[strindex], strbuflen - strindex, 53 | ", user name %.*s", data->username.lenstring.len, data->username.lenstring.data); 54 | if (data->password.lenstring.data && data->password.lenstring.len > 0) 55 | strindex += snprintf(&strbuf[strindex], strbuflen - strindex, 56 | ", password %.*s", data->password.lenstring.len, data->password.lenstring.data); 57 | return strindex; 58 | } 59 | 60 | 61 | int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent) 62 | { 63 | int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc); 64 | return strindex; 65 | } 66 | 67 | 68 | int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained, 69 | unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen) 70 | { 71 | int strindex = snprintf(strbuf, strbuflen, 72 | "PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s", 73 | dup, qos, retained, packetid, 74 | (topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data, 75 | payloadlen, (payloadlen < 20) ? payloadlen : 20, payload); 76 | return strindex; 77 | } 78 | 79 | 80 | int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid) 81 | { 82 | int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid); 83 | if (dup) 84 | strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup); 85 | return strindex; 86 | } 87 | 88 | 89 | int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count, 90 | MQTTString topicFilters[], int requestedQoSs[]) 91 | { 92 | return snprintf(strbuf, strbuflen, 93 | "SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d", 94 | dup, packetid, count, 95 | topicFilters[0].lenstring.len, topicFilters[0].lenstring.data, 96 | requestedQoSs[0]); 97 | } 98 | 99 | 100 | int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs) 101 | { 102 | return snprintf(strbuf, strbuflen, 103 | "SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]); 104 | } 105 | 106 | 107 | int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, 108 | int count, MQTTString topicFilters[]) 109 | { 110 | return snprintf(strbuf, strbuflen, 111 | "UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s", 112 | dup, packetid, count, 113 | topicFilters[0].lenstring.len, topicFilters[0].lenstring.data); 114 | } 115 | 116 | 117 | #if defined(MQTT_CLIENT) 118 | char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) 119 | { 120 | int index = 0; 121 | int rem_length = 0; 122 | MQTTHeader header = {0}; 123 | int strindex = 0; 124 | 125 | header.byte = buf[index++]; 126 | index += MQTTPacket_decodeBuf(&buf[index], &rem_length); 127 | 128 | switch (header.bits.type) 129 | { 130 | 131 | case CONNACK: 132 | { 133 | unsigned char sessionPresent, connack_rc; 134 | if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1) 135 | strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent); 136 | } 137 | break; 138 | case PUBLISH: 139 | { 140 | unsigned char dup, retained, *payload; 141 | unsigned short packetid; 142 | int qos, payloadlen; 143 | MQTTString topicName = MQTTString_initializer; 144 | if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, 145 | &payload, &payloadlen, buf, buflen) == 1) 146 | strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, 147 | topicName, payload, payloadlen); 148 | } 149 | break; 150 | case PUBACK: 151 | case PUBREC: 152 | case PUBREL: 153 | case PUBCOMP: 154 | { 155 | unsigned char packettype, dup; 156 | unsigned short packetid; 157 | if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) 158 | strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); 159 | } 160 | break; 161 | case SUBACK: 162 | { 163 | unsigned short packetid; 164 | int maxcount = 1, count = 0; 165 | int grantedQoSs[1]; 166 | if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1) 167 | strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs); 168 | } 169 | break; 170 | case UNSUBACK: 171 | { 172 | unsigned short packetid; 173 | if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1) 174 | strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid); 175 | } 176 | break; 177 | case PINGREQ: 178 | case PINGRESP: 179 | case DISCONNECT: 180 | strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); 181 | break; 182 | } 183 | return strbuf; 184 | } 185 | #endif 186 | 187 | #if defined(MQTT_SERVER) 188 | char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen) 189 | { 190 | int index = 0; 191 | int rem_length = 0; 192 | MQTTHeader header = {0}; 193 | int strindex = 0; 194 | 195 | header.byte = buf[index++]; 196 | index += MQTTPacket_decodeBuf(&buf[index], &rem_length); 197 | 198 | switch (header.bits.type) 199 | { 200 | case CONNECT: 201 | { 202 | MQTTPacket_connectData data; 203 | int rc; 204 | if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1) 205 | strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data); 206 | } 207 | break; 208 | case PUBLISH: 209 | { 210 | unsigned char dup, retained, *payload; 211 | unsigned short packetid; 212 | int qos, payloadlen; 213 | MQTTString topicName = MQTTString_initializer; 214 | if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName, 215 | &payload, &payloadlen, buf, buflen) == 1) 216 | strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid, 217 | topicName, payload, payloadlen); 218 | } 219 | break; 220 | case PUBACK: 221 | case PUBREC: 222 | case PUBREL: 223 | case PUBCOMP: 224 | { 225 | unsigned char packettype, dup; 226 | unsigned short packetid; 227 | if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1) 228 | strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid); 229 | } 230 | break; 231 | case SUBSCRIBE: 232 | { 233 | unsigned char dup; 234 | unsigned short packetid; 235 | int maxcount = 1, count = 0; 236 | MQTTString topicFilters[1]; 237 | int requestedQoSs[1]; 238 | if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count, 239 | topicFilters, requestedQoSs, buf, buflen) == 1) 240 | strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);; 241 | } 242 | break; 243 | case UNSUBSCRIBE: 244 | { 245 | unsigned char dup; 246 | unsigned short packetid; 247 | int maxcount = 1, count = 0; 248 | MQTTString topicFilters[1]; 249 | if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1) 250 | strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters); 251 | } 252 | break; 253 | case PINGREQ: 254 | case PINGRESP: 255 | case DISCONNECT: 256 | strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]); 257 | break; 258 | } 259 | strbuf[strbuflen] = '\0'; 260 | return strbuf; 261 | } 262 | #endif 263 | -------------------------------------------------------------------------------- /Src/stm32f1xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f1xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2019 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "main.h" 23 | #include "stm32f1xx_it.h" 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | #include "usart.h" 27 | #include "stm32f1xx_hal_uart.h" 28 | /* USER CODE END Includes */ 29 | 30 | /* Private typedef -----------------------------------------------------------*/ 31 | /* USER CODE BEGIN TD */ 32 | 33 | /* USER CODE END TD */ 34 | 35 | /* Private define ------------------------------------------------------------*/ 36 | /* USER CODE BEGIN PD */ 37 | 38 | /* USER CODE END PD */ 39 | 40 | /* Private macro -------------------------------------------------------------*/ 41 | /* USER CODE BEGIN PM */ 42 | 43 | /* USER CODE END PM */ 44 | 45 | /* Private variables ---------------------------------------------------------*/ 46 | /* USER CODE BEGIN PV */ 47 | extern uint8_t rxBuffer[RX_BUFFER_SIZE]; 48 | extern int recv_end_flag; 49 | extern int rx_len; 50 | /* USER CODE END PV */ 51 | 52 | /* Private function prototypes -----------------------------------------------*/ 53 | /* USER CODE BEGIN PFP */ 54 | 55 | /* USER CODE END PFP */ 56 | 57 | /* Private user code ---------------------------------------------------------*/ 58 | /* USER CODE BEGIN 0 */ 59 | 60 | /* USER CODE END 0 */ 61 | 62 | /* External variables --------------------------------------------------------*/ 63 | extern TIM_HandleTypeDef htim2; 64 | extern DMA_HandleTypeDef hdma_usart1_tx; 65 | extern DMA_HandleTypeDef hdma_usart1_rx; 66 | extern DMA_HandleTypeDef hdma_usart2_rx; 67 | extern DMA_HandleTypeDef hdma_usart2_tx; 68 | extern UART_HandleTypeDef huart1; 69 | extern UART_HandleTypeDef huart2; 70 | /* USER CODE BEGIN EV */ 71 | 72 | /* USER CODE END EV */ 73 | 74 | /******************************************************************************/ 75 | /* Cortex-M3 Processor Interruption and Exception Handlers */ 76 | /******************************************************************************/ 77 | /** 78 | * @brief This function handles Non maskable interrupt. 79 | */ 80 | void NMI_Handler(void) 81 | { 82 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 83 | 84 | /* USER CODE END NonMaskableInt_IRQn 0 */ 85 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 86 | 87 | /* USER CODE END NonMaskableInt_IRQn 1 */ 88 | } 89 | 90 | /** 91 | * @brief This function handles Hard fault interrupt. 92 | */ 93 | void HardFault_Handler(void) 94 | { 95 | /* USER CODE BEGIN HardFault_IRQn 0 */ 96 | 97 | /* USER CODE END HardFault_IRQn 0 */ 98 | while (1) 99 | { 100 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 101 | /* USER CODE END W1_HardFault_IRQn 0 */ 102 | } 103 | } 104 | 105 | /** 106 | * @brief This function handles Memory management fault. 107 | */ 108 | void MemManage_Handler(void) 109 | { 110 | /* USER CODE BEGIN MemoryManagement_IRQn 0 */ 111 | 112 | /* USER CODE END MemoryManagement_IRQn 0 */ 113 | while (1) 114 | { 115 | /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ 116 | /* USER CODE END W1_MemoryManagement_IRQn 0 */ 117 | } 118 | } 119 | 120 | /** 121 | * @brief This function handles Prefetch fault, memory access fault. 122 | */ 123 | void BusFault_Handler(void) 124 | { 125 | /* USER CODE BEGIN BusFault_IRQn 0 */ 126 | 127 | /* USER CODE END BusFault_IRQn 0 */ 128 | while (1) 129 | { 130 | /* USER CODE BEGIN W1_BusFault_IRQn 0 */ 131 | /* USER CODE END W1_BusFault_IRQn 0 */ 132 | } 133 | } 134 | 135 | /** 136 | * @brief This function handles Undefined instruction or illegal state. 137 | */ 138 | void UsageFault_Handler(void) 139 | { 140 | /* USER CODE BEGIN UsageFault_IRQn 0 */ 141 | 142 | /* USER CODE END UsageFault_IRQn 0 */ 143 | while (1) 144 | { 145 | /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ 146 | /* USER CODE END W1_UsageFault_IRQn 0 */ 147 | } 148 | } 149 | 150 | /** 151 | * @brief This function handles System service call via SWI instruction. 152 | */ 153 | void SVC_Handler(void) 154 | { 155 | /* USER CODE BEGIN SVCall_IRQn 0 */ 156 | 157 | /* USER CODE END SVCall_IRQn 0 */ 158 | /* USER CODE BEGIN SVCall_IRQn 1 */ 159 | 160 | /* USER CODE END SVCall_IRQn 1 */ 161 | } 162 | 163 | /** 164 | * @brief This function handles Debug monitor. 165 | */ 166 | void DebugMon_Handler(void) 167 | { 168 | /* USER CODE BEGIN DebugMonitor_IRQn 0 */ 169 | 170 | /* USER CODE END DebugMonitor_IRQn 0 */ 171 | /* USER CODE BEGIN DebugMonitor_IRQn 1 */ 172 | 173 | /* USER CODE END DebugMonitor_IRQn 1 */ 174 | } 175 | 176 | /** 177 | * @brief This function handles Pendable request for system service. 178 | */ 179 | void PendSV_Handler(void) 180 | { 181 | /* USER CODE BEGIN PendSV_IRQn 0 */ 182 | 183 | /* USER CODE END PendSV_IRQn 0 */ 184 | /* USER CODE BEGIN PendSV_IRQn 1 */ 185 | 186 | /* USER CODE END PendSV_IRQn 1 */ 187 | } 188 | 189 | /** 190 | * @brief This function handles System tick timer. 191 | */ 192 | void SysTick_Handler(void) 193 | { 194 | /* USER CODE BEGIN SysTick_IRQn 0 */ 195 | 196 | /* USER CODE END SysTick_IRQn 0 */ 197 | HAL_IncTick(); 198 | /* USER CODE BEGIN SysTick_IRQn 1 */ 199 | 200 | /* USER CODE END SysTick_IRQn 1 */ 201 | } 202 | 203 | /******************************************************************************/ 204 | /* STM32F1xx Peripheral Interrupt Handlers */ 205 | /* Add here the Interrupt Handlers for the used peripherals. */ 206 | /* For the available peripheral interrupt handler names, */ 207 | /* please refer to the startup file (startup_stm32f1xx.s). */ 208 | /******************************************************************************/ 209 | 210 | /** 211 | * @brief This function handles DMA1 channel4 global interrupt. 212 | */ 213 | void DMA1_Channel4_IRQHandler(void) 214 | { 215 | /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */ 216 | 217 | /* USER CODE END DMA1_Channel4_IRQn 0 */ 218 | HAL_DMA_IRQHandler(&hdma_usart1_tx); 219 | /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */ 220 | 221 | /* USER CODE END DMA1_Channel4_IRQn 1 */ 222 | } 223 | 224 | /** 225 | * @brief This function handles DMA1 channel5 global interrupt. 226 | */ 227 | void DMA1_Channel5_IRQHandler(void) 228 | { 229 | /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */ 230 | 231 | /* USER CODE END DMA1_Channel5_IRQn 0 */ 232 | HAL_DMA_IRQHandler(&hdma_usart1_rx); 233 | /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */ 234 | 235 | /* USER CODE END DMA1_Channel5_IRQn 1 */ 236 | } 237 | 238 | /** 239 | * @brief This function handles DMA1 channel6 global interrupt. 240 | */ 241 | void DMA1_Channel6_IRQHandler(void) 242 | { 243 | /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */ 244 | 245 | /* USER CODE END DMA1_Channel6_IRQn 0 */ 246 | HAL_DMA_IRQHandler(&hdma_usart2_rx); 247 | /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */ 248 | // HAL_UART_Receive_DMA(&huart1, rxBuffer, RX_BUFFER_SIZE); 249 | /* USER CODE END DMA1_Channel6_IRQn 1 */ 250 | } 251 | 252 | /** 253 | * @brief This function handles DMA1 channel7 global interrupt. 254 | */ 255 | void DMA1_Channel7_IRQHandler(void) 256 | { 257 | /* USER CODE BEGIN DMA1_Channel7_IRQn 0 */ 258 | 259 | /* USER CODE END DMA1_Channel7_IRQn 0 */ 260 | HAL_DMA_IRQHandler(&hdma_usart2_tx); 261 | /* USER CODE BEGIN DMA1_Channel7_IRQn 1 */ 262 | 263 | /* USER CODE END DMA1_Channel7_IRQn 1 */ 264 | } 265 | 266 | /** 267 | * @brief This function handles TIM2 global interrupt. 268 | */ 269 | void TIM2_IRQHandler(void) 270 | { 271 | /* USER CODE BEGIN TIM2_IRQn 0 */ 272 | 273 | /* USER CODE END TIM2_IRQn 0 */ 274 | HAL_TIM_IRQHandler(&htim2); 275 | /* USER CODE BEGIN TIM2_IRQn 1 */ 276 | 277 | /* USER CODE END TIM2_IRQn 1 */ 278 | } 279 | 280 | /** 281 | * @brief This function handles USART1 global interrupt. 282 | */ 283 | void USART1_IRQHandler(void) 284 | { 285 | /* USER CODE BEGIN USART1_IRQn 0 */ 286 | uint32_t tmp_flag = 0; 287 | uint32_t temp; 288 | tmp_flag = __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); 289 | if((tmp_flag != RESET)) 290 | { 291 | __HAL_UART_CLEAR_IDLEFLAG(&huart1); 292 | temp = huart1.Instance->SR; // read as clear 293 | temp = huart1.Instance->DR; 294 | HAL_UART_DMAStop(&huart1); 295 | temp = hdma_usart1_rx.Instance->CNDTR; 296 | rx_len = RX_BUFFER_SIZE - temp; 297 | recv_end_flag = 1; 298 | HAL_UART_IdleCpltCallback(&huart1); 299 | } 300 | /* USER CODE END USART1_IRQn 0 */ 301 | HAL_UART_IRQHandler(&huart1); 302 | /* USER CODE BEGIN USART1_IRQn 1 */ 303 | 304 | /* USER CODE END USART1_IRQn 1 */ 305 | } 306 | 307 | /** 308 | * @brief This function handles USART2 global interrupt. 309 | */ 310 | void USART2_IRQHandler(void) 311 | { 312 | /* USER CODE BEGIN USART2_IRQn 0 */ 313 | uint32_t tmp_flag = 0; 314 | uint32_t temp; 315 | tmp_flag = __HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); 316 | if((tmp_flag != RESET)) 317 | { 318 | __HAL_UART_CLEAR_IDLEFLAG(&huart2); 319 | temp = huart2.Instance->SR; // read as clear 320 | temp = huart2.Instance->DR; 321 | HAL_UART_DMAStop(&huart2); 322 | temp = hdma_usart2_rx.Instance->CNDTR; 323 | rx_len = RX_BUFFER_SIZE - temp; 324 | recv_end_flag = 1; 325 | HAL_UART_IdleCpltCallback(&huart2); 326 | } 327 | 328 | /* USER CODE END USART2_IRQn 0 */ 329 | HAL_UART_IRQHandler(&huart2); 330 | /* USER CODE BEGIN USART2_IRQn 1 */ 331 | 332 | /* USER CODE END USART2_IRQn 1 */ 333 | } 334 | 335 | /* USER CODE BEGIN 1 */ 336 | 337 | /* USER CODE END 1 */ 338 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 339 | -------------------------------------------------------------------------------- /Src/MQTTPacket/src/MQTTPacket.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2014 IBM Corp. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * and the Eclipse Distribution License is available at 11 | * http://www.eclipse.org/org/documents/edl-v10.php. 12 | * 13 | * Contributors: 14 | * Ian Craggs - initial API and implementation and/or initial documentation 15 | * Sergio R. Caprile - non-blocking packet read functions for stream transport 16 | *******************************************************************************/ 17 | 18 | #include "StackTrace.h" 19 | #include "MQTTPacket.h" 20 | 21 | #include 22 | 23 | /** 24 | * Encodes the message length according to the MQTT algorithm 25 | * @param buf the buffer into which the encoded data is written 26 | * @param length the length to be encoded 27 | * @return the number of bytes written to buffer 28 | */ 29 | int MQTTPacket_encode(unsigned char* buf, int length) 30 | { 31 | int rc = 0; 32 | 33 | FUNC_ENTRY; 34 | do 35 | { 36 | char d = length % 128; 37 | length /= 128; 38 | /* if there are more digits to encode, set the top bit of this digit */ 39 | if (length > 0) 40 | d |= 0x80; 41 | buf[rc++] = d; 42 | } while (length > 0); 43 | FUNC_EXIT_RC(rc); 44 | return rc; 45 | } 46 | 47 | 48 | /** 49 | * Decodes the message length according to the MQTT algorithm 50 | * @param getcharfn pointer to function to read the next character from the data source 51 | * @param value the decoded length returned 52 | * @return the number of bytes read from the socket 53 | */ 54 | int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value) 55 | { 56 | unsigned char c; 57 | int multiplier = 1; 58 | int len = 0; 59 | #define MAX_NO_OF_REMAINING_LENGTH_BYTES 4 60 | 61 | FUNC_ENTRY; 62 | *value = 0; 63 | do 64 | { 65 | int rc = MQTTPACKET_READ_ERROR; 66 | 67 | if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES) 68 | { 69 | rc = MQTTPACKET_READ_ERROR; /* bad data */ 70 | goto exit; 71 | } 72 | rc = (*getcharfn)(&c, 1); 73 | if (rc != 1) 74 | goto exit; 75 | *value += (c & 127) * multiplier; 76 | multiplier *= 128; 77 | } while ((c & 128) != 0); 78 | exit: 79 | FUNC_EXIT_RC(len); 80 | return len; 81 | } 82 | 83 | 84 | int MQTTPacket_len(int rem_len) 85 | { 86 | rem_len += 1; /* header byte */ 87 | 88 | /* now remaining_length field */ 89 | if (rem_len < 128) 90 | rem_len += 1; 91 | else if (rem_len < 16384) 92 | rem_len += 2; 93 | else if (rem_len < 2097151) 94 | rem_len += 3; 95 | else 96 | rem_len += 4; 97 | return rem_len; 98 | } 99 | 100 | 101 | static unsigned char* bufptr; 102 | 103 | int bufchar(unsigned char* c, int count) 104 | { 105 | int i; 106 | 107 | for (i = 0; i < count; ++i) 108 | *c = *bufptr++; 109 | return count; 110 | } 111 | 112 | 113 | int MQTTPacket_decodeBuf(unsigned char* buf, int* value) 114 | { 115 | bufptr = buf; 116 | return MQTTPacket_decode(bufchar, value); 117 | } 118 | 119 | 120 | /** 121 | * Calculates an integer from two bytes read from the input buffer 122 | * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned 123 | * @return the integer value calculated 124 | */ 125 | int readInt(unsigned char** pptr) 126 | { 127 | unsigned char* ptr = *pptr; 128 | int len = 256*(*ptr) + (*(ptr+1)); 129 | *pptr += 2; 130 | return len; 131 | } 132 | 133 | 134 | /** 135 | * Reads one character from the input buffer. 136 | * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned 137 | * @return the character read 138 | */ 139 | char readChar(unsigned char** pptr) 140 | { 141 | char c = **pptr; 142 | (*pptr)++; 143 | return c; 144 | } 145 | 146 | 147 | /** 148 | * Writes one character to an output buffer. 149 | * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 150 | * @param c the character to write 151 | */ 152 | void writeChar(unsigned char** pptr, char c) 153 | { 154 | **pptr = c; 155 | (*pptr)++; 156 | } 157 | 158 | 159 | /** 160 | * Writes an integer as 2 bytes to an output buffer. 161 | * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 162 | * @param anInt the integer to write 163 | */ 164 | void writeInt(unsigned char** pptr, int anInt) 165 | { 166 | **pptr = (unsigned char)(anInt / 256); 167 | (*pptr)++; 168 | **pptr = (unsigned char)(anInt % 256); 169 | (*pptr)++; 170 | } 171 | 172 | 173 | /** 174 | * Writes a "UTF" string to an output buffer. Converts C string to length-delimited. 175 | * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 176 | * @param string the C string to write 177 | */ 178 | void writeCString(unsigned char** pptr, const char* string) 179 | { 180 | int len = strlen(string); 181 | writeInt(pptr, len); 182 | memcpy(*pptr, string, len); 183 | *pptr += len; 184 | } 185 | 186 | 187 | int getLenStringLen(char* ptr) 188 | { 189 | int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1)); 190 | return len; 191 | } 192 | 193 | 194 | void writeMQTTString(unsigned char** pptr, MQTTString mqttstring) 195 | { 196 | if (mqttstring.lenstring.len > 0) 197 | { 198 | writeInt(pptr, mqttstring.lenstring.len); 199 | memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len); 200 | *pptr += mqttstring.lenstring.len; 201 | } 202 | else if (mqttstring.cstring) 203 | writeCString(pptr, mqttstring.cstring); 204 | else 205 | writeInt(pptr, 0); 206 | } 207 | 208 | 209 | /** 210 | * @param mqttstring the MQTTString structure into which the data is to be read 211 | * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned 212 | * @param enddata pointer to the end of the data: do not read beyond 213 | * @return 1 if successful, 0 if not 214 | */ 215 | int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata) 216 | { 217 | int rc = 0; 218 | 219 | FUNC_ENTRY; 220 | /* the first two bytes are the length of the string */ 221 | if (enddata - (*pptr) > 1) /* enough length to read the integer? */ 222 | { 223 | mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */ 224 | if (&(*pptr)[mqttstring->lenstring.len] <= enddata) 225 | { 226 | mqttstring->lenstring.data = (char*)*pptr; 227 | *pptr += mqttstring->lenstring.len; 228 | rc = 1; 229 | } 230 | } 231 | mqttstring->cstring = NULL; 232 | FUNC_EXIT_RC(rc); 233 | return rc; 234 | } 235 | 236 | 237 | /** 238 | * Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string 239 | * @param mqttstring the string to return the length of 240 | * @return the length of the string 241 | */ 242 | int MQTTstrlen(MQTTString mqttstring) 243 | { 244 | int rc = 0; 245 | 246 | if (mqttstring.cstring) 247 | rc = strlen(mqttstring.cstring); 248 | else 249 | rc = mqttstring.lenstring.len; 250 | return rc; 251 | } 252 | 253 | 254 | /** 255 | * Compares an MQTTString to a C string 256 | * @param a the MQTTString to compare 257 | * @param bptr the C string to compare 258 | * @return boolean - equal or not 259 | */ 260 | int MQTTPacket_equals(MQTTString* a, char* bptr) 261 | { 262 | int alen = 0, 263 | blen = 0; 264 | char *aptr; 265 | 266 | if (a->cstring) 267 | { 268 | aptr = a->cstring; 269 | alen = strlen(a->cstring); 270 | } 271 | else 272 | { 273 | aptr = a->lenstring.data; 274 | alen = a->lenstring.len; 275 | } 276 | blen = strlen(bptr); 277 | 278 | return (alen == blen) && (strncmp(aptr, bptr, alen) == 0); 279 | } 280 | 281 | 282 | /** 283 | * Helper function to read packet data from some source into a buffer 284 | * @param buf the buffer into which the packet will be serialized 285 | * @param buflen the length in bytes of the supplied buffer 286 | * @param getfn pointer to a function which will read any number of bytes from the needed source 287 | * @return integer MQTT packet type, or -1 on error 288 | * @note the whole message must fit into the caller's buffer 289 | */ 290 | int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int)) 291 | { 292 | int rc = -1; 293 | MQTTHeader header = {0}; 294 | int len = 0; 295 | int rem_len = 0; 296 | 297 | /* 1. read the header byte. This has the packet type in it */ 298 | if ((*getfn)(buf, 1) != 1) 299 | goto exit; 300 | 301 | len = 1; 302 | /* 2. read the remaining length. This is variable in itself */ 303 | MQTTPacket_decode(getfn, &rem_len); 304 | len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */ 305 | 306 | /* 3. read the rest of the buffer using a callback to supply the rest of the data */ 307 | if((rem_len + len) > buflen) 308 | goto exit; 309 | if (rem_len && ((*getfn)(buf + len, rem_len) != rem_len)) 310 | goto exit; 311 | 312 | header.byte = buf[0]; 313 | rc = header.bits.type; 314 | exit: 315 | return rc; 316 | } 317 | 318 | /** 319 | * Decodes the message length according to the MQTT algorithm, non-blocking 320 | * @param trp pointer to a transport structure holding what is needed to solve getting data from it 321 | * @param value the decoded length returned 322 | * @return integer the number of bytes read from the socket, 0 for call again, or -1 on error 323 | */ 324 | static int MQTTPacket_decodenb(MQTTTransport *trp) 325 | { 326 | unsigned char c; 327 | int rc = MQTTPACKET_READ_ERROR; 328 | 329 | FUNC_ENTRY; 330 | if(trp->len == 0){ /* initialize on first call */ 331 | trp->multiplier = 1; 332 | trp->rem_len = 0; 333 | } 334 | do { 335 | int frc; 336 | if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES) 337 | goto exit; 338 | if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1) 339 | goto exit; 340 | if (frc == 0){ 341 | rc = 0; 342 | goto exit; 343 | } 344 | ++(trp->len); 345 | trp->rem_len += (c & 127) * trp->multiplier; 346 | trp->multiplier *= 128; 347 | } while ((c & 128) != 0); 348 | rc = trp->len; 349 | exit: 350 | FUNC_EXIT_RC(rc); 351 | return rc; 352 | } 353 | 354 | /** 355 | * Helper function to read packet data from some source into a buffer, non-blocking 356 | * @param buf the buffer into which the packet will be serialized 357 | * @param buflen the length in bytes of the supplied buffer 358 | * @param trp pointer to a transport structure holding what is needed to solve getting data from it 359 | * @return integer MQTT packet type, 0 for call again, or -1 on error 360 | * @note the whole message must fit into the caller's buffer 361 | */ 362 | int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp) 363 | { 364 | int rc = -1, frc; 365 | MQTTHeader header = {0}; 366 | 367 | switch(trp->state){ 368 | default: 369 | trp->state = 0; 370 | /*FALLTHROUGH*/ 371 | case 0: 372 | /* read the header byte. This has the packet type in it */ 373 | if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1) 374 | goto exit; 375 | if (frc == 0) 376 | return 0; 377 | trp->len = 0; 378 | ++trp->state; 379 | /*FALLTHROUGH*/ 380 | /* read the remaining length. This is variable in itself */ 381 | case 1: 382 | if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR) 383 | goto exit; 384 | if(frc == 0) 385 | return 0; 386 | trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */ 387 | if((trp->rem_len + trp->len) > buflen) 388 | goto exit; 389 | ++trp->state; 390 | /*FALLTHROUGH*/ 391 | case 2: 392 | if(trp->rem_len){ 393 | /* read the rest of the buffer using a callback to supply the rest of the data */ 394 | if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1) 395 | goto exit; 396 | if (frc == 0) 397 | return 0; 398 | trp->rem_len -= frc; 399 | trp->len += frc; 400 | if(trp->rem_len) 401 | return 0; 402 | } 403 | header.byte = buf[0]; 404 | rc = header.bits.type; 405 | break; 406 | } 407 | 408 | exit: 409 | trp->state = 0; 410 | return rc; 411 | } 412 | 413 | -------------------------------------------------------------------------------- /Src/system_stm32f1xx.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f1xx.c 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. 6 | * 7 | * 1. This file provides two functions and one global variable to be called from 8 | * user application: 9 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 10 | * factors, AHB/APBx prescalers and Flash settings). 11 | * This function is called at startup just after reset and 12 | * before branch to main program. This call is made inside 13 | * the "startup_stm32f1xx_xx.s" file. 14 | * 15 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 16 | * by the user application to setup the SysTick 17 | * timer or configure other parameters. 18 | * 19 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 20 | * be called whenever the core clock is changed 21 | * during program execution. 22 | * 23 | * 2. After each device reset the HSI (8 MHz) is used as system clock source. 24 | * Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to 25 | * configure the system clock before to branch to main program. 26 | * 27 | * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on 28 | * the product used), refer to "HSE_VALUE". 29 | * When HSE is used as system clock source, directly or through PLL, and you 30 | * are using different crystal you have to adapt the HSE value to your own 31 | * configuration. 32 | * 33 | ****************************************************************************** 34 | * @attention 35 | * 36 | *

© Copyright (c) 2017 STMicroelectronics. 37 | * All rights reserved.

38 | * 39 | * This software component is licensed by ST under BSD 3-Clause license, 40 | * the "License"; You may not use this file except in compliance with the 41 | * License. You may obtain a copy of the License at: 42 | * opensource.org/licenses/BSD-3-Clause 43 | * 44 | ****************************************************************************** 45 | */ 46 | 47 | /** @addtogroup CMSIS 48 | * @{ 49 | */ 50 | 51 | /** @addtogroup stm32f1xx_system 52 | * @{ 53 | */ 54 | 55 | /** @addtogroup STM32F1xx_System_Private_Includes 56 | * @{ 57 | */ 58 | 59 | #include "stm32f1xx.h" 60 | 61 | /** 62 | * @} 63 | */ 64 | 65 | /** @addtogroup STM32F1xx_System_Private_TypesDefinitions 66 | * @{ 67 | */ 68 | 69 | /** 70 | * @} 71 | */ 72 | 73 | /** @addtogroup STM32F1xx_System_Private_Defines 74 | * @{ 75 | */ 76 | 77 | #if !defined (HSE_VALUE) 78 | #define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz. 79 | This value can be provided and adapted by the user application. */ 80 | #endif /* HSE_VALUE */ 81 | 82 | #if !defined (HSI_VALUE) 83 | #define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz. 84 | This value can be provided and adapted by the user application. */ 85 | #endif /* HSI_VALUE */ 86 | 87 | /*!< Uncomment the following line if you need to use external SRAM */ 88 | #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 89 | /* #define DATA_IN_ExtSRAM */ 90 | #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 91 | 92 | /*!< Uncomment the following line if you need to relocate your vector Table in 93 | Internal SRAM. */ 94 | /* #define VECT_TAB_SRAM */ 95 | #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. 96 | This value must be a multiple of 0x200. */ 97 | 98 | 99 | /** 100 | * @} 101 | */ 102 | 103 | /** @addtogroup STM32F1xx_System_Private_Macros 104 | * @{ 105 | */ 106 | 107 | /** 108 | * @} 109 | */ 110 | 111 | /** @addtogroup STM32F1xx_System_Private_Variables 112 | * @{ 113 | */ 114 | 115 | /* This variable is updated in three ways: 116 | 1) by calling CMSIS function SystemCoreClockUpdate() 117 | 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 118 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 119 | Note: If you use this function to configure the system clock; then there 120 | is no need to call the 2 first functions listed above, since SystemCoreClock 121 | variable is updated automatically. 122 | */ 123 | uint32_t SystemCoreClock = 16000000; 124 | const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 125 | const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4}; 126 | 127 | /** 128 | * @} 129 | */ 130 | 131 | /** @addtogroup STM32F1xx_System_Private_FunctionPrototypes 132 | * @{ 133 | */ 134 | 135 | #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 136 | #ifdef DATA_IN_ExtSRAM 137 | static void SystemInit_ExtMemCtl(void); 138 | #endif /* DATA_IN_ExtSRAM */ 139 | #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 140 | 141 | /** 142 | * @} 143 | */ 144 | 145 | /** @addtogroup STM32F1xx_System_Private_Functions 146 | * @{ 147 | */ 148 | 149 | /** 150 | * @brief Setup the microcontroller system 151 | * Initialize the Embedded Flash Interface, the PLL and update the 152 | * SystemCoreClock variable. 153 | * @note This function should be used only after reset. 154 | * @param None 155 | * @retval None 156 | */ 157 | void SystemInit (void) 158 | { 159 | /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 160 | /* Set HSION bit */ 161 | RCC->CR |= 0x00000001U; 162 | 163 | /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 164 | #if !defined(STM32F105xC) && !defined(STM32F107xC) 165 | RCC->CFGR &= 0xF8FF0000U; 166 | #else 167 | RCC->CFGR &= 0xF0FF0000U; 168 | #endif /* STM32F105xC */ 169 | 170 | /* Reset HSEON, CSSON and PLLON bits */ 171 | RCC->CR &= 0xFEF6FFFFU; 172 | 173 | /* Reset HSEBYP bit */ 174 | RCC->CR &= 0xFFFBFFFFU; 175 | 176 | /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 177 | RCC->CFGR &= 0xFF80FFFFU; 178 | 179 | #if defined(STM32F105xC) || defined(STM32F107xC) 180 | /* Reset PLL2ON and PLL3ON bits */ 181 | RCC->CR &= 0xEBFFFFFFU; 182 | 183 | /* Disable all interrupts and clear pending bits */ 184 | RCC->CIR = 0x00FF0000U; 185 | 186 | /* Reset CFGR2 register */ 187 | RCC->CFGR2 = 0x00000000U; 188 | #elif defined(STM32F100xB) || defined(STM32F100xE) 189 | /* Disable all interrupts and clear pending bits */ 190 | RCC->CIR = 0x009F0000U; 191 | 192 | /* Reset CFGR2 register */ 193 | RCC->CFGR2 = 0x00000000U; 194 | #else 195 | /* Disable all interrupts and clear pending bits */ 196 | RCC->CIR = 0x009F0000U; 197 | #endif /* STM32F105xC */ 198 | 199 | #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 200 | #ifdef DATA_IN_ExtSRAM 201 | SystemInit_ExtMemCtl(); 202 | #endif /* DATA_IN_ExtSRAM */ 203 | #endif 204 | 205 | #ifdef VECT_TAB_SRAM 206 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 207 | #else 208 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 209 | #endif 210 | } 211 | 212 | /** 213 | * @brief Update SystemCoreClock variable according to Clock Register Values. 214 | * The SystemCoreClock variable contains the core clock (HCLK), it can 215 | * be used by the user application to setup the SysTick timer or configure 216 | * other parameters. 217 | * 218 | * @note Each time the core clock (HCLK) changes, this function must be called 219 | * to update SystemCoreClock variable value. Otherwise, any configuration 220 | * based on this variable will be incorrect. 221 | * 222 | * @note - The system frequency computed by this function is not the real 223 | * frequency in the chip. It is calculated based on the predefined 224 | * constant and the selected clock source: 225 | * 226 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 227 | * 228 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 229 | * 230 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 231 | * or HSI_VALUE(*) multiplied by the PLL factors. 232 | * 233 | * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value 234 | * 8 MHz) but the real value may vary depending on the variations 235 | * in voltage and temperature. 236 | * 237 | * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value 238 | * 8 MHz or 25 MHz, depending on the product used), user has to ensure 239 | * that HSE_VALUE is same as the real frequency of the crystal used. 240 | * Otherwise, this function may have wrong result. 241 | * 242 | * - The result of this function could be not correct when using fractional 243 | * value for HSE crystal. 244 | * @param None 245 | * @retval None 246 | */ 247 | void SystemCoreClockUpdate (void) 248 | { 249 | uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U; 250 | 251 | #if defined(STM32F105xC) || defined(STM32F107xC) 252 | uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U; 253 | #endif /* STM32F105xC */ 254 | 255 | #if defined(STM32F100xB) || defined(STM32F100xE) 256 | uint32_t prediv1factor = 0U; 257 | #endif /* STM32F100xB or STM32F100xE */ 258 | 259 | /* Get SYSCLK source -------------------------------------------------------*/ 260 | tmp = RCC->CFGR & RCC_CFGR_SWS; 261 | 262 | switch (tmp) 263 | { 264 | case 0x00U: /* HSI used as system clock */ 265 | SystemCoreClock = HSI_VALUE; 266 | break; 267 | case 0x04U: /* HSE used as system clock */ 268 | SystemCoreClock = HSE_VALUE; 269 | break; 270 | case 0x08U: /* PLL used as system clock */ 271 | 272 | /* Get PLL clock source and multiplication factor ----------------------*/ 273 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 274 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 275 | 276 | #if !defined(STM32F105xC) && !defined(STM32F107xC) 277 | pllmull = ( pllmull >> 18U) + 2U; 278 | 279 | if (pllsource == 0x00U) 280 | { 281 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 282 | SystemCoreClock = (HSI_VALUE >> 1U) * pllmull; 283 | } 284 | else 285 | { 286 | #if defined(STM32F100xB) || defined(STM32F100xE) 287 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U; 288 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 289 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 290 | #else 291 | /* HSE selected as PLL clock entry */ 292 | if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) 293 | {/* HSE oscillator clock divided by 2 */ 294 | SystemCoreClock = (HSE_VALUE >> 1U) * pllmull; 295 | } 296 | else 297 | { 298 | SystemCoreClock = HSE_VALUE * pllmull; 299 | } 300 | #endif 301 | } 302 | #else 303 | pllmull = pllmull >> 18U; 304 | 305 | if (pllmull != 0x0DU) 306 | { 307 | pllmull += 2U; 308 | } 309 | else 310 | { /* PLL multiplication factor = PLL input clock * 6.5 */ 311 | pllmull = 13U / 2U; 312 | } 313 | 314 | if (pllsource == 0x00U) 315 | { 316 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 317 | SystemCoreClock = (HSI_VALUE >> 1U) * pllmull; 318 | } 319 | else 320 | {/* PREDIV1 selected as PLL clock entry */ 321 | 322 | /* Get PREDIV1 clock source and division factor */ 323 | prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; 324 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U; 325 | 326 | if (prediv1source == 0U) 327 | { 328 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 329 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 330 | } 331 | else 332 | {/* PLL2 clock selected as PREDIV1 clock entry */ 333 | 334 | /* Get PREDIV2 division factor and PLL2 multiplication factor */ 335 | prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U; 336 | pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U; 337 | SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; 338 | } 339 | } 340 | #endif /* STM32F105xC */ 341 | break; 342 | 343 | default: 344 | SystemCoreClock = HSI_VALUE; 345 | break; 346 | } 347 | 348 | /* Compute HCLK clock frequency ----------------*/ 349 | /* Get HCLK prescaler */ 350 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; 351 | /* HCLK clock frequency */ 352 | SystemCoreClock >>= tmp; 353 | } 354 | 355 | #if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG) 356 | /** 357 | * @brief Setup the external memory controller. Called in startup_stm32f1xx.s 358 | * before jump to __main 359 | * @param None 360 | * @retval None 361 | */ 362 | #ifdef DATA_IN_ExtSRAM 363 | /** 364 | * @brief Setup the external memory controller. 365 | * Called in startup_stm32f1xx_xx.s/.c before jump to main. 366 | * This function configures the external SRAM mounted on STM3210E-EVAL 367 | * board (STM32 High density devices). This SRAM will be used as program 368 | * data memory (including heap and stack). 369 | * @param None 370 | * @retval None 371 | */ 372 | void SystemInit_ExtMemCtl(void) 373 | { 374 | __IO uint32_t tmpreg; 375 | /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 376 | required, then adjust the Register Addresses */ 377 | 378 | /* Enable FSMC clock */ 379 | RCC->AHBENR = 0x00000114U; 380 | 381 | /* Delay after an RCC peripheral clock enabling */ 382 | tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN); 383 | 384 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ 385 | RCC->APB2ENR = 0x000001E0U; 386 | 387 | /* Delay after an RCC peripheral clock enabling */ 388 | tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN); 389 | 390 | (void)(tmpreg); 391 | 392 | /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ 393 | /*---------------- SRAM Address lines configuration -------------------------*/ 394 | /*---------------- NOE and NWE configuration --------------------------------*/ 395 | /*---------------- NE3 configuration ----------------------------------------*/ 396 | /*---------------- NBL0, NBL1 configuration ---------------------------------*/ 397 | 398 | GPIOD->CRL = 0x44BB44BBU; 399 | GPIOD->CRH = 0xBBBBBBBBU; 400 | 401 | GPIOE->CRL = 0xB44444BBU; 402 | GPIOE->CRH = 0xBBBBBBBBU; 403 | 404 | GPIOF->CRL = 0x44BBBBBBU; 405 | GPIOF->CRH = 0xBBBB4444U; 406 | 407 | GPIOG->CRL = 0x44BBBBBBU; 408 | GPIOG->CRH = 0x444B4B44U; 409 | 410 | /*---------------- FSMC Configuration ---------------------------------------*/ 411 | /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ 412 | 413 | FSMC_Bank1->BTCR[4U] = 0x00001091U; 414 | FSMC_Bank1->BTCR[5U] = 0x00110212U; 415 | } 416 | #endif /* DATA_IN_ExtSRAM */ 417 | #endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */ 418 | 419 | /** 420 | * @} 421 | */ 422 | 423 | /** 424 | * @} 425 | */ 426 | 427 | /** 428 | * @} 429 | */ 430 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 431 | --------------------------------------------------------------------------------