mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-24 11:54:49 +00:00
CL: wifi: CC3220: Enterprise auth support PUBLISHED_FROM=ce445eb5b740073c9a3f9811f1acd404ce134f2e
303 lines
8.3 KiB
C
303 lines
8.3 KiB
C
/*
|
|
* Copyright (c) 2014-2018 Cesanta Software Limited
|
|
* All rights reserved
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the ""License"");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an ""AS IS"" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/* Standard libc interface to TI SimpleLink FS. */
|
|
|
|
#if defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS)
|
|
|
|
#include "common/platforms/simplelink/sl_fs_slfs.h"
|
|
|
|
#include <errno.h>
|
|
|
|
#if CS_PLATFORM == CS_P_CC3200
|
|
#include <inc/hw_types.h>
|
|
#endif
|
|
|
|
#include "common/cs_dbg.h"
|
|
#include "common/mg_mem.h"
|
|
|
|
#if SL_MAJOR_VERSION_NUM < 2
|
|
int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token) {
|
|
_i32 fh;
|
|
_i32 r = sl_FsOpen(fname, flags, (unsigned long *) token, &fh);
|
|
return (r < 0 ? r : fh);
|
|
}
|
|
#else /* SL_MAJOR_VERSION_NUM >= 2 */
|
|
int slfs_open(const unsigned char *fname, uint32_t flags, uint32_t *token) {
|
|
return sl_FsOpen(fname, flags, (unsigned long *) token);
|
|
}
|
|
#endif
|
|
|
|
/* From sl_fs.c */
|
|
int set_errno(int e);
|
|
const char *drop_dir(const char *fname, bool *is_slfs);
|
|
|
|
/*
|
|
* With SLFS, you have to pre-declare max file size. Yes. Really.
|
|
* 64K should be enough for everyone. Right?
|
|
*/
|
|
#ifndef FS_SLFS_MAX_FILE_SIZE
|
|
#define FS_SLFS_MAX_FILE_SIZE (64 * 1024)
|
|
#endif
|
|
|
|
struct sl_file_open_info {
|
|
char *name;
|
|
size_t size;
|
|
uint32_t flags;
|
|
uint32_t *token;
|
|
};
|
|
|
|
struct sl_fd_info {
|
|
_i32 fh;
|
|
_off_t pos;
|
|
size_t size;
|
|
};
|
|
|
|
static struct sl_fd_info s_sl_fds[MAX_OPEN_SLFS_FILES];
|
|
static struct sl_file_open_info s_sl_file_open_infos[MAX_OPEN_SLFS_FILES];
|
|
|
|
static struct sl_file_open_info *fs_slfs_find_foi(const char *name,
|
|
bool create);
|
|
|
|
static int sl_fs_to_errno(_i32 r) {
|
|
DBG(("SL error: %d", (int) r));
|
|
switch (r) {
|
|
case SL_FS_OK:
|
|
return 0;
|
|
case SL_ERROR_FS_FILE_NAME_EXIST:
|
|
return EEXIST;
|
|
case SL_ERROR_FS_WRONG_FILE_NAME:
|
|
return EINVAL;
|
|
case SL_ERROR_FS_NO_AVAILABLE_NV_INDEX:
|
|
case SL_ERROR_FS_NOT_ENOUGH_STORAGE_SPACE:
|
|
return ENOSPC;
|
|
case SL_ERROR_FS_FAILED_TO_ALLOCATE_MEM:
|
|
return ENOMEM;
|
|
case SL_ERROR_FS_FILE_NOT_EXISTS:
|
|
return ENOENT;
|
|
case SL_ERROR_FS_NOT_SUPPORTED:
|
|
return ENOTSUP;
|
|
}
|
|
return ENXIO;
|
|
}
|
|
|
|
int fs_slfs_open(const char *pathname, int flags, mode_t mode) {
|
|
int fd;
|
|
for (fd = 0; fd < MAX_OPEN_SLFS_FILES; fd++) {
|
|
if (s_sl_fds[fd].fh <= 0) break;
|
|
}
|
|
if (fd >= MAX_OPEN_SLFS_FILES) return set_errno(ENOMEM);
|
|
struct sl_fd_info *fi = &s_sl_fds[fd];
|
|
|
|
/*
|
|
* Apply path manipulations again, in case we got here directly
|
|
* (via TI libc's "add_device").
|
|
*/
|
|
pathname = drop_dir(pathname, NULL);
|
|
|
|
_u32 am = 0;
|
|
fi->size = (size_t) -1;
|
|
int rw = (flags & 3);
|
|
size_t new_size = 0;
|
|
struct sl_file_open_info *foi =
|
|
fs_slfs_find_foi(pathname, false /* create */);
|
|
if (foi != NULL) {
|
|
LOG(LL_DEBUG, ("FOI for %s: %d 0x%x %p", pathname, (int) foi->size,
|
|
(unsigned int) foi->flags, foi->token));
|
|
}
|
|
if (rw == O_RDONLY) {
|
|
SlFsFileInfo_t sl_fi;
|
|
_i32 r = sl_FsGetInfo((const _u8 *) pathname, 0, &sl_fi);
|
|
if (r == SL_FS_OK) {
|
|
fi->size = SL_FI_FILE_SIZE(sl_fi);
|
|
}
|
|
am = SL_FS_READ;
|
|
} else {
|
|
if (!(flags & O_TRUNC) || (flags & O_APPEND)) {
|
|
// FailFS files cannot be opened for append and will be truncated
|
|
// when opened for write.
|
|
return set_errno(ENOTSUP);
|
|
}
|
|
if (flags & O_CREAT) {
|
|
if (foi->size > 0) {
|
|
new_size = foi->size;
|
|
} else {
|
|
new_size = FS_SLFS_MAX_FILE_SIZE;
|
|
}
|
|
am = FS_MODE_OPEN_CREATE(new_size, 0);
|
|
} else {
|
|
am = SL_FS_WRITE;
|
|
}
|
|
#if SL_MAJOR_VERSION_NUM >= 2
|
|
am |= SL_FS_OVERWRITE;
|
|
#endif
|
|
}
|
|
uint32_t *token = NULL;
|
|
if (foi != NULL) {
|
|
am |= foi->flags;
|
|
token = foi->token;
|
|
}
|
|
fi->fh = slfs_open((_u8 *) pathname, am, token);
|
|
LOG(LL_DEBUG, ("sl_FsOpen(%s, 0x%x, %p) sz %u = %d", pathname, (int) am,
|
|
token, (unsigned int) new_size, (int) fi->fh));
|
|
int r;
|
|
if (fi->fh >= 0) {
|
|
fi->pos = 0;
|
|
r = fd;
|
|
} else {
|
|
r = set_errno(sl_fs_to_errno(fi->fh));
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int fs_slfs_close(int fd) {
|
|
struct sl_fd_info *fi = &s_sl_fds[fd];
|
|
if (fi->fh <= 0) return set_errno(EBADF);
|
|
_i32 r = sl_FsClose(fi->fh, NULL, NULL, 0);
|
|
LOG(LL_DEBUG, ("sl_FsClose(%d) = %d", (int) fi->fh, (int) r));
|
|
s_sl_fds[fd].fh = -1;
|
|
return set_errno(sl_fs_to_errno(r));
|
|
}
|
|
|
|
ssize_t fs_slfs_read(int fd, void *buf, size_t count) {
|
|
struct sl_fd_info *fi = &s_sl_fds[fd];
|
|
if (fi->fh <= 0) return set_errno(EBADF);
|
|
/* Simulate EOF. sl_FsRead @ file_size return SL_FS_ERR_OFFSET_OUT_OF_RANGE.
|
|
*/
|
|
if (fi->pos == fi->size) return 0;
|
|
_i32 r = sl_FsRead(fi->fh, fi->pos, buf, count);
|
|
DBG(("sl_FsRead(%d, %d, %d) = %d", (int) fi->fh, (int) fi->pos, (int) count,
|
|
(int) r));
|
|
if (r >= 0) {
|
|
fi->pos += r;
|
|
return r;
|
|
}
|
|
return set_errno(sl_fs_to_errno(r));
|
|
}
|
|
|
|
ssize_t fs_slfs_write(int fd, const void *buf, size_t count) {
|
|
struct sl_fd_info *fi = &s_sl_fds[fd];
|
|
if (fi->fh <= 0) return set_errno(EBADF);
|
|
_i32 r = sl_FsWrite(fi->fh, fi->pos, (_u8 *) buf, count);
|
|
DBG(("sl_FsWrite(%d, %d, %d) = %d", (int) fi->fh, (int) fi->pos, (int) count,
|
|
(int) r));
|
|
if (r >= 0) {
|
|
fi->pos += r;
|
|
return r;
|
|
}
|
|
return set_errno(sl_fs_to_errno(r));
|
|
}
|
|
|
|
int fs_slfs_stat(const char *pathname, struct stat *s) {
|
|
SlFsFileInfo_t sl_fi;
|
|
/*
|
|
* Apply path manipulations again, in case we got here directly
|
|
* (via TI libc's "add_device").
|
|
*/
|
|
pathname = drop_dir(pathname, NULL);
|
|
_i32 r = sl_FsGetInfo((const _u8 *) pathname, 0, &sl_fi);
|
|
if (r == SL_FS_OK) {
|
|
s->st_mode = S_IFREG | 0666;
|
|
s->st_nlink = 1;
|
|
s->st_size = SL_FI_FILE_SIZE(sl_fi);
|
|
return 0;
|
|
}
|
|
return set_errno(sl_fs_to_errno(r));
|
|
}
|
|
|
|
int fs_slfs_fstat(int fd, struct stat *s) {
|
|
struct sl_fd_info *fi = &s_sl_fds[fd];
|
|
if (fi->fh <= 0) return set_errno(EBADF);
|
|
s->st_mode = 0666;
|
|
s->st_mode = S_IFREG | 0666;
|
|
s->st_nlink = 1;
|
|
s->st_size = fi->size;
|
|
return 0;
|
|
}
|
|
|
|
off_t fs_slfs_lseek(int fd, off_t offset, int whence) {
|
|
if (s_sl_fds[fd].fh <= 0) return set_errno(EBADF);
|
|
switch (whence) {
|
|
case SEEK_SET:
|
|
s_sl_fds[fd].pos = offset;
|
|
break;
|
|
case SEEK_CUR:
|
|
s_sl_fds[fd].pos += offset;
|
|
break;
|
|
case SEEK_END:
|
|
return set_errno(ENOTSUP);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int fs_slfs_unlink(const char *pathname) {
|
|
/*
|
|
* Apply path manipulations again, in case we got here directly
|
|
* (via TI libc's "add_device").
|
|
*/
|
|
pathname = drop_dir(pathname, NULL);
|
|
return set_errno(sl_fs_to_errno(sl_FsDel((const _u8 *) pathname, 0)));
|
|
}
|
|
|
|
int fs_slfs_rename(const char *from, const char *to) {
|
|
return set_errno(ENOTSUP);
|
|
}
|
|
|
|
static struct sl_file_open_info *fs_slfs_find_foi(const char *name,
|
|
bool create) {
|
|
int i = 0;
|
|
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) {
|
|
if (s_sl_file_open_infos[i].name != NULL &&
|
|
strcmp(drop_dir(s_sl_file_open_infos[i].name, NULL), name) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (i != MAX_OPEN_SLFS_FILES) return &s_sl_file_open_infos[i];
|
|
if (!create) return NULL;
|
|
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) {
|
|
if (s_sl_file_open_infos[i].name == NULL) break;
|
|
}
|
|
if (i == MAX_OPEN_SLFS_FILES) {
|
|
i = 0; /* Evict a random slot. */
|
|
}
|
|
if (s_sl_file_open_infos[i].name != NULL) {
|
|
free(s_sl_file_open_infos[i].name);
|
|
}
|
|
s_sl_file_open_infos[i].name = strdup(name);
|
|
return &s_sl_file_open_infos[i];
|
|
}
|
|
|
|
void fs_slfs_set_file_size(const char *name, size_t size) {
|
|
struct sl_file_open_info *foi = fs_slfs_find_foi(name, true /* create */);
|
|
foi->size = size;
|
|
}
|
|
|
|
void fs_slfs_set_file_flags(const char *name, uint32_t flags, uint32_t *token) {
|
|
struct sl_file_open_info *foi = fs_slfs_find_foi(name, true /* create */);
|
|
foi->flags = flags;
|
|
foi->token = token;
|
|
}
|
|
|
|
void fs_slfs_unset_file_flags(const char *name) {
|
|
struct sl_file_open_info *foi = fs_slfs_find_foi(name, false /* create */);
|
|
if (foi == NULL) return;
|
|
free(foi->name);
|
|
memset(foi, 0, sizeof(*foi));
|
|
}
|
|
|
|
#endif /* defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS) */
|