OBJS = \
motors.o keypad.o display_basic.o coinmech.o chime.o \
helpers.o main_basic.o sci.o \
- vectors.o start.o romsrc.o xmodem.o
+ vectors.o start.o romsrc.o xmodem.o mic.o
INCLUDES = vend.h keypad.h chime.h asm.h display_basic.h ports.h types.h
# debugging doesn't get compiled into the ROM image
CFLAGS = -m68hc11 -mshort -Wall -O1 \
- -msoft-reg-count=0 -ffixed-z -g -fomit-frame-pointer
+ -msoft-reg-count=0 -ffixed-z -g #-fomit-frame-pointer
LDFLAGS = -m68hc11 -mshort -Wl,-m,m68hc11elfb \
-nostartfiles \
+ -Wl,-defsym,_nvram=0x0800 \
-Wl,-defsym,_io_ports=0x1000 \
-Wl,-defsym,_switch_input=0x1800 \
-Wl,-defsym,_misc_input=0x2000 \
#include "chime.h"
volatile u8 chime_count;
+volatile u8 unchime_count; /* silence counter */
void chime() {
/* called from the RTI interrupt, sees if we need to turn the chime on or
--chime_count; /* interrupts masked here, so this won't result in badness */
} else
chime_off();
+ if (unchime_count) --unchime_count;
}
#define CHIME_TIME 5 /* number of RTIs to have the chime on (6.6ms each) */
extern volatile u8 chime_count;
+extern volatile u8 unchime_count;
/* outside world interface */
extern inline void chime_start() { chime_count = CHIME_TIME; }
+extern inline void unchime_start() { unchime_count = CHIME_TIME; }
extern inline void chime_for(u8 time) { chime_count = time; }
+extern inline void unchime_for(u8 time) { unchime_count = time; }
void chime(); /* RTI interrupt */
char* c;
for (c = dst; c < dst+count; c++) *c = val;
}
+
+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'-10;
+ 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;
+}
+
#include "sci.h"
#include "vend.h"
#include "xmodem.h"
-//#include "sha1.h"
+#include "mic.h"
u8 last_standalone;
u8 last_switch_input;
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];
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'-10;
- 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')
+ 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) {
}
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() {
chime_start();
send_string("5N4X0RZ R US" CRLF);
+
+ mic_challenge = 0;
+ mic_set_secret("ABCDEFGH12345678");
last_standalone = is_standalone();
if (last_standalone)
}
if (sci_have_packet) {
- if (must_verify()) {
- //SHA1_Init(&ctx);
- //SHA1_Update(&ctx, sci_rx_buf, my_strlen(sci_rx_buf));
- //SHA1_Final(sha1_digest, &ctx);
- }
switch (sci_rx_buf[0]) {
case '\0':
case '#':
case 'B':
do_chime();
break;
+ case 'C':
+ do_silence();
+ break;
case 'P':
ping_pong();
break;
#include "vend.h"
-#define BUFFER_LEN 12
+#define BUFFER_LEN 20
#define CRLF "\r\n"
#define SERIAL_TIMEOUT -2
#!/usr/bin/perl -w
# keep the format of this next line the same to match regex in check-romsrc.pl
-$origin = 0x9800;
+$origin = 0x9d80;
$hole_start = 0xb600;
$hole_size = 0x0200;
#define home_sensors _home_sensors
#define is_standalone() (misc_input & 0x01) /* DIP sw 1 */
-#define must_verify() (misc_input & 0x02) /* DIP sw 2 */
+#define must_verify() !(misc_input & 0x02) /* DIP sw 2 */
extern u16 _stack;
+extern char _nvram[]; /* 2048 bytes of nvram! */
+// uncomment for testing. char _nvram[20]; /* 2048 bytes of nvram! */
+/* NVRAM map:
+ *
+ * START LEN
+ * 0x800 0x02 mic.h - current challenge
+ * 0x802 0x10 mic.h - current secret password
+ * 0x812
+ *
+ */
/******* from helpers.c *******/
void delay(u16 ms);
bool my_strncmp(char* a, char* b, u8 len);
void my_memcpy(char* dst, char* src, u8 size);
void my_memset(char* dst, u8 val, u16 count);
+char* u82hex(u8 a);
+u8 hex2u8(char msb, char lsb);
+char nibble2hexchar(u8 b);
+u8 hexchar2u8(char b);
/******** Some meaningful bits ******/
#define PORTA_CHIME 0x10 /* chime is on when set */
/* Calculate a CRC-16 for the LEN byte message pointed at by P. */
/* Pads with ^Z up to 128 bytes if told to */
-static unsigned short
-docrc (unsigned char *p, int len, bool pad)
+unsigned short
+docrc (unsigned char *p, short len, bool pad, unsigned short crc)
{
- int len2 = len;
- unsigned short crc = 0;
+ short len2 = len;
- while (len-- > 0)
- crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++];
+ while (len-- > 0) {
+ crc = (crc << 8) ^ (crctab[(crc >> 8) ^ *p]);
+ p++;
+ }
if (pad && len2 < 128) {
len = 128-len;
while (len-- > 0)
if (crcflag) {
u16 crc;
- crc = docrc ((unsigned char*)packet, len, 1);
+ crc = docrc ((unsigned char*)packet, len, 1, 0);
s[0] = crc >> 8;
s[1] = crc & 0xff;
void xmodem_finish_xfer ();
#define XMODEM_DATASIZE 128 /* The data size is ALWAYS 128 */
-#define XMODEM_1KDATASIZE 1024 /* Unless it's 1024!!! */
#define XMODEM_PACKETSIZE 133 /* data + packet headers and crc */
-#define XMODEM_1KPACKETSIZE 1024 + 5 /* data + packet headers and crc */
-#define XMODEM_DATAOFFSET 3 /* Offset to start of actual data */
+
+unsigned short docrc (unsigned char *p, short len, bool pad, unsigned short crcstart);