Message Integrity Checking
[uccvend-snackrom.git] / ROM2 / main_basic.c
index 5c35aab..a6a8a15 100644 (file)
@@ -13,6 +13,8 @@
 #include "motors.h"
 #include "sci.h"
 #include "vend.h"
+#include "xmodem.h"
+#include "mic.h"
 
 u8 last_standalone;
 u8 last_switch_input;
@@ -61,6 +63,10 @@ void dispense_something() {
        u8 slot;
 
        if (check_standalone()) return;
+       if (must_verify() && !mic_verify((void*)sci_rx_buf)) {
+               send_string("019 Message verification failed." CRLF);
+               return;
+       }
 
        if (my_strncmp("ALL", (char*)sci_rx_buf+1, 3)) {
                char motor[3];
@@ -173,42 +179,56 @@ void send_door_msg(bool open) {
                send_string(" door closed." CRLF);
 }
 
-u8 hexchar2u8(char b) {
-       if (b >= '0' && b <= '9') return b-'0';
-       if (b >= 'a' && b <= 'f') return b-'a'+0x0a;
-       if (b >= 'A' && b <= 'F') return b-'A'+0x0a;
-       return 0;
-}
-
-char nibble2hexchar(u8 b) {
-       if (b <= 9) return b+'0';
-       if (b >= 10 && b <= 15) return b+'A';
-       return 'X';
-}
-
-u8 hex2u8(char msb, char lsb) {
-       return (hexchar2u8(msb) << 4) + hexchar2u8(lsb);
-}
-
-static char hexconv_buf[3];
-char* u82hex(u8 a) {
-       hexconv_buf[0] = nibble2hexchar((a&0xf0) >> 4);
-       hexconv_buf[1] = nibble2hexchar(a&0x0f);
-       hexconv_buf[2] = '\0';
-       return hexconv_buf;
-}
-
 void do_chime() {
        if (check_standalone()) return;
        if (sci_rx_buf[1] == '\0')
                chime_start();
-       else if (sci_rx_buf[2] != '\0' && sci_rx_buf[3] == '\0')
-               chime_start(hex2u8(sci_rx_buf[1], sci_rx_buf[2]));
+       else if (sci_rx_buf[1] == 'S') { /* synchronous beep */
+               if (sci_rx_buf[2] == '\0')
+                       chime_start();
+               else if (sci_rx_buf[3] != '\0' && sci_rx_buf[4] == '\0')
+                       chime_for(hex2u8(sci_rx_buf[2], sci_rx_buf[3]));
+               else {
+                       send_string("510 Unknown chime duration." CRLF);
+                       return;
+               }
+               while (chime_count); /* spin */
+               send_string("500 Chimed." CRLF);
+               return;
+       } else if (sci_rx_buf[2] != '\0' && sci_rx_buf[3] == '\0')
+               chime_for(hex2u8(sci_rx_buf[1], sci_rx_buf[2]));
        else {
                send_string("510 Unknown chime duration." CRLF);
                return;
        }
-       send_string("500 Chimed." CRLF);
+       send_string("500 Chime started." CRLF);
+       return;
+}
+
+void do_silence() {
+       if (check_standalone()) return;
+       if (sci_rx_buf[1] == '\0')
+               unchime_start();
+       else if (sci_rx_buf[1] == 'S') { /* synchronous beep */
+               if (sci_rx_buf[2] == '\0')
+                       unchime_start();
+               else if (sci_rx_buf[3] != '\0' && sci_rx_buf[4] == '\0')
+                       unchime_for(hex2u8(sci_rx_buf[2], sci_rx_buf[3]));
+               else {
+                       send_string("511 Unknown silence duration." CRLF);
+                       return;
+               }
+               while (unchime_count); /* spin */
+               send_string("501 Silenced." CRLF);
+               return;
+       } else if (sci_rx_buf[2] != '\0' && sci_rx_buf[3] == '\0')
+               unchime_for(hex2u8(sci_rx_buf[1], sci_rx_buf[2]));
+       else {
+               send_string("511 Unknown silence duration." CRLF);
+               return;
+       }
+       send_string("500 Silence started." CRLF);
+       return;
 }
 
 void print_switches(u8 prompted) {
@@ -233,7 +253,11 @@ void ping_pong() {
 }
 
 void send_prompt() {
-       send_string(is_standalone()?"$ ":"# ");
+       if (must_verify()) {
+               send_string(u82hex(mic_challenge >> 8));
+               send_string(u82hex(mic_challenge & 0xff));
+       }
+       send_string(is_standalone()?"% ":"# ");
 }
 
 void about() {
@@ -289,6 +313,8 @@ void moo() {
 "    -------------|   " CRLF
 "        | |    | | " CRLF
 "       <__/    \\__>" CRLF
+"" CRLF
+"  ... Where's the cheese?" CRLF
        );
 }
 
@@ -304,10 +330,73 @@ void help() {
                " B[nn]         beep for a duration nn (optional)" CRLF
                " S[...]        query all internal switch states" CRLF
                " H[...]        this help screen" CRLF
+               " GETROM        download the ROM source code using xmodem" CRLF
                "Comments start with a #" CRLF
        );
 }
 
+extern const char _rom_src_data[];
+extern const u16 _rom_src_len;
+void getrom() {
+       if (!my_strncmp("ETROM", (char*)sci_rx_buf+1, 5)) {
+               unknown_command();
+               return;
+       }
+       char s[4];
+       send_string("Writing to serial port (maybe). Size is 0x");
+       send_string(u82hex(_rom_src_len >> 8));
+       send_string(u82hex(_rom_src_len & 0xff));
+       send_string("@0x");
+       send_string(u82hex((u16)(&_rom_src_data) >> 8));
+       send_string(u82hex((u16)(&_rom_src_data) & 0xff));
+       send_string(" with signature ");
+       s[0] = _rom_src_data[0];
+       s[1] = _rom_src_data[1];
+       s[2] = _rom_src_data[2];
+       s[3] = '\0';
+       send_string(s);
+       send_string(CRLF " Type YES to download rom.tar.bz2 via XMODEM: ");
+       msg_clr();
+       while (!sci_have_packet); /* spin */
+       if (!my_strncmp("YES", (char*)sci_rx_buf, 3)) {
+               send_string(CRLF "Transfer cancelled." CRLF);
+               return;
+       }
+
+       sci_init();
+       sci_doing_xmodem = 1;
+       if (!xmodem_init_xfer()) {
+               sci_doing_xmodem = 0;
+               send_string("XMODEM init failed. Nobody's listening :(" CRLF);
+               return;
+       }
+       char *p = (char*)_rom_src_data;
+       char *end = (char*)_rom_src_data+_rom_src_len;
+       bool aborted = 0;
+       while (1) {
+               if (p + 128 > end) {
+                       /* send partial packet */
+                       if (!xmodem_send_packet((char*)p, end-p)) aborted = 1;
+                       break;
+               } if ((u16)p == 0xb600) {
+                       /* we have an eeprom here. skip it. */
+                       p += 0x0200;
+                       continue;
+               } else if (!xmodem_send_packet((char*)p, 128)) {
+                       aborted = 1;
+                       break;
+               }
+               p += 128;
+       }
+
+       xmodem_finish_xfer();
+       sci_doing_xmodem = 0;
+       if (aborted)
+               send_string(CRLF "Transfer aborted." CRLF);
+       else
+               send_string(CRLF "Transfer complete." CRLF);
+}
+
 void quit() {
        if (my_strncmp("UIT", (char*)sci_rx_buf+1, 3))
                send_string("013 You can't quit you doofus." CRLF);
@@ -315,6 +404,9 @@ void quit() {
                unknown_command();
 }
 
+//SHA1_CTX ctx;
+//u8 sha1_digest[SHA1_SIGNATURE_SIZE];
+
 int main() {
        u8 i;
        for (i = 0; i < 11; i++)
@@ -336,7 +428,6 @@ int main() {
 
        set_msg("  CRUEL   ");
 
-       //comm_init();
        //coinmech_init();
        sci_init();
        keypad_init();
@@ -351,6 +442,9 @@ int main() {
        chime_start();
 
        send_string("5N4X0RZ R US" CRLF);
+
+       mic_challenge = 0;
+       mic_set_secret("ABCDEFGH12345678");
        
        last_standalone = is_standalone();
        if (last_standalone)
@@ -372,7 +466,8 @@ int main() {
                        last_door_open = door_open();
                        send_door_msg(last_door_open);
                        chime_start();
-                       set_msg(last_door_open?"DOOR OPEN ":"DOOR CLOSE");
+                       if (is_standalone())
+                               set_msg(last_door_open?"DOOR OPEN ":"DOOR CLOSE");
                }
 
                if (last_standalone != is_standalone()) {
@@ -414,6 +509,9 @@ int main() {
                                case 'B': 
                                        do_chime();
                                        break;
+                               case 'C': 
+                                       do_silence();
+                                       break;
                                case 'P':
                                        ping_pong();
                                        break;
@@ -429,6 +527,9 @@ int main() {
                                case 'Q':
                                        quit();
                                        break;
+                               case 'G':
+                                       getrom();
+                                       break;
                                default:
                                        // shurg
                                        unknown_command();

UCC git Repository :: git.ucc.asn.au