[270] | 1 | /*
|
---|
| 2 | * TOPPERS ECHONET Lite Communication Middleware
|
---|
[279] | 3 | *
|
---|
[286] | 4 | * Copyright (C) 2014-2017 Cores Co., Ltd. Japan
|
---|
[279] | 5 | *
|
---|
[270] | 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 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
|
---|
[279] | 28 | * ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
[270] | 29 | * (b) åé
|
---|
| 30 | å¸ã®å½¢æ
|
---|
| 31 | ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSããã¸ã§ã¯ãã«
|
---|
| 32 | * å ±åãããã¨ï¼
|
---|
| 33 | * (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
|
---|
[279] | 34 | * 害ãããï¼ä¸è¨èä½æ¨©è
|
---|
[270] | 35 | ããã³TOPPERSããã¸ã§ã¯ããå
|
---|
| 36 | 責ãããã¨ï¼
|
---|
| 37 | * ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
|
---|
[279] | 38 | * ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
|
---|
| 39 | ããã³TOPPERSããã¸ã§ã¯ãã
|
---|
| 40 | * å
|
---|
[270] | 41 | 責ãããã¨ï¼
|
---|
[279] | 42 | *
|
---|
| 43 | * æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
|
---|
| 44 | ã
|
---|
| 45 | * ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
|
---|
| 46 | * ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
|
---|
| 47 | * ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ã
|
---|
| 48 | * ã®è²¬ä»»ãè² ããªãï¼
|
---|
| 49 | *
|
---|
| 50 | * @(#) $Id: main.c 286 2017-05-02 15:25:33Z coas-nagasima $
|
---|
| 51 | */
|
---|
| 52 |
|
---|
| 53 | /*
|
---|
| 54 | * ãµã³ãã«ããã°ã©ã (1)ã®æ¬ä½
|
---|
| 55 | */
|
---|
| 56 |
|
---|
| 57 | #include <sys/types.h>
|
---|
[270] | 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>
|
---|
[279] | 67 | #include <signal.h>
|
---|
[270] | 68 | #include <time.h>
|
---|
[279] | 69 | #include <sys/time.h>
|
---|
| 70 | #include <sys/unistd.h>
|
---|
| 71 | #include <errno.h>
|
---|
| 72 |
|
---|
[270] | 73 | #include <string.h>
|
---|
[279] | 74 | #include <mruby.h>
|
---|
| 75 | #include <mruby/compile.h>
|
---|
| 76 | #include <mruby/proc.h>
|
---|
| 77 | #include <mruby/array.h>
|
---|
| 78 | #include <mruby/data.h>
|
---|
| 79 | #include <mruby/class.h>
|
---|
[270] | 80 | #include <mruby/dump.h>
|
---|
[279] | 81 | #include <mruby/string.h>
|
---|
| 82 | #include <usrcmd.h>
|
---|
| 83 |
|
---|
| 84 | #define ETHER_MAX_LEN 1518
|
---|
| 85 | #define IF_FLAG_UP 1
|
---|
[270] | 86 | #define IF_FLAG_LINK_UP 2
|
---|
[279] | 87 | #define MAKE_IPV4_ADDR(a,b,c,d) htonl(((uint32_t)(a)<<24)|((uint32_t)(b)<<16)|((uint32_t)(c)<<8)|(d))
|
---|
| 88 |
|
---|
| 89 | struct udp_msg
|
---|
| 90 | {
|
---|
| 91 | struct sockaddr_in dst;
|
---|
| 92 | int len;
|
---|
| 93 | uint8_t buffer[ETHER_MAX_LEN];
|
---|
| 94 | };
|
---|
| 95 |
|
---|
| 96 | typedef struct
|
---|
[270] | 97 | {
|
---|
[279] | 98 | cmd_table_t *table;
|
---|
| 99 | cmd_table_t *count;
|
---|
| 100 | } cmd_table_info_t;
|
---|
| 101 |
|
---|
| 102 | extern int mrbc_main(int argc, char **argv);
|
---|
| 103 | extern int mrdb_main(int argc, char **argv);
|
---|
| 104 | extern int mruby_main(int argc, char **argv);
|
---|
| 105 | extern int mirb_main(int argc, char **argv);
|
---|
| 106 | extern int tcc_main(int argc, char **argv);
|
---|
| 107 | extern int vi_main(int argc, char **argv);
|
---|
| 108 | extern int onitest_main(int argc, char **argv);
|
---|
| 109 | extern int tcp_echo_main(int argc, char **argv);
|
---|
| 110 | extern int echo_client_main(int argc, char **argv);
|
---|
| 111 | extern int mrdb_break(void);
|
---|
| 112 |
|
---|
| 113 | static 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},
|
---|
[270] | 117 | {"mirb", "Embeddable Interactive Ruby Shell", mirb_main},
|
---|
[279] | 118 | {"tcc", "Tiny C compiler", tcc_main},
|
---|
[270] | 119 | {"vi", "Text editor", vi_main},
|
---|
[279] | 120 | {"cd", "change directory", usrcmd_cd },
|
---|
| 121 | {"ls", "list files", usrcmd_ls },
|
---|
| 122 | {"cp", "copy file", usrcmd_cp },
|
---|
| 123 | {"rm", "remove file", usrcmd_rm },
|
---|
[270] | 124 | {"mv", "move file", usrcmd_mv },
|
---|
[279] | 125 | {"mkdir", "Make directory", usrcmd_mkdir},
|
---|
[270] | 126 | {"hexdump", "Hex dump", usrcmd_hexdump},
|
---|
[279] | 127 | {"onitest", "Onigumo Test", onitest_main},
|
---|
| 128 | {"tcp_echo", "TCP echo server/client", tcp_echo_main},
|
---|
[270] | 129 | {"help", "This is a description text string for help command.", usrcmd_help},
|
---|
[279] | 130 | {"info", "This is a description text string for info command.", usrcmd_info},
|
---|
| 131 | {"exit", "Exit Natural Tyny Shell", usrcmd_exit},
|
---|
| 132 | };
|
---|
| 133 | cmd_table_info_t cmd_table_info = { &cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
|
---|
[270] | 134 |
|
---|
[279] | 135 | int echonet = 1;
|
---|
[270] | 136 | struct timeval main_time;
|
---|
[279] | 137 | struct RClass *_module_target_board;
|
---|
| 138 | int sock;
|
---|
[270] | 139 |
|
---|
| 140 | int main(int argc, char **argv)
|
---|
[279] | 141 | {
|
---|
[270] | 142 | if (argc == 0) {
|
---|
[279] | 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 | }
|
---|
[270] | 150 | p++;
|
---|
[279] | 151 | }
|
---|
[270] | 152 | printf("Unknown command found.\n");
|
---|
[279] | 153 | return 0;
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | int run_mruby_code(int argc, char **argv, const uint8_t *code, const char *cmdline)
|
---|
[270] | 157 | {
|
---|
[279] | 158 | mrb_state *mrb;
|
---|
| 159 | struct RProc* n;
|
---|
| 160 | struct mrb_irep *irep;
|
---|
| 161 | mrb_value ARGV;
|
---|
[270] | 162 | mrbc_context *c;
|
---|
[279] | 163 | mrb_value v;
|
---|
[270] | 164 | mrb_sym zero_sym;
|
---|
[279] | 165 |
|
---|
| 166 | echonet = 0;
|
---|
[270] | 167 |
|
---|
[279] | 168 | /* mrubyã®åæå */
|
---|
| 169 | mrb = mrb_open();
|
---|
| 170 | if (mrb == NULL)
|
---|
| 171 | return -1;
|
---|
[270] | 172 |
|
---|
[279] | 173 | int ai = mrb_gc_arena_save(mrb);
|
---|
| 174 | ARGV = mrb_ary_new_capa(mrb, argc);
|
---|
| 175 | for (int i = 0; i < argc; i++) {
|
---|
[270] | 176 | mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, argv[i]));
|
---|
[279] | 177 | }
|
---|
| 178 | mrb_define_global_const(mrb, "ARGV", ARGV);
|
---|
| 179 |
|
---|
| 180 | c = mrbc_context_new(mrb);
|
---|
| 181 | c->dump_result = TRUE;
|
---|
[270] | 182 |
|
---|
[279] | 183 | /* Set $0 */
|
---|
[270] | 184 | zero_sym = mrb_intern_lit(mrb, "$0");
|
---|
| 185 | mrbc_filename(mrb, c, cmdline);
|
---|
[279] | 186 | mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
|
---|
| 187 |
|
---|
[270] | 188 | irep = mrb_read_irep(mrb, code);
|
---|
| 189 | n = mrb_proc_new(mrb, irep);
|
---|
[279] | 190 | mrb_run(mrb, n, mrb_nil_value());
|
---|
[270] | 191 |
|
---|
[279] | 192 | mrb_gc_arena_restore(mrb, ai);
|
---|
| 193 | mrbc_context_free(mrb, c);
|
---|
[270] | 194 | if (mrb->exc) {
|
---|
[279] | 195 | if (!mrb_undef_p(v)) {
|
---|
| 196 | mrb_print_error(mrb);
|
---|
| 197 | }
|
---|
[270] | 198 | n = -1;
|
---|
[279] | 199 | }
|
---|
| 200 |
|
---|
[270] | 201 | mrb_close(mrb);
|
---|
| 202 | return 0;
|
---|
| 203 | }
|
---|
[279] | 204 |
|
---|
| 205 | int tcp_echo_main(int argc, char **argv)
|
---|
[270] | 206 | {
|
---|
[279] | 207 | extern const uint8_t echo_server_code[];
|
---|
[270] | 208 | extern const uint8_t echo_client_code[];
|
---|
| 209 |
|
---|
[279] | 210 | if (argc >= 2) {
|
---|
[270] | 211 | if (strcmp(argv[1], "-s") == 0) {
|
---|
[279] | 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 |
|
---|
[270] | 219 | printf("tcp_echo -s port\n");
|
---|
[279] | 220 | printf("tcp_echo -c ipaddr port\n");
|
---|
[270] | 221 |
|
---|
| 222 | return 0;
|
---|
[279] | 223 | }
|
---|
[270] | 224 |
|
---|
[279] | 225 | int usrcmd_help(int argc, char **argv)
|
---|
[270] | 226 | {
|
---|
| 227 | const cmd_table_t *p = cmd_table_info.table;
|
---|
[279] | 228 | for (int i = 0; i < cmd_table_info.count; i++) {
|
---|
[270] | 229 | printf(p->cmd);
|
---|
[279] | 230 | printf("\t:");
|
---|
| 231 | printf(p->desc);
|
---|
| 232 | printf("\n");
|
---|
[270] | 233 | p++;
|
---|
[279] | 234 | }
|
---|
[270] | 235 | return 0;
|
---|
[279] | 236 | }
|
---|
[270] | 237 |
|
---|
[279] | 238 | void sigusr1_handler(int sig)
|
---|
| 239 | {
|
---|
| 240 | printf("signal called\n");
|
---|
| 241 | }
|
---|
| 242 |
|
---|
[270] | 243 | void mrb_target_board_init()
|
---|
[279] | 244 | {
|
---|
| 245 | int ret;
|
---|
| 246 | struct sockaddr_in ep;
|
---|
| 247 | struct ip_mreq mreq;
|
---|
[270] | 248 |
|
---|
| 249 | signal(SIGUSR1, sigusr1_handler);
|
---|
[279] | 250 |
|
---|
| 251 | sock = socket(AF_INET, SOCK_DGRAM, 0);
|
---|
[270] | 252 |
|
---|
[279] | 253 | memset(&ep, 0, sizeof(ep));
|
---|
| 254 | ep.sin_family = AF_INET;
|
---|
| 255 | ep.sin_port = htons(3610);
|
---|
[270] | 256 | ep.sin_addr.s_addr = INADDR_ANY;
|
---|
| 257 | //ep.sin_addr.s_addr = MAKE_IPV4_ADDR(192,168,137,200);
|
---|
| 258 |
|
---|
[279] | 259 | ret = bind(sock, &ep, sizeof(ep));
|
---|
| 260 | if (ret != 0) {
|
---|
| 261 | printf("bind %d", ret);
|
---|
[270] | 262 | return;
|
---|
| 263 | }
|
---|
| 264 |
|
---|
| 265 | mreq.imr_interface.s_addr = INADDR_ANY;
|
---|
[279] | 266 | mreq.imr_multiaddr.s_addr = MAKE_IPV4_ADDR(224, 0, 23, 0);
|
---|
[270] | 267 |
|
---|
[279] | 268 | ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
|
---|
[270] | 269 | if (ret != 0) {
|
---|
| 270 | printf("setsockopt %d", ret);
|
---|
[279] | 271 | return;
|
---|
[270] | 272 | }
|
---|
[279] | 273 |
|
---|
[270] | 274 | ret = gettimeofday(&main_time, NULL);
|
---|
| 275 | if (ret != 0) {
|
---|
| 276 | printf("gettimeofday");
|
---|
| 277 | return;
|
---|
| 278 | }
|
---|
| 279 | }
|
---|
| 280 |
|
---|
[279] | 281 | void mrb_target_board_final()
|
---|
| 282 | {
|
---|
| 283 | close(sock);
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | void mrb_target_board_break()
|
---|
[270] | 287 | {
|
---|
[279] | 288 | raise(SIGUSR1);
|
---|
[270] | 289 | }
|
---|
[279] | 290 |
|
---|
[270] | 291 | /*
|
---|
[279] | 292 | * ã¢ããªã±ã¼ã·ã§ã³ã¿ã¹ã¯ã®ç»é²
|
---|
| 293 | */
|
---|
| 294 | static mrb_value mrb_target_board_wait_msg(mrb_state *mrb, mrb_value self)
|
---|
| 295 | {
|
---|
| 296 | int tmr;
|
---|
| 297 | struct timeval timer, *ptimer;
|
---|
[270] | 298 | struct timeval now, elps;
|
---|
| 299 | int ret, ret2;
|
---|
[279] | 300 | struct udp_msg _msg;
|
---|
| 301 | struct udp_msg *msg = &_msg;
|
---|
| 302 | mrb_value arv[3];
|
---|
| 303 | fd_set readfds, writefds, errorfds;
|
---|
| 304 |
|
---|
| 305 | mrb_get_args(mrb, "i", &tmr);
|
---|
| 306 |
|
---|
[270] | 307 | if (tmr < 0)
|
---|
[279] | 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);
|
---|
[270] | 319 | FD_SET(sock, &writefds);
|
---|
| 320 | FD_SET(sock, &errorfds);
|
---|
[279] | 321 |
|
---|
| 322 | /* ã¡ãã»ã¼ã¸å¾
|
---|
| 323 | ã¡ */
|
---|
[270] | 324 | memset(msg, 0, sizeof(*msg));
|
---|
| 325 | ret = select(sock + 1, &readfds, &writefds, &errorfds, ptimer);
|
---|
| 326 | if (ret < 0)
|
---|
[279] | 327 | mrb_raise(mrb, E_RUNTIME_ERROR, "socket select error");
|
---|
| 328 | if (FD_ISSET(sock, &readfds)) {
|
---|
| 329 | int fromlen = sizeof(msg->dst);
|
---|
[270] | 330 | msg->len = recvfrom(sock, msg->buffer, sizeof(msg->buffer), 0, &msg->dst, &fromlen);
|
---|
| 331 | if (msg->len < 0) {
|
---|
[279] | 332 | printf("recvfrom %d", msg->len);
|
---|
[270] | 333 | return mrb_nil_value();
|
---|
| 334 | }
|
---|
| 335 | }
|
---|
| 336 |
|
---|
[279] | 337 | ret2 = gettimeofday(&now, NULL);
|
---|
[270] | 338 | if (ret2 != 0) {
|
---|
| 339 | printf("gettimeofday");
|
---|
| 340 | return mrb_nil_value();
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | timersub(&now, &main_time, &elps);
|
---|
| 344 | arv[0] = mrb_fixnum_value(elps.tv_sec);
|
---|
| 345 | main_time = now;
|
---|
| 346 |
|
---|
| 347 | /* ã¿ã¤ã ã¢ã¦ãã®å ´å */
|
---|
| 348 | if (ret == 0) {
|
---|
| 349 | return mrb_ary_new_from_values(mrb, 1, arv);
|
---|
| 350 | }
|
---|
| 351 |
|
---|
| 352 | /* å
|
---|
| 353 | é¨ã¤ãã³ãã®å ´å */
|
---|
| 354 | if (msg->dst.sin_addr.s_addr == 0) {
|
---|
| 355 | /* Ethernet Link up */
|
---|
| 356 | if (msg->buffer[0] & IF_FLAG_LINK_UP) {
|
---|
| 357 | arv[1] = mrb_fixnum_value(1);
|
---|
| 358 | }
|
---|
| 359 | /* EP Link up */
|
---|
| 360 | else if (msg->buffer[0] & IF_FLAG_UP) {
|
---|
| 361 | arv[1] = mrb_fixnum_value(2);
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | return mrb_ary_new_from_values(mrb, 2, arv);
|
---|
| 365 | }
|
---|
| 366 | /* Echoneté»æåä¿¡ã®å ´å */
|
---|
| 367 | else {
|
---|
| 368 | /* éä¿¡ç«¯ç¹ */
|
---|
| 369 | arv[1] = mrb_str_new(mrb, (char *)&msg->dst, sizeof(msg->dst));
|
---|
| 370 |
|
---|
| 371 | /* åä¿¡ãã¼ã¿ */
|
---|
| 372 | arv[2] = mrb_str_new(mrb, (char *)msg->buffer, msg->len);
|
---|
| 373 |
|
---|
| 374 | return mrb_ary_new_from_values(mrb, 3, arv);
|
---|
| 375 | }
|
---|
| 376 | }
|
---|
| 377 |
|
---|
[279] | 378 | /*
|
---|
| 379 | * ã¢ããªã±ã¼ã·ã§ã³ã¿ã¹ã¯ã®ç»é²
|
---|
[270] | 380 | */
|
---|
| 381 | static mrb_value mrb_target_board_restart(mrb_state *mrb, mrb_value self)
|
---|
| 382 | {
|
---|
[279] | 383 | /* DHCPéå§ */
|
---|
[270] | 384 |
|
---|
| 385 | return self;
|
---|
| 386 | }
|
---|
| 387 |
|
---|
[279] | 388 | /*
|
---|
[270] | 389 | * éä¿¡ã¬ã¤ã¤ã¼ã¸ã®éä¿¡
|
---|
[279] | 390 | */
|
---|
[270] | 391 | static mrb_value mrb_target_board_snd_msg(mrb_state *mrb, mrb_value self)
|
---|
[279] | 392 | {
|
---|
[270] | 393 | mrb_value rep;
|
---|
| 394 | mrb_value rdat;
|
---|
| 395 | struct sockaddr_in *ep;
|
---|
| 396 | int ret;
|
---|
| 397 |
|
---|
| 398 | mrb_get_args(mrb, "SS", &rep, &rdat);
|
---|
| 399 |
|
---|
| 400 | if (RSTRING_LEN(rep) != sizeof(struct sockaddr_in)) {
|
---|
| 401 | mrb_raise(mrb, E_RUNTIME_ERROR, "snd_msg");
|
---|
| 402 | return mrb_nil_value();
|
---|
| 403 | }
|
---|
| 404 |
|
---|
[279] | 405 | ep = (struct sockaddr_in *)RSTRING_PTR(rep);
|
---|
[270] | 406 |
|
---|
| 407 | ret = sendto(sock, RSTRING_PTR(rdat), RSTRING_LEN(rdat), 0, (struct sockaddr *)ep, sizeof(*ep));
|
---|
| 408 | if (ret < 0) {
|
---|
[279] | 409 | mrb_raise(mrb, E_RUNTIME_ERROR, "sendto");
|
---|
[270] | 410 | return mrb_nil_value();
|
---|
| 411 | }
|
---|
| 412 |
|
---|
| 413 | return mrb_nil_value();
|
---|
[279] | 414 | }
|
---|
[270] | 415 |
|
---|
[279] | 416 | /*
|
---|
[270] | 417 | * ãã¼ã«ã«ã¢ãã¬ã¹ã確èª
|
---|
| 418 | */
|
---|
| 419 | static mrb_value mrb_target_board_is_local_addr(mrb_state *mrb, mrb_value self)
|
---|
| 420 | {
|
---|
| 421 | mrb_value rep;
|
---|
| 422 | struct sockaddr_in *ep;
|
---|
| 423 |
|
---|
| 424 | mrb_get_args(mrb, "S", &rep);
|
---|
[279] | 425 |
|
---|
[270] | 426 | if (RSTRING_LEN(rep) < sizeof(struct sockaddr_in)) {
|
---|
| 427 | mrb_raise(mrb, E_RUNTIME_ERROR, "is_local_addr");
|
---|
| 428 | return mrb_nil_value();
|
---|
[279] | 429 | }
|
---|
[270] | 430 |
|
---|
| 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();
|
---|
[279] | 434 | }
|
---|
[270] | 435 |
|
---|
[279] | 436 | /*
|
---|
[270] | 437 | * ãã«ããã£ã¹ãã¢ãã¬ã¹ã確èª
|
---|
| 438 | */
|
---|
| 439 | static mrb_value mrb_target_board_is_multicast_addr(mrb_state *mrb, mrb_value self)
|
---|
| 440 | {
|
---|
| 441 | mrb_value rep;
|
---|
| 442 | struct sockaddr_in *ep;
|
---|
| 443 |
|
---|
| 444 | mrb_get_args(mrb, "S", &rep);
|
---|
[279] | 445 |
|
---|
[270] | 446 | if (RSTRING_LEN(rep) < sizeof(struct sockaddr_in)) {
|
---|
| 447 | mrb_raise(mrb, E_RUNTIME_ERROR, "is_multicast_addr");
|
---|
| 448 | return mrb_nil_value();
|
---|
[279] | 449 | }
|
---|
[270] | 450 |
|
---|
| 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();
|
---|
[279] | 454 | }
|
---|
| 455 |
|
---|
[270] | 456 | /*
|
---|
[279] | 457 | * åä¸ã¢ãã¬ã¹ã確èª
|
---|
[270] | 458 | */
|
---|
| 459 | static mrb_value mrb_target_board_equals_addr(mrb_state *mrb, mrb_value self)
|
---|
| 460 | {
|
---|
| 461 | mrb_value rep1, rep2;
|
---|
| 462 | struct sockaddr_in *ep1, *ep2;
|
---|
| 463 |
|
---|
| 464 | mrb_get_args(mrb, "SS", &rep1, &rep2);
|
---|
[279] | 465 |
|
---|
[270] | 466 | if ((RSTRING_LEN(rep1) != sizeof(struct sockaddr_in)) || (RSTRING_LEN(rep2) != sizeof(struct sockaddr_in))) {
|
---|
| 467 | mrb_raise(mrb, E_RUNTIME_ERROR, "equals_addr");
|
---|
[279] | 468 | return mrb_nil_value();
|
---|
| 469 | }
|
---|
| 470 |
|
---|
| 471 | ep1 = (struct sockaddr_in *)RSTRING_PTR(rep1);
|
---|
[270] | 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();
|
---|
| 475 | }
|
---|
| 476 |
|
---|
| 477 | /*
|
---|
| 478 | * ãã¼ã«ã«ã¢ãã¬ã¹ã®åå¾
|
---|
| 479 | */
|
---|
| 480 | static mrb_value mrb_target_board_get_local_addr(mrb_state *mrb, mrb_value self)
|
---|
| 481 | {
|
---|
| 482 | struct sockaddr_in ep;
|
---|
[279] | 483 | mrb_value rep;
|
---|
[270] | 484 |
|
---|
| 485 | memset(&ep, 0, sizeof(ep));
|
---|
[279] | 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);
|
---|
| 489 |
|
---|
[270] | 490 | rep = mrb_str_new(mrb, (char *)&ep, sizeof(ep));
|
---|
| 491 |
|
---|
| 492 | return rep;
|
---|
| 493 | }
|
---|
| 494 |
|
---|
| 495 | /*
|
---|
| 496 | * ãã«ããã£ã¹ãã¢ãã¬ã¹ã®åå¾
|
---|
| 497 | */
|
---|
[279] | 498 | static mrb_value mrb_target_board_get_multicast_addr(mrb_state *mrb, mrb_value self)
|
---|
| 499 | {
|
---|
| 500 | struct sockaddr_in ep;
|
---|
[270] | 501 | mrb_value rep;
|
---|
| 502 |
|
---|
| 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);
|
---|
| 507 |
|
---|
| 508 | rep = mrb_str_new(mrb, (char *)&ep, sizeof(ep));
|
---|
| 509 |
|
---|
| 510 | return rep;
|
---|
[279] | 511 | }
|
---|
| 512 |
|
---|
[270] | 513 | void mrb_mruby_others_gem_init(mrb_state* mrb)
|
---|
| 514 | {
|
---|
| 515 | if (!echonet)
|
---|
| 516 | return;
|
---|
[279] | 517 |
|
---|
| 518 | _module_target_board = mrb_define_module(mrb, "TargetBoard");
|
---|
| 519 |
|
---|
| 520 | mrb_define_class_method(mrb, _module_target_board, "wait_msg", mrb_target_board_wait_msg, MRB_ARGS_REQ(1));
|
---|
[270] | 521 | mrb_define_class_method(mrb, _module_target_board, "restart", mrb_target_board_restart, MRB_ARGS_NONE());
|
---|
[279] | 522 | mrb_define_class_method(mrb, _module_target_board, "snd_msg", mrb_target_board_snd_msg, MRB_ARGS_REQ(2));
|
---|
| 523 | mrb_define_class_method(mrb, _module_target_board, "is_local_addr", mrb_target_board_is_local_addr, MRB_ARGS_REQ(1));
|
---|
| 524 | mrb_define_class_method(mrb, _module_target_board, "is_multicast_addr", mrb_target_board_is_multicast_addr, MRB_ARGS_REQ(1));
|
---|
| 525 | mrb_define_class_method(mrb, _module_target_board, "equals_addr", mrb_target_board_equals_addr, MRB_ARGS_REQ(2));
|
---|
| 526 | mrb_define_class_method(mrb, _module_target_board, "get_local_addr", mrb_target_board_get_local_addr, MRB_ARGS_NONE());
|
---|
| 527 | 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();
|
---|
| 530 | }
|
---|
| 531 |
|
---|
| 532 | void mrb_mruby_others_gem_final(mrb_state* mrb)
|
---|
| 533 | {
|
---|
| 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.
|
---|
| 545 | int _end;
|
---|
| 546 | uint32_t _stack;
|
---|
| 547 |
|
---|
| 548 | // Turn off the errno macro and use actual global variable instead.
|
---|
| 549 | #undef errno
|
---|
| 550 | int errno;
|
---|
| 551 |
|
---|
| 552 | static unsigned char* heap = (unsigned char*)&_end;
|
---|
| 553 |
|
---|
| 554 | // Dynamic memory allocation related syscall.
|
---|
| 555 | caddr_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 |
|
---|
| 568 | char *optarg;
|
---|
| 569 | int _data, _mdata, _edata;
|
---|
| 570 | int _bss, _ebss;
|
---|
| 571 |
|
---|
| 572 | int _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")))
|
---|
| 582 | const void *HardwareVectors[] FVECT_SECT = {
|
---|
| 583 | _PowerON_Reset,
|
---|
| 584 | mrdb_break,
|
---|
| 585 | };
|
---|
| 586 |
|
---|
| 587 | char stack_space[0x100000] __attribute__ ((section (".stack")));
|
---|