Add MQTT, network and debug functions
This commit is contained in:
parent
dea6cb3689
commit
7d5bd14503
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,6 +12,7 @@
|
||||
*.cmd
|
||||
/*.c
|
||||
/*.h
|
||||
/.launches
|
||||
|
||||
# Node artifact files
|
||||
node_modules/
|
||||
@ -58,3 +59,4 @@ Thumbs.db
|
||||
*.mov
|
||||
*.wmv
|
||||
|
||||
/Debug/
|
||||
|
||||
11
src/debug/debug.h
Normal file
11
src/debug/debug.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#define IF_SEVERITY 0
|
||||
#include "debug_if.h"
|
||||
|
||||
inline UART_Handle uartHandle;
|
||||
// UART_control(uartHandle, UART_CMD_RXDISABLE, NULL);
|
||||
|
||||
#endif
|
||||
89
src/debug/debug_if.h
Normal file
89
src/debug/debug_if.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Texas Instruments Incorporated
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
// Includes
|
||||
//*****************************************************************************
|
||||
// Standard includes
|
||||
|
||||
#ifndef DEBUG_IF_H
|
||||
#define DEBUG_IF_H
|
||||
|
||||
/* Define Debug Method */
|
||||
#define D_UART_PRINT 0
|
||||
#define D_DISPLAY_PRINT 1
|
||||
#define F_USER_DEFINED 2
|
||||
|
||||
#define D_DEBUG_METHOD D_UART_PRINT
|
||||
|
||||
|
||||
/* Define Supported Modules */
|
||||
#define D_GENERAL_IF (1)
|
||||
#define D_MQTT_IF (1)
|
||||
#define D_OTA_IF (1)
|
||||
|
||||
/* Define Severity Level */
|
||||
enum
|
||||
{
|
||||
E_TRACE, E_DEBUG, E_INFO, E_WARNING, E_ERROR, E_FATAL, E_DISABLED
|
||||
};
|
||||
|
||||
#define IF_NAME "GEN"
|
||||
#ifndef IF_SEVERITY
|
||||
#define IF_SEVERITY E_INFO
|
||||
#endif
|
||||
|
||||
|
||||
#if (D_DEBUG_METHOD == D_UART_PRINT)
|
||||
#include "uart_term.h"
|
||||
#define PRINTF(...) UART_PRINT(__VA_ARGS__);UART_PRINT("\n\r");
|
||||
#elif (D_DEBUG_METHOD == D_DISPLAY_PRINT)
|
||||
#include <ti/display/Display.h>
|
||||
extern Display_Handle display;
|
||||
#define PRINTF(_module_, _severity_, ...) Display_printf(display, 0, 0, __VA_ARGS__);
|
||||
#else
|
||||
/* USER DEFIND PRINT METHOD */
|
||||
#ifndef PRINTF
|
||||
#error "Missing definition of PRINTF method"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define sl_printf(_severity_, ...) if(_severity_)>= D_SEVERITY) { PRINTF("[" IF_NAME "] "__VA_ARGS__); }
|
||||
#define LOG_FATAL( ...) if(E_FATAL >= IF_SEVERITY) { PRINTF("[" IF_NAME "::FATAL] "__VA_ARGS__); }
|
||||
#define LOG_ERROR( ...) if(E_ERROR >= IF_SEVERITY) { PRINTF("[" IF_NAME "::ERROR] "__VA_ARGS__); }
|
||||
#define LOG_WARNING( ...) if(E_WARNING >= IF_SEVERITY) { PRINTF("[" IF_NAME "::WARN] "__VA_ARGS__); }
|
||||
#define LOG_INFO( ...) if(E_INFO >= IF_SEVERITY) { PRINTF("[" IF_NAME "::INFO] "__VA_ARGS__); }
|
||||
#define LOG_DEBUG( ...) if(E_DEBUG >= IF_SEVERITY) { PRINTF("[" IF_NAME "::DEBUG] "__VA_ARGS__); }
|
||||
#define LOG_TRACE( ...) if(E_TRACE >= IF_SEVERITY) { PRINTF("[" IF_NAME "::TRACE] "__VA_ARGS__); }
|
||||
|
||||
|
||||
#endif // DEBUG_IF_H
|
||||
340
src/debug/uart_term.c
Normal file
340
src/debug/uart_term.c
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Texas Instruments Incorporated
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Terminal
|
||||
*/
|
||||
|
||||
// Standard includes
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "uart_term.h"
|
||||
|
||||
extern int vsnprintf(char * s,
|
||||
size_t n,
|
||||
const char * format,
|
||||
va_list arg);
|
||||
|
||||
//*****************************************************************************
|
||||
// LOCAL DEFINES
|
||||
//*****************************************************************************
|
||||
#define IS_SPACE(x) (x == 32 ? 1 : 0)
|
||||
|
||||
//*****************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//*****************************************************************************
|
||||
static UART_Handle uartHandle;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Initialization
|
||||
//!
|
||||
//! This function
|
||||
//! 1. Configures the UART to be used.
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return none
|
||||
//
|
||||
//*****************************************************************************
|
||||
UART_Handle InitTerm(void)
|
||||
{
|
||||
UART_Params uartParams;
|
||||
|
||||
UART_init();
|
||||
UART_Params_init(&uartParams);
|
||||
|
||||
uartParams.writeDataMode = UART_DATA_BINARY;
|
||||
uartParams.readDataMode = UART_DATA_BINARY;
|
||||
uartParams.readReturnMode = UART_RETURN_FULL;
|
||||
uartParams.readEcho = UART_ECHO_OFF;
|
||||
uartParams.baudRate = 115200;
|
||||
|
||||
uartHandle = UART_open(CONFIG_UART_0, &uartParams);
|
||||
/* remove uart receive from LPDS dependency */
|
||||
UART_control(uartHandle, UART_CMD_RXDISABLE, NULL);
|
||||
|
||||
return(uartHandle);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! prints the formatted string on to the console
|
||||
//!
|
||||
//! \param[in] format - is a pointer to the character string specifying the
|
||||
//! format in the following arguments need to be
|
||||
//! interpreted.
|
||||
//! \param[in] [variable number of] arguments according to the format in the
|
||||
//! first parameters
|
||||
//!
|
||||
//! \return count of characters printed
|
||||
//
|
||||
//*****************************************************************************
|
||||
int Report(const char *pcFormat,
|
||||
...)
|
||||
{
|
||||
int iRet = 0;
|
||||
char *pcBuff;
|
||||
char *pcTemp;
|
||||
int iSize = 256;
|
||||
va_list list;
|
||||
|
||||
pcBuff = (char*)malloc(iSize);
|
||||
if(pcBuff == NULL)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
va_start(list,pcFormat);
|
||||
iRet = vsnprintf(pcBuff, iSize, pcFormat, list);
|
||||
va_end(list);
|
||||
if((iRet > -1) && (iRet < iSize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSize *= 2;
|
||||
if((pcTemp = realloc(pcBuff, iSize)) == NULL)
|
||||
{
|
||||
Message("Could not reallocate memory\n\r");
|
||||
iRet = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcBuff = pcTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
Message(pcBuff);
|
||||
free(pcBuff);
|
||||
|
||||
return(iRet);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Trim the spaces from left and right end of given string
|
||||
//!
|
||||
//! \param pcInput - string on which trimming happens
|
||||
//!
|
||||
//! \return length of trimmed string
|
||||
//
|
||||
//*****************************************************************************
|
||||
int TrimSpace(char * pcInput)
|
||||
{
|
||||
size_t size;
|
||||
char *endStr;
|
||||
char *strData = pcInput;
|
||||
char index = 0;
|
||||
|
||||
size = strlen(strData);
|
||||
|
||||
if(!size)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
endStr = strData + size - 1;
|
||||
while((endStr >= strData) && (IS_SPACE(*endStr)))
|
||||
{
|
||||
endStr--;
|
||||
}
|
||||
*(endStr + 1) = '\0';
|
||||
|
||||
while(*strData && IS_SPACE(*strData))
|
||||
{
|
||||
strData++;
|
||||
index++;
|
||||
}
|
||||
memmove(pcInput, strData, strlen(strData) + 1);
|
||||
|
||||
return(strlen(pcInput));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Get the Command string from UART
|
||||
//!
|
||||
//! \param[in] pucBuffer - is the command store to which command will be
|
||||
//! populated
|
||||
//! \param[in] ucBufLen - is the length of buffer store available
|
||||
//!
|
||||
//! \return Length of the bytes received. -1 if buffer length exceeded.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
int GetCmd(char *pcBuffer,
|
||||
unsigned int uiBufLen)
|
||||
{
|
||||
char cChar;
|
||||
int iLen = 0;
|
||||
|
||||
UART_readPolling(uartHandle, &cChar, 1);
|
||||
|
||||
iLen = 0;
|
||||
|
||||
//
|
||||
// Checking the end of Command
|
||||
//
|
||||
while(1)
|
||||
{
|
||||
//
|
||||
// Handling overflow of buffer
|
||||
//
|
||||
if(iLen >= uiBufLen)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//
|
||||
// Copying Data from UART into a buffer
|
||||
//
|
||||
if((cChar == '\r') || (cChar == '\n'))
|
||||
{
|
||||
UART_writePolling(uartHandle, &cChar, 1);
|
||||
break;
|
||||
}
|
||||
else if(cChar == '\b')
|
||||
{
|
||||
//
|
||||
// Deleting last character when you hit backspace
|
||||
//
|
||||
char ch;
|
||||
|
||||
UART_writePolling(uartHandle, &cChar, 1);
|
||||
ch = ' ';
|
||||
UART_writePolling(uartHandle, &ch, 1);
|
||||
if(iLen)
|
||||
{
|
||||
UART_writePolling(uartHandle, &cChar, 1);
|
||||
iLen--;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch = '\a';
|
||||
UART_writePolling(uartHandle, &ch, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Echo the received character
|
||||
//
|
||||
UART_writePolling(uartHandle, &cChar, 1);
|
||||
|
||||
*(pcBuffer + iLen) = cChar;
|
||||
iLen++;
|
||||
}
|
||||
|
||||
UART_readPolling(uartHandle, &cChar, 1);
|
||||
}
|
||||
|
||||
*(pcBuffer + iLen) = '\0';
|
||||
|
||||
return(iLen);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Outputs a character string to the console
|
||||
//!
|
||||
//! This function
|
||||
//! 1. prints the input string character by character on to the console.
|
||||
//!
|
||||
//! \param[in] str - is the pointer to the string to be printed
|
||||
//!
|
||||
//! \return none
|
||||
//!
|
||||
//! \note If UART_NONPOLLING defined in than Message or UART write should be
|
||||
//! called in task/thread context only.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void Message(const char *str)
|
||||
{
|
||||
#ifdef UART_NONPOLLING
|
||||
UART_write(uartHandle, str, strlen(str));
|
||||
#else
|
||||
UART_writePolling(uartHandle, str, strlen(str));
|
||||
#endif
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the console window
|
||||
//!
|
||||
//! This function
|
||||
//! 1. clears the console window.
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return none
|
||||
//
|
||||
//*****************************************************************************
|
||||
void ClearTerm()
|
||||
{
|
||||
Message("\33[2J\r");
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read a character from the console
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return Character
|
||||
//
|
||||
//*****************************************************************************
|
||||
char getch(void)
|
||||
{
|
||||
char ch;
|
||||
|
||||
UART_readPolling(uartHandle, &ch, 1);
|
||||
return(ch);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Outputs a character to the console
|
||||
//!
|
||||
//! \param[in] char - A character to be printed
|
||||
//!
|
||||
//! \return none
|
||||
//
|
||||
//*****************************************************************************
|
||||
void putch(char ch)
|
||||
{
|
||||
UART_writePolling(uartHandle, &ch, 1);
|
||||
}
|
||||
36
src/debug/uart_term.h
Normal file
36
src/debug/uart_term.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __UART_IF_H__
|
||||
#define __UART_IF_H__
|
||||
|
||||
// TI-Driver includes
|
||||
#include <ti/drivers/UART.h>
|
||||
#include "ti_drivers_config.h"
|
||||
|
||||
//Defines
|
||||
|
||||
#define UART_PRINT Report
|
||||
#define DBG_PRINT Report
|
||||
#define ERR_PRINT(x) Report("Error [%d] at line [%d] in function [%s] \n\r",\
|
||||
x, __LINE__, \
|
||||
__FUNCTION__)
|
||||
|
||||
/* API */
|
||||
|
||||
UART_Handle InitTerm(void);
|
||||
|
||||
int Report(const char *pcFormat,
|
||||
...);
|
||||
|
||||
int TrimSpace(char * pcInput);
|
||||
|
||||
int GetCmd(char *pcBuffer,
|
||||
unsigned int uiBufLen);
|
||||
|
||||
void Message(const char *str);
|
||||
|
||||
void ClearTerm();
|
||||
|
||||
char getch(void);
|
||||
|
||||
void putch(char ch);
|
||||
|
||||
#endif // __UART_IF_H__
|
||||
18
src/main.c
18
src/main.c
@ -4,15 +4,18 @@
|
||||
#include <ti/drivers/GPIO.h>
|
||||
#include "ti_drivers_config.h"
|
||||
|
||||
#include "./header.h"
|
||||
#include "debug/debug.h"
|
||||
#include "header.h"
|
||||
|
||||
void Hardware_init(){
|
||||
Board_init();
|
||||
GPIO_init();
|
||||
uartHandle = InitTerm();
|
||||
LOG_TRACE("Hardware initialisation done\r\n");
|
||||
}
|
||||
|
||||
int main(void){
|
||||
Hardware_init() // initilize hardware
|
||||
Hardware_init(); // initilize hardware
|
||||
|
||||
// ==============================================
|
||||
// === tread for G sensor =======================
|
||||
@ -23,14 +26,5 @@ int main(void){
|
||||
|
||||
BIOS_start();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ======== dummyOutput ========
|
||||
* Dummy SysMin output function needed for benchmarks and size comparison
|
||||
* of FreeRTOS and TI-RTOS solutions.
|
||||
*/
|
||||
void dummyOutput(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
171
src/mqtt.c
171
src/mqtt.c
@ -0,0 +1,171 @@
|
||||
#include "mqtt/mqtt.h"
|
||||
|
||||
void MQTTTask(void * args){
|
||||
mq_attr attr;
|
||||
Timer_Params params;
|
||||
// UART_Handle uartHandle;
|
||||
MQTTClient_Handle mqttClientHandle;
|
||||
|
||||
// uartHandle = InitTerm();
|
||||
// UART_control(uartHandle, UART_CMD_RXDISABLE, NULL);
|
||||
|
||||
// GPIO_init();
|
||||
SPI_init();
|
||||
// Timer_init();
|
||||
|
||||
int32_t ret = ti_net_SlNet_initConfig();
|
||||
if(0 != ret)
|
||||
{
|
||||
LOG_ERROR("Failed to initialize SlNetSock\n\r");
|
||||
}
|
||||
// GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
|
||||
// GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
|
||||
// GPIO_write(CONFIG_GPIO_LED_2, CONFIG_GPIO_LED_OFF);
|
||||
|
||||
// GPIO_setCallback(CONFIG_GPIO_BUTTON_0, pushButtonPublishHandler);
|
||||
// GPIO_setCallback(CONFIG_GPIO_BUTTON_1, pushButtonConnectionHandler);
|
||||
|
||||
|
||||
// configuring the timer to toggle an LED until the AP is connected
|
||||
// Timer_Params_init(¶ms);
|
||||
// params.period = 1000000;
|
||||
// params.periodUnits = Timer_PERIOD_US;
|
||||
// params.timerMode = Timer_CONTINUOUS_CALLBACK;
|
||||
// params.timerCallback = (Timer_CallBackFxn)timerLEDCallback;
|
||||
|
||||
// timer0 = Timer_open(CONFIG_TIMER_0, ¶ms);
|
||||
// if (timer0 == NULL) {
|
||||
// LOG_ERROR("failed to initialize timer\r\n");
|
||||
// while(1);
|
||||
// }
|
||||
|
||||
attr.mq_maxmsg = 10;
|
||||
attr.mq_msgsize = sizeof(struct msgQueue);
|
||||
appQueue = mq_open("appQueue", O_CREAT, 0, &attr);
|
||||
if(((int)appQueue) <= 0){
|
||||
while(1);
|
||||
}
|
||||
|
||||
ret = WifiInit();
|
||||
if(ret < 0){
|
||||
while(1);
|
||||
}
|
||||
|
||||
// GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
|
||||
// GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
|
||||
// GPIO_write(CONFIG_GPIO_LED_2, CONFIG_GPIO_LED_OFF);
|
||||
|
||||
// params.period = 1500000;
|
||||
// params.periodUnits = Timer_PERIOD_US;
|
||||
// params.timerMode = Timer_ONESHOT_CALLBACK;
|
||||
// params.timerCallback = (Timer_CallBackFxn)timerCallback;
|
||||
|
||||
// timer0 = Timer_open(CONFIG_TIMER_0, ¶ms);
|
||||
// if (timer0 == NULL) {
|
||||
// LOG_ERROR("failed to initialize timer\r\n");
|
||||
// while(1);
|
||||
// }
|
||||
|
||||
// MQTT_DEMO:
|
||||
|
||||
ret = MQTT_IF_Init(mqttInitParams);
|
||||
if(ret < 0){
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* In case a persistent session is being used, subscribe is called before connect so that the module
|
||||
* is aware of the topic callbacks the user is using. This is important because if the broker is holding
|
||||
* messages for the client, after CONNACK the client may receive the messages before the module is aware
|
||||
* of the topic callbacks. The user may still call subscribe after connect but have to be aware of this.
|
||||
*/
|
||||
ret = MQTT_IF_Subscribe(mqttClientHandle, "Broker/To/cc32xx", MQTT_QOS_2, BrokerCB);
|
||||
ret |= MQTT_IF_Subscribe(mqttClientHandle, "cc32xx/ToggleLED1", MQTT_QOS_2, ToggleLED1CB);
|
||||
ret |= MQTT_IF_Subscribe(mqttClientHandle, "cc32xx/ToggleLED2", MQTT_QOS_2, ToggleLED2CB);
|
||||
ret |= MQTT_IF_Subscribe(mqttClientHandle, "cc32xx/ToggleLED3", MQTT_QOS_2, ToggleLED3CB);
|
||||
if(ret < 0){
|
||||
while(1);
|
||||
}
|
||||
else{
|
||||
LOG_INFO("Subscribed to all topics successfully\r\n");
|
||||
}
|
||||
|
||||
mqttClientHandle = MQTT_IF_Connect(mqttClientParams, mqttConnParams, MQTT_EventCallback);
|
||||
if(mqttClientHandle < 0){
|
||||
while(1);
|
||||
}
|
||||
|
||||
// wait for CONNACK
|
||||
while(connected == 0);
|
||||
|
||||
// GPIO_enableInt(CONFIG_GPIO_BUTTON_0);
|
||||
|
||||
|
||||
struct msgQueue queueElement;
|
||||
while(1){
|
||||
mq_receive(appQueue, (char*)&queueElement, sizeof(struct msgQueue), NULL);
|
||||
|
||||
if(queueElement.event == APP_MQTT_PUBLISH){
|
||||
LOG_TRACE("APP_MQTT_PUBLISH\r\n");
|
||||
|
||||
MQTT_IF_Publish(mqttClientHandle,
|
||||
"cc32xx/ToggleLED1",
|
||||
"LED 1 toggle\r\n",
|
||||
strlen("LED 1 toggle\r\n"),
|
||||
MQTT_QOS_2);
|
||||
|
||||
// GPIO_clearInt(CONFIG_GPIO_BUTTON_0);
|
||||
// GPIO_enableInt(CONFIG_GPIO_BUTTON_0);
|
||||
}
|
||||
else if(queueElement.event == APP_MQTT_CON_TOGGLE){
|
||||
|
||||
LOG_TRACE("APP_MQTT_CON_TOGGLE %d\r\n", connected);
|
||||
|
||||
if(connected){
|
||||
ret = MQTT_IF_Disconnect(mqttClientHandle);
|
||||
if(ret >= 0){
|
||||
connected = 0;
|
||||
}
|
||||
}else{
|
||||
mqttClientHandle = MQTT_IF_Connect(mqttClientParams, mqttConnParams, MQTT_EventCallback);
|
||||
if((int)mqttClientHandle >= 0){
|
||||
connected = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(queueElement.event == APP_MQTT_DEINIT){
|
||||
break;
|
||||
}
|
||||
else if(queueElement.event == APP_BTN_HANDLER){
|
||||
|
||||
struct msgQueue queueElement;
|
||||
|
||||
ret = detectLongPress();
|
||||
if(ret == 0){
|
||||
|
||||
LOG_TRACE("APP_BTN_HANDLER SHORT PRESS\r\n");
|
||||
queueElement.event = APP_MQTT_CON_TOGGLE;
|
||||
}
|
||||
else{
|
||||
|
||||
LOG_TRACE("APP_BTN_HANDLER LONG PRESS\r\n");
|
||||
queueElement.event = APP_MQTT_DEINIT;
|
||||
}
|
||||
|
||||
ret = mq_send(appQueue, (const char*)&queueElement, sizeof(struct msgQueue), 0);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("msg queue send error %d", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit = 1;
|
||||
if(connected){
|
||||
MQTT_IF_Disconnect(mqttClientHandle);
|
||||
}
|
||||
MQTT_IF_Deinit();
|
||||
|
||||
// LOG_INFO("looping the MQTT functionality of the example for demonstration purposes only\r\n");
|
||||
// sleep(2);
|
||||
// goto MQTT_DEMO;
|
||||
}
|
||||
84
src/mqtt/mqtt.h
Normal file
84
src/mqtt/mqtt.h
Normal file
@ -0,0 +1,84 @@
|
||||
#include "./mqtt_if.h"
|
||||
|
||||
// #define SL_TASKSTACKSIZE 2048
|
||||
// #define SPAWN_TASK_PRIORITY 9
|
||||
|
||||
// #define MQTT_MODULE_TASK_PRIORITY 2
|
||||
// #define MQTT_MODULE_TASK_STACK_SIZE 2048
|
||||
|
||||
#define MQTT_WILL_TOPIC "jesus_cc32xx_will_topic"
|
||||
#define MQTT_WILL_MSG "will_msg_works"
|
||||
#define MQTT_WILL_QOS MQTT_QOS_2
|
||||
#define MQTT_WILL_RETAIN false
|
||||
|
||||
#define MQTT_CLIENT_PASSWORD NULL
|
||||
#define MQTT_CLIENT_USERNAME NULL
|
||||
#define MQTT_CLIENT_KEEPALIVE 0
|
||||
#define MQTT_CLIENT_CLEAN_CONNECT true
|
||||
#define MQTT_CLIENT_MQTT_V3_1 true
|
||||
#define MQTT_CLIENT_BLOCKING_SEND true
|
||||
|
||||
#define MQTT_CONNECTION_FLAGS MQTTCLIENT_NETCONN_URL
|
||||
#define MQTT_CONNECTION_ADDRESS "mqtt.eclipse.org"
|
||||
#define MQTT_CONNECTION_PORT_NUMBER 1883
|
||||
|
||||
mqd_t appQueue;
|
||||
int connected;
|
||||
int deinit;
|
||||
Timer_Handle timer0;
|
||||
int longPress = 0;
|
||||
|
||||
/* Client ID */
|
||||
/* If ClientId isn't set, the MAC address of the device will be copied into */
|
||||
/* the ClientID parameter. */
|
||||
char ClientId[13] = {'\0'};
|
||||
|
||||
enum{
|
||||
APP_MQTT_PUBLISH,
|
||||
APP_MQTT_CON_TOGGLE,
|
||||
APP_MQTT_DEINIT,
|
||||
APP_BTN_HANDLER
|
||||
};
|
||||
|
||||
struct msgQueue
|
||||
{
|
||||
int event;
|
||||
char* payload;
|
||||
};
|
||||
|
||||
// MQTT_IF_InitParams_t mqttInitParams =
|
||||
// {
|
||||
// MQTT_MODULE_TASK_STACK_SIZE, // stack size for mqtt module - default is 2048
|
||||
// MQTT_MODULE_TASK_PRIORITY // thread priority for MQTT - default is 2
|
||||
// };
|
||||
|
||||
MQTTClient_Will mqttWillParams =
|
||||
{
|
||||
MQTT_WILL_TOPIC, // will topic
|
||||
MQTT_WILL_MSG, // will message
|
||||
MQTT_WILL_QOS, // will QoS
|
||||
MQTT_WILL_RETAIN // retain flag
|
||||
};
|
||||
|
||||
MQTT_IF_ClientParams_t mqttClientParams =
|
||||
{
|
||||
ClientId, // client ID
|
||||
MQTT_CLIENT_USERNAME, // user name
|
||||
MQTT_CLIENT_PASSWORD, // password
|
||||
MQTT_CLIENT_KEEPALIVE, // keep-alive time
|
||||
MQTT_CLIENT_CLEAN_CONNECT, // clean connect flag
|
||||
MQTT_CLIENT_MQTT_V3_1, // true = 3.1, false = 3.1.1
|
||||
MQTT_CLIENT_BLOCKING_SEND, // blocking send flag
|
||||
&mqttWillParams // will parameters
|
||||
};
|
||||
|
||||
MQTTClient_ConnParams mqttConnParams =
|
||||
{
|
||||
MQTT_CONNECTION_FLAGS, // connection flags
|
||||
MQTT_CONNECTION_ADDRESS, // server address
|
||||
MQTT_CONNECTION_PORT_NUMBER, // port number of MQTT server
|
||||
0, // method for secure socket
|
||||
0, // cipher for secure socket
|
||||
0, // number of files for secure connection
|
||||
NULL // secure files
|
||||
};
|
||||
665
src/mqtt/mqtt_if.c
Normal file
665
src/mqtt/mqtt_if.c
Normal file
@ -0,0 +1,665 @@
|
||||
/*
|
||||
* mqttclient_if.c
|
||||
*
|
||||
* Created on: Jan 22, 2020
|
||||
* Author: a0227533
|
||||
*/
|
||||
|
||||
#include "mqtt_if.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <mqueue.h>
|
||||
|
||||
#include "../debug/debug.h"
|
||||
|
||||
|
||||
enum{
|
||||
MQTT_STATE_IDLE,
|
||||
MQTT_STATE_INITIALIZED,
|
||||
MQTT_STATE_CONNECTED
|
||||
};
|
||||
|
||||
#define MQTT_EVENT_RECV MQTT_EVENT_MAX // event for when receiving data from subscribed topics
|
||||
|
||||
#define MQTTAPPTHREADSIZE 2048
|
||||
|
||||
// structure for linked list elements to manage the topics
|
||||
struct Node
|
||||
{
|
||||
MQTTClient_SubscribeParams topicParams;
|
||||
MQTT_IF_TopicCallback_f topicCB;
|
||||
struct Node* next;
|
||||
};
|
||||
|
||||
struct msgQueue
|
||||
{
|
||||
int event;
|
||||
char* topic;
|
||||
char* payload;
|
||||
};
|
||||
|
||||
static struct mqttContext
|
||||
{
|
||||
mqd_t msgQueue;
|
||||
pthread_mutex_t *moduleMutex;
|
||||
MQTTClient_Handle mqttClient;
|
||||
MQTT_IF_EventCallback_f eventCB;
|
||||
struct Node* head;
|
||||
int moduleState;
|
||||
uint8_t clientDisconnectFlag;
|
||||
} mMQTTContext = {NULL, NULL, NULL, NULL, NULL, MQTT_STATE_IDLE, 0};
|
||||
|
||||
// Callback invoked by the internal MQTT library to notify the application of MQTT events
|
||||
void MQTTClientCallback(int32_t event, void *metaData, uint32_t metaDateLen, void *data, uint32_t dataLen)
|
||||
{
|
||||
int status;
|
||||
struct msgQueue queueElement;
|
||||
|
||||
switch((MQTTClient_EventCB)event)
|
||||
{
|
||||
case MQTTClient_OPERATION_CB_EVENT:
|
||||
{
|
||||
switch(((MQTTClient_OperationMetaDataCB *)metaData)->messageType)
|
||||
{
|
||||
case MQTTCLIENT_OPERATION_CONNACK:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: CONNACK\r\n");
|
||||
queueElement.event = MQTT_EVENT_CONNACK;
|
||||
break;
|
||||
}
|
||||
|
||||
case MQTTCLIENT_OPERATION_EVT_PUBACK:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: PUBACK\r\n");
|
||||
queueElement.event = MQTT_EVENT_PUBACK;
|
||||
break;
|
||||
}
|
||||
|
||||
case MQTTCLIENT_OPERATION_SUBACK:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: SUBACK\r\n");
|
||||
queueElement.event = MQTT_EVENT_SUBACK;
|
||||
break;
|
||||
}
|
||||
|
||||
case MQTTCLIENT_OPERATION_UNSUBACK:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: UNSUBACK\r\n");
|
||||
queueElement.event = MQTT_EVENT_UNSUBACK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MQTTClient_RECV_CB_EVENT:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: RECV CB\r\n");
|
||||
|
||||
MQTTClient_RecvMetaDataCB *receivedMetaData;
|
||||
char *topic;
|
||||
char *payload;
|
||||
|
||||
receivedMetaData = (MQTTClient_RecvMetaDataCB *)metaData;
|
||||
|
||||
// copying received topic data locally to send over msg queue
|
||||
topic = (char*)malloc(receivedMetaData->topLen+1);
|
||||
memcpy(topic, receivedMetaData->topic, receivedMetaData->topLen);
|
||||
topic[receivedMetaData->topLen] = 0;
|
||||
|
||||
payload = (char*)malloc(dataLen+1);
|
||||
memcpy(payload, data, dataLen);
|
||||
payload[dataLen] = 0;
|
||||
|
||||
queueElement.event = MQTT_EVENT_RECV;
|
||||
queueElement.topic = topic;
|
||||
queueElement.payload = payload;
|
||||
|
||||
break;
|
||||
}
|
||||
case MQTTClient_DISCONNECT_CB_EVENT:
|
||||
{
|
||||
LOG_TRACE("MQTT CLIENT CB: DISCONNECT\r\n");
|
||||
|
||||
queueElement.event = MQTT_EVENT_SERVER_DISCONNECT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// signaling the MQTTAppThead of events received from the internal MQTT module
|
||||
status = mq_send(mMQTTContext.msgQueue, (char*)&queueElement, sizeof(struct msgQueue), 0);
|
||||
if(status < 0){
|
||||
LOG_ERROR("msg queue send error %d", status);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function used to compare topic strings and accounts for MQTT wild cards
|
||||
int MQTTHelperTopicMatching(char *s, char *p)
|
||||
{
|
||||
char *s_next = (char*)-1, *p_next;
|
||||
|
||||
for(; s_next; s=s_next+1, p=p_next+1)
|
||||
{
|
||||
int len;
|
||||
|
||||
if(s[0] == '#')
|
||||
return 1;
|
||||
|
||||
s_next = strchr(s, '/');
|
||||
p_next = strchr(p, '/');
|
||||
|
||||
len = ((s_next) ? (s_next - s) : (strlen(s))) + 1;
|
||||
if(s[0] != '+')
|
||||
{
|
||||
if(memcmp(s, p, len) != 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return (p_next)?0:1;
|
||||
}
|
||||
|
||||
// This is the application thread for the MQTT module that signals
|
||||
void *MQTTAppThread(void *threadParams)
|
||||
{
|
||||
int ret;
|
||||
struct msgQueue queueElement;
|
||||
|
||||
while(1)
|
||||
{
|
||||
mq_receive(mMQTTContext.msgQueue, (char*)&queueElement, sizeof(struct msgQueue), NULL);
|
||||
|
||||
ret = 0;
|
||||
|
||||
if(queueElement.event == MQTT_EVENT_RECV)
|
||||
{
|
||||
LOG_TRACE("MQTT APP THREAD: RECV TOPIC = %s", queueElement.topic);
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
|
||||
if(mMQTTContext.head != NULL){
|
||||
|
||||
struct Node* tmp = mMQTTContext.head;
|
||||
|
||||
// check what queueElement.topic to invoke the appropriate topic callback event for the user
|
||||
while(ret == 0){
|
||||
ret = MQTTHelperTopicMatching(tmp->topicParams.topic, queueElement.topic);
|
||||
if(ret == 1){
|
||||
|
||||
LOG_DEBUG("TOPIC MATCH %s\r\n", queueElement.topic);
|
||||
|
||||
tmp->topicCB(queueElement.topic, queueElement.payload);
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
if(tmp == NULL){
|
||||
LOG_INFO("Cannot invoke CB for topic not in topic list\r\n");
|
||||
LOG_INFO("TOPIC: %s \tPAYLOAD: %s\r\n", queueElement.topic, queueElement.payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
free(queueElement.topic);
|
||||
free(queueElement.payload);
|
||||
}
|
||||
// when MQTT_IF_Deinit is called we must close the message queue and terminate the MQTTAppThread
|
||||
else if(queueElement.event == MQTT_EVENT_DESTROY)
|
||||
{
|
||||
LOG_TRACE("MQTT APP THREAD: DESTROY\r\n");
|
||||
|
||||
mMQTTContext.eventCB(queueElement.event);
|
||||
|
||||
ret = mq_close(mMQTTContext.msgQueue);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("msg queue close error %d", ret);
|
||||
}
|
||||
pthread_exit(0);
|
||||
}
|
||||
else if(queueElement.event == MQTT_EVENT_SERVER_DISCONNECT){
|
||||
|
||||
LOG_TRACE("MQTT APP THREAD: DISCONNECT\r\n");
|
||||
|
||||
int tmp; // tmp is to avoid invoking the eventCB while mutex is still locked to prevent deadlock
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
|
||||
// checks if the disconnect event came because the client called disconnect or the server disconnected
|
||||
if(mMQTTContext.clientDisconnectFlag == 1){
|
||||
tmp = 1;
|
||||
mMQTTContext.clientDisconnectFlag = 0;
|
||||
}
|
||||
else{
|
||||
tmp = 0;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
if(tmp == 1){
|
||||
mMQTTContext.eventCB(MQTT_EVENT_CLIENT_DISCONNECT);
|
||||
}
|
||||
else{
|
||||
mMQTTContext.eventCB(queueElement.event);
|
||||
}
|
||||
}
|
||||
else if(queueElement.event == MQTT_EVENT_CONNACK){
|
||||
|
||||
LOG_TRACE("MQTT APP THREAD: CONNACK\r\n");
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
|
||||
// in case the user re-connects to a server this checks if there is a list of topics to
|
||||
// automatically subscribe to the topics again
|
||||
if(mMQTTContext.head != NULL){
|
||||
|
||||
struct Node* curr = mMQTTContext.head;
|
||||
struct Node* prev;
|
||||
struct Node* tmp;
|
||||
|
||||
// iterate through the linked list until the end is reached
|
||||
while(curr != NULL){
|
||||
|
||||
tmp = curr;
|
||||
|
||||
ret = MQTTClient_subscribe(mMQTTContext.mqttClient, &curr->topicParams, 1);
|
||||
// if subscribing to a topic fails we must remove the node from the list since we are no longer subscribed
|
||||
if(ret < 0){
|
||||
|
||||
LOG_ERROR("SUBSCRIBE FAILED: %s", curr->topicParams.topic);
|
||||
|
||||
// if the node to remove is the head update the head pointer
|
||||
if(curr == mMQTTContext.head){
|
||||
mMQTTContext.head = curr->next;
|
||||
curr = curr->next;
|
||||
}
|
||||
else if(curr->next != NULL){
|
||||
prev->next = curr->next;
|
||||
curr = curr->next->next;
|
||||
}
|
||||
else{
|
||||
prev->next = curr->next;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
// delete the node from the linked list
|
||||
free(tmp->topicParams.topic);
|
||||
free(tmp);
|
||||
}
|
||||
else{
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
// notify the user of the connection event
|
||||
mMQTTContext.eventCB(queueElement.event);
|
||||
}
|
||||
else{
|
||||
|
||||
LOG_TRACE("MQTT APP THREAD: OTHER\r\n");
|
||||
// if the module received any other event nothing else needs to be done except call it
|
||||
mMQTTContext.eventCB(queueElement.event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this thread is for the internal MQTT library and is required for the library to function
|
||||
void *MQTTContextThread(void *threadParams)
|
||||
{
|
||||
int ret;
|
||||
|
||||
LOG_TRACE("CONTEXT THREAD: RUNNING\r\n");
|
||||
|
||||
MQTTClient_run((MQTTClient_Handle)threadParams);
|
||||
|
||||
LOG_TRACE("CONTEXT THREAD: MQTTClient_run RETURN\r\n");
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
|
||||
ret = MQTTClient_delete(mMQTTContext.mqttClient);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("client delete error %d", ret);
|
||||
}
|
||||
|
||||
LOG_TRACE("CONTEXT THREAD: MQTT CLIENT DELETED")
|
||||
|
||||
mMQTTContext.moduleState = MQTT_STATE_INITIALIZED;
|
||||
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
LOG_TRACE("CONTEXT THREAD EXIT\r\n");
|
||||
|
||||
pthread_exit(0);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
int MQTT_IF_Init(MQTT_IF_InitParams_t initParams)
|
||||
{
|
||||
int ret;
|
||||
mq_attr attr;
|
||||
pthread_attr_t threadAttr;
|
||||
struct sched_param schedulingparams;
|
||||
pthread_t mqttAppThread = (pthread_t) NULL;
|
||||
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_IDLE){
|
||||
LOG_ERROR("library only supports 1 active init call\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// the mutex is to protect data in the mMQTTContext structure from being manipulated or accessed at the wrong time
|
||||
mMQTTContext.moduleMutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if(mMQTTContext.moduleMutex == NULL){
|
||||
LOG_ERROR("malloc failed: mutex\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pthread_mutex_init(mMQTTContext.moduleMutex, (const pthread_mutexattr_t *)NULL);
|
||||
if (ret != 0){
|
||||
LOG_ERROR("mutex init failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
// initializing the message queue for the MQTT module
|
||||
attr.mq_maxmsg = 10;
|
||||
attr.mq_msgsize = sizeof(struct msgQueue);
|
||||
mMQTTContext.msgQueue = mq_open("msgQueue", O_CREAT, 0, &attr);
|
||||
if(((int)mMQTTContext.msgQueue) <= 0){
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return (int)mMQTTContext.msgQueue;
|
||||
}
|
||||
|
||||
pthread_attr_init(&threadAttr);
|
||||
schedulingparams.sched_priority = initParams.threadPriority;
|
||||
ret = pthread_attr_setschedparam(&threadAttr, &schedulingparams);
|
||||
ret |= pthread_attr_setstacksize(&threadAttr, initParams.stackSize);
|
||||
ret |= pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
|
||||
ret |= pthread_create(&mqttAppThread, &threadAttr, MQTTAppThread, NULL);
|
||||
if(ret == 0){
|
||||
mMQTTContext.moduleState = MQTT_STATE_INITIALIZED;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MQTT_IF_Deinit(MQTTClient_Handle mqttClientHandle)
|
||||
{
|
||||
int ret;
|
||||
struct msgQueue queueElement;
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_INITIALIZED){
|
||||
if(mMQTTContext.moduleState == MQTT_STATE_CONNECTED){
|
||||
LOG_ERROR("call disconnect before calling deinit\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
else if(mMQTTContext.moduleState == MQTT_STATE_IDLE){
|
||||
LOG_ERROR("init has not been called\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
queueElement.event = MQTT_EVENT_DESTROY;
|
||||
|
||||
// since user called MQTT_IF_Deinit send the signal to the app thread so it may terminate itself
|
||||
ret = mq_send(mMQTTContext.msgQueue, (const char*)&queueElement, sizeof(struct msgQueue), 0);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("msg queue send error %d", ret);
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct Node* tmp = mMQTTContext.head;
|
||||
|
||||
// in case the user did not unsubscribe to topics this loop will free any memory that was allocated
|
||||
while(tmp != NULL){
|
||||
free(tmp->topicParams.topic);
|
||||
mMQTTContext.head = tmp->next;
|
||||
free(tmp);
|
||||
tmp = mMQTTContext.head;
|
||||
}
|
||||
|
||||
// setting the MQTT module state back so that user can call init if they wish to use it again
|
||||
mMQTTContext.moduleState = MQTT_STATE_IDLE;
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MQTTClient_Handle MQTT_IF_Connect(MQTT_IF_ClientParams_t mqttClientParams, MQTTClient_ConnParams mqttConnParams, MQTT_IF_EventCallback_f mqttCB)
|
||||
{
|
||||
int ret;
|
||||
pthread_attr_t threadAttr;
|
||||
struct sched_param priParam;
|
||||
pthread_t mqttContextThread = (pthread_t) NULL;
|
||||
MQTTClient_Params clientParams;
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
// if the user has not called init this will return error since they're trying to connect without intializing the module
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_INITIALIZED){
|
||||
|
||||
if(mMQTTContext.moduleState == MQTT_STATE_CONNECTED){
|
||||
LOG_ERROR("mqtt library is already connected to a broker\r\n");
|
||||
}
|
||||
else{
|
||||
LOG_ERROR("must call init before calling connect\r\n");
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return (MQTTClient_Handle)-1;
|
||||
}
|
||||
|
||||
// copying the event callback the user registered for the module context
|
||||
mMQTTContext.eventCB = mqttCB;
|
||||
|
||||
// preparing the data for MQTTClient_create
|
||||
clientParams.blockingSend = mqttClientParams.blockingSend;
|
||||
clientParams.clientId = mqttClientParams.clientID;
|
||||
clientParams.connParams = &mqttConnParams;
|
||||
clientParams.mqttMode31 = mqttClientParams.mqttMode31;
|
||||
|
||||
mMQTTContext.mqttClient = MQTTClient_create(MQTTClientCallback, &clientParams);
|
||||
if(mMQTTContext.mqttClient == NULL){
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return (MQTTClient_Handle)-1;
|
||||
}
|
||||
|
||||
pthread_attr_init(&threadAttr);
|
||||
priParam.sched_priority = 2;
|
||||
ret = pthread_attr_setschedparam(&threadAttr, &priParam);
|
||||
ret |= pthread_attr_setstacksize(&threadAttr, MQTTAPPTHREADSIZE);
|
||||
ret |= pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
|
||||
ret |= pthread_create(&mqttContextThread, &threadAttr, MQTTContextThread, NULL);
|
||||
if(ret != 0){
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return (MQTTClient_Handle)-1;
|
||||
}
|
||||
|
||||
// if the user included additional parameters for the client MQTTClient_set will be called
|
||||
if(mqttClientParams.willParams != NULL){
|
||||
MQTTClient_set(mMQTTContext.mqttClient, MQTTClient_WILL_PARAM, mqttClientParams.willParams, sizeof(MQTTClient_Will));
|
||||
}
|
||||
|
||||
if(mqttClientParams.username != NULL){
|
||||
MQTTClient_set(mMQTTContext.mqttClient, MQTTClient_USER_NAME, mqttClientParams.username, strlen(mqttClientParams.username));
|
||||
}
|
||||
|
||||
if(mqttClientParams.password != NULL){
|
||||
MQTTClient_set(mMQTTContext.mqttClient, MQTTClient_PASSWORD, mqttClientParams.password, strlen(mqttClientParams.password));
|
||||
}
|
||||
|
||||
if(mqttClientParams.cleanConnect == false){
|
||||
MQTTClient_set(mMQTTContext.mqttClient, MQTTClient_CLEAN_CONNECT, &mqttClientParams.cleanConnect, sizeof(mqttClientParams.cleanConnect));
|
||||
}
|
||||
|
||||
if(mqttClientParams.keepaliveTime > 0){
|
||||
MQTTClient_set(mMQTTContext.mqttClient, MQTTClient_KEEPALIVE_TIME, &mqttClientParams.keepaliveTime, sizeof(mqttClientParams.keepaliveTime));
|
||||
}
|
||||
|
||||
ret = MQTTClient_connect(mMQTTContext.mqttClient);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("connect failed: %d\r\n", ret);
|
||||
}
|
||||
else{
|
||||
mMQTTContext.moduleState = MQTT_STATE_CONNECTED;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
if(ret < 0){
|
||||
return (MQTTClient_Handle)ret;
|
||||
}
|
||||
else{
|
||||
return mMQTTContext.mqttClient;
|
||||
}
|
||||
}
|
||||
|
||||
int MQTT_IF_Disconnect(MQTTClient_Handle mqttClientHandle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_CONNECTED){
|
||||
LOG_ERROR("not connected to broker\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mMQTTContext.clientDisconnectFlag = 1;
|
||||
|
||||
ret = MQTTClient_disconnect(mqttClientHandle);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("disconnect error %d", ret);
|
||||
}
|
||||
else{
|
||||
mMQTTContext.moduleState = MQTT_STATE_INITIALIZED;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MQTT_IF_Subscribe(MQTTClient_Handle mqttClientHandle, char* topic, unsigned int qos, MQTT_IF_TopicCallback_f topicCB)
|
||||
{
|
||||
int ret = 0;
|
||||
struct Node* topicEntry = NULL;
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
if(mMQTTContext.moduleState == MQTT_STATE_IDLE){
|
||||
LOG_ERROR("user must call MQTT_IF_Init before using the MQTT module\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// preparing the topic node to add it to the linked list that tracks all the subscribed topics
|
||||
topicEntry = (struct Node*)malloc(sizeof(struct Node));
|
||||
if(topicEntry == NULL){
|
||||
LOG_ERROR("malloc failed: list entry\n\r");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
topicEntry->topicParams.topic = (char*)malloc((strlen(topic)+1)*sizeof(char));
|
||||
if(topicEntry->topicParams.topic == NULL){
|
||||
LOG_ERROR("malloc failed: topic\n\r");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(topicEntry->topicParams.topic, topic);
|
||||
topicEntry->topicParams.qos = qos;
|
||||
topicEntry->topicCB = topicCB;
|
||||
|
||||
// adding the topic node to the linked list
|
||||
topicEntry->next = mMQTTContext.head;
|
||||
mMQTTContext.head = topicEntry;
|
||||
|
||||
if(mMQTTContext.moduleState == MQTT_STATE_CONNECTED){
|
||||
ret = MQTTClient_subscribe(mMQTTContext.mqttClient, &topicEntry->topicParams, 1);
|
||||
// if the client fails to subscribe to the node remove the topic from the list
|
||||
if(ret < 0){
|
||||
LOG_ERROR("subscribe failed %d. removing topic from list", ret);
|
||||
free(topicEntry->topicParams.topic);
|
||||
free(topicEntry);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MQTT_IF_Unsubscribe(MQTTClient_Handle mqttClientHandle, char* topic)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_CONNECTED){
|
||||
LOG_ERROR("not connected to broker\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
MQTTClient_UnsubscribeParams unsubParams;
|
||||
unsubParams.topic = topic;
|
||||
|
||||
ret = MQTTClient_unsubscribe(mMQTTContext.mqttClient, &unsubParams, 1);
|
||||
if(ret < 0){
|
||||
LOG_ERROR("unsub failed\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return ret;
|
||||
}
|
||||
else{
|
||||
// since unsubscribe succeeded the topic linked list must be updated to remove the topic node
|
||||
struct Node* curr = mMQTTContext.head;
|
||||
struct Node* prev;
|
||||
|
||||
while(curr != NULL){
|
||||
|
||||
// compare the current topic to the user passed topic
|
||||
ret = MQTTHelperTopicMatching(curr->topicParams.topic, topic);
|
||||
// if there is a match update the node pointers and remove the node
|
||||
if(ret == 1){
|
||||
|
||||
if(curr == mMQTTContext.head){
|
||||
mMQTTContext.head = curr->next;
|
||||
}
|
||||
else{
|
||||
prev->next = curr->next;
|
||||
}
|
||||
free(curr->topicParams.topic);
|
||||
free(curr);
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return ret;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
}
|
||||
|
||||
LOG_ERROR("topic does not exist\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MQTT_IF_Publish(MQTTClient_Handle mqttClientParams, char* topic, char* payload, unsigned short payloadLen, int flags)
|
||||
{
|
||||
pthread_mutex_lock(mMQTTContext.moduleMutex);
|
||||
if(mMQTTContext.moduleState != MQTT_STATE_CONNECTED){
|
||||
LOG_ERROR("not connected to broker\r\n");
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_unlock(mMQTTContext.moduleMutex);
|
||||
|
||||
return MQTTClient_publish(mqttClientParams,
|
||||
(char*)topic,
|
||||
strlen((char*)topic),
|
||||
(char*)payload,
|
||||
payloadLen,
|
||||
flags);
|
||||
}
|
||||
142
src/mqtt/mqtt_if.h
Normal file
142
src/mqtt/mqtt_if.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* mqtt_module.h
|
||||
*
|
||||
* Created on: Jan 21, 2020
|
||||
* Author: a0227533
|
||||
*/
|
||||
|
||||
#ifndef MQTT_IF_H_
|
||||
#define MQTT_IF_H_
|
||||
|
||||
#include <ti/net/mqtt/mqttclient.h>
|
||||
|
||||
#define MQTTCLIENT_MAX_SIMULTANEOUS_SUB_TOPICS 4
|
||||
|
||||
// MQTT events for event callback
|
||||
enum
|
||||
{
|
||||
MQTT_EVENT_CONNACK,
|
||||
MQTT_EVENT_SUBACK,
|
||||
MQTT_EVENT_PUBACK,
|
||||
MQTT_EVENT_UNSUBACK,
|
||||
MQTT_EVENT_SERVER_DISCONNECT,
|
||||
MQTT_EVENT_CLIENT_DISCONNECT,
|
||||
MQTT_EVENT_DESTROY,
|
||||
MQTT_EVENT_MAX
|
||||
};
|
||||
|
||||
typedef void (*MQTT_IF_TopicCallback_f)(char* topic, char* payload);
|
||||
typedef void (*MQTT_IF_EventCallback_f)(int32_t event);
|
||||
|
||||
typedef struct MQTT_IF_ClientParams
|
||||
{
|
||||
char *clientID;
|
||||
char *username;
|
||||
char *password;
|
||||
uint16_t keepaliveTime;
|
||||
bool cleanConnect;
|
||||
bool mqttMode31; // false 3.1.1 (default) : true 3.1
|
||||
bool blockingSend;
|
||||
MQTTClient_Will *willParams;
|
||||
} MQTT_IF_ClientParams_t;
|
||||
|
||||
typedef struct MQTT_IF_initParams
|
||||
{
|
||||
unsigned int stackSize;
|
||||
uint8_t threadPriority;
|
||||
} MQTT_IF_InitParams_t;
|
||||
|
||||
/**
|
||||
\brief Create the infrastructure for the MQTT_IF (mqtt interface) module
|
||||
|
||||
\param[in] initParams: parameters to set stack size and thread priority for module
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Deinit()
|
||||
*/
|
||||
int MQTT_IF_Init(MQTT_IF_InitParams_t initParams);
|
||||
|
||||
/**
|
||||
\brief Destroys the infrastructure created from calling MQTT_IF_Init
|
||||
|
||||
\param[in] mqttClientHandle: handle for the mqtt client module instance
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Init()
|
||||
*/
|
||||
int MQTT_IF_Deinit();
|
||||
|
||||
/**
|
||||
\brief Connect will set all client and connection parameters and initiate a connection to the broker.
|
||||
It will also register the event callback defined in the user's application and the create an
|
||||
internal context thread for the internal MQTT library
|
||||
|
||||
\param[in] mqttClientParams: params for the mqtt client parameters
|
||||
\param[in] mqttConnParams: params for the mqtt connection parameters
|
||||
\param[in] mqttCB: the callback that is registered when for MQTT operation events (e.g. CONNACK, SUBACK...)
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Disconnect()
|
||||
*/
|
||||
MQTTClient_Handle MQTT_IF_Connect(MQTT_IF_ClientParams_t mqttClientParams, MQTTClient_ConnParams mqttConnParams, MQTT_IF_EventCallback_f mqttCB);
|
||||
|
||||
/**
|
||||
\brief Instructs the internal MQTT library to close the MQTT connection to the broker
|
||||
|
||||
\param[in] mqttClientHandle: handle for the mqtt client module instance
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Connect()
|
||||
*/
|
||||
int MQTT_IF_Disconnect(MQTTClient_Handle mqttClientHandle);
|
||||
|
||||
/**
|
||||
\brief Subscribes to the topics specified by the caller in subscriptionInfo. Topic subscriptions are agnostic to the
|
||||
\ connection status. Meaning if you subscribe to topics then disconnect, the MQTT_IF module will still hold the topics
|
||||
\ so on re-connect the original topics are subscribed to again automatically.
|
||||
|
||||
\param[in] mqttClientHandle: handle for the mqtt client module instance
|
||||
\param[in] subscriptionInfo: data structure containing all the data required to subscribe
|
||||
\param[in] numOfTopics: number of topics stored in subscriptionInfo
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Unsubscribe()
|
||||
*/
|
||||
int MQTT_IF_Subscribe(MQTTClient_Handle mqttClientHandle, char* topic, unsigned int qos, MQTT_IF_TopicCallback_f topicCB);
|
||||
|
||||
/**
|
||||
\brief Unsubscribes to the topics specified by the caller in subscriptionInfo
|
||||
|
||||
\param[in] mqttClientHandle: handle for the mqtt client module instance
|
||||
\param[in] subscriptionInfo: data structure containing all the data required to subscribe
|
||||
\param[in] numOfTopics: number of topics stored in subscriptionInfo
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
\sa MQTT_IF_Subscribe()
|
||||
*/
|
||||
int MQTT_IF_Unsubscribe(MQTTClient_Handle mqttClientHandle, char* topic);
|
||||
|
||||
/**
|
||||
\brief Publishes to the topic specified by the user
|
||||
|
||||
\param[in] mqttClientHandle: handle for the mqtt client module instance
|
||||
\param[in] topic: topic user wants to publish to
|
||||
\param[in] payload: payload to publish to topic
|
||||
\param[in] payloadLen: length of payload passed by the user
|
||||
\param[in] flags QOS define MQTT_PUBLISH_QOS_0, MQTT_PUBLISH_QOS_1 or MQTT_PUBLISH_QOS_2
|
||||
use MQTT_PUBLISH_RETAIN is message should be retained
|
||||
|
||||
\return Success 0 or Failure -1
|
||||
|
||||
*/
|
||||
//\param[in] flags QOS define MQTT_PUBLISH_QOS_0, MQTT_PUBLISH_QOS_1 or MQTT_PUBLISH_QOS_2
|
||||
//use MQTT_PUBLISH_RETAIN if message should be retained
|
||||
int MQTT_IF_Publish(MQTTClient_Handle mqttClientHandle, char* topic, char* payload, unsigned short payloadLen, int flags);
|
||||
|
||||
#endif /* MQTT_IF_H_ */
|
||||
852
src/network/network_if.c
Normal file
852
src/network/network_if.c
Normal file
@ -0,0 +1,852 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Texas Instruments Incorporated
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
// network_if.c
|
||||
//
|
||||
// Networking interface functions for CC32xx device
|
||||
//
|
||||
//*****************************************************************************
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup common_interface
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
/* Standard includes */
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Kernel (Non OS/Free-RTOS/TI-RTOS) includes */
|
||||
#include <pthread.h>
|
||||
#include <mqueue.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Simplelink includes */
|
||||
#include <ti/drivers/net/wifi/simplelink.h>
|
||||
|
||||
/* Common interface includes */
|
||||
#include "network_if.h"
|
||||
#include "../debug/uart_term.h"
|
||||
|
||||
//*****************************************************************************
|
||||
// LOCAL DEFINES
|
||||
//*****************************************************************************
|
||||
|
||||
/* Network App specific status/error codes which are */
|
||||
/* used only in this file. */
|
||||
typedef enum
|
||||
{
|
||||
/* Choosing this number to avoid overlap with host-driver's error codes. */
|
||||
DEVICE_NOT_IN_STATION_MODE = -0x7F0,
|
||||
DEVICE_NOT_IN_AP_MODE = DEVICE_NOT_IN_STATION_MODE - 1,
|
||||
DEVICE_NOT_IN_P2P_MODE = DEVICE_NOT_IN_AP_MODE - 1,
|
||||
|
||||
STATUS_CODE_MAX = -0xBB8
|
||||
} e_NetAppStatusCodes;
|
||||
|
||||
//*****************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//*****************************************************************************
|
||||
|
||||
/* Station IP address */
|
||||
unsigned long g_ulStaIp = 0;
|
||||
/* Network Gateway IP address */
|
||||
unsigned long g_ulGatewayIP = 0;
|
||||
/* Connection SSID */
|
||||
unsigned char g_ucConnectionSSID[SL_WLAN_SSID_MAX_LENGTH + 1];
|
||||
/* Connection BSSID */
|
||||
unsigned char g_ucConnectionBSSID[SL_WLAN_BSSID_LENGTH ];
|
||||
/* SimpleLink Status */
|
||||
volatile unsigned long g_ulStatus = 0;
|
||||
/* Connection time delay index */
|
||||
volatile unsigned short g_usConnectIndex;
|
||||
|
||||
//*****************************************************************************
|
||||
// SimpleLink Asynchronous Event Handlers -- Start
|
||||
//*****************************************************************************
|
||||
void SimpleLinkHttpServerEventHandler(
|
||||
SlNetAppHttpServerEvent_t *pSlHttpServerEvent,
|
||||
SlNetAppHttpServerResponse_t *
|
||||
pSlHttpServerResponse)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest,
|
||||
SlNetAppResponse_t *pNetAppResponse)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//!
|
||||
//! On Successful completion of Wlan Connect, This function triggers connection
|
||||
//! status to be set.
|
||||
//!
|
||||
//! \param[in] pSlWlanEvent - pointer indicating Event type
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pSlWlanEvent)
|
||||
{
|
||||
SlWlanEventDisconnect_t* pEventData = NULL;
|
||||
|
||||
switch(pSlWlanEvent->Id)
|
||||
{
|
||||
case SL_WLAN_EVENT_CONNECT:
|
||||
SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
|
||||
memcpy(g_ucConnectionSSID, pSlWlanEvent->Data.Connect.SsidName,
|
||||
pSlWlanEvent->Data.Connect.SsidLen);
|
||||
memcpy(g_ucConnectionBSSID, pSlWlanEvent->Data.Connect.Bssid,
|
||||
SL_WLAN_BSSID_LENGTH);
|
||||
|
||||
UART_PRINT(
|
||||
"[WLAN EVENT] STA Connected to the AP: %s , BSSID: "
|
||||
"%x:%x:%x:%x:%x:%x\n\r", g_ucConnectionSSID,
|
||||
g_ucConnectionBSSID[0], g_ucConnectionBSSID[1],
|
||||
g_ucConnectionBSSID[2],
|
||||
g_ucConnectionBSSID[3], g_ucConnectionBSSID[4],
|
||||
g_ucConnectionBSSID[5]);
|
||||
break;
|
||||
|
||||
case SL_WLAN_EVENT_DISCONNECT:
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
|
||||
|
||||
pEventData = &pSlWlanEvent->Data.Disconnect;
|
||||
|
||||
/* If the user has initiated 'Disconnect' request, 'reason_code' */
|
||||
/* is SL_WLAN_DISCONNECT_USER_INITIATED */
|
||||
if(SL_WLAN_DISCONNECT_USER_INITIATED == pEventData->ReasonCode)
|
||||
{
|
||||
UART_PRINT("Device disconnected from the AP on application's "
|
||||
"request \n\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
UART_PRINT("Device disconnected from the AP on an ERROR..!! \n\r");
|
||||
}
|
||||
break;
|
||||
|
||||
case SL_WLAN_EVENT_STA_ADDED:
|
||||
/* when device is in AP mode and any client connects to it. */
|
||||
SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
break;
|
||||
|
||||
case SL_WLAN_EVENT_STA_REMOVED:
|
||||
/* when device is in AP mode and any client disconnects from it. */
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
|
||||
break;
|
||||
|
||||
default:
|
||||
UART_PRINT("[WLAN EVENT] Unexpected event %d\n\r", pSlWlanEvent->Id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! The Function Handles the Fatal errors
|
||||
//!
|
||||
//! \param[in] slFatalErrorEvent - Pointer to Fatal Error Event info
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent)
|
||||
{
|
||||
switch(slFatalErrorEvent->Id)
|
||||
{
|
||||
case SL_DEVICE_EVENT_FATAL_DEVICE_ABORT:
|
||||
UART_PRINT(
|
||||
"[ERROR] - FATAL ERROR: Abort NWP event detected: "
|
||||
"AbortType=%d, AbortData=0x%x\n\r",
|
||||
slFatalErrorEvent->Data.DeviceAssert.Code,
|
||||
slFatalErrorEvent->Data.DeviceAssert.Value);
|
||||
break;
|
||||
|
||||
case SL_DEVICE_EVENT_FATAL_DRIVER_ABORT:
|
||||
UART_PRINT("[ERROR] - FATAL ERROR: Driver Abort detected. \n\r");
|
||||
break;
|
||||
|
||||
case SL_DEVICE_EVENT_FATAL_NO_CMD_ACK:
|
||||
UART_PRINT(
|
||||
"[ERROR] - FATAL ERROR: No Cmd Ack detected "
|
||||
"[cmd opcode = 0x%x] \n\r",
|
||||
slFatalErrorEvent->Data.NoCmdAck.Code);
|
||||
break;
|
||||
|
||||
case SL_DEVICE_EVENT_FATAL_SYNC_LOSS:
|
||||
UART_PRINT("[ERROR] - FATAL ERROR: Sync loss detected n\r");
|
||||
break;
|
||||
|
||||
case SL_DEVICE_EVENT_FATAL_CMD_TIMEOUT:
|
||||
UART_PRINT(
|
||||
"[ERROR] - FATAL ERROR: Async event timeout detected "
|
||||
"[event opcode =0x%x] \n\r",
|
||||
slFatalErrorEvent->Data.CmdTimeout.Code);
|
||||
break;
|
||||
|
||||
default:
|
||||
UART_PRINT("[ERROR] - FATAL ERROR: Unspecified error detected \n\r");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function handles network events such as IP acquisition, IP leased, IP
|
||||
//! released etc.
|
||||
//!
|
||||
//! \param[in] pNetAppEvent - Pointer to NetApp Event Info
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
|
||||
{
|
||||
switch(pNetAppEvent->Id)
|
||||
{
|
||||
case SL_NETAPP_EVENT_IPV4_ACQUIRED:
|
||||
case SL_NETAPP_EVENT_IPV6_ACQUIRED:
|
||||
SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
|
||||
UART_PRINT("[NETAPP EVENT] IP acquired by the device\n\r");
|
||||
break;
|
||||
|
||||
case SL_NETAPP_EVENT_DHCPV4_LEASED:
|
||||
SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
|
||||
g_ulStaIp = (pNetAppEvent)->Data.IpLeased.IpAddress;
|
||||
|
||||
UART_PRINT("[NETAPP EVENT] IP Leased to Client: IP=%d.%d.%d.%d , ",
|
||||
SL_IPV4_BYTE(g_ulStaIp,
|
||||
3),
|
||||
SL_IPV4_BYTE(g_ulStaIp,
|
||||
2),
|
||||
SL_IPV4_BYTE(g_ulStaIp, 1), SL_IPV4_BYTE(g_ulStaIp, 0));
|
||||
break;
|
||||
|
||||
case SL_NETAPP_EVENT_DHCPV4_RELEASED:
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);
|
||||
|
||||
UART_PRINT("[NETAPP EVENT] IP Released for Client: "
|
||||
"IP=%d.%d.%d.%d , ", SL_IPV4_BYTE(g_ulStaIp,
|
||||
3),
|
||||
SL_IPV4_BYTE(g_ulStaIp,
|
||||
2),
|
||||
SL_IPV4_BYTE(g_ulStaIp, 1), SL_IPV4_BYTE(g_ulStaIp, 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
UART_PRINT("[NETAPP EVENT] Unexpected event [0x%x] \n\r",
|
||||
pNetAppEvent->Id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function handles resource request
|
||||
//!
|
||||
//! \param[in] pNetAppRequest - Contains the resource requests
|
||||
//! \param[in] pNetAppResponse - Should be filled by the user with the
|
||||
//! relevant response information
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkNetAppRequestHandler(SlNetAppRequest_t *pNetAppRequest,
|
||||
SlNetAppResponse_t *pNetAppResponse)
|
||||
{
|
||||
/* Unused in this application */
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function handles HTTP server events
|
||||
//!
|
||||
//! \param[in] pServerEvent - Contains the relevant event information
|
||||
//! \param[in] pServerResponse - Should be filled by the user with the
|
||||
//! relevant response information
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//****************************************************************************
|
||||
void SimpleLinkHttpServerCallback(SlNetAppHttpServerEvent_t *pHttpEvent,
|
||||
SlNetAppHttpServerResponse_t *pHttpResponse)
|
||||
{
|
||||
/* Unused in this application */
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function handles General Events
|
||||
//!
|
||||
//! \param[in] pDevEvent - Pointer to General Event Info
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
|
||||
{
|
||||
/* Most of the general errors are not FATAL. are to be handled */
|
||||
/* appropriately by the application. */
|
||||
UART_PRINT("[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n",
|
||||
pDevEvent->Data.Error.Code,
|
||||
pDevEvent->Data.Error.Source);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function handles socket events indication
|
||||
//!
|
||||
//! \param[in] pSock - Pointer to Socket Event Info
|
||||
//!
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
|
||||
{
|
||||
/* This application doesn't work w/ socket - Events are not expected */
|
||||
switch(pSock->Event)
|
||||
{
|
||||
case SL_SOCKET_TX_FAILED_EVENT:
|
||||
switch(pSock->SocketAsyncEvent.SockTxFailData.Status)
|
||||
{
|
||||
case SL_ERROR_BSD_ECLOSE:
|
||||
UART_PRINT(
|
||||
"[SOCK ERROR] - close socket (%d) operation "
|
||||
"failed to transmit all queued packets\n\r",
|
||||
pSock->SocketAsyncEvent.SockTxFailData.Sd);
|
||||
break;
|
||||
default:
|
||||
UART_PRINT(
|
||||
"[SOCK ERROR] - TX FAILED : socket %d , "
|
||||
"reason (%d) \n\n",
|
||||
pSock->SocketAsyncEvent.SockTxFailData.Sd,
|
||||
pSock->SocketAsyncEvent.SockTxFailData.Status);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SL_SOCKET_ASYNC_EVENT:
|
||||
{
|
||||
UART_PRINT("[SOCK ERROR] an event received on socket %d\r\n",
|
||||
pSock->SocketAsyncEvent.SockAsyncData.Sd);
|
||||
switch(pSock->SocketAsyncEvent.SockAsyncData.Type)
|
||||
{
|
||||
case SL_SSL_NOTIFICATION_CONNECTED_SECURED:
|
||||
UART_PRINT("[SOCK ERROR] SSL handshake done");
|
||||
break;
|
||||
case SL_SSL_NOTIFICATION_HANDSHAKE_FAILED:
|
||||
UART_PRINT("[SOCK ERROR] SSL handshake failed with error %d\r\n",
|
||||
pSock->SocketAsyncEvent.SockAsyncData.Val);
|
||||
break;
|
||||
case SL_SSL_ACCEPT:
|
||||
UART_PRINT(
|
||||
"[SOCK ERROR] Recoverable error occurred "
|
||||
"during the handshake %d\r\n",
|
||||
pSock->SocketAsyncEvent.SockAsyncData.Val);
|
||||
break;
|
||||
case SL_OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED:
|
||||
UART_PRINT("[SOCK ERROR] Other peer terminated the SSL layer.\r\n");
|
||||
break;
|
||||
case SL_SSL_NOTIFICATION_WRONG_ROOT_CA:
|
||||
UART_PRINT("[SOCK ERROR] Used wrong CA to verify the peer.\r\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UART_PRINT("[SOCK EVENT] - Unexpected Event [%x0x]\n\n", pSock->Event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// SimpleLink Asynchronous Event Handlers -- End
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function initializes the application variables
|
||||
//!
|
||||
//! \param None
|
||||
//!
|
||||
//! \return 0 on success, negative error-code on error
|
||||
//
|
||||
//*****************************************************************************
|
||||
void InitializeAppVariables(void)
|
||||
{
|
||||
g_ulStatus = 0;
|
||||
g_ulStaIp = 0;
|
||||
g_ulGatewayIP = 0;
|
||||
|
||||
memset(g_ucConnectionSSID, 0, sizeof(g_ucConnectionSSID));
|
||||
memset(g_ucConnectionBSSID, 0, sizeof(g_ucConnectionBSSID));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! The function initializes a CC32xx device and triggers it to start operation
|
||||
//!
|
||||
//! \param[in] uiMode - device mode in which device will be configured
|
||||
//!
|
||||
//! \return 0 : success, -ve : failure
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_InitDriver(uint32_t uiMode)
|
||||
{
|
||||
long lRetVal = -1;
|
||||
|
||||
/* Reset CC32xx Network State Machine */
|
||||
InitializeAppVariables();
|
||||
|
||||
/* Following function configure the device to default state by cleaning */
|
||||
/* the persistent settings stored in NVMEM (viz. connection profiles */
|
||||
/* & policies, power policy etc) Applications may choose to skip this */
|
||||
/* step if the developer is sure that the device is in its default state */
|
||||
/* at start of application. Note that all profiles and persistent */
|
||||
/* settings that were done on the device will be lost. */
|
||||
lRetVal = sl_Start(NULL, NULL, NULL);
|
||||
|
||||
if(lRetVal < 0)
|
||||
{
|
||||
UART_PRINT("Failed to start the device \n\r");
|
||||
LOOP_FOREVER();
|
||||
}
|
||||
|
||||
switch(lRetVal)
|
||||
{
|
||||
case ROLE_STA:
|
||||
UART_PRINT("Device came up in Station mode\n\r");
|
||||
break;
|
||||
case ROLE_AP:
|
||||
UART_PRINT("Device came up in Access-Point mode\n\r");
|
||||
break;
|
||||
case ROLE_P2P:
|
||||
UART_PRINT("Device came up in P2P mode\n\r");
|
||||
break;
|
||||
default:
|
||||
UART_PRINT("Error:unknown mode\n\r");
|
||||
break;
|
||||
}
|
||||
|
||||
if(uiMode != lRetVal)
|
||||
{
|
||||
UART_PRINT("Switching Networking mode on application request\n\r");
|
||||
|
||||
/* Switch to AP role and restart */
|
||||
lRetVal = sl_WlanSetMode(uiMode);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
lRetVal = sl_Stop(SL_STOP_TIMEOUT);
|
||||
lRetVal = sl_Start(0, 0, 0);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
if(lRetVal == uiMode)
|
||||
{
|
||||
switch(lRetVal)
|
||||
{
|
||||
case ROLE_STA:
|
||||
UART_PRINT("Device came up in Station mode\n\r");
|
||||
break;
|
||||
case ROLE_AP:
|
||||
UART_PRINT("Device came up in Access-Point mode\n\r");
|
||||
/* If the device is in AP mode, we need to wait for this */
|
||||
/* event before doing anything. */
|
||||
while(!IS_IP_ACQUIRED(g_ulStatus))
|
||||
{
|
||||
usleep(1000);
|
||||
}
|
||||
break;
|
||||
case ROLE_P2P:
|
||||
UART_PRINT("Device came up in P2P mode\n\r");
|
||||
break;
|
||||
default:
|
||||
UART_PRINT("Error:unknown mode\n\r");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UART_PRINT("could not configure correct networking mode\n\r");
|
||||
LOOP_FOREVER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(lRetVal == ROLE_AP)
|
||||
{
|
||||
while(!IS_IP_ACQUIRED(g_ulStatus))
|
||||
{
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! The function de-initializes a CC32xx device
|
||||
//!
|
||||
//! \param None
|
||||
//!
|
||||
//! \return On success, zero is returned. On error, other
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_DeInitDriver(void)
|
||||
{
|
||||
long lRetVal = -1;
|
||||
|
||||
UART_PRINT("SL Disconnect...\n\r");
|
||||
|
||||
/* Disconnect from the AP */
|
||||
lRetVal = Network_IF_DisconnectFromAP();
|
||||
|
||||
/* Stop the simplelink host */
|
||||
sl_Stop(SL_STOP_TIMEOUT);
|
||||
|
||||
/* Reset the state to uninitialized */
|
||||
Network_IF_ResetMCUStateMachine();
|
||||
return(lRetVal);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Connect to an Access Point using the specified SSID
|
||||
//!
|
||||
//! \param[in] pcSsid - is a string of the AP's SSID
|
||||
//! \param[in] SecurityParams - is Security parameter for AP
|
||||
//!
|
||||
//! \return On success, zero is returned. On error, -ve value is returned
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_ConnectAP(char *pcSsid,
|
||||
SlWlanSecParams_t SecurityParams)
|
||||
{
|
||||
char acCmdStore[128];
|
||||
unsigned short usConnTimeout;
|
||||
unsigned char ucRecvdAPDetails;
|
||||
long lRetVal;
|
||||
unsigned long ulIP = 0;
|
||||
unsigned long ulSubMask = 0;
|
||||
unsigned long ulDefGateway = 0;
|
||||
unsigned long ulDns = 0;
|
||||
|
||||
g_usConnectIndex = 0;
|
||||
|
||||
/* Disconnect from the AP */
|
||||
Network_IF_DisconnectFromAP();
|
||||
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
|
||||
|
||||
/* Continue only if SSID is not empty */
|
||||
if(pcSsid != NULL)
|
||||
{
|
||||
/* This triggers the CC32xx to connect to a specific AP. */
|
||||
lRetVal =
|
||||
sl_WlanConnect((signed char *) pcSsid, strlen((const char *) pcSsid),
|
||||
NULL, &SecurityParams, NULL);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
/* Wait for ~10 sec to check if connection to desire AP succeeds */
|
||||
while(g_usConnectIndex < 10)
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
if(IS_CONNECTED(g_ulStatus) && IS_IP_ACQUIRED(g_ulStatus))
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_usConnectIndex++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UART_PRINT("Empty SSID, Could not connect\n\r");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Check and loop until AP connection successful, else ask new AP SSID */
|
||||
while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus)))
|
||||
{
|
||||
/* Disconnect the previous attempt */
|
||||
Network_IF_DisconnectFromAP();
|
||||
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
|
||||
CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_ACQUIRED);
|
||||
UART_PRINT("Device could not connect to %s\n\r", pcSsid);
|
||||
|
||||
do
|
||||
{
|
||||
ucRecvdAPDetails = 0;
|
||||
|
||||
UART_PRINT("\n\r\n\rPlease enter the AP(open) SSID name # ");
|
||||
|
||||
/* Get the AP name to connect over the UART */
|
||||
lRetVal = GetCmd(acCmdStore, sizeof(acCmdStore));
|
||||
if(lRetVal > 0)
|
||||
{
|
||||
/* remove start/end spaces if any */
|
||||
lRetVal = TrimSpace(acCmdStore);
|
||||
|
||||
if(lRetVal)
|
||||
{
|
||||
/* Parse the AP name */
|
||||
strncpy(pcSsid, acCmdStore, lRetVal);
|
||||
if(pcSsid != NULL)
|
||||
{
|
||||
ucRecvdAPDetails = 1;
|
||||
pcSsid[lRetVal] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while(ucRecvdAPDetails == 0);
|
||||
|
||||
/* Set Security Parameters to OPEN security type. */
|
||||
SecurityParams.Key = (signed char *) "";
|
||||
SecurityParams.KeyLen = 0;
|
||||
SecurityParams.Type = SL_WLAN_SEC_TYPE_OPEN;
|
||||
|
||||
UART_PRINT("\n\rTrying to connect to AP: %s ...\n\r", pcSsid);
|
||||
|
||||
/* Get the current timer tick and setup the timeout accordingly. */
|
||||
usConnTimeout = g_usConnectIndex + 15;
|
||||
|
||||
/* This triggers the CC32xx to connect to specific AP. */
|
||||
lRetVal =
|
||||
sl_WlanConnect((signed char *) pcSsid, strlen((const char *) pcSsid),
|
||||
NULL, &SecurityParams,NULL);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
/* Wait ~10 sec to check if connection to specified AP succeeds */
|
||||
while(!(IS_CONNECTED(g_ulStatus)) || !(IS_IP_ACQUIRED(g_ulStatus)))
|
||||
{
|
||||
sleep(1);
|
||||
|
||||
if(g_usConnectIndex >= usConnTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_usConnectIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put message on UART */
|
||||
UART_PRINT("\n\rDevice has connected to %s\n\r", pcSsid);
|
||||
|
||||
/* Get IP address */
|
||||
lRetVal = Network_IF_IpConfigGet(&ulIP, &ulSubMask, &ulDefGateway, &ulDns);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
/* Send the information */
|
||||
UART_PRINT("Device IP Address is %d.%d.%d.%d \n\r\n\r",
|
||||
SL_IPV4_BYTE(ulIP, 3), SL_IPV4_BYTE(ulIP, 2), SL_IPV4_BYTE(ulIP,
|
||||
1),
|
||||
SL_IPV4_BYTE(ulIP, 0));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Disconnects from an Access Point
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return 0 disconnected done, other already disconnected
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_DisconnectFromAP(void)
|
||||
{
|
||||
long lRetVal = 0;
|
||||
|
||||
if(IS_CONNECTED(g_ulStatus))
|
||||
{
|
||||
lRetVal = sl_WlanDisconnect();
|
||||
if(0 == lRetVal)
|
||||
{
|
||||
while(IS_CONNECTED(g_ulStatus))
|
||||
{
|
||||
usleep(1000);
|
||||
}
|
||||
return(lRetVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(lRetVal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(lRetVal);
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Get the IP Address of the device.
|
||||
//!
|
||||
//! \param[in] pulIP - IP Address of Device
|
||||
//! \param[in] pulSubnetMask - Subnetmask of Device
|
||||
//! \param[in] pulDefaultGateway - Default Gateway value
|
||||
//! \param[in] pulDNSServer - DNS Server
|
||||
//!
|
||||
//! \return On success, zero is returned. On error, -1 is returned
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_IpConfigGet(unsigned long *pulIP,
|
||||
unsigned long *pulSubnetMask,
|
||||
unsigned long *pulDefaultGateway,
|
||||
unsigned long *pulDNSServer)
|
||||
{
|
||||
unsigned short usDHCP = 0;
|
||||
long lRetVal = -1;
|
||||
unsigned short len = sizeof(SlNetCfgIpV4Args_t);
|
||||
SlNetCfgIpV4Args_t ipV4 = { 0 };
|
||||
|
||||
/* get network configuration */
|
||||
lRetVal =
|
||||
sl_NetCfgGet(SL_NETCFG_IPV4_STA_ADDR_MODE, &usDHCP, &len,
|
||||
(unsigned char *) &ipV4);
|
||||
ASSERT_ON_ERROR(lRetVal);
|
||||
|
||||
*pulIP = ipV4.Ip;
|
||||
*pulSubnetMask = ipV4.IpMask;
|
||||
*pulDefaultGateway = ipV4.IpGateway;
|
||||
*pulDefaultGateway = ipV4.IpDnsServer;
|
||||
|
||||
return(lRetVal);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! This function obtains the server IP address using a DNS lookup
|
||||
//!
|
||||
//! \param[in] pcHostName The server hostname
|
||||
//! \param[out] pDestinationIP This parameter is filled with host IP address
|
||||
//!
|
||||
//! \return On success, +ve value is returned. On error, -ve value is returned
|
||||
//
|
||||
//*****************************************************************************
|
||||
long Network_IF_GetHostIP(char* pcHostName,
|
||||
unsigned long * pDestinationIP)
|
||||
{
|
||||
long lStatus = 0;
|
||||
|
||||
lStatus =
|
||||
sl_NetAppDnsGetHostByName((signed char *) pcHostName, strlen(
|
||||
pcHostName), pDestinationIP, SL_AF_INET);
|
||||
ASSERT_ON_ERROR(lStatus);
|
||||
|
||||
UART_PRINT("Get Host IP succeeded.\n\rHost: %s IP: %d.%d.%d.%d \n\r\n\r",
|
||||
pcHostName, SL_IPV4_BYTE(*pDestinationIP,
|
||||
3), SL_IPV4_BYTE(*pDestinationIP,
|
||||
2),
|
||||
SL_IPV4_BYTE(*pDestinationIP, 1),
|
||||
SL_IPV4_BYTE(*pDestinationIP, 0));
|
||||
|
||||
return(lStatus);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Reset state from the state machine
|
||||
//!
|
||||
//! \param None
|
||||
//!
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void Network_IF_ResetMCUStateMachine()
|
||||
{
|
||||
g_ulStatus = 0;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Return the current state bits
|
||||
//!
|
||||
//! \param None
|
||||
//!
|
||||
//! \return none
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long Network_IF_CurrentMCUState()
|
||||
{
|
||||
return(g_ulStatus);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Sets a state from the state machine
|
||||
//!
|
||||
//! \param[in] cStat - Status of State Machine defined in e_StatusBits
|
||||
//!
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void Network_IF_SetMCUMachineState(char cStat)
|
||||
{
|
||||
SET_STATUS_BIT(g_ulStatus, cStat);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Unsets a state from the state machine
|
||||
//!
|
||||
//! \param[in] cStat - Status of State Machine defined in e_StatusBits
|
||||
//!
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void Network_IF_UnsetMCUMachineState(char cStat)
|
||||
{
|
||||
CLR_STATUS_BIT(g_ulStatus, cStat);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
176
src/network/network_if.h
Normal file
176
src/network/network_if.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Texas Instruments Incorporated
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//*****************************************************************************
|
||||
// network_if.h
|
||||
//
|
||||
// Networking interface macro and function prototypes for CC32xx device
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __NETWORK_IF__H__
|
||||
#define __NETWORK_IF__H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Simplelink includes */
|
||||
#include <ti/drivers/net/wifi/simplelink.h>
|
||||
|
||||
/* Values for below macros shall be modified as per access-point(AP) */
|
||||
/* properties SimpleLink device will connect to following AP when application */
|
||||
/* is executed. */
|
||||
|
||||
/* AP SSID */
|
||||
#define SSID_NAME "SPN24"
|
||||
/* Security type (OPEN or WEP or WPA) */
|
||||
#define SECURITY_TYPE SL_WLAN_SEC_TYPE_OPEN
|
||||
/* Password of the secured AP */
|
||||
#define SECURITY_KEY ""
|
||||
|
||||
#define SSID_AP_MODE "<ap-ssid>"
|
||||
#define SEC_TYPE_AP_MODE SL_WLAN_SEC_TYPE_OPEN
|
||||
#define PASSWORD_AP_MODE ""
|
||||
|
||||
/* Loop forever, user can change it as per application's requirement */
|
||||
#define LOOP_FOREVER() \
|
||||
{ \
|
||||
while(1) {; } \
|
||||
}
|
||||
|
||||
/* check the error code and handle it */
|
||||
#define ASSERT_ON_ERROR(error_code) \
|
||||
{ \
|
||||
if(error_code < 0) \
|
||||
{ \
|
||||
ERR_PRINT(error_code); \
|
||||
return error_code; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SL_STOP_TIMEOUT 200
|
||||
|
||||
/* Status bits - used to set/reset the corresponding bits in given a variable */
|
||||
typedef enum
|
||||
{
|
||||
/* If this bit is set: Network Processor is powered up */
|
||||
STATUS_BIT_NWP_INIT = 0,
|
||||
|
||||
/* If this bit is set: the device is connected to the AP or client is */
|
||||
/* connected to device (AP) */
|
||||
STATUS_BIT_CONNECTION,
|
||||
|
||||
/* If this bit is set: the device has leased IP to any connected client. */
|
||||
STATUS_BIT_IP_LEASED,
|
||||
|
||||
/* If this bit is set: the device has acquired an IP */
|
||||
STATUS_BIT_IP_ACQUIRED,
|
||||
|
||||
/* If this bit is set: the SmartConfiguration process is started from */
|
||||
/* SmartConfig app */
|
||||
STATUS_BIT_SMARTCONFIG_START,
|
||||
|
||||
/* If this bit is set: the device (P2P mode) found any p2p-device in scan */
|
||||
STATUS_BIT_P2P_DEV_FOUND,
|
||||
|
||||
/* If this bit is set: the device (P2P mode) found any p2p-negotiation */
|
||||
/* request */
|
||||
STATUS_BIT_P2P_REQ_RECEIVED,
|
||||
|
||||
/* If this bit is set: the device(P2P mode) connection to client (or */
|
||||
/* reverse way) is failed */
|
||||
STATUS_BIT_CONNECTION_FAILED,
|
||||
|
||||
/* If this bit is set: the device has completed the ping operation */
|
||||
STATUS_BIT_PING_DONE,
|
||||
|
||||
/* If this bit is set: the device has acquired an IPv6 address. */
|
||||
STATUS_BIT_IPV6L_ACQUIRED,
|
||||
|
||||
/* If this bit is set: the device has acquired an IPv6 address. */
|
||||
STATUS_BIT_IPV6G_ACQUIRED,
|
||||
STATUS_BIT_AUTHENTICATION_FAILED,
|
||||
STATUS_BIT_RESET_REQUIRED,
|
||||
}e_StatusBits;
|
||||
|
||||
#define CLR_STATUS_BIT_ALL(status_variable) (status_variable = 0)
|
||||
#define SET_STATUS_BIT(status_variable, bit) (status_variable |= (1 << (bit)))
|
||||
#define CLR_STATUS_BIT(status_variable, bit) (status_variable &= ~(1 << (bit)))
|
||||
#define CLR_STATUS_BIT_ALL(status_variable) (status_variable = 0)
|
||||
#define GET_STATUS_BIT(status_variable, bit) (0 != \
|
||||
(status_variable & (1 << (bit))))
|
||||
|
||||
#define IS_CONNECTED(status_variable) GET_STATUS_BIT( \
|
||||
status_variable, \
|
||||
STATUS_BIT_CONNECTION)
|
||||
|
||||
#define IS_IP_ACQUIRED(status_variable) GET_STATUS_BIT( \
|
||||
status_variable, \
|
||||
STATUS_BIT_IP_ACQUIRED)
|
||||
|
||||
//*****************************************************************************
|
||||
// APIs
|
||||
//*****************************************************************************
|
||||
long Network_IF_InitDriver(uint32_t uiMode);
|
||||
long Network_IF_DeInitDriver(void);
|
||||
long Network_IF_ConnectAP(char * pcSsid,
|
||||
SlWlanSecParams_t SecurityParams);
|
||||
long Network_IF_DisconnectFromAP();
|
||||
long Network_IF_IpConfigGet(unsigned long *aucIP,
|
||||
unsigned long *aucSubnetMask,
|
||||
unsigned long *aucDefaultGateway,
|
||||
unsigned long *aucDNSServer);
|
||||
long Network_IF_GetHostIP(char* pcHostName,
|
||||
unsigned long * pDestinationIP);
|
||||
unsigned long Network_IF_CurrentMCUState(void);
|
||||
void Network_IF_UnsetMCUMachineState(char stat);
|
||||
void Network_IF_SetMCUMachineState(char stat);
|
||||
void Network_IF_ResetMCUStateMachine(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __NETWORK_IF__H__
|
||||
Loading…
x
Reference in New Issue
Block a user