diff --git a/ide/mplabx/wolfssh.c b/ide/mplabx/wolfssh.c index 3edc891f..915cd500 100644 --- a/ide/mplabx/wolfssh.c +++ b/ide/mplabx/wolfssh.c @@ -24,7 +24,6 @@ #include "definitions.h" #include "tcpip/tcpip.h" -//#include "driver/spi_flash/at25df/drv_at25df.h" #include "system/fs/sys_fs.h" #include "system/fs/sys_fs_media_manager.h" @@ -33,9 +32,11 @@ #include #include -#define NO_FILESYSTEM -#include -#undef NO_FILESYSETM +#ifndef NO_FILESYSTEM + #define NO_FILESYSTEM + #include + #undef NO_FILESYSTEM +#endif /* !NO_FILESYSTEM */ #include #include @@ -388,9 +389,14 @@ static byte find_char(const byte* str, const byte* buf, word32 bufSz) #if 1 static void logCb(enum wolfSSH_LogLevel lvl, const char *const msg) { - if (lvl == WS_LOG_SFTP && wolfSSH_LogEnabled()) { + if ( wolfSSH_LogEnabled() + #if 1 /* optionally filter out just the SFTP logs */ + && lvl == WS_LOG_SFTP + #endif + ) { SYS_CONSOLE_PRINT(msg); SYS_CONSOLE_PRINT("\r\n"); + SYS_CONSOLE_Flush(SYS_CONSOLE_DEFAULT_INSTANCE); SYS_CONSOLE_Tasks(sysObj.sysConsole0); } } @@ -408,9 +414,54 @@ void APP_Initialize ( void ) #endif } -#define APP_MOUNT_NAME "/mnt/myDrive1/" -#define APP_DEVICE_NAME "/dev/nvma1" -#define APP_FS_TYPE FAT +#ifndef NO_FILESYSTEM + #define APP_MOUNT_NAME "/mnt/myDrive1/" + #define APP_DEVICE_NAME "/dev/nvma1" + #ifdef SYS_FS_LFS_MAX_SS + #define APP_FS_TYPE LITTLEFS + #elif defined(SYS_FS_FAT_MAX_SS) + #define APP_FS_TYPE FAT + #else + #error untested file system setup + #endif + +static void CreateTestFile(void) +{ + SYS_FS_RESULT result; + SYS_FS_HANDLE fileHandle; + char testData[] = "Test Data"; + SYS_FS_ERROR fsError; + + /* Test change to the root directory */ + result = SYS_FS_DirectoryChange("/mnt/myDrive1"); + if(result != SYS_FS_RES_SUCCESS) { + fsError = SYS_FS_Error(); + SYS_CONSOLE_PRINT("Change to root failed! Error: %d\r\n", fsError); + return; + } + SYS_CONSOLE_PRINT("Changed to root directory\r\n"); + + /* Try to create and write to a test file */ + fileHandle = SYS_FS_FileOpen("test.txt", (SYS_FS_FILE_OPEN_WRITE)); + if(fileHandle == SYS_FS_HANDLE_INVALID) + { + fsError = SYS_FS_Error(); + SYS_CONSOLE_PRINT("File open failed! Error: %d\r\n", fsError); + return; + } + + result = SYS_FS_FileWrite(fileHandle, testData, strlen(testData)); + if(result == -1) + { + fsError = SYS_FS_Error(); + SYS_CONSOLE_PRINT("File write failed! Error: %d\r\n", fsError); + SYS_FS_FileClose(fileHandle); + return; + } + + SYS_FS_FileClose(fileHandle); + SYS_CONSOLE_PRINT("File operations successful!\r\n"); +} static int CheckDriveStatus(void) @@ -437,6 +488,7 @@ static int CheckDriveStatus(void) SYS_CONSOLE_PRINT("Failed to get current directory: %d\r\n", SYS_FS_Error()); ret = -1; } + CreateTestFile(); return ret; } @@ -463,7 +515,15 @@ static int TryMount(void) } return ret; } +#endif /* !NO_FILESYSTEM */ +/* Debugging heap and stack available */ +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && \ + INCLUDE_uxTaskGetStackHighWaterMark == 1 + static int currentStack = 0; + static int savedStack = 0; + static int minHeap = 600000; +#endif void APP_Tasks ( void ) { @@ -479,10 +539,15 @@ void APP_Tasks ( void ) appData.state = APP_SSH_ERROR; } + #ifndef NO_FILESYSTEM SYS_CONSOLE_PRINT("Attempting filesystem mount...\r\n"); appData.state = APP_SSH_MOUNT_FILESYSTEM; + #else + appData.state = APP_SSH_USERAUTH_INIT; + #endif break; + #ifndef NO_FILESYSTEM case APP_SSH_MOUNT_FILESYSTEM: ret = TryMount(); switch (ret) { @@ -503,33 +568,46 @@ void APP_Tasks ( void ) { SYS_FS_FORMAT_PARAM opt; + #if defined(SYS_FS_LFS_MAX_SS) + /* Work buffer used by FAT FS during Format */ + uint8_t CACHE_ALIGN work[SYS_FS_LFS_MAX_SS]; + #elif defined(SYS_FS_FAT_MAX_SS) /* Work buffer used by FAT FS during Format */ uint8_t CACHE_ALIGN work[SYS_FS_FAT_MAX_SS]; - - opt.fmt = SYS_FS_FORMAT_FAT; + #endif + + opt.fmt = APP_FS_TYPE; opt.au_size = 0; - if (SYS_FS_DriveFormat (APP_MOUNT_NAME, &opt, (void *)work, SYS_FS_FAT_MAX_SS) != SYS_FS_RES_SUCCESS) + #if defined(SYS_FS_LFS_MAX_SS) + if (SYS_FS_DriveFormat (APP_MOUNT_NAME, &opt, (void *)work, + SYS_FS_LFS_MAX_SS) != SYS_FS_RES_SUCCESS) + #elif defined(SYS_FS_FAT_MAX_SS) + if (SYS_FS_DriveFormat (APP_MOUNT_NAME, &opt, (void *)work, + SYS_FS_FAT_MAX_SS) != SYS_FS_RES_SUCCESS) + #endif { - /* Format of the disk failed. */ - //appData.state = APP_ERROR; + + /* Fatal error with failing to format the file system */ SYS_CONSOLE_PRINT("Failed to format file system\r\n"); + vTaskDelay(500); + + /* continue on to wolfSSH which still could host echo server */ + appData.state = APP_SSH_USERAUTH_INIT; } - else - { + else { SYS_CONSOLE_PRINT("Formated file system\r\n"); - /* Format succeeded. Open a file. */ appData.state = APP_SSH_FORMAT_CHECK; } - break; } + break; case APP_SSH_FORMAT_CHECK: - vTaskDelay(100); if (CheckDriveStatus() == 0) { appData.state = APP_SSH_USERAUTH_INIT; } break; + #endif /* !NO_FILESYSTEM */ case APP_SSH_USERAUTH_INIT: wolfSSH_SetUserAuth(ctx, wsUserAuth); @@ -582,7 +660,7 @@ void APP_Tasks ( void ) handle = TCPIP_STACK_IndexToNet(i); if (!TCPIP_STACK_NetIsReady(handle)) { - return; // interface not ready yet! + return; /* interface not ready yet */ } addr.Val = TCPIP_STACK_NetAddress(handle); SYS_CONSOLE_MESSAGE(TCPIP_STACK_NetNameGet(handle)); @@ -672,6 +750,27 @@ void APP_Tasks ( void ) break; case APP_SSH_SFTP: + #if defined(INCLUDE_uxTaskGetStackHighWaterMark) && \ + INCLUDE_uxTaskGetStackHighWaterMark == 1 + currentStack = uxTaskGetStackHighWaterMark(NULL); + if (savedStack != currentStack) { + savedStack = currentStack; + SYS_CONSOLE_PRINT("Stack bytes free = %d\r\n", currentStack * 4); + } + + if (xPortGetMinimumEverFreeHeapSize() < minHeap) { + minHeap = xPortGetMinimumEverFreeHeapSize(); + SYS_CONSOLE_PRINT("Min heap available water mark = %d bytes\r\n", minHeap); + SYS_CONSOLE_PRINT("Total heap free = %d bytes\r\n", xPortGetFreeHeapSize()); + } + #endif + + if (!TCPIP_TCP_IsConnected(wolfSSH_get_fd(ssh))) { + SYS_CONSOLE_PRINT("TCP socket was disconnected\r\n"); + appData.state = APP_SSH_CLEANUP; + break; + } + if (wolfSSH_SFTP_PendingSend(ssh)) { /* Yes, process the SFTP data. */ ret = wolfSSH_SFTP_read(ssh); @@ -690,30 +789,28 @@ void APP_Tasks ( void ) } } - if (TCPIP_TCP_GetIsReady(wolfSSH_get_fd(ssh)) > 0) { - ret = wolfSSH_worker(ssh, NULL); - error = wolfSSH_get_error(ssh); - if (ret == WS_REKEYING) { - /* In a rekey, keeping turning the crank. */ - break; - } + ret = wolfSSH_worker(ssh, NULL); + error = wolfSSH_get_error(ssh); + if (ret == WS_REKEYING) { + /* In a rekey, keeping turning the crank. */ + break; + } - if (error == WS_WANT_READ || error == WS_WANT_WRITE || - error == WS_WINDOW_FULL) { - ret = error; - break; - } + if (error == WS_WANT_READ || error == WS_WANT_WRITE || + error == WS_WINDOW_FULL) { + ret = error; + break; + } - if (error == WS_EOF) { - appData.state = APP_SSH_CLEANUP; - break; - } - - if (ret != WS_SUCCESS && ret != WS_CHAN_RXD) { - /* If not successful and no channel data, leave. */ - appData.state = APP_SSH_CLEANUP; - break; - } + if (error == WS_EOF) { + appData.state = APP_SSH_CLEANUP; + break; + } + + if (ret != WS_SUCCESS && ret != WS_CHAN_RXD) { + /* If not successful and no channel data, leave. */ + appData.state = APP_SSH_CLEANUP; + break; } ret = wolfSSH_stream_peek(ssh, peek_buf, sizeof(peek_buf)); @@ -721,6 +818,10 @@ void APP_Tasks ( void ) /* Yes, process the SFTP data. */ ret = wolfSSH_SFTP_read(ssh); error = wolfSSH_get_error(ssh); + if (ret == WS_MEMORY_E) { + SYS_CONSOLE_PRINT("Ran out of memory for malloc\r\n"); + appData.state = APP_SSH_CLEANUP; + } if (error == WS_WANT_READ || error == WS_WANT_WRITE || error == WS_CHAN_RXD || error == WS_REKEYING || error == WS_WINDOW_FULL) diff --git a/src/internal.c b/src/internal.c index 8d8297c0..d2883262 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11737,12 +11737,13 @@ static int SignHEcdsa(WOLFSSH* ssh, byte* sig, word32* sigSz, WMEMCPY(sig + idx, s, sSz); } - #ifdef WOLFSSH_SMALL_STACK - if (r) - WFREE(r, heap, DYNTYPE_BUFFER); - if (s) - WFREE(s, heap, DYNTYPE_BUFFER); - #endif +#ifdef WOLFSSH_SMALL_STACK + if (r) + WFREE(r, heap, DYNTYPE_BUFFER); + if (s) + WFREE(s, heap, DYNTYPE_BUFFER); + WOLFSSH_UNUSED(heap); /* could be unused in error case, resolve warning */ +#endif WLOG(WS_LOG_DEBUG, "Leaving SignHEcdsa(), ret = %d", ret); return ret; diff --git a/src/io.c b/src/io.c index acc36bce..671cec4b 100644 --- a/src/io.c +++ b/src/io.c @@ -326,6 +326,19 @@ int wsEmbedRecv(WOLFSSH* ssh, void* data, word32 sz, void* ctx) } #endif +#ifdef MICROCHIP_MPLAB_HARMONY + /* check is still connected */ + if (!TCPIP_TCP_IsConnected(sd)) + { + return WS_CBIO_ERR_CONN_CLOSE; + } + + /* check for data ready to be read */ + if (TCPIP_TCP_GetIsReady(sd) <= 0) { + return WS_CBIO_ERR_WANT_READ; + } +#endif + recvd = (int)RECV_FUNCTION(sd, buf, sz, ssh->rflags); recvd = wsReturnCode(recvd, sd); diff --git a/src/port.c b/src/port.c index 0617f9a7..2b63f72c 100644 --- a/src/port.c +++ b/src/port.c @@ -52,7 +52,14 @@ int wfopen(WFILE* f, const char* filename, SYS_FS_FILE_OPEN_ATTRIBUTES mode) { if (f != NULL) { *f = SYS_FS_FileOpen(filename, mode); - return *f == WBADFILE; + if (*f == WBADFILE) { + WLOG(WS_LOG_SFTP, "Failed to open file %s", filename); + return 1; + } + else { + WLOG(WS_LOG_SFTP, "Opened file %s", filename); + return 0; + } } return 1; } @@ -118,15 +125,15 @@ int wfopen(WFILE** f, const char* filename, const char* mode) /* This is current inline in the source. */ #elif defined(MICROCHIP_MPLAB_HARMONY) - int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, const unsigned int* shortOffset) { int ret; ret = (int)WFSEEK(NULL, &fd, shortOffset[0], SYS_FS_SEEK_SET); - if (ret != -1) + if (ret != -1) { ret = (int)WFWRITE(NULL, buf, 1, sz, &fd); + } return ret; } diff --git a/src/wolfsftp.c b/src/wolfsftp.c index 81279118..7a67a604 100644 --- a/src/wolfsftp.c +++ b/src/wolfsftp.c @@ -2083,9 +2083,12 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) #ifdef MICROCHIP_MPLAB_HARMONY fd = WBADFILE; - WFILE* f = &fd; - - WLOG(WS_LOG_SFTP, "Ret of WFOPEN = %d", WFOPEN(ssh->fs, &f, dir, m)); + { + WFILE* f = &fd; + if (WFOPEN(ssh->fs, &f, dir, m) != WS_SUCCESS) { + fd = -1; + } + } #else fd = WOPEN(ssh->fs, dir, m, atr.per); #endif @@ -3147,6 +3150,12 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out, return WS_BAD_ARGUMENT; } + if (*dir == SYS_FS_HANDLE_INVALID) { + WLOG(WS_LOG_SFTP, "READ dir attempted with invalid handle"); + return WS_BAD_ARGUMENT; + } + WMEMSET(&stat, 0, sizeof(WSTAT_T)); + /* 0 return and dp.name[0] == 0 means end-of-dir */ if (SYS_FS_DirRead(*dir, &stat) != SYS_FS_RES_SUCCESS || stat.fname[0] == '\0') { @@ -3511,6 +3520,7 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz) } #endif /* NO_WOLFSSH_DIR */ + /* Handles packet to write a file * * returns WS_SUCCESS on success @@ -3579,6 +3589,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WS_INVALID_STATE_E; } else { + WLOG(WS_LOG_SFTP, "Wrote %d bytes to file", ret); ret = WS_SUCCESS; } } @@ -3781,6 +3792,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) if (outSz > sz) { /* need to increase buffer size for holding status packet */ WFREE(out, ssh->ctx->heap, DYNTYPE_BUFFER); + WLOG(WS_LOG_SFTP, "Allocating a new buffer of size %d", outSz); out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER); if (out == NULL) { return WS_MEMORY_E; @@ -3968,7 +3980,7 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) WMEMCPY((byte*)&fd, data + idx, sz); #ifdef MICROCHIP_MPLAB_HARMONY - WFCLOSE(ssh->fs, &fd); + ret = WFCLOSE(ssh->fs, &fd); #else ret = WCLOSE(ssh->fs, fd); #endif @@ -4927,14 +4939,16 @@ int SFTP_GetAttributesStat(WS_SFTP_FILEATRB* atr, WSTAT_T* stats) atr->flags |= WOLFSSH_FILEATRB_PERM; if ((stats->fattrib & SYS_FS_ATTR_DIR) & SYS_FS_ATTR_MASK) { atr->per |= 0x41ED; /* 755 with directory */ - } else { + } + else { atr->per |= 0x8000; } /* check for read only */ if ((stats->fattrib & SYS_FS_ATTR_RDO) & SYS_FS_ATTR_MASK) { atr->per |= 0x124; /* octal 444 */ - } else { + } + else { atr->per |= 0x1ED; /* octal 755 */ } @@ -4955,14 +4969,33 @@ int SFTP_GetAttributesStat(WS_SFTP_FILEATRB* atr, WSTAT_T* stats) static int SFTP_GetAttributesHelper(WS_SFTP_FILEATRB* atr, const char* fName) { WSTAT_T stats; - + SYS_FS_RESULT res; + char buffer[255]; + + WMEMSET(&stats, 0, sizeof(WSTAT_T)); + WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB)); + + res = SYS_FS_CurrentDriveGet(buffer); + if (res == SYS_FS_RES_SUCCESS) { + if (WSTRCMP(fName, buffer) == 0) { + atr->flags |= WOLFSSH_FILEATRB_PERM; + atr->per |= 0x41ED; /* 755 with directory */ + atr->per |= 0x1ED; /* octal 755 */ + + atr->flags |= WOLFSSH_FILEATRB_SIZE; + atr->sz[0] = 0; + atr->sz[1] = 0; + + atr->mtime = 30912; + WLOG(WS_LOG_SFTP, "Setting mount point as directory"); + return WS_SUCCESS; + } + } + if (WSTAT(ssh->fs, fName, &stats) != 0) { WLOG(WS_LOG_SFTP, "Issue with WSTAT call"); return WS_BAD_FILE_E; } - - WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB)); - return SFTP_GetAttributesStat(atr, &stats); } @@ -5303,6 +5336,9 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz) ret = WS_FATAL_ERROR; } + + WLOG(WS_LOG_SFTP, "SFTP default path = %s name after get and clean = %s", + ssh->sftpDefaultPath, name); /* try to get file attributes and send back to client */ if (ret == WS_SUCCESS) { WMEMSET((byte*)&atr, 0, sizeof(WS_SFTP_FILEATRB)); diff --git a/wolfssh/port.h b/wolfssh/port.h index 41213d12..c0e2d4f5 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -403,13 +403,11 @@ extern "C" { WOLFSSH_API int wfopen(WFILE* f, const char* filenmae, SYS_FS_FILE_OPEN_ATTRIBUTES mode); - //int z_fs_chdir(const char *path); - /* Use wolfCrypt z_fs_open and z_fs_close */ #define WFOPEN(fs,f,fn,m) wfopen(*(f),(fn),(m)) #define WFCLOSE(fs,f) SYS_FS_FileClose(*(f)) #define WFREAD(fs,b,s,a,f) SYS_FS_FileRead(*(f),(b),(s)*(a)) - #define WFWRITE(fs,b,s,a,f) SYS_FS_FileWrite(*(f),(b),(s)) + #define WFWRITE(fs,b,s,a,f) SYS_FS_FileWrite(*(f),(b),(s)*(a)) #define WFSEEK(fs,s,o,w) SYS_FS_FileSeek(*(s),(o),(w)) #define WFTELL(fs,s) SYS_FS_FileTell(*(s)) #define WREWIND(fs,s) SYS_FS_FileSeek(*(s), 0, SYS_FS_SEEK_SET) @@ -1364,7 +1362,6 @@ extern "C" { #elif defined(MICROCHIP_MPLAB_HARMONY) - #define WDIR SYS_FS_HANDLE #define WSTAT_T SYS_FS_FSTAT