CLI example for NNN50

Dependencies:   NNN50_WIFI_API

Fork of NNN50_WiFi_HelloWorld by Delta

Files at this revision

API Documentation at this revision

Comitter:
silviaChen
Date:
Thu Sep 14 01:48:08 2017 +0000
Parent:
8:08230913074f
Commit message:
Support both BLE UART service and WiFi CLI command

Changed in this revision

CLI_Source/command-interpreter.cpp Show annotated file Show diff for this revision Revisions of this file
CLI_Source/command-interpreter.h Show annotated file Show diff for this revision Revisions of this file
CLI_Source/core_cli.cpp Show annotated file Show diff for this revision Revisions of this file
CLI_Source/wifi_cli.cpp Show annotated file Show diff for this revision Revisions of this file
CLI_Source/wifi_cli.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CLI_Source/command-interpreter.cpp	Thu Sep 14 01:48:08 2017 +0000
@@ -0,0 +1,501 @@
+/**
+ * File: command-interpreter.c
+ * Description: processes commands incoming over the serial port.
+ *
+ * Copyright 2014 by CYNTEC Corporation.  All rights reserved.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "mbed.h"
+#include "command-interpreter.h"
+
+extern Serial console;
+
+// Command parsing state
+typedef struct {
+
+  // Finite-state machine's current state. 
+  uint8_t state;
+
+  // The command line is stored in this buffer.
+  uint8_t buffer[CYNTEC_COMMAND_BUFFER_LENGTH];
+
+  // Indices of the tokens (command(s) and arguments) in the above buffer.
+  uint8_t tokenIndices[MAX_TOKEN_COUNT];
+
+  // The number of tokens read in, including the command(s). 
+  uint8_t tokenCount;
+
+  // Used while reading in the command line.
+  uint8_t index;
+
+  // First error found in this command. 
+  uint8_t error;
+
+  // The token number of the first true argument after possible nested commands.
+  uint8_t argOffset;
+  
+  //gill
+  uint8_t totalBuffer[CYNTEC_COMMAND_BUFFER_LENGTH];
+  uint8_t totalIndex;
+
+} CyntecCommandState;
+
+static CyntecCommandState commandState;
+
+// Remember the previous character seen by emberProcessCommandString() to ignore
+// an LF following a CR.
+static uint8_t previousCharacter = 0;
+CyntecCommandEntry *cyntecCurrentCommand;
+
+enum {
+  CMD_AWAITING_ARGUMENT,
+  CMD_READING_ARGUMENT,
+  CMD_READING_TO_EOL                   // clean up after error
+};
+
+
+
+const char* cyntecCommandErrorNames[] =
+  {
+    "",
+    "No such command;",
+    "Wrong number of arguments;",
+    "Argument out of range;",
+    "Argument syntax error;",		
+    "No matched argument;",
+	"Wrong command order;",
+	"Invalid state to perform operation;",
+    "Function call fail;"
+  };
+
+	/**
+*   @brief Converts a character representation of a hex to real value.
+*   @param c is the hex value in char format
+*   @return the value of the hex otherwise INVALID_HEX_CHARACTER
+*/
+
+uint8_t cyntecAtoi(uint8_t *str, uint8_t len)
+{
+	uint8_t result = 0;
+	uint8_t i = 0;
+	
+	while( *str != '\0' && i < len)
+	{
+		result *= 10;
+		result = result + ( *str - '0' );
+		str++;
+		i++;
+	}
+	
+	return result;
+}
+int cyntecAtoInt(uint8_t *str)
+{
+	int result = 0;
+	uint8_t i = 0;
+	bool is_negative = false;
+	
+	if (*str == '-') {
+		is_negative = true;
+		str++;
+	}
+	while( *str != '\0')
+	{
+		result *= 10;
+		result = result + ( *str - '0' );
+		str++;
+		i++;
+	}
+	
+	if (is_negative)
+		return -result;
+	else
+		return result;
+}
+uint8_t cyntecArgToUint8(uint8_t *str, uint8_t len)
+{
+	uint8_t result = 0;
+	uint8_t num[2];
+	uint8_t i;
+	
+	if ( len != 2 )
+	{
+		return 0;
+	}
+	
+	for ( i = 0 ; i < 2 ; i++ )
+	{
+		if ('0' <= str[i] && str[i] <= '9')
+			num[i] = str[i] - '0';
+		else if ('a' <= str[i] && str[i] <= 'f')
+			num[i] = str[i] - 'a' + 10;
+		else if ('A' <= str[i] && str[i] <= 'F')
+			num[i] = str[i] - 'A' + 10;
+		else
+			return 0;
+	}
+	
+	result |= num[0] << 4;
+	result |= num[1] << 0;
+	
+	return result;
+}
+
+uint16_t cyntecAtoiUint16(uint8_t *str, uint8_t len)
+{
+	uint16_t result = 0;
+	uint16_t i = 0;
+	
+	while( *str != '\0' && i < len)
+	{
+		result *= 10;
+		result = result + ( *str - '0' );
+		str++;
+		i++;
+	}
+	
+	return result;
+}
+
+uint16_t cyntecArgToUint16(uint8_t *str, uint8_t len)
+{
+	uint16_t result = 0;
+	uint8_t num[4];
+	uint8_t i;
+	
+	if ( len != 4 )
+	{
+		return 0;
+	}
+	
+	for ( i = 0 ; i < 4 ; i++ )
+	{
+		if ('0' <= str[i] && str[i] <= '9')
+			num[i] = str[i] - '0';
+		else if ('a' <= str[i] && str[i] <= 'f')
+			num[i] = str[i] - 'a' + 10;
+		else if ('A' <= str[i] && str[i] <= 'F')
+			num[i] = str[i] - 'A' + 10;
+		else
+			return 0;
+	}
+	
+	result |= num[0] << 12;
+	result |= num[1] << 8;
+	result |= num[2] << 4;
+	result |= num[3] << 0;
+	
+	return result;
+}
+
+//gill 20150918
+uint32_t cyntecHexToUint32(uint8_t *str, uint8_t len)
+{
+	if (len > 8)
+		return 0;
+	uint32_t result = 0;
+	uint16_t i = 0;
+	
+	while( *str != '\0' && i < len)
+	{
+		result *= 16;
+		result = result + ( *str - '0' );
+		str++;
+		i++;
+	}
+	
+	return result;
+}
+
+
+
+
+uint8_t cyntecStrCmp(uint8_t *src, uint8_t *dst, uint8_t len)
+{
+	uint8_t i = 0;
+	
+	while ( *src != '\0' && *dst != '\0' && i < len ) 
+	{
+		if ( *src != *dst )
+			return 0;
+		i++;
+		src++;
+		dst++;
+	}
+	
+	return 1;
+}
+	
+// Initialize the state machine.
+void cyntecCommandReaderInit(void)
+{
+  commandState.state = CMD_AWAITING_ARGUMENT;
+  commandState.index = 0;
+  commandState.tokenIndices[0] = 0;
+  commandState.tokenCount = 0;
+  commandState.error = CYNTEC_CMD_SUCCESS;
+  commandState.argOffset = 0;
+	cyntecCurrentCommand = NULL;
+	commandState.totalIndex = 0; //gill
+}
+
+static uint8_t tokenLength(uint8_t num)
+{
+  return (commandState.tokenIndices[num + 1] 
+          - commandState.tokenIndices[num]);
+}
+
+static uint8_t *tokenPointer(uint8_t tokenNum)
+{
+  return (commandState.buffer + commandState.tokenIndices[tokenNum]);
+}
+
+void cyntecCommandActionHandler(const CommandAction action)
+{
+  (*action)();
+	clearBuffer();
+}
+
+static bool getNestedCommand(CyntecCommandEntry *entry,
+                                CyntecCommandEntry **nestedCommand)
+{
+  if ( entry -> action == NULL ) {
+    *nestedCommand = (CyntecCommandEntry*)entry->subMenu;
+    return true;
+  } else {
+    return false;
+  }
+}
+
+static void cyntecPrintCommandUsage(CyntecCommandEntry *entry) 
+{
+  CyntecCommandEntry *commandFinger;
+
+	if (entry == NULL) {
+		entry = commandFinger = cyntecCommandTable;
+	} else {
+		getNestedCommand(entry, &commandFinger);
+		
+		console.printf("%s-%s\r\n",entry->name,entry->description);
+	}
+	
+  if ( commandFinger != NULL ) {
+    for (; commandFinger->name != NULL; commandFinger++) {
+			console.printf("%s - %s\r\n",commandFinger->name,commandFinger->description);
+    }   
+  }
+	
+}
+
+void cyntecCommandErrorHandler(uint8_t status)
+{
+		//Silvia 20161111 modify
+		console.printf("\r\nERROR;%s\r\n\r\n", cyntecCommandErrorNames[status]);
+		cyntecPrintCommandUsage(cyntecCurrentCommand);
+}
+
+static CyntecCommandEntry *commandLookup(CyntecCommandEntry *commandFinger, 
+                                        uint8_t tokenNum)
+{
+  uint8_t *inputCommand = tokenPointer(tokenNum);
+  uint8_t inputLength = tokenLength(tokenNum);
+
+  for (; commandFinger->name != NULL; commandFinger++) {
+    const char *entryFinger = commandFinger->name;
+    uint8_t *inputFinger = inputCommand;
+    for (;; entryFinger++, inputFinger++) {
+      bool endInput = (inputFinger - inputCommand == inputLength);
+      bool endEntry = (*entryFinger == 0);
+      if (endInput && endEntry) {
+        return commandFinger;  // Exact match.
+      } else if ((*inputFinger) != (*entryFinger)) {
+        break;
+      }
+    }
+  }
+  return NULL;
+}
+
+void callCommandAction(void)
+{
+	CyntecCommandEntry *commandFinger = cyntecCommandTable;
+	uint8_t tokenNum = 0;
+	
+	if (commandState.tokenCount == 0) {
+    	cyntecCommandReaderInit();
+		return;
+  	}
+	
+	// Lookup the command.
+  	while (true) {
+		commandFinger = commandLookup(commandFinger, tokenNum);
+		if (commandFinger == NULL) {
+      		commandState.error = CYNTEC_CMD_ERR_NO_SUCH_COMMAND;
+			break;
+    	} else {
+			cyntecCurrentCommand = commandFinger;
+      		tokenNum += 1;
+      		commandState.argOffset += 1;
+
+      		if ( getNestedCommand(commandFinger, &commandFinger) ) {
+        		if (tokenNum >= commandState.tokenCount) {
+          			commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS;
+					break;
+        		}
+      		} else {
+        		break;
+      		}
+    	}
+	}
+
+  	if (commandState.error == CYNTEC_CMD_SUCCESS) {
+    	cyntecCommandActionHandler(commandFinger->action);
+  	} else {
+		cyntecCommandErrorHandler(commandState.error);;
+  	}	
+	
+	cyntecCommandReaderInit();
+}
+
+/*
+ * 
+ */
+void cyntecEndArgument(uint8_t input)
+{
+  if (commandState.tokenCount == MAX_TOKEN_COUNT) {
+		commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS;
+    	commandState.state = CMD_READING_TO_EOL;
+	}
+	
+	commandState.tokenCount += 1;
+	commandState.tokenIndices[commandState.tokenCount] = commandState.index;
+	commandState.state = CMD_AWAITING_ARGUMENT;
+	
+  if (input == '\r' || input == '\n') {
+		callCommandAction();
+  }
+}
+
+/*
+ * 
+ */
+void cyntecWriteToBuffer(uint8_t input)
+{
+	if (commandState.index == CYNTEC_COMMAND_BUFFER_LENGTH) {
+		commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS;
+		commandState.state = CMD_READING_TO_EOL;
+	} else {
+		commandState.buffer[commandState.index] = input;
+		commandState.index += 1;
+	}
+}
+
+
+/*
+ * Process the given char as a command.
+ */
+void cyntecProcessCommandInput(uint8_t input) {
+	
+	bool isEol = false;
+  	bool isSpace = false;
+
+	if (previousCharacter == '\r' && input == '\n') {
+		previousCharacter = input;
+    	return;
+  	}
+	
+  	previousCharacter = input;	
+  	isEol = ((input == '\r') || (input == '\n'));
+  	isSpace = (input == ' ');
+	
+	switch (commandState.state) {
+    case CMD_AWAITING_ARGUMENT:
+      if (!isEol)
+        cyntecWriteToTotalBuffer(input); // total buffer including space
+      if (isEol) {
+        callCommandAction();
+      } else if (! isSpace) {
+        commandState.state = CMD_READING_ARGUMENT;
+        cyntecWriteToBuffer(input);
+      }
+      break;
+	case CMD_READING_ARGUMENT:
+	  if (!isEol)
+        cyntecWriteToTotalBuffer(input);
+      if (isEol || isSpace) {
+        cyntecEndArgument(input);
+      } else {
+        cyntecWriteToBuffer(input);
+      }			
+			break;
+    case CMD_READING_TO_EOL:
+      if (isEol) {
+        if (commandState.error != CYNTEC_CMD_SUCCESS) {
+          cyntecCommandErrorHandler(commandState.error);
+        }
+        cyntecCommandReaderInit();
+      }
+      break;			
+	}
+}
+
+
+/** Retrieves unsigned integer arguments. */
+uint8_t *cyntecGetCommandArgument(uint8_t argNum, uint8_t *length)
+{
+  uint8_t tokenNum = argNum + commandState.argOffset;
+
+  if (length != NULL) {
+    *length = tokenLength(tokenNum);
+  }
+  return tokenPointer(tokenNum);
+}
+
+void clearBuffer(void)
+{
+	uint16_t i;
+	for (i=0;i<CYNTEC_COMMAND_BUFFER_LENGTH;i++)
+	{
+		commandState.buffer[i] = NULL;
+	}
+}
+
+/** Retrieves the token count. */
+uint8_t cyntecGetCommandTokenCnt()
+{
+	return commandState.tokenCount;
+}
+
+/*
+gill add for accept blank in name 20150904
+uint8_t *cyntecGetCommandBuffer()
+void cyntecWriteToTotalBuffer(uint8_t input)
+uint8_t *cyntecGetCommandTotalBuffer(void)
+uint8_t cyntecGetTotalIndex(void)
+*/
+
+	
+void cyntecWriteToTotalBuffer(uint8_t input)
+{
+	if (commandState.totalIndex == CYNTEC_COMMAND_BUFFER_LENGTH) {
+		commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS;
+		commandState.state = CMD_READING_TO_EOL;
+	} else {
+		commandState.totalBuffer[commandState.totalIndex] = input;
+		commandState.totalIndex += 1;
+	}
+}
+
+uint8_t *cyntecGetCommandTotalBuffer(void)
+{
+	return commandState.totalBuffer;
+}
+
+uint8_t cyntecGetTotalIndex(void)
+{
+	return commandState.totalIndex;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CLI_Source/command-interpreter.h	Thu Sep 14 01:48:08 2017 +0000
@@ -0,0 +1,104 @@
+/** @file command-interpreter.h
+* @brief Processes commands coming from the serial port.
+* See @ref commands for documentation.
+*
+* Copyright 2014 by DELTA Corporation.  All rights reserved.
+*/
+
+#ifndef COMMAND_INTERPRETER_H
+#define COMMAND_INTERPRETER_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "mbed.h"
+//#inlcude "nordic/boards.h"
+
+//#define DELTA_BLE_ON 1
+#define DELTA_WIFI_ON 1
+
+#ifndef CYNTEC_COMMAND_BUFFER_LENGTH
+#define CYNTEC_COMMAND_BUFFER_LENGTH 255
+#endif
+
+#ifndef MAX_TOKEN_COUNT
+#define MAX_TOKEN_COUNT 16
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif 
+
+enum {
+  CYNTEC_CMD_SUCCESS,                 
+  CYNTEC_CMD_ERR_NO_SUCH_COMMAND,
+	CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS,
+  CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE,        
+  CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR,	
+  CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT,
+	CYNTEC_CMD_ERR_WRONG_CMD_ORDER,
+	CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION,
+  CYNTEC_CMD_ERR_CALL_FAIL
+};
+
+typedef void (*CommandAction)(void);
+
+typedef const struct {
+  /** Use letters, digits, and underscores, '_', for the command name.
+   * Command names are case-sensitive.
+   */
+  const char *name;
+  /** A reference to a function in the application that implements the 
+   *  command.
+   *  If this entry refers to a nested command, then action field
+   *  has to be set to NULL.
+   */
+  CommandAction action;
+	/*
+   *  In case of a nested command (action is NULL), then this field
+   *  contains a pointer to the nested CyntecCommandEntry array.
+	 */
+	const char *subMenu;
+  /** A description of the command.
+   */
+  const char *description;
+} CyntecCommandEntry;
+
+extern CyntecCommandEntry cyntecCommandTable[];
+
+uint8_t cyntecAtoi(uint8_t *str, uint8_t len);
+int cyntecAtoInt(uint8_t *str);
+uint8_t cyntecArgToUint8(uint8_t *str, uint8_t len);
+uint16_t cyntecAtoiUint16(uint8_t *str, uint8_t len);
+uint16_t cyntecArgToUint16(uint8_t *str, uint8_t len);
+uint32_t cyntecHexToUint32(uint8_t *str, uint8_t len);
+uint8_t cyntecStrCmp(uint8_t *src, uint8_t *dst, uint8_t len);
+
+/**
+ * @brief Process the given char as a command.
+ **/
+void cyntecProcessCommandInput(uint8_t input);
+
+/** @brief Initialize the command interpreter.
+ */
+void cyntecCommandReaderInit(void);
+
+/** Retrieves unsigned integer arguments. */
+uint8_t *cyntecGetCommandArgument(uint8_t argNum, uint8_t *length);
+uint8_t *cyntecGetMinusArgument(uint8_t argNum, uint8_t *length);
+extern void clearBuffer(void);
+
+/** Retrieves the token count. */
+uint8_t cyntecGetCommandTokenCnt(void);
+
+//gill add for accept blank in name 20150904
+//uint8_t *cyntecGetCommandBuffer(void);
+uint8_t *cyntecGetCommandTotalBuffer(void);
+void cyntecWriteToTotalBuffer(uint8_t input);
+uint8_t cyntecGetTotalIndex(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CLI_Source/core_cli.cpp	Thu Sep 14 01:48:08 2017 +0000
@@ -0,0 +1,40 @@
+/**
+ * File: core-cli.c
+ * Description: Core CLI commands used by all applications regardless of profile.
+ *
+ * Copyright 2014 by CYNTEC Corporation.  All rights reserved.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "command-interpreter.h"
+#include "nrf.h"
+
+//#if (DELTA_BLE_ON == 1)
+//#include "ble_cli.h"
+//#endif
+#if (DELTA_WIFI_ON == 1)
+#include "wifi_cli.h"
+#endif
+
+
+CyntecCommandEntry cyntecCommandTable[] = {
+//#if (DELTA_BLE_ON == 1)
+//#if SIMPLE_CMD_NAME
+//    {"BLE", NULL, (const char*) bleCommandSets, "Command set for BLE module"},
+//#else
+//    {"cynb", NULL, (const char*) bleCommandSets, "Command set for BLE module"},
+//#endif
+//#endif
+
+#if (DELTA_WIFI_ON == 1)
+//#if SIMPLE_CMD_NAME
+//    {"WIFI", NULL, (const char*) wifiCommandSets, "Command set for WiFi module"},
+//#else
+    {"w", NULL, (const char*) wifiCommandSets, "Command set for WiFi module"},
+//#endif
+#endif
+    {NULL, NULL, NULL, NULL},
+};
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CLI_Source/wifi_cli.cpp	Thu Sep 14 01:48:08 2017 +0000
@@ -0,0 +1,1017 @@
+/**
+ * File: wifi-cli.c
+ * Description: WIFI CLI commands used by all applications WIFI of profile.
+ *
+ * Copyright 2015 by CYNTEC Corporation.  All rights reserved.
+ * Author: Lester Lee
+ */
+
+#include "wifi_cli.h"
+
+#define AP_SSID_MAX_LEN 33
+#define AP_PW_MAX_LEN 64
+#define STATIC_IP_MAX_LEN 15
+#define TCP_SEND_MAX_LEN 1400
+#define UDP_SEND_MAX_LEN 1400
+#define DELTA_WIFI_DEBUG
+#define WIFI_MAX_AP_NUMBER 15
+
+// General configuration parameters
+WIFIDevice wifiDevice;
+EthernetInterface eth;
+TCPSocketConnection tcpConnect;
+UDPSocket udpSocket;
+Endpoint cliEndpoint;
+TCPSocketServer tcpServer;
+char static_ip[STATIC_IP_MAX_LEN] = "192.168.1.1";
+extern Serial console;
+extern const char* cyntecCommandErrorNames[];
+
+static uint8_t is_Listen = false;
+static tstrM2mWifiscanResult saveAP[WIFI_MAX_AP_NUMBER];
+static bool wifiIniState = false;
+
+typedef struct deviceNetwork_s {
+    char ap_ssid[AP_SSID_MAX_LEN+1];
+    char ap_pw[AP_PW_MAX_LEN+1];
+    uint8_t ap_sec;
+} deviceNetwork_t;
+deviceNetwork_t devNetwork[4]; // 0-2 for setNetwork, 3 for set_ap
+
+static uint8_t cyntecIsValidIP(uint8_t *startIdx, uint8_t totalLen)
+{
+    uint8_t *ipIdx = startIdx;
+    uint8_t *tempIdx = ipIdx;
+    uint8_t IPAddr[3];
+    //uint8_t IPTokenLen = 0;
+    int16_t ipToken;
+    while ( (tempIdx - startIdx) <= totalLen ) {
+        if (*tempIdx == '.' || ((tempIdx - startIdx) == totalLen)) {
+            memset( IPAddr, 0, 3);
+            memcpy( IPAddr, ipIdx, (tempIdx - ipIdx));
+
+            ipToken = atoi((const char *)IPAddr);
+            if (ipToken > 255 || ipToken < 0)
+                return 1;
+
+            ipIdx = tempIdx + 1;
+        }
+        tempIdx++;
+    }
+    return 0;
+}
+
+static void cyntecPrintOk(void)
+{
+    console.printf("\r\nOK\r\n\r\n");
+}
+
+static void cyntecPrintError(uint8_t errIdx)
+{
+    console.printf("\r\nERROR;%s\r\n\r\n",cyntecCommandErrorNames[errIdx]);
+}
+
+/////////**** WIFI Device Implement ****//////////
+static void cyn_wifi_device_sleep()
+{
+    if (cyntecGetCommandTokenCnt() != 2) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+        return;
+    }
+    uint8_t err_code = wifiDevice.sleep();
+    if (err_code == 0)
+        cyntecPrintOk();
+    else {
+        console.printf("ERROR;%d\r\n",err_code);
+        return;
+    }
+}
+
+static void cyn_wifi_device_network()
+{
+    //if (wifiIniState == true) {
+//        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_CMD_ORDER);
+//        return;
+//    }
+    if (cyntecGetCommandTokenCnt() == 6) {
+        uint8_t argLen = 0;
+        uint8_t *argSSID;
+        uint8_t *argPW;
+        uint8_t *argSec;
+        uint8_t security = 0;
+        uint8_t *argPriority;
+        /* 0~2, 0 is highest */
+        uint8_t priority = 0;
+
+        /* handle priority */
+        argPriority = cyntecGetCommandArgument(3, NULL);
+        priority = atoi((const char*)argPriority);
+        
+        if(priority > 2) {
+    		cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+    	}
+
+        /* handle SSID */
+        argSSID = cyntecGetCommandArgument(0, &argLen);
+        if ( argLen > AP_SSID_MAX_LEN ) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+        memset( devNetwork[priority].ap_ssid , 0, AP_SSID_MAX_LEN+1);
+        memcpy( devNetwork[priority].ap_ssid, argSSID, argLen);
+
+        /* handle Password */
+        argPW = cyntecGetCommandArgument(1, &argLen);
+        if ( argLen > AP_PW_MAX_LEN ) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+        memset( devNetwork[priority].ap_pw, 0, AP_PW_MAX_LEN+1);
+        memcpy( devNetwork[priority].ap_pw, argPW, argLen);
+        
+        /* handle security */
+        argSec = cyntecGetCommandArgument(2, &argLen);
+        //security = atoi((const char*)argSec);
+        char numSec[1];
+    	memcpy( numSec, argSec, 1);
+    	security = atoi(numSec);
+    	
+    	if(security > 4) {
+    		cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+    	}
+    	
+        devNetwork[priority].ap_sec = security;
+
+        /* call setup API */
+        wifiDevice.setNetwork(devNetwork[priority].ap_sec, devNetwork[priority].ap_ssid, devNetwork[priority].ap_pw, priority);
+        cyntecPrintOk();
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+void scanCallback(tstrM2mWifiscanResult result)
+{
+	console.printf("scanCallback\r\n");
+	console.printf("[%d], ", result.u8index);
+	console.printf("%d, ", result.s8rssi);
+	console.printf("%d, ", result.u8AuthType);
+	console.printf("%d,", result.u8ch);
+	for(int i=0;i<6;i++) {
+        console.printf(" %02x", result.au8BSSID[i]);
+    }
+    
+    console.printf(", ");
+    console.printf("%s\r\n", result.au8SSID);
+}
+
+static void cyn_wifi_device_ap_scan()
+{
+    if (wifiIniState == false) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_CMD_ORDER);
+        return;
+    }
+    memset(saveAP,0,sizeof(saveAP));
+    int scanResult = 0;
+    scanResult = wifiDevice.apScan(scanCallback);
+    if (scanResult >= 0) {
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("scan AP number:%d\r\n",scanResult);
+#endif
+        cyntecPrintOk();
+        return;
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+        return;
+    }
+}
+
+static void cyn_wifi_set_ap()
+{
+    if (cyntecGetCommandTokenCnt() != 6) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+    uint8_t argLen = 0;
+    uint8_t * argSSID;
+    uint8_t * argPW;
+    uint8_t * argSEC;
+    uint8_t * argCH;
+
+    /* handle SSID */
+    argSSID = cyntecGetCommandArgument(0, &argLen);
+    if ( argLen > AP_SSID_MAX_LEN ) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+    memset( devNetwork[3].ap_ssid , 0, AP_SSID_MAX_LEN+1);
+    memcpy( devNetwork[3].ap_ssid, argSSID, argLen);
+
+    /* handle Password */
+    argPW = cyntecGetCommandArgument(1, &argLen);
+    if ( argLen > AP_PW_MAX_LEN ) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+    memset( devNetwork[3].ap_pw, 0, AP_PW_MAX_LEN+1);
+    memcpy( devNetwork[3].ap_pw, argPW, argLen);
+
+    /* handle Security */
+    tenuM2mSecType setSec  = M2M_WIFI_SEC_OPEN;
+    argSEC = cyntecGetCommandArgument(2, &argLen);
+    char numSec[argLen];
+    memcpy( numSec, argSEC, argLen);
+    int sec = atoi(numSec);
+    
+    if(sec == 0)
+    	setSec = M2M_WIFI_SEC_OPEN;
+    else if(sec == 1)
+    	setSec = M2M_WIFI_SEC_WEP;
+    else {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+
+    /* handle Channel */
+    argCH = cyntecGetCommandArgument(3, &argLen);
+    int setChan = atoi((char *)argCH);
+
+    if (setChan > 14 || setChan < 1) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+#ifdef DELTA_WIFI_DEBUG
+    console.printf("argSSID:%s\r\n",devNetwork[3].ap_ssid);
+    console.printf("argPW:%s\r\n",devNetwork[3].ap_pw);
+    console.printf("sec:%i\r\n",sec);
+    console.printf("setChan:%i\r\n",setChan);
+#endif
+
+    /* call Enable Access Point API */
+    if (wifiDevice.enableAccessPoint(devNetwork[3].ap_ssid, devNetwork[3].ap_pw, static_ip, setSec, setChan) != 0)
+    	cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    else
+    	cyntecPrintOk();
+
+}
+
+/////////**** WIFI Ethernet Implement ****//////////
+static void cyn_wifi_ethernet_init()
+{
+    uint8_t argLen = 0;
+    uint8_t *argIP;
+    //EthernetInterface ethInterface;
+    uint8_t result;
+    if (cyntecGetCommandTokenCnt() == 2) {
+        /* use DHCP to get IP */
+        result = eth.init();
+        if ( result == 0 ) {
+            cyntecPrintOk();
+            wifiIniState = true;
+        } else {
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+        }
+
+    } else if ( cyntecGetCommandTokenCnt() == 3 ) {
+        /* use static to get IP */
+        argIP = cyntecGetCommandArgument(0, &argLen);
+
+        if ( cyntecIsValidIP(argIP,argLen) != 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        memset( static_ip, 0, STATIC_IP_MAX_LEN);
+        memcpy( static_ip, argIP, argLen);
+        if ( eth.init((const char *)static_ip, NULL, NULL) == 0) {
+            cyntecPrintOk();
+            wifiIniState = true;
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+
+    return;
+}
+static void cyn_wifi_ethernet_connect()
+{
+    int timeout_ms = 5000;
+    uint8_t *argTimeout;
+    //EthernetInterface ethInterface;
+    if (cyntecGetCommandTokenCnt() != 2 & cyntecGetCommandTokenCnt() != 3)
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    if (cyntecGetCommandTokenCnt() == 2) {
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("\r\n");
+        console.printf("Connecting..., Waiting for 5000 ms...");
+        console.printf("\r\n\r\n");
+#endif
+        if (eth.connect() == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    }
+    if (cyntecGetCommandTokenCnt() == 3) {
+        argTimeout = cyntecGetCommandArgument(0, NULL);
+        timeout_ms = atoi((const char*)argTimeout);
+
+        if (timeout_ms < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("\r\nConnecting..., Waiting for ");
+        console.printf((char*)argTimeout);
+        console.printf(" ms...\r\n\r\n");
+#endif
+        if (eth.connect(timeout_ms) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    }
+    return;
+}
+static void cyn_wifi_ethernet_disconnect()
+{
+    if (eth.disconnect() == 0)
+    	cyntecPrintOk();
+    else
+    	cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+}
+static void cyn_wifi_ethernet_mac()
+{
+    char mac_addr[19];
+    memset(mac_addr, 0, 19);
+    memcpy(mac_addr, eth.getMACAddress(), 19);
+
+    console.printf("\r\nOK;%s\r\n\r\n",mac_addr);
+
+    return;
+}
+static void cyn_wifi_ethernet_ip()
+{
+    char ip_addr[15] = "\0";
+    memset(ip_addr, 0, 15);
+    memcpy(ip_addr, eth.getIPAddress(), 15);
+
+    console.printf("\r\nOK;%s\r\n\r\n",ip_addr);
+
+    return;
+}
+
+static void cyn_wifi_ethernet_isConnected()
+{
+    bool is_connected = false;
+    is_connected = wifiDevice.is_AP_connected();
+
+    if (is_connected == true)
+        console.printf("\r\nOK;TRUE\r\n\r\n");
+    else
+        console.printf("\r\nOK;FALSE\r\n\r\n");
+}
+
+/////////**** WIFI TCP Socket Server Implement ****//////////
+static void cyn_wifi_tcp_server_bind()
+{
+    int port = 1;
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if (tcpServer.bind(port) == 0)
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    } else if (cyntecGetCommandTokenCnt() == 3) {
+        port = atoi((const char*)(cyntecGetCommandArgument(0, NULL)));
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("port:%i\r\n",port);
+#endif
+        if (port < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        if ( tcpServer.bind(port) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_server_listen()
+{
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( tcpServer.listen() == 0 ) {
+            cyntecPrintOk();
+            is_Listen = true;
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_server_accept()
+{
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if (is_Listen == false) {
+            cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION);
+            return;
+        }
+
+        if ( tcpServer.accept(tcpConnect) == 0 ) {
+            cyntecPrintOk();
+            is_Listen = false;
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_server_blocking()
+{
+    bool blocking = false;
+    unsigned int timeout;
+
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 3) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        tcpServer.set_blocking(blocking, 1500);
+        cyntecPrintOk();
+
+    } else if (cyntecGetCommandTokenCnt() == 4) {
+
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        arg = cyntecGetCommandArgument(1, NULL);
+        timeout = (unsigned int)atoi((const char *)arg);
+
+        tcpServer.set_blocking(blocking, timeout);
+        cyntecPrintOk();
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_server_close()
+{
+    bool shutdown = true;
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( tcpServer.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    } else if (cyntecGetCommandTokenCnt() == 3) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '0')
+            shutdown = false;
+
+        if ( tcpServer.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+/////////**** WIFI TCP Socket Connection ****//////////
+static void cyn_wifi_tcp_connection_connect()
+{
+    uint8_t connect_ip[STATIC_IP_MAX_LEN];
+    int port;
+
+    uint8_t argLen = 0;
+    uint8_t *argIP;
+
+    if (cyntecGetCommandTokenCnt() == 4) {
+        /* handle IP arg */
+        argIP = cyntecGetCommandArgument(0, &argLen);
+        memset( connect_ip, 0, STATIC_IP_MAX_LEN);
+        memcpy( connect_ip, argIP, argLen);
+
+        /* handle Port arg */
+        port = atoi((const char *)cyntecGetCommandArgument(1, NULL));
+
+        if ( tcpConnect.connect((const char *)connect_ip, port) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_connection_is_connected()
+{
+    bool is_connected = false;
+    is_connected = tcpConnect.is_connected();
+
+    if (is_connected == true)
+        console.printf("\r\nOK;TRUE\r\n\r\n");
+    else
+        console.printf("\r\nOK;FALSE\r\n\r\n");
+}
+
+static void cyn_wifi_tcp_connection_send()
+{
+    char msg[TCP_SEND_MAX_LEN+1];
+    int sendData;
+    uint8_t * argAllBuf = cyntecGetCommandTotalBuffer();
+    int sendLen = 0; // Maximum 1400
+    uint8_t sendLenCharNum = 0; // Maximum 4
+    uint8_t *argLeng = cyntecGetCommandArgument(0,&sendLenCharNum);
+    sendLen = cyntecAtoi(argLeng,sendLenCharNum);
+    //sendLen = cyntecAtoInt(argLeng);
+    console.printf("len:%d\r\n", sendLen);
+    if (sendLen > TCP_SEND_MAX_LEN || sendLen < 0) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() <4 ) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() >= 4) {
+        if ( tcpConnect.is_connected() == false ) {
+            cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION);
+            return;
+        }
+
+        /* handle Message arg */
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("sendLen:%i,Buf:%s,Index:%i\r\n",sendLen,&argAllBuf[26+sendLenCharNum],cyntecGetTotalIndex());
+#endif
+        memset( msg, 0, TCP_SEND_MAX_LEN+1);
+        for (uint8_t i=0; i<sendLen; i++)
+            msg[i] = argAllBuf[26+sendLenCharNum+i];
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("msg:%s\r\n",msg);
+#endif
+        sendData = tcpConnect.send(msg, sendLen);
+        if ( sendData >= 0 ) {
+            console.printf("\r\nOK;");
+            console.printf("%i\r\n\r\n",sendData);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    }
+}
+
+static void cyn_wifi_tcp_connection_send_all()
+{
+    char msg[TCP_SEND_MAX_LEN+1];
+    int sendData;
+    uint8_t * argAllBuf = cyntecGetCommandTotalBuffer();
+    int sendLen = 0; // Maximum 1400
+    uint8_t sendLenCharNum = 0; // Maximum 4
+    uint8_t *argLeng = cyntecGetCommandArgument(0,&sendLenCharNum);
+    sendLen = cyntecAtoi(argLeng,sendLenCharNum);
+    if (sendLen > TCP_SEND_MAX_LEN) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() <4 ) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() >= 4) {
+        if ( tcpConnect.is_connected() == false ) {
+            cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION);
+            return;
+        }
+
+        /* handle Message arg */
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("sendLen:%i,Buf:%s,Index:%i\r\n",sendLen,&argAllBuf[30+sendLenCharNum],cyntecGetTotalIndex());
+#endif
+        memset( msg, 0, TCP_SEND_MAX_LEN+1);
+        for (uint8_t i=0; i<sendLen; i++)
+            msg[i] = argAllBuf[30+sendLenCharNum+i];
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("msg:%s\r\n",msg);
+#endif
+        sendData = tcpConnect.send_all(msg, sendLen);
+        if ( sendData >= 0 ) {
+            console.printf("\r\nOK;");
+            console.printf("%i\r\n\r\n",sendData);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    }
+}
+
+static void cyn_wifi_tcp_connection_receive()
+{
+    char msg[TCP_SEND_MAX_LEN+1];
+    int argLen = 0;
+
+    if (cyntecGetCommandTokenCnt() == 3) {
+        /* handle Message arg */
+        argLen = atoi((const char *)cyntecGetCommandArgument(0, NULL));
+        //console.printf("argLen:%d\r\n",argLen);
+        if (argLen > TCP_SEND_MAX_LEN || argLen < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        memset( msg, 0, TCP_SEND_MAX_LEN+1);
+
+        if ( tcpConnect.receive(msg, argLen) >= 0 ) {
+            console.printf("\r\nOK;%s\r\n\r\n",msg);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_tcp_connection_receive_all()
+{
+    char msg[TCP_SEND_MAX_LEN+1];
+    int argLen = 0;
+
+    if (cyntecGetCommandTokenCnt() == 3) {
+        /* handle Message arg */
+        argLen = atoi((const char *)cyntecGetCommandArgument(0, NULL));
+
+        if (argLen > TCP_SEND_MAX_LEN || argLen < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        memset( msg, 0, TCP_SEND_MAX_LEN+1);
+
+        if ( tcpConnect.receive_all(msg, argLen) >= 0 ) {
+            console.printf("\r\nOK;%s\r\n\r\n",msg);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+static void cyn_wifi_tcp_connection_blocking()
+{
+    bool blocking = false;
+    unsigned int timeout;
+
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 3) {
+
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        tcpConnect.set_blocking(blocking, 1500);
+        cyntecPrintOk();
+
+    } else if (cyntecGetCommandTokenCnt() == 4) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        arg = cyntecGetCommandArgument(1, NULL);
+        timeout = (unsigned int)atoi((const char *)arg);
+
+        tcpConnect.set_blocking(blocking, timeout);
+        cyntecPrintOk();
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+static void cyn_wifi_tcp_connection_close()
+{
+    bool shutdown = true;
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( tcpConnect.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else if (cyntecGetCommandTokenCnt() == 3) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '0')
+            shutdown = false;
+
+        if ( tcpConnect.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+/////////**** WIFI UDP Socket Implement ****//////////
+static void cyn_wifi_udp_init()
+{
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( udpSocket.init() == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_udp_bind()
+{
+    int port = 1;
+    if (cyntecGetCommandTokenCnt() == 2) {
+        udpSocket.bind(port);
+        cyntecPrintOk();
+//			if ( udpSocket.bind(port) == 0 )
+//				cyntecPrintOk();
+//			else
+//				cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else if (cyntecGetCommandTokenCnt() == 3) {
+        port = atoi((const char*)(cyntecGetCommandArgument(0, NULL)));
+
+        if (port < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        udpSocket.bind(port);
+        cyntecPrintOk();
+//			if ( udpSocket.bind(port) == 0 )
+//				cyntecPrintOk();
+//			else
+//				cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_udp_set_broadcasting()
+{
+    bool broadcast = true;
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( udpSocket.set_broadcasting(broadcast) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else if (cyntecGetCommandTokenCnt() == 3) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '0')
+            broadcast = false;
+
+        if ( udpSocket.set_broadcasting(broadcast) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+static void cyn_wifi_udp_send_to()
+{
+    char msg[UDP_SEND_MAX_LEN+1];
+    int sendData;
+    uint8_t * argAllBuf = cyntecGetCommandTotalBuffer();
+    int sendLen = 0;  // Maximum 1400, need to be integer
+    uint8_t sendLenCharNum = 0; // Maximum 4
+    uint8_t *argLeng = cyntecGetCommandArgument(0,&sendLenCharNum);
+    sendLen = cyntecAtoi(argLeng,sendLenCharNum);
+    //sendLen = cyntecAtoInt(argLeng); 
+    if (sendLen > UDP_SEND_MAX_LEN || sendLen < 0) {
+        cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() <4 ) {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+        return;
+    }
+    if (cyntecGetCommandTokenCnt() >= 4) {
+
+        /* handle Message arg */
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("sendLen:%i,Buf:%s,Index:%i\r\n",sendLen,&argAllBuf[15+sendLenCharNum],cyntecGetTotalIndex());
+#endif
+        memset( msg, 0, UDP_SEND_MAX_LEN+1);
+        for (int i=0; i<sendLen; i++)
+            msg[i] = argAllBuf[15+sendLenCharNum+i];
+#ifdef DELTA_WIFI_DEBUG
+        console.printf("msg:%s\r\n",msg);
+#endif
+        sendData = udpSocket.sendTo(cliEndpoint, msg, sendLen);
+        if ( sendData >= 0 ) {
+            console.printf("\r\nOK;");
+            console.printf("%i\r\n\r\n",sendData);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+    }
+}
+
+static void cyn_wifi_udp_received_from()
+{
+    char msg[UDP_SEND_MAX_LEN+1];
+    int argLen = 0;
+
+    if (cyntecGetCommandTokenCnt() == 3) {
+        /* handle Message arg */
+        argLen = atoi((const char *)cyntecGetCommandArgument(0, NULL));
+
+        if (argLen > UDP_SEND_MAX_LEN || argLen < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        memset( msg, 0, UDP_SEND_MAX_LEN+1);
+
+        if ( udpSocket.receiveFrom(cliEndpoint, msg, argLen) >= 0 ) {
+            console.printf("\r\nOK;%s\r\n\r\n",msg);
+        } else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_udp_blocking()
+{
+    bool blocking = false;
+    unsigned int timeout;
+
+    uint8_t *arg;
+    if (cyntecGetCommandTokenCnt() == 3) {
+
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        udpSocket.set_blocking(blocking, 1500);
+        cyntecPrintOk();
+
+    } else if (cyntecGetCommandTokenCnt() == 4) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '1')
+            blocking = true;
+
+        arg = cyntecGetCommandArgument(1, NULL);
+        timeout = (unsigned int)atoi((const char *)arg);
+
+        udpSocket.set_blocking(blocking, timeout);
+        cyntecPrintOk();
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_udp_close()
+{
+    bool shutdown = true;
+    uint8_t *arg;
+
+    if (cyntecGetCommandTokenCnt() == 2) {
+        if ( udpSocket.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else if (cyntecGetCommandTokenCnt() == 3) {
+        arg = cyntecGetCommandArgument(0, NULL);
+        if (arg[0] == '0')
+            shutdown = false;
+
+        if ( udpSocket.close(shutdown) == 0 )
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    }	else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+
+
+
+/////////**** WIFI UDP Endpoint Implement ****//////////
+static void cyn_wifi_udp_endpoint_reset_address()
+{
+    if (cyntecGetCommandTokenCnt() == 2) {
+        cliEndpoint.reset_address();
+        cyntecPrintOk();
+    } else {
+        cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS);
+    }
+}
+static void cyn_wifi_udp_endpoint_address()
+{
+    uint8_t argHost[STATIC_IP_MAX_LEN];
+    int port;
+
+    uint8_t *arg;
+    uint8_t argLen;
+
+    if ( cyntecGetCommandTokenCnt() == 4 ) {
+        /* handle Host addr */
+        arg = cyntecGetCommandArgument(0, &argLen);
+
+        if ( cyntecIsValidIP(arg,argLen) != 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        memset( argHost, 0, STATIC_IP_MAX_LEN);
+        memcpy( argHost, arg, argLen);
+
+        /* Handle Port */
+        port = atoi((const char *)(cyntecGetCommandArgument(1, NULL)));
+        if (port < 0) {
+            cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE);
+            return;
+        }
+
+        if ( cliEndpoint.set_address((const char *)argHost, (const int)port) == 0)
+            cyntecPrintOk();
+        else
+            cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL);
+
+    } else {
+        console.printf("\r\nOK;%s\r\n\r\n",cliEndpoint.get_address());
+    }
+}
+//static void cyn_wifi_udp_endpoint_get_address(){}
+static void cyn_wifi_udp_endpoint_port()   // 2015/1/20: Lester add
+{
+    console.printf("\r\nOK;%d\r\n\r\n",cliEndpoint.get_port());
+}
+
+
+CyntecCommandEntry wifiCommandSets[] = {
+    /////////**** WIFI Device ****//////////
+    {"device_sleep", cyn_wifi_device_sleep, NULL, "Set WIFI module to sleep mode"},
+    {"device_network", cyn_wifi_device_network, NULL, " <SSID> <PASSWORD> <SECURITY> <PRIORITY> Set SSID and PASSWORD for WIFI module"},
+    {"device_apscan", cyn_wifi_device_ap_scan, NULL, "Scan for available access point on all channels."},
+    {"device_setap",cyn_wifi_set_ap, NULL, " <SSID> <PASSWORD> <SECURITY> <CHANNEL>Set Access Point in given configuration"},
+
+    /////////**** WIFI Ethernet ****//////////
+    {"eth_init", cyn_wifi_ethernet_init, NULL, " <STATIC IP> Initialize the interface to use DHCP"},
+    {"eth_connect", cyn_wifi_ethernet_connect, NULL, "<TIMEOUT MS> Bring up the WiFi connection"},
+    {"eth_disconnect", cyn_wifi_ethernet_disconnect, NULL, "Bring the interface down"},
+    {"eth_mac", cyn_wifi_ethernet_mac, NULL, "Get MAC addr of Ethernet Interface"},
+    {"eth_ip", cyn_wifi_ethernet_ip, NULL, "Get IP addr of Ehternet Interface"},
+    {"eth_isConnect", cyn_wifi_ethernet_isConnected, NULL, "Check if the device is connected to Access Point"},
+
+    /////////**** WIFI TCP Socket Server ****//////////
+    {"tcp_server_bind", cyn_wifi_tcp_server_bind, NULL, " <PORT> Bind a socket to a port"},
+    {"tcp_server_listen", cyn_wifi_tcp_server_listen, NULL, "Start listening for incomming connections"},
+    {"tcp_server_accept", cyn_wifi_tcp_server_accept, NULL, "Accept a new connection"},
+    {"tcp_server_blocking", cyn_wifi_tcp_server_blocking, NULL, " <SETTING> <TIMEOUT MS> Set blocking mode and timeout"},
+    {"tcp_server_close", cyn_wifi_tcp_server_close, NULL, " <SHUTDOWN> Close the socket"},
+
+    /////////**** WIFI TCP Socket Connection ****//////////
+    {"tcp_connection_connect", cyn_wifi_tcp_connection_connect, NULL, " <IPADDR> <PORT> Connects TCP socket to the server"},
+    {"tcp_connection_is_connect", cyn_wifi_tcp_connection_is_connected, NULL, "Check if the socket is connected"},
+    {"tcp_connection_send", cyn_wifi_tcp_connection_send, NULL, " <DATALEN> <DATA> Send data to the remote host"},
+    {"tcp_connection_send_all", cyn_wifi_tcp_connection_send_all, NULL, " <DATALEN> <DATA> Send all the data to the remote host"},
+    {"tcp_connection_receive", cyn_wifi_tcp_connection_receive, NULL, " <DATALEN> Receive data from the remote host"},
+    {"tcp_connection_receive_all", cyn_wifi_tcp_connection_receive_all, NULL, "<DATALEN> Receive all the data from the remote host"},
+    {"tcp_connection_blocking", cyn_wifi_tcp_connection_blocking, NULL, "<SETTING> <TIMEOUT MS> Set blocking mode and timeout"},
+    {"tcp_connection_close", cyn_wifi_tcp_connection_close, NULL, "<SHUTDOWN> Close the connection"},
+
+    /////////**** WIFI UDP Socket ****//////////
+    {"udp_init", cyn_wifi_udp_init, NULL, "Init UDP Client Socket"},
+    {"udp_bind", cyn_wifi_udp_bind, NULL, " <PORT> Bind UDP Server Socket to a port"},
+    {"udp_set_broadcasting", cyn_wifi_udp_set_broadcasting, NULL, " <IS_BROADCAST> Set socket in broadcasting"},
+    {"udp_send_to", cyn_wifi_udp_send_to, NULL, " <DATALEN> <DATA> Send a packet to a remote endpoint"},
+    {"udp_received_from", cyn_wifi_udp_received_from, NULL, " <DATALEN> Receive a packet from a remote endpont"},
+    {"udp_blocking", cyn_wifi_udp_blocking, NULL, " <DATALEN> Set blocking mode and timeout"},
+    {"udp_close", cyn_wifi_udp_close, NULL, " <SHUTDOWN> Close the socket"},
+
+    /////////**** WIFI UDP Endpoint ****//////////
+    {"udp_endpoint_reset", cyn_wifi_udp_endpoint_reset_address, NULL, "Reset the address of this endpoint"},
+    {"udp_endpoint_address", cyn_wifi_udp_endpoint_address, NULL, " <IPADDR> <PORT> Set/Get the address of this endpoint"},
+    {"udp_endpoint_port", cyn_wifi_udp_endpoint_port, NULL, "Get the port of this endpoint"},
+
+    {NULL, NULL, NULL, NULL},
+};
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CLI_Source/wifi_cli.h	Thu Sep 14 01:48:08 2017 +0000
@@ -0,0 +1,20 @@
+/*
+ * wifi-cli.h
+ * Copyright 2014 by Delta Corporation. All rights reserved.
+ */
+//#ifdef __cplusplus
+//extern "C" {
+//#endif 
+#include "command-interpreter.h" 
+extern CyntecCommandEntry wifiCommandSets[];
+#include <stdlib.h>
+#include <string.h>
+#include "mbed.h"
+#include "WIFIDevice.h"
+#include "EthernetInterface.h"
+//#ifdef __cplusplus
+//}
+//#endif
+
+
+
--- a/main.cpp	Thu Jun 29 04:21:01 2017 +0000
+++ b/main.cpp	Thu Sep 14 01:48:08 2017 +0000
@@ -1,79 +1,147 @@
-/******************** (C) COPYRIGHT 2016 Delta Electronics, Inc. ***************
-*
-* File Name : main.cpp
-* Authors   : Tsungta Wu - CPBG (tsungta.wu@deltaww.com)
-* Version   : V.1.0.0
-* Date      : 2016/Nov/24
-*
-* This example only show the most basic WiFi operation include AP scan and connect 
-* The usage of TCP/UDP socket please refer to the mbed Handbook from the link below
-* https://developer.mbed.org/handbook/Socket
-*
-*******************************************************************************/
+#include <mbed.h>
+
+#include "Gap.h"
+#include "command-interpreter.h"  
+#include "ble/BLE.h"
+#include "ble/services/BatteryService.h"
+#include "ble/services/DeviceInformationService.h"
+#include "ble/services/UARTService.h"
+
+#define uart_buffer_size    64      //Do not increase uart_buffer_size to prevent out of memory, 
+#define uart_baudrate       38400   //supported baudrate range between 1200 to 230400 (38400) for NQ620 (NNN50)
+unsigned char uart_buf[uart_buffer_size];
+unsigned int i = 0;
+bool isGetCommand = false;
+
+Serial console(USBTX, USBRX);
 
-#include "mbed.h"
-#include "EthernetInterface.h"
-#include "WIFIDevice.h"
+DeviceInformationService *deviceInfo;
+BatteryService *batteryService;
+static UARTService *uartServicePtr;
+const static char     DEVICE_NAME[]        = "DELTA_CLI_UART";
+static const uint16_t uuid16_list[]        = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
+                                              GattService::UUID_BATTERY_SERVICE,
+                                              GattService::UUID_DEVICE_INFORMATION_SERVICE};
 
-const char* ECHO_SERVER_ADDRESS = "192.168.2.13";
-const int ECHO_SERVER_PORT = 1030;
-
-void scanCallback(tstrM2mWifiscanResult result)
-{
-    printf("SSID: %s \n", result.au8SSID);
-    printf("RSSI: %i \n", result.s8rssi);
+void CLI_execute() {
+        if (uart_buf[i-2] != '\r' || uart_buf[i-1] != '\n') return; //detecting \r\n
+        
+        isGetCommand = true;
+            
+}
+void uart_interrupt() {
+    uart_buf[i++] = console.getc();
+    CLI_execute();
 }
 
-int main() {
-
-    EthernetInterface eth;
-    WIFIDevice wifi;
-
-    eth.init();
+void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
+{
+    console.printf("Connected\r\n");
+}
 
-    wifi.apScan(scanCallback);
-             
-    wifi.setNetwork(M2M_WIFI_SEC_WPA_PSK, "TP-LINK_2.4G_TTWU", "0972753720"); 
-    
-    eth.connect();    
-
-    if(wifi.is_AP_connected())
-        printf("Connect Success! \n");
-    else
-        printf("Connect Fail! \n");    
-
-    printf("MAC: %s\n", eth.getMACAddress());            
-    printf("IP: %s\n", eth.getIPAddress());
-    printf("Gateway: %s\n", eth.getGateway());
-    printf("NetworkMask: %s\n", eth.getNetworkMask()); 
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    console.printf("Disconnected\r\n");
+    BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
+}
 
-    UDPSocket sock;
-    sock.init();
-    
-    Endpoint echo_server;
-    echo_server.set_address(ECHO_SERVER_ADDRESS, ECHO_SERVER_PORT);
-    
-    char out_buffer[] = "Hello World";
-    printf("Sending  message '%s' to server (%s)\n",out_buffer,ECHO_SERVER_ADDRESS);
-    sock.sendTo(echo_server, out_buffer, sizeof(out_buffer));
-    
-    char in_buffer[256];    //IMPORTANT, array size MUST >= the actual received data size or set to maximum of 1400 if there is uncertainty
-    int n = sock.receiveFrom(echo_server, in_buffer, sizeof(in_buffer));
-    
-    if(n <0)
-        in_buffer[0] = '\0';//IMPORTANT, in case n = -1 when set_bloacking is timeout, prevent the illegal array in_buffer[-1] access 
-    else
-        in_buffer[n] = '\0';
-        
-    printf("Received message from server: '%s'\n", in_buffer);
-    
-    sock.close();
-    
-    eth.disconnect();                             
-    
-    wifi.sleep();
-                                 
-    while(1) {
+void onTimeoutCallback(Gap::TimeoutSource_t source)
+{
+    switch (source) {
+        case Gap::TIMEOUT_SRC_ADVERTISING:
+            console.printf("Advertising timeout\r\n");
+            break;  
+        case Gap::TIMEOUT_SRC_SECURITY_REQUEST:
+            console.printf("Security request timeout\r\n");
+            break;
+        case Gap::TIMEOUT_SRC_SCAN:
+            console.printf("Scanning timeout\r\n");
+            break;
+        case Gap::TIMEOUT_SRC_CONN:
+            console.printf("Connection timeout\r\n");
+            break;
+    }
+}
+
+void serverDataWrittenCallback(const GattWriteCallbackParams *response) {
+    console.printf("serverDataWrittenCallback\r\n");
+    if (response->handle == uartServicePtr->getTXCharacteristicHandle()) {
+        for(int j=0;j<response->len;j++) {
+            console.printf("data: %02X\r\n", response->data[j]);
+        }
     }
 }
 
+void dataSentCallback(const unsigned callback) {
+    //uart.printf("dataSentCallback\r\n");
+}
+
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE &ble          = params->ble;
+    ble_error_t error = params->error;
+
+    if (error != BLE_ERROR_NONE) {
+        return;
+    }
+    
+    ble.gap().onDisconnection(disconnectionCallback);
+    ble.gap().onConnection(onConnectionCallback);
+    ble.gap().onTimeout(onTimeoutCallback);
+    ble.gattServer().onDataWritten(serverDataWrittenCallback);
+    ble.gattServer().onDataSent(dataSentCallback);
+
+    /* Setup primary service. */
+    uartServicePtr = new UARTService(ble);
+
+    /* Setup auxiliary service. */
+    batteryService = new BatteryService(ble, 100);
+    deviceInfo = new DeviceInformationService(ble, "DELTA", "NQ620", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+
+    /* Setup advertising. */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(50); /* 50ms */
+    ble.gap().startAdvertising();
+    console.printf("Start advertising\r\n");
+}
+
+int main(void)
+{
+    
+    console.attach(&uart_interrupt);
+    console.baud(uart_baudrate);
+    console.printf("Application Start\r\n");
+    
+    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
+    ble.init(bleInitComplete);
+
+    /* SpinWait for initialization to complete. This is necessary because the
+     * BLE object is used in the main loop below. */
+    while (ble.hasInitialized()  == false) { /* spin loop */ }
+    
+    while(1) {
+        if(isGetCommand) {
+            isGetCommand = false;
+            
+            if(uart_buf[0] == 'b') {
+                if (ble.getGapState().connected) {
+                    
+                    //Write data via RX characteristic
+                    ble.gattServer().write(uartServicePtr->getRXCharacteristicHandle(), static_cast<const uint8_t *>(uart_buf)+2, i-4);
+                }
+            }
+            else{
+                for (int j=0; j<i; j++)
+                    cyntecProcessCommandInput(uart_buf[j]);
+                    //console.putc(uart_buf[j]);//used for debug only
+            }
+            
+            i=0;
+        }
+        
+        ble.waitForEvent(); // low power wait for event
+    }
+}