Ignore:
Timestamp:
Apr 29, 2017, 4:33:37 PM (7 years ago)
Author:
coas-nagasima
Message:

ファイルを追加、更新。

Location:
EcnlProtoTool/trunk/prototool
Files:
62 added
8 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/prototool/src/arduino.c

    r278 r279  
    11#include <arduino.h>
    22#include <mruby.h>
     3#include <stdlib.h>
     4#include <stdio.h>
     5#include <fcntl.h>
    36#include "../llbruby.h"
    47
     
    1619i2c_t Wire5;
    1720
    18 FATFS RomDisk;
    19 SD Sd;
    20 
    2121char ExeFilename[64];
    2222
     
    2727void randomSeed(long seed)
    2828{
     29        srand(seed);
    2930}
    3031
    3132long arduino_random(long min, long max)
    3233{
    33         return min;
     34        return (long)(((double)rand() / (double)RAND_MAX) / ((double)max - (double)min)) + min;
    3435}
    3536
     
    223224int EEP_fopen(FILEEEP *fp, const char *str, char mode)
    224225{
    225         FRESULT ret;
    226         BYTE fm;
     226        int ret;
     227        int fm;
    227228
    228229        switch (mode){
    229230        case 0:
    230                 fm = FA_READ;
     231                fm = O_RDONLY;
    231232                break;
    232233        case 1:
    233                 fm = FA_READ | FA_WRITE | FA_CREATE_NEW;
     234                fm = O_RDWR | O_CREAT;
    234235                break;
    235236        case 2:
    236                 fm = FA_READ | FA_WRITE;
     237                fm = O_RDWR;
    237238                break;
    238239        default:
     
    240241        }
    241242
    242         ret = f_open(&fp->fp, str, fm);
    243 
    244         return (ret == FR_OK) ? 0 : -1;
     243        ret = open(str, fm);
     244        if (ret < 0) {
     245                fp->fd = 0;
     246                return -1;
     247        }
     248        fp->fd = ret;
     249
     250        return 0;
    245251}
    246252
    247253int EEP_fwrite(FILEEEP *fp, byte *data, int *len)
    248254{
    249         FRESULT ret;
    250 
    251         ret = f_write(&fp->fp, data, (UINT)*len, (UINT *)len);
    252 
    253         return (ret == FR_OK) ? 1 : -1;
     255        int ret;
     256
     257        ret = write(fp->fd, data, *len);
     258        if (ret < 0) {
     259                *len = 0;
     260                return -1;
     261        }
     262        *len = ret;
     263
     264        return 0;
    254265}
    255266
    256267int EEP_fread(FILEEEP *fp)
    257268{
    258         FRESULT ret;
     269        int ret;
    259270        char c;
    260         UINT br;
    261 
    262         ret = f_read(&fp->fp, &c, 1, &br);
    263         if (ret != FR_OK)
     271
     272        ret = read(fp->fd, &c, 1);
     273        if (ret < 0)
    264274                return -1;
    265275
     
    269279void EEP_fclose(FILEEEP *fp)
    270280{
    271         f_close(&fp->fp);
     281        close(fp->fd);
    272282}
    273283
    274284int EEP_fseek(FILEEEP *fp, int pos, int mode)
    275285{
    276         FRESULT ret;
     286        int ret;
    277287
    278288        switch (mode){
    279289        case EEP_SEEKTOP:
    280                 ret = f_lseek(&fp->fp, pos);
     290                ret = lseek(fp->fd, pos, SEEK_SET);
    281291                break;
    282292        case EEP_SEEKCUR:
    283                 ret = f_lseek(&fp->fp, fp->fp.fptr + pos);
     293                ret = lseek(fp->fd, pos, SEEK_CUR);
    284294                break;
    285295        case EEP_SEEKEND:
    286                 ret = f_lseek(&fp->fp, fp->fp.fsize - pos);
     296                ret = lseek(fp->fd, pos, SEEK_END);
    287297                break;
    288298        default:
    289                 ret = FR_INVALID_PARAMETER;
    290                 break;
    291         }
    292 
    293         if (ret != FR_OK)
    294                 f_lseek(&fp->fp, 0);
    295 
    296         return fp->fp.fptr;
     299                return -1;
     300                break;
     301        }
     302
     303        if (ret < 0)
     304                return false;
     305
     306        return true;
    297307}
    298308
    299309int EEP_ffilesize(const char *str)
    300310{
    301         FRESULT ret;
    302         FILINFO fno;
    303 
    304         ret = f_stat(str, &fno);
    305         if (ret != FR_OK)
     311        int ret;
     312        struct stat fno;
     313
     314        ret = stat(str, &fno);
     315        if (ret < 0)
    306316                return 0;
    307317
    308         return fno.fsize;
     318        return fno.st_size;
    309319}
    310320
    311321bool EEP_fEof(FILEEEP *fp)
    312322{
    313         return f_tell(&fp->fp) == f_size(&fp->fp);
     323        int ret, pos;
     324        struct stat fno;
     325
     326        ret = fstat(fp->fd, &fno);
     327        if (ret < 0)
     328                return false;
     329
     330        pos = lseek(fp->fd, 0, SEEK_CUR);
     331
     332        return pos == fno.st_size;
    314333}
    315334
    316335bool EEP_fexist(const char *path)
    317336{
    318         FRESULT ret;
    319         FILINFO fno;
    320 
    321         ret = f_stat(path, &fno);
    322 
    323         return (ret == FR_OK);
     337        int ret;
     338        struct stat fno;
     339
     340        ret = stat(path, &fno);
     341
     342        return (ret == 0);
    324343}
    325344
    326345bool EEP_fcopy(const char *src, const char *dst)
    327346{
    328         FIL fsrc, fdst;
    329         BYTE buffer[512];
    330         FRESULT res;
    331         UINT br, bw;
    332 
    333         res = f_open(&fsrc, src, FA_OPEN_EXISTING | FA_READ);
    334         if (res != FR_OK)
    335                 return false;
    336 
    337         res = f_open(&fdst, dst, FA_CREATE_ALWAYS | FA_WRITE);
    338         if (res != FR_OK){
    339                 f_close(&fsrc);
     347        int fsrc, fdst;
     348        unsigned char buffer[512];
     349        int res = true;
     350        int br, bw;
     351
     352        fsrc = open(src, O_RDONLY);
     353        if (fsrc < 0)
     354                return false;
     355
     356        fdst = open(dst, O_RDWR | O_CREAT);
     357        if (fdst < 0){
     358                close(fsrc);
    340359                return false;
    341360        }
    342361
    343362        for (;;) {
    344                 res = f_read(&fsrc, buffer, sizeof(buffer), &br);
    345                 if ((res != FR_OK) || br == 0)
     363                br = read(fsrc, buffer, sizeof(buffer));
     364                if (br < 0) {
     365                        res = false;
    346366                        break;
    347 
    348                 res = f_write(&fdst, buffer, br, &bw);
    349                 if ((res != FR_OK) || bw < br)
     367                }
     368                if (br == 0)
    350369                        break;
    351         }
    352 
    353         f_close(&fsrc);
    354         f_close(&fdst);
    355 
    356         return (res == FR_OK);
     370
     371                bw = write(fdst, buffer, br);
     372                if ((bw < 0) || bw < br) {
     373                        res = false;
     374                        break;
     375                }
     376        }
     377
     378        close(fsrc);
     379        close(fdst);
     380
     381        return res;
    357382}
    358383
    359384bool EEP_fdelete(const char *path)
    360385{
    361         FRESULT res;
    362 
    363         res = f_unlink(path);
    364 
    365         return (res == FR_OK);
    366 }
    367 
    368 bool SD_begin()
    369 {
    370         DSTATUS dst;
    371         FRESULT res;
    372         BYTE pdrv = 1, type;
    373 
    374         if (Sd.FatFs.fs_type != 0)
    375                 return true;
    376 
    377         if ((dst = disk_initialize(pdrv)) != RES_OK) {
    378                 return false;
    379         }
    380 
    381         if ((dst = disk_ioctl(pdrv, MMC_GET_TYPE, &type)) != RES_OK) {
    382                 Sd.dst = dst;
    383                 Sd.type = 0;
    384         }
    385         else {
    386                 Sd.dst = RES_OK;
    387                 Sd.type = type;
    388         }
    389 
    390         if ((res = f_mount(&Sd.FatFs, "1:", 1)) != FR_OK) {
    391                 return false;
    392         }
    393 
     386        int res;
     387
     388        res = unlink(path);
     389
     390        return (res == 0);
     391}
     392
     393bool SD_open(File *file, const char *path, int mode)
     394{
     395        int ret;
     396
     397        if (!SD_begin())
     398                return false;
     399
     400        ret = open(path, mode);
     401        if (ret < 0) {
     402                file->fd = 0;
     403                return false;
     404        }
     405
     406        file->fd = ret;
    394407        return true;
    395408}
    396409
    397 bool SD_open(File *file, const char *path, int mode)
    398 {
    399         FRESULT ret;
     410bool SD_rmdir(const char *path)
     411{
     412        int ret;
    400413
    401414        if (!SD_begin())
    402415                return false;
    403416
    404         ret = f_open(&file->fp, path, mode);
    405 
    406         return ret == FR_OK;
    407 }
    408 
    409 bool SD_rmdir(const char *path)
    410 {
    411         FRESULT ret;
     417        ret = rmdir(path);
     418
     419        return ret == 0;
     420}
     421
     422bool SD_rename(const char *path1, const char *path2)
     423{
     424        int ret;
    412425
    413426        if (!SD_begin())
    414427                return false;
    415428
    416         ret = f_unlink(path);
    417 
    418         return ret == FR_OK;
    419 }
    420 
    421 bool SD_rename(const char *path1, const char *path2)
    422 {
    423         FRESULT ret;
     429        ret = rename(path1, path2);
     430       
     431        return ret == 0;
     432}
     433
     434bool SD_remove(const char *path)
     435{
     436        int ret;
    424437
    425438        if (!SD_begin())
    426439                return false;
    427440
    428         ret = f_rename(path1, path2);
    429        
    430         return ret == FR_OK;
    431 }
    432 
    433 bool SD_remove(const char *path)
    434 {
    435         FRESULT ret;
     441        ret = unlink(path);
     442
     443        return ret == 0;
     444}
     445
     446bool SD_exists(const char *path)
     447{
     448        int ret;
     449        struct stat fno;
    436450
    437451        if (!SD_begin())
    438452                return false;
    439453
    440         ret = f_unlink(path);
    441 
    442         return ret == FR_OK;
    443 }
    444 
    445 bool SD_exists(const char *path)
    446 {
    447         FRESULT ret;
    448         FILINFO fno;
     454        ret = stat(path, &fno);
     455
     456        return ret == 0;
     457}
     458
     459bool SD_mkdir(const char *path)
     460{
     461        int ret;
    449462
    450463        if (!SD_begin())
    451464                return false;
    452465
    453         ret = f_stat(path, &fno);
    454 
    455         return ret == FR_OK;
    456 }
    457 
    458 bool SD_mkdir(const char *path)
    459 {
    460         FRESULT ret;
    461 
    462         if (!SD_begin())
    463                 return false;
    464 
    465         ret = f_mkdir(path);
    466 
    467         return ret == FR_OK;
    468 }
    469 
    470 int file_write(File *fd, unsigned char *str, int len)
    471 {
    472         FRESULT ret;
    473         UINT bw;
    474 
    475         ret = f_write(&fd->fp, str, len, &bw);
    476         if (ret != FR_OK)
    477                 return -1;
    478 
    479         return bw;
    480 }
    481 
    482 void file_close(File *fd)
    483 {
    484         f_close(&fd->fp);
    485 }
    486 
    487 int file_size(File *fd)
    488 {
    489         return f_size(&fd->fp);
    490 }
    491 
    492 int file_position(File *fd)
    493 {
    494         return fd->fp.fptr;
    495 }
    496 
    497 void file_flush(File *fd)
    498 {
    499         f_flush(&fd->fp);
    500 }
    501 
    502 bool file_seek(File *fd, int pos)
    503 {
    504         FRESULT ret;
    505 
    506         ret = f_lseek(&fd->fp, pos);
    507 
    508         return ret != FR_OK;
    509 }
    510 
    511 int file_read(File *fd)
    512 {
    513         FRESULT ret;
     466        ret = mkdir(path, 0777);
     467
     468        return ret == 0;
     469}
     470
     471int file_write(File *fp, unsigned char *str, int len)
     472{
     473        int ret;
     474
     475        ret = write(fp->fd, str, len);
     476        if (ret < 0)
     477                return -1;
     478
     479        return ret;
     480}
     481
     482void file_close(File *fp)
     483{
     484        close(fp->fd);
     485}
     486
     487int file_size(File *fp)
     488{
     489        int ret;
     490        struct stat fno;
     491
     492        ret = fstat(fp->fd, &fno);
     493        if (ret < 0)
     494                return -1;
     495
     496        return fno.st_size;
     497}
     498
     499int file_position(File *fp)
     500{
     501        int ret;
     502        struct stat fno;
     503
     504        ret = lseek(fp->fd, 0, SEEK_CUR);
     505        if (ret < 0)
     506                return -1;
     507
     508        return ret;
     509}
     510
     511void file_flush(File *fp)
     512{
     513        fsync(fp->fd);
     514}
     515
     516bool file_seek(File *fp, int pos)
     517{
     518        int ret;
     519
     520        ret = lseek(fp->fd, pos, SEEK_SET);
     521
     522        return ret == 0;
     523}
     524
     525int file_read(File *fp)
     526{
     527        int ret;
    514528        char c;
    515         UINT br;
    516 
    517         ret = f_read(&fd->fp, &c, 1, &br);
    518         if (ret != FR_OK)
     529
     530        ret = read(fp->fd, &c, 1);
     531        if (ret < 0)
    519532                return -1;
    520533
     
    524537void system_reboot(int mode)
    525538{
    526 
     539        exit(mode);
    527540}
    528541
     
    531544        return 0;
    532545}
    533 
    534 DWORD get_fattime(void)
    535 {
    536         time_t temp;
    537         struct tm _tm;
    538 
    539         time(&temp);
    540         gmtime_r(&temp, &_tm);
    541 
    542         return    ((DWORD)(_tm.tm_year - 1980) << 25)
    543                 | ((DWORD)_tm.tm_mon << 21)
    544                 | ((DWORD)_tm.tm_mday << 16)
    545                 | ((DWORD)_tm.tm_hour << 11)
    546                 | ((DWORD)_tm.tm_min << 5)
    547                 | ((DWORD)_tm.tm_sec >> 1);
    548 }
    549 
    550 void mrb_gr_peach_gem_init(mrb_state *mrb)
    551 {
    552 }
    553 
    554 void mrb_gr_peach_gem_final(mrb_state *mrb)
    555 {
    556 
    557 }
  • EcnlProtoTool/trunk/prototool/src/arduino.h

    r278 r279  
    3030#include <us_ticker_api.h>
    3131#include <wait_api.h>
    32 #include "diskio.h"
    33 #include "ff.h"
    3432
    3533#ifndef bool
     
    116114
    117115typedef struct File {
    118         FIL fp;
     116        int  fd;
    119117} File;
    120118
     
    130128int file_read(File *fd);
    131129
    132 typedef struct SD {
    133         DSTATUS dst;
    134         BYTE type;
    135         FATFS FatFs;
    136 } SD;
    137 
    138 extern SD Sd;
    139 
    140130bool SD_begin();
    141131bool SD_open(File *file, const char *path, int mode);
     
    147137
    148138typedef struct FILEEEP {
    149         FIL fp;
     139        int fd;
    150140} FILEEEP;
    151141
  • EcnlProtoTool/trunk/prototool/src/main.c

    r270 r279  
    11/*
    22 *  TOPPERS ECHONET Lite Communication Middleware
    3  * 
    4  *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
    5  * 
     3 *
     4 *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
     5 *
    66 *  上記著作権è€
    77は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
     
    4040 *      å
    4141è²¬ã™ã‚‹ã“と.
    42  * 
     42 *
    4343 *  本ソフトウェアは,無保証で提供されているものである.上記著作権è€
    4444お
     
    4747 *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
    4848 *  の責任を負わない.
    49  * 
     49 *
    5050 *  @(#) $Id$
    5151 */
    5252
    53 /*
    54  *  サンプルプログラム(1)の本体
    55  */
    56 
    57 #include <kernel.h>
    58 #include <t_syslog.h>
    59 #include <t_stdlib.h>
    60 #include <sil.h>
    61 #include <stdlib.h>
     53 /*
     54  *  サンプルプログラム(1)の本体
     55  */
     56
     57#include <sys/types.h>
     58#include <sys/socket.h>
     59#include <sys/un.h>
     60#include <netinet/in.h>
     61#include <netinet/tcp.h>
     62#include <arpa/inet.h>
     63#include <fcntl.h>
     64#include <netdb.h>
     65#include <unistd.h>
     66#include <setjmp.h>
     67#include <signal.h>
     68#include <time.h>
     69#include <sys/time.h>
     70#include <sys/unistd.h>
     71#include <errno.h>
     72
    6273#include <string.h>
    63 #include "syssvc/serial.h"
    64 #include "syssvc/syslog.h"
    65 #include "kernel_cfg.h"
    66 #include "main.h"
    67 #include "rza1.h"
    6874#include <mruby.h>
    6975#include <mruby/compile.h>
     
    7480#include <mruby/dump.h>
    7581#include <mruby/string.h>
    76 #include <tinet_config.h>
    77 #include <netinet/in.h>
    78 #include <netinet/in_itron.h>
    79 #include <tinet_nic_defs.h>
    80 #include <tinet_cfg.h>
    81 #include <netinet/in_var.h>
    82 #include <net/ethernet.h>
    83 #include <net/if6_var.h>
    84 #include <net/net.h>
    85 #include <net/if_var.h>
    86 #include <netinet/udp_var.h>
    87 #include <ethernet_api.h>
    88 #include "../webserver/httpd.h"
    89 #include "../webserver/httpd-fs.h"
    90 #include "../webserver/http-strings.h"
    91 #include "../webserver/base64.h"
    92 #include "../webserver/sha1.h"
    93 #include "mruby_arduino.h"
    94 #include "gpio_api.h"
    95 #include "arduino.h"
    96 #include "ff.h"
    97 
    98 #ifndef _MSC_VER
    99 void strcpy_s(char *dst, int size, const char *src);
    100 void strcat_s(char *dst, int size, const char *src);
    101 #endif
    102 
    103 uint8_t mac_addr[6] = {0x00, 0x30, 0x13, 0x06, 0x62, 0xC0};
    104 
    105 SYSTIM main_time;
    106 struct httpd_state *uploding;
    107 
    108 static void netif_link_callback(T_IFNET *ether);
    109 static void execute_ruby();
    110 
    111 /*  TCP 送受信ウィンドバッファ  */
    112 uint8_t tcp_swbuf1[TCP_SWBUF_SIZE];
    113 uint8_t tcp_rwbuf1[TCP_RWBUF_SIZE];
    114 uint8_t tcp_swbuf2[TCP_SWBUF_SIZE];
    115 uint8_t tcp_rwbuf2[TCP_RWBUF_SIZE];
    116 
    117 #define ISO_nl      0x0a
    118 #define ISO_space   0x20
    119 #define ISO_bang    0x21
    120 #define ISO_percent 0x25
    121 #define ISO_period  0x2e
    122 #define ISO_slash   0x2f
    123 #define ISO_colon   0x3a
    124 
    125 ID ecn_api_mailboxid;
    126 ID WEBSOCKET_MBXID;
    127 
    128 struct httpd_state httpd_state[2] = {
    129         {MAIN1_TASK, TCP_CEPID1},
    130         {MAIN2_TASK, TCP_CEPID2},
    131 };
    132 
    133 /*
    134 *  ネットワーク層の選択
    135 */
    136 
    137 #ifdef SUPPORT_INET6
    138 
    139 #define TCP_ACP_CEP(c,r,d,t)    tcp6_acp_cep(c,r,d,t)
    140 #define IP2STR(s,a)             ipv62str(s,a)
    141 
    142 #else   /* of #ifdef SUPPORT_INET6 */
    143 
    144 #ifdef SUPPORT_INET4
    145 
    146 #define TCP_ACP_CEP(c,r,d,t)    tcp_acp_cep(c,r,d,t)
    147 #define IP2STR(s,a)             ip2str(s,a)
    148 
    149 #endif  /* of #ifdef SUPPORT_INET4 */
    150 
    151 #endif  /* of #ifdef SUPPORT_INET6 */
    152 
    153 struct httpd_state *get_httpd(ID cepid)
    154 {
    155         for (int i = 0; i < 2; i++) {
    156                 if (httpd_state[i].cepid != cepid)
    157                         continue;
    158 
    159                 return &httpd_state[i];
    160         }
    161         return NULL;
    162 }
    163 
    164 struct websocket *websocket_getws(ID wbsid)
    165 {
    166         for (int i = 0; i < 2; i++) {
    167                 if (httpd_state[i].websocket.wbsid != wbsid)
    168                         continue;
    169 
    170                 return &httpd_state[i].websocket;
    171         }
    172         return NULL;
    173 }
    174 
    175 void send_file(struct httpd_state *s)
    176 {
    177         char *buf;
    178         int len, slen;
    179 
    180         while (s->file.len > 0) {
    181                 slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
    182                 if (slen < 0) {
    183                         syslog(LOG_ERROR, "send_file#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
    184                         s->state = STATE_CLOSING;
    185                         break;
    186                 }
    187                 if (slen == 0)
    188                         return;
    189 
    190                 len = s->file.len;
    191                 if (len > slen)
    192                         len = slen;
    193 
    194                 len = httpd_fs_read(&s->file, buf, len);
    195                 if (len <= 0) {
    196                         syslog(LOG_ERROR, "send_file#httpd_fs_read(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, len);
    197                         break;
    198                 }
    199 
    200                 s->file.len -= len;
    201                 s->file.pos += len;
    202 
    203                 if ((slen = tcp_snd_buf(s->cepid, len)) != E_OK) {
    204                         syslog(LOG_ERROR, "send_file#tcp_snd_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
    205                         s->state = STATE_CLOSING;
    206                         break;
    207                 }
    208         }
    209 
    210         syslog(LOG_NOTICE, "close:     %s.%d %s", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
    211         httpd_fs_close(&s->file);
    212         s->file.len = 0;
    213         s->file.pos = 0;
    214 
    215         s->out.state = OUT_STATE_SEND_END;
    216 }
    217 
    218 void send_data(struct httpd_state *s)
    219 {
    220         char *buf;
    221         int len, slen;
    222 
    223         while (s->response_len > 0) {
    224                 slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
    225                 if (slen < 0) {
    226                         syslog(LOG_ERROR, "send_data#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
    227                         s->state = STATE_CLOSING;
    228                         break;
    229                 }
    230                 if (slen == 0)
    231                         return;
    232 
    233                 len = s->response_len;
    234                 if (len > slen)
    235                         len = slen;
    236 
    237                 memcpy(buf, &s->response_body[s->response_pos], len);
    238 
    239                 s->response_len -= len;
    240                 s->response_pos += len;
    241 
    242                 if ((slen = tcp_snd_buf(s->cepid, len)) != E_OK) {
    243                         syslog(LOG_ERROR, "send_data#tcp_snd_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
    244                         s->state = STATE_CLOSING;
    245                         break;
    246                 }
    247         }
    248 
    249         s->response_body = NULL;
    250         s->response_len = 0;
    251         s->response_pos = 0;
    252 
    253         s->out.state = OUT_STATE_SEND_END;
    254 }
    255 
    256 void send_headers(struct httpd_state *s, const char *statushdr)
    257 {
    258         int len;
    259         char *ptr;
    260 
    261         len = strlen(statushdr);
    262         tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
    263 
    264         if ((s->filename[0] == '0') && (s->file.len > 0)) {
    265                 len = sizeof(http_content_encoding_gzip) - 1;
    266                 tcp_snd_dat(s->cepid, (void *)http_content_encoding_gzip, len, TMO_FEVR);
    267         }
    268 
    269         if (s->file.redirect) {
    270                 len = sizeof(http_location) - 1;
    271                 tcp_snd_dat(s->cepid, (void *)http_location, len, TMO_FEVR);
    272                 if (s->filename[0] == '1') {
    273                         len = 2;
    274                         tcp_snd_dat(s->cepid, "/~", len, TMO_FEVR);
    275                 }
    276                 len = strlen(s->filename);
    277                 tcp_snd_dat(s->cepid, s->filename, len, TMO_FEVR);
    278                 if (s->query != NULL) {
    279                         tcp_snd_dat(s->cepid, "?", 1, TMO_FEVR);
    280                         len = strlen(s->query);
    281                         tcp_snd_dat(s->cepid, s->query, len, TMO_FEVR);
    282                 }
    283                 len = 2;
    284                 tcp_snd_dat(s->cepid, "\r", len, TMO_FEVR);
    285         }
    286 
    287         ptr = strrchr(s->filename, ISO_period);
    288         if (ptr == NULL) {
    289                 len = sizeof(http_content_type_binary) - 1;
    290                 tcp_snd_dat(s->cepid, (void *)http_content_type_binary, len, TMO_FEVR);
    291         }
    292         else if (strncmp(http_html, ptr, sizeof(http_html) - 1) == 0 ||
    293                 strncmp(http_htm, ptr, sizeof(http_htm) - 1) == 0) {
    294                 len = sizeof(http_content_type_html) - 1;
    295                 tcp_snd_dat(s->cepid, (void *)http_content_type_html, len, TMO_FEVR);
    296         }
    297         else if (strncmp(http_css, ptr, sizeof(http_css) - 1) == 0) {
    298                 len = sizeof(http_content_type_css) - 1;
    299                 tcp_snd_dat(s->cepid, (void *)http_content_type_css, len, TMO_FEVR);
    300         }
    301         else if (strncmp(http_js, ptr, sizeof(http_js) - 1) == 0) {
    302                 len = sizeof(http_content_type_js) - 1;
    303                 tcp_snd_dat(s->cepid, (void *)http_content_type_js, len, TMO_FEVR);
    304         }
    305         else if (strncmp(http_json, ptr, sizeof(http_json) - 1) == 0) {
    306                 len = sizeof(http_content_type_json) - 1;
    307                 tcp_snd_dat(s->cepid, (void *)http_content_type_json, len, TMO_FEVR);
    308         }
    309         else if (strncmp(http_png, ptr, sizeof(http_png) - 1) == 0) {
    310                 len = sizeof(http_content_type_png) - 1;
    311                 tcp_snd_dat(s->cepid, (void *)http_content_type_png, len, TMO_FEVR);
    312         }
    313         else if (strncmp(http_gif, ptr, sizeof(http_gif) - 1) == 0) {
    314                 len = sizeof(http_content_type_gif) - 1;
    315                 tcp_snd_dat(s->cepid, (void *)http_content_type_gif, len, TMO_FEVR);
    316         }
    317         else if (strncmp(http_jpg, ptr, sizeof(http_jpg) - 1) == 0) {
    318                 len = sizeof(http_content_type_jpg) - 1;
    319                 tcp_snd_dat(s->cepid, (void *)http_content_type_jpg, len, TMO_FEVR);
    320         }
    321         else if (strncmp(http_svg, ptr, sizeof(http_svg) - 1) == 0) {
    322                 len = sizeof(http_content_type_svg) - 1;
    323                 tcp_snd_dat(s->cepid, (void *)http_content_type_svg, len, TMO_FEVR);
    324         }
    325         else if (strncmp(http_text, ptr, sizeof(http_text) - 1) == 0) {
    326                 len = sizeof(http_content_type_text) - 1;
    327                 tcp_snd_dat(s->cepid, (void *)http_content_type_text, len, TMO_FEVR);
    328         }
    329         else if (strncmp(http_eot, ptr, sizeof(http_eot) - 1) == 0) {
    330                 len = sizeof(http_content_type_eot) - 1;
    331                 tcp_snd_dat(s->cepid, (void *)http_content_type_eot, len, TMO_FEVR);
    332         }
    333         else if (strncmp(http_ttf, ptr, sizeof(http_ttf) - 1) == 0) {
    334                 len = sizeof(http_content_type_ttf) - 1;
    335                 tcp_snd_dat(s->cepid, (void *)http_content_type_ttf, len, TMO_FEVR);
    336         }
    337         else if (strncmp(http_woff, ptr, sizeof(http_woff) - 1) == 0) {
    338                 len = sizeof(http_content_type_woff) - 1;
    339                 tcp_snd_dat(s->cepid, (void *)http_content_type_woff, len, TMO_FEVR);
    340         }
    341         else if (strncmp(http_woff2, ptr, sizeof(http_woff2) - 1) == 0) {
    342                 len = sizeof(http_content_type_woff2) - 1;
    343                 tcp_snd_dat(s->cepid, (void *)http_content_type_woff2, len, TMO_FEVR);
    344         }
    345         else if (strncmp(http_ico, ptr, sizeof(http_ico) - 1) == 0) {
    346                 len = sizeof(http_content_type_ico) - 1;
    347                 tcp_snd_dat(s->cepid, (void *)http_content_type_ico, len, TMO_FEVR);
    348         }
    349         else {
    350                 len = sizeof(http_content_type_plain) - 1;
    351                 tcp_snd_dat(s->cepid, (void *)http_content_type_plain, len, TMO_FEVR);
    352         }
    353 
    354         if (s->file.len > 0) {
    355                 len = sizeof(http_content_length) - 1;
    356                 tcp_snd_dat(s->cepid, (void *)http_content_length, len, TMO_FEVR);
    357                 sprintf(s->temp, "%d\r\n", s->file.len);
    358                 tcp_snd_dat(s->cepid, (void *)s->temp, strlen(s->temp), TMO_FEVR);
    359         }
    360 
    361         if (s->message.should_keep_alive && s->reset == 0) {
    362                 len = sizeof(http_connection_keep_alive) - 1;
    363                 tcp_snd_dat(s->cepid, (void *)http_connection_keep_alive, len, TMO_FEVR);
    364         }
    365         else {
    366                 len = sizeof(http_connection_close) - 1;
    367                 tcp_snd_dat(s->cepid, (void *)http_connection_close, len, TMO_FEVR);
    368         }
    369 
    370         tcp_snd_dat(s->cepid, (void *)http_crnl, 2, TMO_FEVR);
    371 
    372         if (s->filename != NULL) {
    373                 s->out.state = OUT_STATE_SEND_FILE;
    374         }
    375         else {
    376                 s->out.state = OUT_STATE_SEND_DATA;
    377         }
    378 }
    379 
    380 void handle_output(struct httpd_state *s)
    381 {
    382         s->out.wait = false;
    383 
    384         switch (s->out.state) {
    385         case OUT_STATE_WAIT_REQUEST:
    386                 s->out.wait = true;
    387                 break;
    388         case OUT_STATE_OPEN_GET_FILE:
    389                 syslog(LOG_NOTICE, "open:      %s.%d %s", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
    390                 if (!httpd_fs_open(s->filename, sizeof(s->message.request_url), &s->file)) {
    391                         s->filename = NULL;
    392                         s->response_body = http_content_404;
    393                         s->response_pos = 0;
    394                         s->response_len = sizeof(http_content_403) - 1;
    395                         s->out.statushdr = http_header_404;
    396                 }
    397                 else {
    398                         s->out.statushdr = s->file.redirect ? http_header_301 : http_header_200;
    399                 }
    400                 s->out.state = OUT_STATE_SEND_HEADER;
    401                 break;
    402         case OUT_STATE_WAIT_POST_BODY:
    403                 s->out.wait = true;
    404                 break;
    405         case OUT_STATE_BODY_RECEIVED:
    406                 s->out.statushdr = http_header_200;
    407                 s->out.state = OUT_STATE_SEND_HEADER;
    408                 break;
    409         case OUT_STATE_SEND_HEADER:
    410                 send_headers(s, s->out.statushdr);
    411                 break;
    412         case OUT_STATE_SEND_FILE:
    413                 send_file(s);
    414                 break;
    415         case OUT_STATE_SEND_DATA:
    416                 send_data(s);
    417                 break;
    418         case OUT_STATE_SEND_END:
    419                 s->out.wait = true;
    420                 if (s->message.should_keep_alive && s->reset == 0) {
    421                         s->out.state = OUT_STATE_WAIT_REQUEST;
    422                 }
    423                 else {
    424                         s->state = STATE_CLOSING;
    425                 }
    426                 break;
    427         }
    428 }
    429 
    430 void send_ws_headers(struct httpd_state *s, const char *statushdr)
    431 {
    432         int len;
    433 
    434         len = strlen(statushdr);
    435         tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
    436 
    437         len = sizeof(http_upgrade) - 1;
    438         tcp_snd_dat(s->cepid, (void *)http_upgrade, len, TMO_FEVR);
    439         len = strlen(s->message.upgrade);
    440         tcp_snd_dat(s->cepid, s->message.upgrade, len, TMO_FEVR);
    441         len = sizeof(http_crnl) - 1;
    442         tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
    443 
    444         len = sizeof(http_connection) - 1;
    445         tcp_snd_dat(s->cepid, (void *)http_connection, len, TMO_FEVR);
    446         len = strlen(s->message.connection);
    447         tcp_snd_dat(s->cepid, s->message.connection, len, TMO_FEVR);
    448         len = sizeof(http_crnl) - 1;
    449         tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
    450 
    451         len = sizeof(http_sec_websocket_accept) - 1;
    452         tcp_snd_dat(s->cepid, (void *)http_sec_websocket_accept, len, TMO_FEVR);
    453         len = strlen(s->message.response_key);
    454         tcp_snd_dat(s->cepid, s->message.response_key, len, TMO_FEVR);
    455         len = sizeof(http_crnl) - 1;
    456         tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
    457 
    458         len = sizeof(http_sec_websocket_protocol) - 1;
    459         tcp_snd_dat(s->cepid, (void *)http_sec_websocket_protocol, len, TMO_FEVR);
    460         len = strlen(s->message.sec_websocket_protocol);
    461         tcp_snd_dat(s->cepid, s->message.sec_websocket_protocol, len, TMO_FEVR);
    462         len = sizeof(http_crnl) - 1;
    463         tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
    464 
    465         len = sizeof(http_crnl) - 1;
    466         tcp_snd_dat(s->cepid, (void *)http_crnl, len, TMO_FEVR);
    467 }
    468 
    469 void send_ws_data(struct httpd_state *s)
    470 {
    471         char *buf;
    472         int slen;
    473 
    474         slen = tcp_get_buf(s->cepid, (void **)&buf, TMO_FEVR);
    475         if (slen < 0) {
    476                 syslog(LOG_ERROR, "send_ws_data#tcp_get_buf(%s.%d) => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, slen);
    477                 return;
    478         }
    479 
    480         websocket_output(&s->websocket, buf, slen);
    481 }
    482 
    483 void handle_ws_output(struct httpd_state *s)
    484 {
    485         char shaHash[20];
    486         SHA_CTX sha1;
    487         int len;
    488 
    489         strlncat(s->message.response_key, sizeof(s->message.response_key),
    490                 s->message.sec_websocket_key, sizeof(s->message.sec_websocket_key));
    491         len = strlncat(s->message.response_key, sizeof(s->message.response_key),
    492                 http_websocket_guid, sizeof(http_websocket_guid));
    493         memset(shaHash, 0, sizeof(shaHash));
    494         SHA1_Init(&sha1);
    495         SHA1_Update(&sha1, (sha1_byte *)s->message.response_key, len);
    496         SHA1_Final((sha1_byte *)shaHash, &sha1);
    497         base64_encode((unsigned char *)s->message.response_key,
    498                 sizeof(s->message.response_key), (unsigned char *)shaHash, sizeof(shaHash));
    499 
    500         send_ws_headers(s, http_header_101);
    501 
    502         s->message.response_key[0] = '\0';
    503 
    504         do {
    505                 while (!websocket_newdata(&s->websocket))
    506                         slp_tsk();
    507 
    508                 send_ws_data(s);
    509         } while ((s->state == STATE_CONNECTED) && (!s->close_req));
    510         s->state = STATE_DISCONNECTED;
    511         websocket_destroy(&s->websocket);
    512         s->close_req = 0;
    513 
    514         s->state = STATE_CLOSING;
    515 }
    516 
    517 void handle_input(struct httpd_state *s)
    518 {
    519         size_t done;
    520         int len;
    521 
    522         s->in.wait = false;
    523 
    524         switch (s->in.state) {
    525         case IN_STATE_START:
    526                 http_parser_init(&s->parser, HTTP_REQUEST);
    527                 s->in.state = IN_STATE_REQUEST;
    528                 break;
    529         case IN_STATE_REQUEST:
    530         case IN_STATE_RESPONSE:
    531         case IN_STATE_UPLOAD:
    532                 if ((len = tcp_rcv_buf(s->cepid, (void **)&s->in.data, TMO_POL)) <= 0) {
    533                         if ((len == E_TMOUT) || (len == 0)) {
    534                                 // 3秒はå¾
    535 ã¤
    536                                 if (main_time - s->in.timer < 30000000) {
    537                                         s->in.wait = true;
    538                                         break;
    539                                 }
    540                         }
    541                         syslog(LOG_ERROR, "handle_input#tcp_rcv_buf#%d(%s.%d) => %d", s->in.state, s->addr, ((T_IPV4EP *)s->dst)->portno, len);
    542                         uploding = NULL;
    543                         s->state = STATE_CLOSING;
    544                         return;
    545                 }
    546                 done = http_parser_execute(&s->parser, &websvr_settings, s->in.data, len);
    547                 tcp_rel_buf(s->cepid, done);
    548                 if (s->parser.http_errno != HPE_OK) {
    549                         syslog(LOG_ERROR, "http_parser error %s.%d => %d", s->addr, ((T_IPV4EP *)s->dst)->portno, s->parser.http_errno);
    550                         uploding = NULL;
    551                         s->state = STATE_CLOSING;
    552                         return;
    553                 }
    554 
    555                 s->parse_pos = done;
    556                 s->parse_len = len - done;
    557                 break;
    558         case IN_STATE_UPLOAD_WAIT:
    559                 if (uploding != NULL) {
    560                         s->in.wait = true;
    561                 }
    562                 else {
    563                         uploding = s;
    564                         s->in.state = IN_STATE_UPLOAD;
    565                 }
    566                 break;
    567         case IN_STATE_WEBSOCKET:
    568                 if (s->parse_len <= 0) {
    569                         if ((len = tcp_rcv_buf(s->cepid, (void **)&s->in.data, TMO_POL)) <= 0) {
    570                                 if ((len == E_TMOUT) || (len == 0)) {
    571                                         s->in.wait = true;
    572                                         break;
    573                                 }
    574                                 syslog(LOG_ERROR, "handle_input#tcp_rcv_buf#%d(%s.%d) => %d", s->in.state, s->addr, ((T_IPV4EP *)s->dst)->portno, len);
    575                                 s->state = STATE_CLOSING;
    576                                 break;
    577                         }
    578 
    579                         s->parse_pos = 0;
    580                         s->parse_len = len;
    581                 }
    582                 else
    583                         len = s->parse_len;
    584                 done = websocket_input(&s->websocket, (void *)s->in.data, s->parse_len);
    585                 tcp_rel_buf(s->cepid, done);
    586                 if ((done != 0) || (s->websocket.rstate.opecode == connection_close)) {
    587                         s->close_req = 1;
    588                         s->state = STATE_CLOSING;
    589                         break;
    590                 }
    591                 s->parse_pos = done;
    592                 s->parse_len -= done;
    593                 break;
    594         case IN_STATE_END:
    595                 s->in.wait = true;
    596                 break;
    597         default:
    598                 s->state = STATE_CLOSING;
    599                 break;
    600         }
    601 }
    602 
    603 /*
    604  *  ノンブロッキングコールのコールバック関数
    605  */
    606 ER
    607 callback_nblk_tcp(ID cepid, FN fncd, void *p_parblk)
    608 {
    609         struct httpd_state *s = get_httpd(cepid);
    610 
    611         if (s == NULL)
    612                 syslog(LOG_NOTICE, "callback_nblk_tcp(%d, %d)", fncd, cepid);
    613         else
    614                 syslog(LOG_NOTICE, "callback_nblk_tcp(%d, %s.%d)", fncd, s->addr, ((T_IPV4EP *)s->dst)->portno);
    615 
    616         return E_PAR;
    617 }
    618 
    619 /*
    620  * メインタスク
    621  */
    622 void main_task(intptr_t exinf)
    623 {
    624         ER ret, ret2;
    625         struct httpd_state *s = &httpd_state[exinf];
    626 
    627         if (exinf == 0) {
    628                 gpio_t led_blue, led_green, led_red, sw;
    629                 gpio_init_out(&led_blue, LED_BLUE);
    630                 gpio_init_out(&led_green, LED_GREEN);
    631                 gpio_init_out(&led_red, LED_RED);
    632                 gpio_init_in(&sw, USER_BUTTON0);
    633 
    634                 bool_t exec = gpio_read(&sw) == 1;
    635 
    636                 gpio_write(&led_blue, 1);
    637                 gpio_write(&led_green, exec ? 1 : 0);
    638                 gpio_write(&led_red, 0);
    639 
    640                 /* 初期化 */
    641                 if (mruby_arduino_init() == 0) {
    642                         gpio_write(&led_blue, 0);
    643                 }
    644                 else {
    645                         gpio_write(&led_blue, 0);
    646                         gpio_write(&led_red, 1);
    647                 }
    648 
    649                 gpio_write(&led_green, 0);
    650 
    651                 /* TINETが起動するまでå¾
    652 ã¤ */
    653                 ether_set_link_callback(netif_link_callback);
    654 
    655                 act_tsk(MAIN2_TASK);
    656 
    657                 if (exec) {
    658                         strcpy_s(RubyFilename, sizeof(RubyFilename), "1:/upload/main.mrb");
    659 
    660                         execute_ruby();
    661                 }
    662         }
    663 
    664         for (;;) {
    665                 ret2 = get_tim(&main_time);
    666                 if (ret2 != E_OK) {
    667                         syslog(LOG_ERROR, "get_tim");
    668                         return;
    669                 }
    670 
    671                 switch (s->state) {
    672                 case STATE_DISCONNECTED:
    673                         memset(&s->dst, 0, sizeof(s->dst));
    674                         if ((ret = TCP_ACP_CEP(s->cepid, TCP_REPID, (T_IPV4EP *)s->dst, TMO_FEVR)) != E_OK) {
    675                                 syslog(LOG_ERROR, "tcp_acp_cep(%d) => %d", s->cepid, ret);
    676                                 tslp_tsk(100000);       // TODO
    677                                 s->state = STATE_CLOSING;
    678                                 break;
    679                         }
    680                         IP2STR(s->addr, &((T_IPV4EP *)s->dst)->ipaddr);
    681                         syslog(LOG_NOTICE, "connected: %s.%d", s->addr, ((T_IPV4EP *)s->dst)->portno);
    682                         memset(&s->in, 0, sizeof(s->in));
    683                         memset(&s->out, 0, sizeof(s->out));
    684                         s->in.timer = main_time;
    685                         s->state = STATE_CONNECTED;
    686                         break;
    687                 case STATE_CONNECTED:
    688                         handle_input(s);
    689                         handle_output(s);
    690                         break;
    691                 case STATE_WEBSOCKET:
    692                         handle_input(s);
    693                         handle_ws_output(s);
    694                         break;
    695                 case STATE_CLOSING:
    696                         syslog(LOG_NOTICE, "close:     %s.%d", s->addr, ((T_IPV4EP *)s->dst)->portno);
    697                         tcp_sht_cep(s->cepid);
    698                         tcp_cls_cep(s->cepid, TMO_FEVR);
    699 
    700                         if (s->reset) {
    701                                 s->reset = 0;
    702                                 s->state = STATE_RESET;
    703                         }
    704                         else{
    705                                 s->state = STATE_DISCONNECTED;
    706                         }
    707                         break;
    708                 case STATE_RESET:
    709                         execute_ruby();
    710                         s->state = STATE_DISCONNECTED;
    711                         break;
    712                 }
    713 
    714                 if (s->in.wait && s->out.wait) {
    715                         tslp_tsk(100000);
    716                 }
    717         }
    718 }
    719 
    720 struct udp_msg {
    721         T_IPV4EP dst;
     82#include <usrcmd.h>
     83
     84#define ETHER_MAX_LEN 1518
     85#define IF_FLAG_UP              1
     86#define IF_FLAG_LINK_UP 2
     87#define MAKE_IPV4_ADDR(a,b,c,d)         htonl(((uint32_t)(a)<<24)|((uint32_t)(b)<<16)|((uint32_t)(c)<<8)|(d))
     88
     89struct udp_msg
     90{
     91        struct sockaddr_in dst;
    72292        int len;
    72393        uint8_t buffer[ETHER_MAX_LEN];
    72494};
    72595
    726 SYSTIM mruby_time;
     96typedef struct
     97{
     98        cmd_table_t *table;
     99        cmd_table_t *count;
     100} cmd_table_info_t;
     101
     102extern int mrbc_main(int argc, char **argv);
     103extern int mrdb_main(int argc, char **argv);
     104extern int mruby_main(int argc, char **argv);
     105extern int mirb_main(int argc, char **argv);
     106extern int tcc_main(int argc, char **argv);
     107extern int vi_main(int argc, char **argv);
     108extern int onitest_main(int argc, char **argv);
     109extern int tcp_echo_main(int argc, char **argv);
     110extern int echo_client_main(int argc, char **argv);
     111extern int mrdb_break(void);
     112
     113static const cmd_table_t cmdlist[] = {
     114        {"mrbc", "mruby compiler executable", mrbc_main},
     115        {"mrdb","mruby debugger command", mrdb_main},
     116        {"mruby","mruby command", mruby_main},
     117        {"mirb", "Embeddable Interactive Ruby Shell", mirb_main},
     118        {"tcc", "Tiny C compiler", tcc_main},
     119        {"vi", "Text editor", vi_main},
     120        {"cd", "change directory", usrcmd_cd },
     121        {"ls", "list files", usrcmd_ls },
     122        {"cp", "copy file", usrcmd_cp },
     123        {"rm", "remove file", usrcmd_rm },
     124        {"mv", "move file", usrcmd_mv },
     125        {"mkdir", "Make directory", usrcmd_mkdir},
     126        {"hexdump", "Hex dump", usrcmd_hexdump},
     127        {"onitest", "Onigumo Test", onitest_main},
     128        {"tcp_echo", "TCP echo server/client", tcp_echo_main},
     129        {"help", "This is a description text string for help command.", usrcmd_help},
     130        {"info", "This is a description text string for info command.", usrcmd_info},
     131        {"exit", "Exit Natural Tyny Shell", usrcmd_exit},
     132};
     133cmd_table_info_t cmd_table_info = { &cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
     134
     135int echonet = 1;
     136struct timeval main_time;
    727137struct RClass *_module_target_board;
    728 
    729 extern const uint8_t main_rb_code[];
    730 uint8_t RubyCode[16 * 1024];
    731 
    732 /* MACアドレスの設定時に呼ばれる */
    733 void mbed_mac_address(char *mac)
    734 {
    735         memcpy(mac, mac_addr, 6);
    736 }
    737 
    738 /*
    739  *  mruby実行タスク
    740  */
    741 void mruby_task(intptr_t exinf)
    742 {
    743         ER ret;
     138int sock;
     139
     140int main(int argc, char **argv)
     141{
     142        if (argc == 0) {
     143                return 0;
     144        }
     145        const cmd_table_t *p = cmd_table_info.table;
     146        for (int i = 0; i < cmd_table_info.count; i++) {
     147                if (strcmp((const char *)argv[0], p->cmd) == 0) {
     148                        return p->func(argc, argv);
     149                }
     150                p++;
     151        }
     152        printf("Unknown command found.\n");
     153        return 0;
     154}
     155
     156int run_mruby_code(int argc, char **argv, const uint8_t *code, const char *cmdline)
     157{
     158        mrb_state *mrb;
    744159        struct RProc* n;
    745160        struct mrb_irep *irep;
    746         mrb_state *mrb;
    747 
    748         syslog(LOG_NOTICE, "mruby_task");
     161        mrb_value ARGV;
     162        mrbc_context *c;
     163        mrb_value v;
     164        mrb_sym zero_sym;
     165
     166        echonet = 0;
    749167
    750168        /* mrubyの初期化 */
    751169        mrb = mrb_open();
    752170        if (mrb == NULL)
    753                 abort();
    754 
    755         ret = get_tim(&mruby_time);
    756         if (ret != E_OK) {
    757                 syslog(LOG_ERROR, "get_tim => %d", ret);
    758                 return;
    759         }
    760 
    761         irep = mrb_read_irep(mrb, RubyCode);
     171                return -1;
     172
     173        int ai = mrb_gc_arena_save(mrb);
     174        ARGV = mrb_ary_new_capa(mrb, argc);
     175        for (int i = 0; i < argc; i++) {
     176                mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, argv[i]));
     177        }
     178        mrb_define_global_const(mrb, "ARGV", ARGV);
     179
     180        c = mrbc_context_new(mrb);
     181        c->dump_result = TRUE;
     182
     183        /* Set $0 */
     184        zero_sym = mrb_intern_lit(mrb, "$0");
     185        mrbc_filename(mrb, c, cmdline);
     186        mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
     187
     188        irep = mrb_read_irep(mrb, code);
    762189        n = mrb_proc_new(mrb, irep);
    763190        mrb_run(mrb, n, mrb_nil_value());
    764191
     192        mrb_gc_arena_restore(mrb, ai);
     193        mrbc_context_free(mrb, c);
     194        if (mrb->exc) {
     195                if (!mrb_undef_p(v)) {
     196                        mrb_print_error(mrb);
     197                }
     198                n = -1;
     199        }
     200
    765201        mrb_close(mrb);
    766 }
    767 
    768 static void execute_ruby()
    769 {
    770         FIL fd;
    771         FRESULT res;
    772         ER ret;
    773 
    774         syslog(LOG_NOTICE, "execute_ruby");
    775 
    776         ret = ter_tsk(MRUBY_TASK);
    777         if ((ret != E_OK) && (ret != E_OBJ)) {
    778                 syslog(LOG_ERROR, "ter_tsk => %d", ret);
    779         }
    780 
    781         tslp_tsk(100000);
    782 
    783         reset_heap();
    784 
    785         strcpy_s(ExeFilename, sizeof(ExeFilename), RubyFilename);
    786         RubyFilename[0] = '\0';
    787         ExeFilename[sizeof(ExeFilename) - 1] = '\0';
    788 
    789         if (ExeFilename[0] == '\0') {
     202        return 0;
     203}
     204
     205int tcp_echo_main(int argc, char **argv)
     206{
     207        extern const uint8_t echo_server_code[];
     208        extern const uint8_t echo_client_code[];
     209
     210        if (argc >= 2) {
     211                if (strcmp(argv[1], "-s") == 0) {
     212                        return run_mruby_code(argc - 2, &argv[2], echo_server_code, "echo_server");
     213                }
     214                else if (strcmp(argv[1], "-c") == 0) {
     215                        return run_mruby_code(argc - 2, &argv[2], echo_client_code, "echo_client");
     216                }
     217        }
     218
     219        printf("tcp_echo -s port\n");
     220        printf("tcp_echo -c ipaddr port\n");
     221
     222        return 0;
     223}
     224
     225int usrcmd_help(int argc, char **argv)
     226{
     227        const cmd_table_t *p = cmd_table_info.table;
     228        for (int i = 0; i < cmd_table_info.count; i++) {
     229                printf(p->cmd);
     230                printf("\t:");
     231                printf(p->desc);
     232                printf("\n");
     233                p++;
     234        }
     235        return 0;
     236}
     237
     238void sigusr1_handler(int sig)
     239{
     240        printf("signal called\n");
     241}
     242
     243void mrb_target_board_init()
     244{
     245        int ret;
     246        struct sockaddr_in ep;
     247        struct ip_mreq mreq;
     248
     249        signal(SIGUSR1, sigusr1_handler);
     250
     251        sock = socket(AF_INET, SOCK_DGRAM, 0);
     252
     253        memset(&ep, 0, sizeof(ep));
     254        ep.sin_family = AF_INET;
     255        ep.sin_port = htons(3610);
     256        ep.sin_addr.s_addr = INADDR_ANY;
     257        //ep.sin_addr.s_addr = MAKE_IPV4_ADDR(192,168,137,200);
     258
     259        ret = bind(sock, &ep, sizeof(ep));
     260        if (ret != 0) {
     261                printf("bind %d", ret);
    790262                return;
    791263        }
    792264
    793         syslog(LOG_NOTICE, "%s", ExeFilename);
    794 
    795         wai_sem(SEM_FILESYSTEM);
    796 
    797         if ((res = f_open(&fd, ExeFilename, FA_OPEN_EXISTING | FA_READ)) == FR_OK) {
    798                 if (fd.fsize < sizeof(RubyCode)) {
    799                         int len = fd.fsize;
    800                         for (int pos = 0; pos < fd.fsize; pos += len) {
    801                                 if (len > 1024)
    802                                         len = 1024;
    803 
    804                                 UINT rlen;
    805                                 if ((res = f_read(&fd, &RubyCode[pos], len, &rlen)) != FR_OK)
    806                                         break;
    807 
    808                                 // 他に使う人のために解放
    809                                 sig_sem(SEM_FILESYSTEM);
    810                                 wai_sem(SEM_FILESYSTEM);
    811                         }
    812                 }
    813                 f_close(&fd);
    814         }
    815 
    816         sig_sem(SEM_FILESYSTEM);
    817 
    818         if (res == FR_OK) {
    819                 ret = act_tsk(MRUBY_TASK);
    820                 if (ret != E_OK) {
    821                         syslog(LOG_ERROR, "act_tsk => %d", ret);
    822                 }
    823         }
    824 }
    825 
    826 ER callback_nblk_udp(ID cepid, FN fncd, void *p_parblk)
    827 {
    828         static struct udp_msg msg_inst[2];
    829         static int msg_no = 0;
    830         struct udp_msg *msg = &msg_inst[msg_no];
    831         ER      error = E_OK;
    832 
    833         switch (fncd) {
    834         case TFN_UDP_CRE_CEP:
    835         case TFN_UDP_RCV_DAT:
    836                 /* ECN_CAP_PUT("[UDP ECHO SRV] callback_nblk_udp() recv: %u", *(int *)p_parblk); */
    837                 memset(msg, 0, sizeof(struct udp_msg));
    838                 if ((msg->len = udp_rcv_dat(cepid, &msg->dst, msg->buffer, sizeof(msg->buffer), 0)) < 0) {
    839                         syslog(LOG_WARNING, "[UDP ECHO SRV] recv, error: %s", itron_strerror(msg->len));
    840                         return msg->len;
    841                 }
    842                 msg_no = (msg_no + 1) % 2;
    843                 return snd_dtq(MRUBY_DATAQUEUE, (intptr_t)msg);
    844 
    845         case TFN_UDP_SND_DAT:
    846                 break;
    847         default:
    848                 syslog(LOG_WARNING, "[UDP ECHO SRV] fncd:0x%04X(%s)", -fncd,
    849                         (fncd == TFN_UDP_CRE_CEP ? "TFN_UDP_CRE_CEP" :
    850                         (fncd == TFN_UDP_RCV_DAT ? "TFN_UDP_RCV_DAT" :
    851                                 (fncd == TFN_UDP_SND_DAT ? "TFN_UDP_SND_DAT" : "undef"))));
    852 
    853                 error = E_PAR;
    854                 break;
    855         }
    856         return error;
    857 }
    858 
    859 static void netif_link_callback(T_IFNET *ether)
    860 {
    861         static struct udp_msg msg_inst[2];
    862         static int msg_no = 0;
    863         struct udp_msg *msg = &msg_inst[msg_no];
    864         T_RTSK rtsk;
    865         ER ret;
    866 
    867         ret = ref_tsk(MRUBY_TASK, &rtsk);
    868         if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
     265        mreq.imr_interface.s_addr = INADDR_ANY;
     266        mreq.imr_multiaddr.s_addr = MAKE_IPV4_ADDR(224, 0, 23, 0);
     267
     268        ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
     269        if (ret != 0) {
     270                printf("setsockopt %d", ret);
    869271                return;
    870 
    871         memset(msg, 0, sizeof(struct udp_msg));
    872 
    873         msg->len = 1;
    874         msg->buffer[0] = ether->flags;
    875 
    876         msg_no = (msg_no + 1) % 2;
    877         snd_dtq(MRUBY_DATAQUEUE, (intptr_t)msg);
     272        }
     273
     274        ret = gettimeofday(&main_time, NULL);
     275        if (ret != 0) {
     276                printf("gettimeofday");
     277                return;
     278        }
     279}
     280
     281void mrb_target_board_final()
     282{
     283        close(sock);
     284}
     285
     286void mrb_target_board_break()
     287{
     288        raise(SIGUSR1);
    878289}
    879290
     
    883294static mrb_value mrb_target_board_wait_msg(mrb_state *mrb, mrb_value self)
    884295{
    885         TMO timer;
    886         SYSTIM now;
    887         ER ret, ret2;
    888         struct udp_msg *msg;
     296        int tmr;
     297        struct timeval timer, *ptimer;
     298        struct timeval now, elps;
     299        int ret, ret2;
     300        struct udp_msg _msg;
     301        struct udp_msg *msg = &_msg;
    889302        mrb_value arv[3];
    890         static int first = 1;
    891 
    892         mrb_get_args(mrb, "i", &timer);
    893         if (timer != TMO_FEVR)
    894                 timer *= 1000;
    895 
    896         if (first) {
    897                 first = 0;
    898                 syslog(LOG_NOTICE, "wait_msg");
    899         }
     303        fd_set readfds, writefds, errorfds;
     304
     305        mrb_get_args(mrb, "i", &tmr);
     306
     307        if (tmr < 0)
     308                ptimer = NULL;
     309        else {
     310                timer.tv_sec = tmr / 1000;
     311                timer.tv_usec = (tmr % 1000) * 1000;
     312                ptimer = &timer;
     313        }
     314
     315        FD_ZERO(&readfds);
     316        FD_ZERO(&writefds);
     317        FD_ZERO(&errorfds);
     318        FD_SET(sock, &readfds);
     319        FD_SET(sock, &writefds);
     320        FD_SET(sock, &errorfds);
    900321
    901322        /* メッセージå¾
    902323ち */
    903         ret = trcv_dtq(MRUBY_DATAQUEUE, (intptr_t *)&msg, timer);
    904         if ((ret != E_OK) && (ret != E_TMOUT)) {
    905                 syslog(LOG_ERROR, "trcv_dtq => %d", ret);
     324        memset(msg, 0, sizeof(*msg));
     325        ret = select(sock + 1, &readfds, &writefds, &errorfds, ptimer);
     326        if (ret < 0)
     327                mrb_raise(mrb, E_RUNTIME_ERROR, "socket select error");
     328        if (FD_ISSET(sock, &readfds)) {
     329                int fromlen = sizeof(msg->dst);
     330                msg->len = recvfrom(sock, msg->buffer, sizeof(msg->buffer), 0, &msg->dst, &fromlen);
     331                if (msg->len < 0) {
     332                        printf("recvfrom %d", msg->len);
     333                        return mrb_nil_value();
     334                }
     335        }
     336
     337        ret2 = gettimeofday(&now, NULL);
     338        if (ret2 != 0) {
     339                printf("gettimeofday");
    906340                return mrb_nil_value();
    907341        }
    908342
    909         ret2 = get_tim(&now);
    910         if (ret2 != E_OK) {
    911                 syslog(LOG_ERROR, "get_tim => %d", ret);
    912                 return mrb_nil_value();
    913         }
    914 
    915         arv[0] = mrb_fixnum_value((now - mruby_time) / 1000);
    916         mruby_time = now;
     343        timersub(&now, &main_time, &elps);
     344        arv[0] = mrb_fixnum_value(elps.tv_sec);
     345        main_time = now;
    917346
    918347        /* タイムアウトの場合 */
    919         if (ret == E_TMOUT) {
     348        if (ret == 0) {
    920349                return mrb_ary_new_from_values(mrb, 1, arv);
    921350        }
     
    923352        /* å†
    924353部イベントの場合 */
    925         if (msg->dst.ipaddr == 0) {
     354        if (msg->dst.sin_addr.s_addr == 0) {
    926355                /* Ethernet Link up */
    927356                if (msg->buffer[0] & IF_FLAG_LINK_UP) {
     
    931360                else if (msg->buffer[0] & IF_FLAG_UP) {
    932361                        arv[1] = mrb_fixnum_value(2);
    933                 }
    934                 else {
    935                         arv[1] = mrb_fixnum_value(0);
    936362                }
    937363
     
    967393        mrb_value rep;
    968394        mrb_value rdat;
    969         T_IPV4EP *ep;
    970         ER_UINT ret;
     395        struct sockaddr_in *ep;
     396        int ret;
    971397
    972398        mrb_get_args(mrb, "SS", &rep, &rdat);
    973399
    974         if (RSTRING_LEN(rep) != sizeof(T_IPV4EP)) {
     400        if (RSTRING_LEN(rep) != sizeof(struct sockaddr_in)) {
    975401                mrb_raise(mrb, E_RUNTIME_ERROR, "snd_msg");
    976402                return mrb_nil_value();
    977403        }
    978404
    979         ep = (T_IPV4EP *)RSTRING_PTR(rep);
    980 
    981         ret = udp_snd_dat(MRUBY_ECNL_UDP_CEPID, ep, RSTRING_PTR(rdat), RSTRING_LEN(rdat), TMO_FEVR);
     405        ep = (struct sockaddr_in *)RSTRING_PTR(rep);
     406
     407        ret = sendto(sock, RSTRING_PTR(rdat), RSTRING_LEN(rdat), 0, (struct sockaddr *)ep, sizeof(*ep));
    982408        if (ret < 0) {
    983                 mrb_raise(mrb, E_RUNTIME_ERROR, "snd_msg");
     409                mrb_raise(mrb, E_RUNTIME_ERROR, "sendto");
    984410                return mrb_nil_value();
    985411        }
     
    994420{
    995421        mrb_value rep;
    996         T_IPV4EP *ep;
     422        struct sockaddr_in *ep;
    997423
    998424        mrb_get_args(mrb, "S", &rep);
    999425
    1000         if (RSTRING_LEN(rep) < sizeof(T_IPV4EP)) {
     426        if (RSTRING_LEN(rep) < sizeof(struct sockaddr_in)) {
    1001427                mrb_raise(mrb, E_RUNTIME_ERROR, "is_local_addr");
    1002428                return mrb_nil_value();
    1003429        }
    1004430
    1005         ep = (T_IPV4EP *)RSTRING_PTR(rep);
    1006 
    1007         return (ep->ipaddr == MAKE_IPV4_ADDR(127, 0, 0, 1)) ? mrb_true_value() : mrb_false_value();
     431        ep = (struct sockaddr_in *)RSTRING_PTR(rep);
     432
     433        return (ep->sin_addr.s_addr == MAKE_IPV4_ADDR(127, 0, 0, 1)) ? mrb_true_value() : mrb_false_value();
    1008434}
    1009435
     
    1014440{
    1015441        mrb_value rep;
    1016         T_IPV4EP *ep;
     442        struct sockaddr_in *ep;
    1017443
    1018444        mrb_get_args(mrb, "S", &rep);
    1019445
    1020         if (RSTRING_LEN(rep) < sizeof(T_IPV4EP)) {
     446        if (RSTRING_LEN(rep) < sizeof(struct sockaddr_in)) {
    1021447                mrb_raise(mrb, E_RUNTIME_ERROR, "is_multicast_addr");
    1022448                return mrb_nil_value();
    1023449        }
    1024450
    1025         ep = (T_IPV4EP *)RSTRING_PTR(rep);
    1026 
    1027         return (ep->ipaddr == MAKE_IPV4_ADDR(224, 0, 23, 0)) ? mrb_true_value() : mrb_false_value();
     451        ep = (struct sockaddr_in *)RSTRING_PTR(rep);
     452
     453        return (ep->sin_addr.s_addr == MAKE_IPV4_ADDR(224, 0, 23, 0)) ? mrb_true_value() : mrb_false_value();
    1028454}
    1029455
     
    1034460{
    1035461        mrb_value rep1, rep2;
    1036         T_IPV4EP *ep1, *ep2;
     462        struct sockaddr_in *ep1, *ep2;
    1037463
    1038464        mrb_get_args(mrb, "SS", &rep1, &rep2);
    1039465
    1040         if ((RSTRING_LEN(rep1) != sizeof(T_IPV4EP)) || (RSTRING_LEN(rep2) != sizeof(T_IPV4EP))) {
     466        if ((RSTRING_LEN(rep1) != sizeof(struct sockaddr_in)) || (RSTRING_LEN(rep2) != sizeof(struct sockaddr_in))) {
    1041467                mrb_raise(mrb, E_RUNTIME_ERROR, "equals_addr");
    1042468                return mrb_nil_value();
    1043469        }
    1044470
    1045         ep1 = (T_IPV4EP *)RSTRING_PTR(rep1);
    1046         ep2 = (T_IPV4EP *)RSTRING_PTR(rep2);
    1047 
    1048         return (ep1->ipaddr == ep2->ipaddr) ? mrb_true_value() : mrb_false_value();
     471        ep1 = (struct sockaddr_in *)RSTRING_PTR(rep1);
     472        ep2 = (struct sockaddr_in *)RSTRING_PTR(rep2);
     473
     474        return (ep1->sin_addr.s_addr == ep2->sin_addr.s_addr) ? mrb_true_value() : mrb_false_value();
    1049475}
    1050476
     
    1054480static mrb_value mrb_target_board_get_local_addr(mrb_state *mrb, mrb_value self)
    1055481{
    1056         T_IPV4EP ep;
     482        struct sockaddr_in ep;
    1057483        mrb_value rep;
    1058484
    1059         ep.ipaddr = MAKE_IPV4_ADDR(127, 0, 0, 1);
    1060         ep.portno = 3610;
     485        memset(&ep, 0, sizeof(ep));
     486        ep.sin_family = AF_INET;
     487        ep.sin_addr.s_addr = MAKE_IPV4_ADDR(127, 0, 0, 1);
     488        ep.sin_port = htons(3610);
    1061489
    1062490        rep = mrb_str_new(mrb, (char *)&ep, sizeof(ep));
     
    1070498static mrb_value mrb_target_board_get_multicast_addr(mrb_state *mrb, mrb_value self)
    1071499{
    1072         T_IPV4EP ep;
     500        struct sockaddr_in ep;
    1073501        mrb_value rep;
    1074502
    1075         ep.ipaddr = MAKE_IPV4_ADDR(224, 0, 23, 0);
    1076         ep.portno = 3610;
     503        memset(&ep, 0, sizeof(ep));
     504        ep.sin_family = AF_INET;
     505        ep.sin_addr.s_addr = MAKE_IPV4_ADDR(224, 0, 23, 0);
     506        ep.sin_port = htons(3610);
    1077507
    1078508        rep = mrb_str_new(mrb, (char *)&ep, sizeof(ep));
     
    1083513void mrb_mruby_others_gem_init(mrb_state* mrb)
    1084514{
     515        if (!echonet)
     516                return;
     517
    1085518        _module_target_board = mrb_define_module(mrb, "TargetBoard");
    1086 
    1087         // mbed Pin Names
    1088         mrb_define_const(mrb, _module_target_board, "LED1", mrb_fixnum_value(LED1));
    1089         mrb_define_const(mrb, _module_target_board, "LED2", mrb_fixnum_value(LED2));
    1090         mrb_define_const(mrb, _module_target_board, "LED3", mrb_fixnum_value(LED3));
    1091         mrb_define_const(mrb, _module_target_board, "LED4", mrb_fixnum_value(LED4));
    1092 
    1093         mrb_define_const(mrb, _module_target_board, "LED_RED", mrb_fixnum_value(LED_RED));
    1094         mrb_define_const(mrb, _module_target_board, "LED_GREEN", mrb_fixnum_value(LED_GREEN));
    1095         mrb_define_const(mrb, _module_target_board, "LED_BLUE", mrb_fixnum_value(LED_BLUE));
    1096         mrb_define_const(mrb, _module_target_board, "LED_USER", mrb_fixnum_value(LED_USER));
    1097 
    1098         mrb_define_const(mrb, _module_target_board, "USBTX", mrb_fixnum_value(USBTX));
    1099         mrb_define_const(mrb, _module_target_board, "USBRX", mrb_fixnum_value(USBRX));
    1100 
    1101         // Arduiono Pin Names
    1102         mrb_define_const(mrb, _module_target_board, "D0", mrb_fixnum_value(D0));
    1103         mrb_define_const(mrb, _module_target_board, "D1", mrb_fixnum_value(D1));
    1104         mrb_define_const(mrb, _module_target_board, "D2", mrb_fixnum_value(D2));
    1105         mrb_define_const(mrb, _module_target_board, "D3", mrb_fixnum_value(D3));
    1106         mrb_define_const(mrb, _module_target_board, "D4", mrb_fixnum_value(D4));
    1107         mrb_define_const(mrb, _module_target_board, "D5", mrb_fixnum_value(D5));
    1108         mrb_define_const(mrb, _module_target_board, "D6", mrb_fixnum_value(D6));
    1109         mrb_define_const(mrb, _module_target_board, "D7", mrb_fixnum_value(D7));
    1110         mrb_define_const(mrb, _module_target_board, "D8", mrb_fixnum_value(D8));
    1111         mrb_define_const(mrb, _module_target_board, "D9", mrb_fixnum_value(D9));
    1112         mrb_define_const(mrb, _module_target_board, "D10", mrb_fixnum_value(D10));
    1113         mrb_define_const(mrb, _module_target_board, "D11", mrb_fixnum_value(D11));
    1114         mrb_define_const(mrb, _module_target_board, "D12", mrb_fixnum_value(D12));
    1115         mrb_define_const(mrb, _module_target_board, "D13", mrb_fixnum_value(D13));
    1116         mrb_define_const(mrb, _module_target_board, "D14", mrb_fixnum_value(D14));
    1117         mrb_define_const(mrb, _module_target_board, "D15", mrb_fixnum_value(D15));
    1118 
    1119         mrb_define_const(mrb, _module_target_board, "A0", mrb_fixnum_value(A0));
    1120         mrb_define_const(mrb, _module_target_board, "A1", mrb_fixnum_value(A1));
    1121         mrb_define_const(mrb, _module_target_board, "A2", mrb_fixnum_value(A2));
    1122         mrb_define_const(mrb, _module_target_board, "A3", mrb_fixnum_value(A3));
    1123         mrb_define_const(mrb, _module_target_board, "A4", mrb_fixnum_value(A4));
    1124         mrb_define_const(mrb, _module_target_board, "A5", mrb_fixnum_value(A5));
    1125 
    1126         mrb_define_const(mrb, _module_target_board, "I2C_SCL", mrb_fixnum_value(I2C_SCL));
    1127         mrb_define_const(mrb, _module_target_board, "I2C_SDA", mrb_fixnum_value(I2C_SDA));
    1128 
    1129         mrb_define_const(mrb, _module_target_board, "USER_BUTTON0", mrb_fixnum_value(USER_BUTTON0));
    1130 
    1131         // Not connected
    1132         mrb_define_const(mrb, _module_target_board, "NC", mrb_fixnum_value(NC));
    1133519
    1134520        mrb_define_class_method(mrb, _module_target_board, "wait_msg", mrb_target_board_wait_msg, MRB_ARGS_REQ(1));
     
    1140526        mrb_define_class_method(mrb, _module_target_board, "get_local_addr", mrb_target_board_get_local_addr, MRB_ARGS_NONE());
    1141527        mrb_define_class_method(mrb, _module_target_board, "get_multicast_addr", mrb_target_board_get_multicast_addr, MRB_ARGS_NONE());
     528
     529        mrb_target_board_init();
    1142530}
    1143531
    1144532void mrb_mruby_others_gem_final(mrb_state* mrb)
    1145533{
    1146 }
     534        if (!echonet)
     535                return;
     536
     537        mrb_target_board_final();
     538}
     539
     540// Provide implementation of _sbrk (low-level dynamic memory allocation
     541// routine) for GCC_ARM which compares new heap pointer with MSP instead of
     542// SP.  This make it compatible with RTX RTOS thread stacks.
     543
     544// Linker defined symbol used by _sbrk to indicate where heap should start.
     545int _end;
     546uint32_t  _stack;
     547
     548// Turn off the errno macro and use actual global variable instead.
     549#undef errno
     550int errno;
     551
     552static unsigned char* heap = (unsigned char*)&_end;
     553
     554// Dynamic memory allocation related syscall.
     555caddr_t _sbrk(int incr) {
     556        unsigned char*        prev_heap = heap;
     557        unsigned char*        new_heap = heap + incr;
     558
     559        if (new_heap >= (unsigned char*)&_stack) {     /* _stack is end of heap section */
     560                errno = ENOMEM;
     561                return (caddr_t)-1;
     562        }
     563
     564        heap = new_heap;
     565        return (caddr_t) prev_heap;
     566}
     567
     568char *optarg;
     569int _data, _mdata, _edata;
     570int _bss, _ebss;
     571
     572int _PowerON_Reset(int argc, char **argv)
     573{
     574        memcpy(&_data, &_mdata, (size_t)&_edata - (size_t)&_data);
     575        memset(&_bss, 0, (size_t)&_ebss - (size_t)&_bss);
     576
     577        optarg = *argv;
     578        return main(argc, argv);
     579}
     580
     581#define FVECT_SECT          __attribute__ ((section (".fvectors")))
     582const void *HardwareVectors[] FVECT_SECT = {
     583        _PowerON_Reset,
     584        mrdb_break,
     585};
     586
     587char stack_space[0x100000] __attribute__ ((section (".stack")));
Note: See TracChangeset for help on using the changeset viewer.