Initial import of NFC GNSS SDK project

This commit is contained in:
chenjintao
2026-09-15 16:10:12 +08:00
commit 2746cc3d4e
3070 changed files with 892062 additions and 0 deletions
@@ -0,0 +1,616 @@
/*
* Author: Chandra Mohan C (willvalab@gmail.com)
* All rights reserved.
*
* Use of this source code is governed by a MIT-style license that can be found
* in the LICENSE file.
*
**-----------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include "./uartshConfig.h"
#include "./uartsh.h"
/*-----------------------------------------------*/
#define HISTORY_COUNT (UARTSH_CONFIG_COMMAND_HISTORY_COUNT + 1)
#define KEY_BS 0X08
#define KEY_DEL 0X7F
#define KEY_ESC_SEQ1 0X1B
#define KEY_SPECIAL_UP 'A'
#define KEY_SPECIAL_DOWN 'B'
#define KEY_SPECIAL_LEFT 'D'
#define KEY_SPECIAL_RIGHT 'C'
#define KEY_ESC_SEQ2 '['
#define KEY_ESC_SEQ3 '3'
#define KEY_ESC_SEQ4 '~'
#define FLAG_ESC_SEQ1 1
#define FLAG_ESC_SEQ2 2
#define FLAG_ESC_SEQ3 3
/*-----------------------------------------------*/
struct UartshEditBuffer
{
int cCount;
char buffer[UARTSH_CONFIG_COMMAND_STRING_SIZE];
};
/*-----------------------------------------------*/
#include "hal_api.h"
#define UARTSH_DEFAULT_TIMEOUT 60000
#define UARTSH_CMD_TIMEOUT 60000*2
void *g_uartsh_mutex = NULL;
static int uart_putchar(sh_cust_type_t *cust_sh, int charx)
{
return cust_sh->write_func(cust_sh->handler,(unsigned char *)&charx,1,100);
}
static char uart_getchar(sh_cust_type_t *cust_sh)
{
char charx=0;
int ret;
do{
if(cust_sh->run_flag==1){
break;
}
ret=cust_sh->read_func(cust_sh->handler,(unsigned char *)&charx,1,100);
if(ret==1){
//cust_sh->time_out_uptime = hal_os_up_time_ms();
break;
}
if(ret<0){
hal_os_task_sleep_ms(100);
}else{
hal_os_task_sleep_ms(10);
}
if((cust_sh->timeout_enable)&&(hal_os_up_time_ms() - cust_sh->time_out_uptime > cust_sh->time_out)){
cust_sh->run_flag = 1;
break;
}
}while(ret!=1);
return charx;
}
void uartsh_puts(sh_cust_type_t *cust_sh, char const* s)
{
if(cust_sh->handler==NULL)return;
#if 0
char c = 0;
while( (c = *s++) )
{
uart_putchar(c);
}
#else
int len = strlen(s);
if(s[len-2]!='\r' && s[len-1]== '\n'){
cust_sh->write_func(cust_sh->handler,(unsigned char *)s,strlen(s)-1,1000);
cust_sh->write_func(cust_sh->handler,(unsigned char *)"\r\n",2,1000);
}else{
cust_sh->write_func(cust_sh->handler,(unsigned char *)s,strlen(s),1000);
}
#endif
}
int uartsh_printf(sh_cust_type_t *cust_sh, const char *fmt, ...)
{
char buf[512]={0};
int len=0;
if(cust_sh->handler==NULL)return -1;
va_list ap;
va_start(ap, fmt);
vsnprintf(buf,sizeof(buf)-1,fmt,ap);
va_end(ap);
len = strlen(buf);
if(buf[len-2]!='\r' && buf[len-1]== '\n'){
cust_sh->write_func(cust_sh->handler,(unsigned char *)buf,len-1,1000);
uartsh_puts(cust_sh,"\r\n");
}else{
cust_sh->write_func(cust_sh->handler,(unsigned char *)buf,len,1000);
}
return len;
}
/*-----------------------------------------------*/
static inline void handleDeleteKey(sh_cust_type_t *cust_sh, struct UartshEditBuffer* pEditBuffer,
size_t* pCursor)
{
unsigned int cursor = *pCursor;
if( cursor < pEditBuffer->cCount )
{
int b = (pEditBuffer->cCount - cursor);
memcpy(&pEditBuffer->buffer[cursor],
&pEditBuffer->buffer[cursor + 1],
b);
pEditBuffer->buffer[--pEditBuffer->cCount] = '\0';
uart_putchar(cust_sh,' ');
uart_putchar(cust_sh,'\b');
uartsh_puts(cust_sh,&pEditBuffer->buffer[cursor]);
uart_putchar(cust_sh,' ');
while(b--)
uart_putchar(cust_sh,'\b');
}
}
/*-----------------------------------------------*/
unsigned int uartsh_gets(sh_cust_type_t *cust_sh, char** input)
{
static struct UartshEditBuffer editBuffer[HISTORY_COUNT] = { { 0, }, };
static int bufferIndex = 0;
static int bufferIndexMax = 0;
if( editBuffer[bufferIndex].cCount )
{
if( bufferIndexMax < (HISTORY_COUNT - 1) )
bufferIndexMax++;
bufferIndex++;
if( bufferIndex > bufferIndexMax )
bufferIndex = 0;
}
struct UartshEditBuffer* pEditBuffer = &editBuffer[bufferIndex];
pEditBuffer->cCount = 0;
pEditBuffer->buffer[0] = '\0';
int hi = bufferIndex;
size_t cursor = 0;
char specialKey = 0;
while( 1 )
{
char c = (char) uart_getchar(cust_sh);
if(cust_sh->run_flag==1){
return -1;
}
#if (UARTSH_CONFIG_END_CHAR & UARTSH_END_CHAR_CR)
if( c == '\r' )
{
#if (UARTSH_CONFIG_END_CHAR == UARTSH_END_CHAR_CRLF)
c = (char) uart_getchar(cust_sh);
if( c != '\n')
continue;
#endif
break;
}
#elif (UARTSH_CONFIG_END_CHAR & UARTSH_END_CHAR_LF)
if( c == '\n' )
{
break;
}
#endif
switch( specialKey )
{
case 0:
{
specialKey = 0;
switch(c)
{
case KEY_ESC_SEQ1:
{
specialKey = FLAG_ESC_SEQ1;
} break;
case UARTSH_CONFIG_KEY_BACKSPACE:
{
if( cursor )
{
cursor--;
int b = (pEditBuffer->cCount - cursor);
memcpy(&pEditBuffer->buffer[cursor],
&pEditBuffer->buffer[cursor + 1],
b);
pEditBuffer->buffer[--pEditBuffer->cCount] = '\0';
uart_putchar(cust_sh,'\b');
uartsh_puts(cust_sh,&pEditBuffer->buffer[cursor]);
uart_putchar(cust_sh,' ');
while(b--)
uart_putchar(cust_sh,'\b');
}
} break;
#if (UARTSH_CONFIG_KEY_BACKSPACE != UARTSH_DELETE_KEY)
case KEY_DEL:
{
handleDeleteKey(cust_sh, pEditBuffer, &cursor );
} break;
#endif
default:
{
//only alphabets and special characters allowed
if( (c >= 0x20) && (c <= 0x7e) )
{
if( pEditBuffer->cCount < (UARTSH_CONFIG_COMMAND_STRING_SIZE - 1) )
{
// insertion
int i = pEditBuffer->cCount;
while( i > cursor )
{
pEditBuffer->buffer[i] = pEditBuffer->buffer[i - 1];
i--;
}
pEditBuffer->buffer[cursor] = c;
pEditBuffer->cCount++;
pEditBuffer->buffer[pEditBuffer->cCount] = '\0';
uartsh_puts(cust_sh,&pEditBuffer->buffer[cursor]);
cursor++;
i = (pEditBuffer->cCount - cursor);
while(i--)
uart_putchar(cust_sh,'\b');
}
}
}
}
} break;
case FLAG_ESC_SEQ1:
{
specialKey = 0;
if( c == KEY_ESC_SEQ2 )
specialKey = FLAG_ESC_SEQ2;
}break;
case FLAG_ESC_SEQ2:
{
specialKey = 0;
switch(c)
{
case KEY_SPECIAL_UP:
{
while( cursor-- )
uart_putchar(cust_sh,'\b');
int oldCount = pEditBuffer->cCount;
hi--;
if( hi < 0 )
hi = bufferIndexMax;
if( hi == bufferIndex )
{
pEditBuffer->cCount = 0;
pEditBuffer->buffer[0] = '\0';
}
else
{
pEditBuffer->cCount = editBuffer[hi].cCount;
memcpy(pEditBuffer->buffer, editBuffer[hi].buffer, (pEditBuffer->cCount + 1));
}
uartsh_puts(cust_sh,pEditBuffer->buffer);
cursor = pEditBuffer->cCount;
if( oldCount > pEditBuffer->cCount )
{
int move = (oldCount - pEditBuffer->cCount);
while( move-- )
uart_putchar(cust_sh,' ');
move = (oldCount - pEditBuffer->cCount);
while( move-- )
uart_putchar(cust_sh,'\b');
}
} break;
case KEY_SPECIAL_DOWN:
{
while( cursor-- )
uart_putchar(cust_sh,'\b');
int oldCount = pEditBuffer->cCount;
hi++;
if( hi > bufferIndexMax )
hi = 0;
if( hi == bufferIndex )
{
pEditBuffer->cCount = 0;
pEditBuffer->buffer[0] = '\0';
}
else
{
pEditBuffer->cCount = editBuffer[hi].cCount;
memcpy(pEditBuffer->buffer, editBuffer[hi].buffer, (pEditBuffer->cCount + 1));
}
uartsh_puts(cust_sh,pEditBuffer->buffer);
cursor = pEditBuffer->cCount;
if( oldCount > pEditBuffer->cCount )
{
int move = (oldCount - pEditBuffer->cCount);
while( move-- )
uart_putchar(cust_sh,' ');
move = (oldCount - pEditBuffer->cCount);
while( move-- )
uart_putchar(cust_sh,'\b');
}
} break;
case KEY_SPECIAL_LEFT:
{
if( cursor )
{
uart_putchar(cust_sh,'\b');
cursor--;
}
} break;
case KEY_SPECIAL_RIGHT:
{
if( cursor < pEditBuffer->cCount )
{
uart_putchar(cust_sh,pEditBuffer->buffer[cursor++]);
}
} break;
case KEY_ESC_SEQ3:
{
specialKey = FLAG_ESC_SEQ3;
} break;
}
}break;
case FLAG_ESC_SEQ3:
{
specialKey = 0;
// deletion
if( c == KEY_ESC_SEQ4 )
{
handleDeleteKey(cust_sh, pEditBuffer, &cursor );
}
}break;
}
//fflush(stdout);
}
uartsh_puts(cust_sh,"\r\n");
// copy current buffer to next buffer only if current buffer has content
if( pEditBuffer->cCount )
{
// as caller uses strtok passed buffer will be spoiled
// copies current edit buffer's content to next buffer and passes to caller
// next call makes use of passed buffer for editing
int bi = (bufferIndex + 1);
if( bi > (HISTORY_COUNT - 1) )
bi = 0;
#if (HISTORY_COUNT >= 2) // as total buffer is 1, no point in copying to itself
memcpy(editBuffer[bi].buffer, pEditBuffer->buffer, (pEditBuffer->cCount + 1));
#endif
*input = editBuffer[bi].buffer;
}
return pEditBuffer->cCount;
}
/*-----------------------------------------------*/
int uartshTokenize(char commandString[], char const tokens[], int argcMax, char* argv[])
{
int argc = 0;
char* token = strtok(commandString, tokens);
while(token != NULL)
{
argv[argc++] = token;
if( argc >= argcMax )
break;
token = strtok(NULL, tokens);
}
return argc;
}
/*-----------------------------------------------*/
UartshCommandHandler uartshGetHandler(UartshCommand cmdlist[], char command[])
{
int commandLength = strlen(command);
int index = 0;
while( cmdlist[index].name != NULL )
{
int appNameSize = strlen(cmdlist[index].name);
// extra check to ensure command length is exactly matching app length
if( commandLength == appNameSize )
{
if( 0 == strncmp(command, cmdlist[index].name, appNameSize) )
{
return cmdlist[index].handler;
}
}
index++;
}
return NULL;
}
/*-----------------------------------------------*/
void uartsh_thread_cb(void *args)
{
char* argv[UARTSH_CONFIG_ARGC_MAX] = { 0, };
int argc = 0;
int first_flag = 0;
sh_cust_type_t *cust_sh = args;
UartshCommand *cmdlist = cust_sh->cmd_list;
cust_sh->time_out = UARTSH_DEFAULT_TIMEOUT;
cust_sh->time_out_uptime = hal_os_up_time_ms();
cust_sh->handler = cust_sh->open_func(cust_sh->port,cust_sh->configbuf);
if(!cust_sh->handler){
RLOGD("sh %s open error",cust_sh->name);
goto exit;
}
RLOGD("shell %s runing",cust_sh->name);
cust_sh->run_flag = 0;
while(cust_sh->run_flag==0)
{
if(first_flag==1){
//uartsh_puts(cust_sh,"\r\n");
uartsh_printf(cust_sh,"cmd# ");
}
first_flag=1;
char* commandString = NULL;
int commandStringLength = 0;
if( 0 == (commandStringLength = uartsh_gets(cust_sh,&commandString)) )
continue;
if(cust_sh->run_flag==1){
break;
}
//uartsh_puts(cust_sh,commandString);
argc = uartshTokenize(commandString, " \n", UARTSH_CONFIG_ARGC_MAX, argv);
uartsh_puts(cust_sh,"\r\n");
size_t commandLength = strlen(argv[0]);
if( 1 == argc )
{
if( commandLength == 4 )
{
if( 0 == strncmp("help", argv[0], 5) )
{
if( NULL == cmdlist )
{
uartsh_puts(cust_sh,"No commands found\r\n");
continue;
}
uartsh_puts(cust_sh,"Supported commands are below:\r\n\n");
int index = 0;
while( cmdlist[index].name != NULL )
{
uartsh_puts(cust_sh," ");
uartsh_puts(cust_sh,cmdlist[index++].name);
uartsh_puts(cust_sh,"\r\n");
}
continue;
}
else if( 0 == strncmp("exit", argv[0], 4) ){
break;
}
}
}
if( NULL == cmdlist )
continue;
UartshCommandHandler handler = uartshGetHandler(cmdlist, argv[0]);
if( NULL == handler ){
RLOGD("\r\nUNKNOWN CMD\r\n");
uartsh_puts(cust_sh,"\r\nUNKNOWN\r\n");
//break;
}else{
RLOGD("\r\nEXEC CMD:%s\r\n", argv[0]);
if(g_uartsh_mutex==NULL){
g_uartsh_mutex = hal_os_mutex_create();
}
hal_os_mutex_lock(g_uartsh_mutex);
int myret = handler(cust_sh,argc, argv);
if( myret != 0 ){
uartsh_printf(cust_sh,"\r\nERROR %d\r\n",myret);
}else{
uartsh_printf(cust_sh,"\r\nOK\r\n");
}
cust_sh->time_out_uptime = hal_os_up_time_ms();
cust_sh->time_out = UARTSH_CMD_TIMEOUT;
hal_os_mutex_unlock(g_uartsh_mutex);
}
hal_os_task_sleep_ms(1);
}
exit:
if(cust_sh->handler){
cust_sh->close_func(cust_sh->handler);
}
cust_sh->handler=NULL;
cust_sh->run_flag =2;
RLOGD("shell %s exit!", cust_sh->name);
hal_os_task_destroy(&cust_sh->thread);
}
int uartshInit(sh_cust_type_t *cust_sh)
{
cust_sh->thread = hal_os_task_create(cust_sh->name,HAL_OS_TASK_PRIORITY_NORMAL,10*1024,uartsh_thread_cb,cust_sh);
if(!cust_sh->thread){
RLOGE("shthread thread error");
cust_sh->run_flag = 1;
return -1;
}
return 0;
}
int uartshExit(sh_cust_type_t *cust_sh)
{
uint64_t start_ms = hal_os_up_time_ms();
if(cust_sh->run_flag!=0)return -1;
cust_sh->run_flag=1;
while (cust_sh->run_flag!=2)
{
if(hal_os_up_time_ms()-start_ms>10000)
{
cust_sh->run_flag = 1;
return -1;
}
hal_os_task_sleep_ms(10);
}
cust_sh->run_flag=1;
return 0;
}
int uartshRunning(sh_cust_type_t *cust_sh)
{
if(cust_sh->run_flag==0 || cust_sh->run_flag==-1){
return 1;
}
return 0;
}