source: azure_iot_hub/trunk/ntshell/src/io_stub.c@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 14.2 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 * @(#) $Id: io_stub.c 388 2019-05-22 11:25:18Z coas-nagasima $
51 */
52#include "shellif.h"
53#include <stdint.h>
54#include "ff.h"
55#include <kernel.h>
56#include <t_syslog.h>
57#include <t_stdlib.h>
58#include <sil.h>
59#include <string.h>
60#include "syssvc/serial.h"
61#include "syssvc/syslog.h"
62#include "fdtable.h"
63#include "util/ntstdio.h"
64#include "usrcmd.h"
65#include "core/ntlibc.h"
66#include "kernel_cfg.h"
67#include "target_syssvc.h"
68
69struct SHELL_DIR {
70 FATFS_DIR dir;
71 struct dirent dirent;
72};
73
74int fresult2errno(FRESULT res)
75{
76 switch (res) {
77 case FR_INVALID_OBJECT:
78 return -EINVAL;
79 case FR_TOO_MANY_OPEN_FILES:
80 return -ENOMEM;
81 case FR_NO_FILE:
82 case FR_NO_PATH:
83 case FR_INVALID_DRIVE:
84 case FR_INVALID_NAME:
85 return -ENOENT;
86 case FR_DISK_ERR:
87 case FR_NO_FILESYSTEM:
88 case FR_NOT_ENABLED:
89 return -ENODEV;
90 case FR_WRITE_PROTECTED:
91 case FR_DENIED:
92 return -EACCES;
93 case FR_EXIST:
94 return -EEXIST;
95 case FR_INT_ERR:
96 default:
97 return -EIO;
98 }
99}
100
101static int file_close(struct SHELL_FILE *fp);
102static size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
103static size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
104static off_t file_seek(struct SHELL_FILE *fp, off_t ofs, int org);
105static int file_ioctl(struct SHELL_FILE *fp, int req, void *arg);
106static bool_t file_readable(struct SHELL_FILE *fp);
107static bool_t file_writable(struct SHELL_FILE *fp);
108static void file_delete(struct SHELL_FILE *fp);
109
110static int dir_close(struct SHELL_FILE *fp);
111static size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
112static size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
113static off_t dir_seek(struct SHELL_FILE *fp, off_t ofs, int org);
114static int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg);
115static bool_t dir_readable(struct SHELL_FILE *fp);
116static bool_t dir_writable(struct SHELL_FILE *fp);
117static void dir_delete(struct SHELL_FILE *fp);
118
119IO_TYPE IO_TYPE_FILE = { file_close, file_read, file_write, file_seek, file_ioctl, file_readable, file_writable, file_delete };
120IO_TYPE IO_TYPE_DIR = { dir_close, dir_read, dir_write, dir_seek, dir_ioctl, dir_readable, dir_writable, dir_delete };
121
122int shell_open(const char *path, int flags, void *arg)
123{
124 FRESULT res;
125 struct SHELL_FILE *fp;
126
127 if (flags & O_DIRECTORY) {
128 fp = new_fp(&IO_TYPE_DIR, 0, 0);
129 if (fp == NULL)
130 return -ENOMEM;
131
132 fp->exinf = malloc(sizeof(struct SHELL_DIR));
133 memset(fp->exinf, 0, sizeof(struct SHELL_DIR));
134
135 FATFS_DIR *dir = &((struct SHELL_DIR *)fp->exinf)->dir;
136 FRESULT res;
137 if ((res = f_opendir(dir, path)) != FR_OK) {
138 delete_fp(fp);
139 return fresult2errno(res);
140 }
141 return 0;
142 }
143
144 fp = new_fp(&IO_TYPE_FILE, 0, 1);
145 if (fp == NULL)
146 return -ENOMEM;
147
148 fp->exinf = malloc(sizeof(FIL));
149 memset(fp->exinf, 0, sizeof(FIL));
150
151 BYTE fmd = 0;
152 switch (flags & O_ACCMODE) {
153 case O_RDONLY:
154 fmd = FA_READ;
155 break;
156 case O_WRONLY:
157 fmd = FA_WRITE;
158 break;
159 default:
160 fmd = FA_READ | FA_WRITE;
161 break;
162 }
163 /* ファイルを作成 */
164 if (flags & O_CREAT) {
165 /* 既存の内
166容は消す */
167 if (flags & O_TRUNC) {
168 fmd |= FA_CREATE_ALWAYS;
169 }
170 /* 新規作成の保障 */
171 else if (flags & O_EXCL) {
172 fmd |= FA_CREATE_NEW;
173 }
174 else {
175 fmd |= FA_OPEN_ALWAYS;
176 }
177 }
178 /* ある場合は開く */
179 else {
180 /* 既存の内
181容は消す */
182 if (flags & O_TRUNC) {
183 fmd |= FA_CREATE_ALWAYS;
184 }
185 }
186
187 if ((res = f_open((FIL *)fp->exinf, path, fmd)) == FR_OK) {
188 fp->handle = fp->fd;
189 return fp->fd;
190 }
191
192 delete_fp(fp);
193 return fresult2errno(res);
194}
195
196int file_close(struct SHELL_FILE *fp)
197{
198 FRESULT res;
199
200 if ((res = f_close((FIL *)fp->exinf)) == FR_OK) {
201 return 0;
202 }
203
204 return -EINVAL;
205}
206
207size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
208{
209 unsigned int ret = 0;
210 FRESULT res;
211
212 if ((res = f_read((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
213 return -EIO;
214
215 return ret;
216}
217
218size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
219{
220 unsigned int ret = 0;
221 FRESULT res;
222
223 if ((res = f_write((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
224 return -EIO;
225
226 return ret;
227}
228
229off_t file_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
230{
231 switch (dir) {
232 case SEEK_SET:
233 dir = F_SEEK_SET;
234 break;
235 case SEEK_CUR:
236 dir = F_SEEK_CUR;
237 break;
238 case SEEK_END:
239 dir = F_SEEK_END;
240 break;
241 default:
242 return -EINVAL;
243 }
244
245 FRESULT res;
246 if ((res = f_seek((FIL *)fp->exinf, ptr, dir)) != FR_OK)
247 return -EIO;
248
249 return ((FIL *)fp->exinf)->fptr;
250}
251
252int file_ioctl(struct SHELL_FILE *fp, int req, void *arg)
253{
254 DRESULT res;
255
256 if ((res = disk_ioctl(((FIL *)fp->exinf)->fs->drv, req, arg) != RES_OK))
257 return -EINVAL;
258
259 return 0;
260}
261
262bool_t file_readable(struct SHELL_FILE *fp)
263{
264 return fp->readevt_w != fp->readevt_r;
265}
266
267bool_t file_writable(struct SHELL_FILE *fp)
268{
269 return fp->writable && (fp->writeevt_w == fp->writeevt_r);
270}
271
272void file_delete(struct SHELL_FILE *fp)
273{
274 free((FIL *)fp->exinf);
275 fp->exinf = NULL;
276}
277
278int shell_close(int fd)
279{
280 struct SHELL_FILE *fp = fd_to_fp(fd);
281 if (fp == NULL)
282 return -EBADF;
283
284 int ret = fp->type->close(fp);
285
286 delete_fp(fp);
287
288 return ret;
289}
290
291ssize_t shell_read(int fd, void *data, size_t len)
292{
293 struct SHELL_FILE *fp = fd_to_fp(fd);
294 if (fp == NULL)
295 return -EBADF;
296
297 return fp->type->read(fp, (unsigned char *)data, len);
298}
299
300int shell_readv(int fd, const struct iovec *iov, int iovcnt)
301{
302 int result = 0;
303 struct SHELL_FILE *fp = fd_to_fp(fd);
304 if (fp == NULL)
305 return -EBADF;
306
307 const struct iovec *end = &iov[iovcnt];
308 for (; iov < end; iov++) {
309 result += fp->type->read(fp, (unsigned char *)iov->iov_base, iov->iov_len);
310 }
311
312 return result;
313}
314
315ssize_t shell_write(int fd, const void *data, size_t len)
316{
317 struct SHELL_FILE *fp = fd_to_fp(fd);
318 if (fp == NULL)
319 return -EBADF;
320
321 return fp->type->write(fp, (unsigned char *)data, len);
322}
323
324int shell_writev(int fd, const struct iovec *iov, int iovcnt)
325{
326 int result = 0;
327 struct SHELL_FILE *fp = fd_to_fp(fd);
328 if (fp == NULL)
329 return -EBADF;
330
331 const struct iovec *end = &iov[iovcnt];
332 for (; iov < end; iov++) {
333 result += fp->type->write(fp, (unsigned char *)iov->iov_base, iov->iov_len);
334 }
335
336 return result;
337}
338
339int shell_llseek(int fd, off_t ptr, off_t *result, int dir)
340{
341 struct SHELL_FILE *fp = fd_to_fp(fd);
342 if (fp == NULL)
343 return -EBADF;
344
345 off_t ret = fp->type->seek(fp, ptr, dir);
346 if (ret < 0)
347 return ret;
348
349 *result = ret;
350 return 0;
351}
352
353int shell_fstat(int fd, struct stat * st)
354{
355 struct SHELL_FILE *fp = fd_to_fp(fd);
356 if (fp == NULL)
357 return -EBADF;
358
359 memset(st, 0, sizeof(*st));
360 st->st_mode = S_IFCHR;
361 //st->st_blksize = 1024;
362 return 0;
363}
364
365int shell_fsync(int fd)
366{
367 struct SHELL_FILE *fp = fd_to_fp(fd);
368 if (fp == NULL)
369 return -EBADF;
370 return -EIO;
371}
372
373int shell_ftruncate(int fd, off_t length)
374{
375 struct SHELL_FILE *fp = fd_to_fp(fd);
376 if (fp == NULL)
377 return -EBADF;
378
379 FRESULT res;
380 if ((res = f_truncate((FIL *)fp->exinf)) != FR_OK)
381 return fresult2errno(res);
382
383 return 0;
384}
385
386int shell_fcntl(int fd, int cmd, void *arg)
387{
388 return shell_ioctl(fd, cmd, arg);
389}
390
391int shell_stat(const char *__restrict path, struct stat *__restrict st)
392{
393 FILINFO fi;
394 FRESULT ret;
395#if FF_USE_LFN
396 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
397 fi.lfname = lfn;
398 fi.lfsize = sizeof lfn;
399#endif
400 if (strcmp(path, ".") == 0) {
401 char cwd[FF_MAX_LFN];
402 if ((ret = f_getcwd(cwd, sizeof(cwd))) != FR_OK) {
403 return fresult2errno(ret);
404 }
405 int l = strlen(cwd);
406 // ルートディレクトリの場合
407 if (cwd[l - 2] == ':' && cwd[l - 1] == '/') {
408 st->st_size = 0;
409 st->st_mtim.tv_nsec = 0;
410 st->st_mtim.tv_sec = 0;
411 st->st_mode = S_IFDIR;
412 return 0;
413 }
414 if ((ret = f_stat(cwd, &fi)) != FR_OK) {
415 return fresult2errno(ret);
416 }
417 }
418 else if ((ret = f_stat(path, &fi)) != FR_OK) {
419 return fresult2errno(ret);
420 }
421
422 st->st_size = fi.fsize;
423 st->st_mtim.tv_nsec = 0;
424 st->st_mtim.tv_sec = fi.fdate + fi.ftime;
425 st->st_mode = (S_IRUSR | S_IRGRP | S_IROTH);
426 st->st_mode |= (fi.fattrib & AM_RDO) ? 0 : (S_IWUSR | S_IWGRP | S_IWOTH);
427 st->st_mode |= (fi.fattrib & (AM_DIR | AM_VOL)) ? S_IFDIR : S_IFREG;
428
429 return 0;
430}
431
432int shell_lstat(const char *__restrict path, struct stat *__restrict st)
433{
434 return shell_stat(path, st);
435}
436
437int shell_link(const char *a, const char *b)
438{
439 return -EPERM;
440}
441
442int shell_unlink(const char *path)
443{
444 FRESULT res;
445
446 if ((res = f_unlink(path)) != FR_OK)
447 return -EIO;
448
449 return 0;
450}
451
452int shell_rmdir(const char *path)
453{
454 FRESULT res;
455
456 if ((res = f_unlink(path)) != FR_OK)
457 return -EIO;
458
459 return 0;
460}
461
462int shell_rename(const char *oldpath, const char *newpath)
463{
464 FRESULT res;
465
466 if ((res = f_rename(oldpath, newpath)) != FR_OK)
467 return fresult2errno(res);
468 return 0;
469}
470
471#define S_IREAD S_IRUSR
472#define S_IWRITE S_IWUSR
473
474int shell_mkdir(const char *path, mode_t mode)
475{
476 FRESULT res;
477
478 if ((res = f_mkdir(path)) != FR_OK)
479 return fresult2errno(res);
480
481 BYTE attr = 0;
482 BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
483
484 if (mode & S_IREAD) {
485 if ((mode & S_IWRITE) == 0) {
486 attr |= AM_RDO;
487 }
488 }
489 else {
490 attr |= AM_SYS;
491 }
492
493 if ((res = f_chmod(path, attr, mask)) != FR_OK) {
494 return fresult2errno(res);
495 }
496
497 return 0;
498}
499
500int shell_chmod(const char *path, mode_t mode)
501{
502 FRESULT res;
503 BYTE attr = 0;
504 BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
505
506 if (mode & S_IREAD) {
507 if ((mode & S_IWRITE) == 0) {
508 attr |= AM_RDO;
509 }
510 }
511 else {
512 attr |= AM_SYS;
513 }
514
515 if ((res = f_chmod(path, attr, mask)) != FR_OK) {
516 return fresult2errno(res);
517 }
518
519 return 0;
520}
521
522char *shell_getcwd(char *buf, size_t size)
523{
524 FRESULT ret;
525 if ((ret = f_getcwd(buf, size)) != FR_OK) {
526 return NULL;
527 }
528
529 return buf;
530}
531
532int shell_chdir(const char *path)
533{
534 FRESULT res;
535 if ((res = f_chdir(path)) != FR_OK) {
536 return fresult2errno(res);
537 }
538
539 return 0;
540}
541
542int shell_chroot(const char *path)
543{
544 shell_abort();
545 return -EPERM;
546}
547
548int dir_close(struct SHELL_FILE *fp)
549{
550 FRESULT res;
551 if ((res = f_closedir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
552 return fresult2errno(res);
553 }
554
555 return 0;
556}
557
558int shell_getdents(int fd, struct dirent *de, size_t len)
559{
560 if (len < sizeof(struct dirent))
561 return -EINVAL;
562
563 struct SHELL_FILE *fp = fd_to_fp(fd);
564 if (fp == NULL)
565 return -EBADF;
566
567 FILINFO fno;
568#if FF_USE_LFN
569 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
570 fno.lfname = lfn;
571 fno.lfsize = sizeof lfn;
572#endif
573 FRESULT res;
574 if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
575 return fresult2errno(res);
576 }
577
578 memset(de, 0, sizeof(*de));
579#if FF_USE_LFN
580 ntlibc_strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name));
581#else
582 ntlibc_strlcpy(de->d_name, fno.fname, sizeof(de->d_name));
583#endif
584
585 return 0;
586}
587
588size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
589{
590 return -EPERM;
591}
592
593size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
594{
595 return -EPERM;
596}
597
598off_t dir_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
599{
600 FRESULT res;
601
602 if (dir != SEEK_SET)
603 return -EINVAL;
604
605 if (ptr == 0) {
606 if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
607 return fresult2errno(res);
608 }
609 }
610 else {
611 FILINFO fno;
612#if FF_USE_LFN
613 static char lfn[FF_MAX_LFN + 1]; /* Buffer to store the LFN */
614 fno.lfname = lfn;
615 fno.lfsize = sizeof lfn;
616#endif
617 if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
618 return fresult2errno(res);
619 }
620
621 for (int i = 0; i < ptr; i++) {
622 if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
623 return fresult2errno(res);
624 }
625 }
626 }
627
628 return ptr;
629}
630
631int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg)
632{
633 return -EINVAL;
634}
635
636bool_t dir_readable(struct SHELL_FILE *fp)
637{
638 return fp->readevt_w != fp->readevt_r;
639}
640
641bool_t dir_writable(struct SHELL_FILE *fp)
642{
643 return false;
644}
645
646void dir_delete(struct SHELL_FILE *fp)
647{
648 free((struct SHELL_DIR *)fp->exinf);
649 fp->exinf = NULL;
650}
651
652pid_t shell_getpid(void)
653{
654 return 1;
655}
656
657int shell_access(const char *path, int mode)
658{
659 struct stat st;
660 int ret;
661
662 ret = shell_stat(path, &st);
663 if (ret != 0)
664 return ret;
665
666 return 0;
667}
Note: See TracBrowser for help on using the repository browser.