diff --git a/.ev3duder b/.ev3duder index a96aa0e..4202bc4 100644 --- a/.ev3duder +++ b/.ev3duder @@ -1 +1 @@ -.. \ No newline at end of file +COM3 \ No newline at end of file diff --git a/Makefile b/Makefile index 7ff508b..32b59a7 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ print-% : ; @echo $* = $($*) ifeq ($(OS),Windows_NT) RM = del /Q FLAGS += -municode +SRCS += src/btwin.c BIN_NAME := $(addsuffix .exe, $(BIN_NAME)) else SRCS += src/btunix.c diff --git a/cat.c b/cat.c new file mode 100644 index 0000000..c489f8e --- /dev/null +++ b/cat.c @@ -0,0 +1,9 @@ +/** @file cat.sh + * @brief cat(1) wrapper for cat'ing to the ev3 LCD + * @author Ahmad Fatoum + */ + +int main(void) +{ + +} \ No newline at end of file diff --git a/cat.sh b/cat.sh new file mode 100644 index 0000000..cc68847 --- /dev/null +++ b/cat.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +## @file cat.sh +## cat(1) wrapper for cat'ing to the ev3 LCD +## calls cat on input, builds a bytecode executable +## and pipes it to the VM via netcat +## @author Ahmad Fatoum + +#consts +LINE_WIDTH = 20 + + +CAT = "$(cat $@)" + +IFS = '\n' read -ra LINE <<< "$IN" +for i in "${LINE[@]}"; do + # loop for each < LINE_WIDTH + # generate bytecode + +done + diff --git a/ev3duder.zip b/ev3duder.zip new file mode 100644 index 0000000..a86538e Binary files /dev/null and b/ev3duder.zip differ diff --git a/src/btserial.h b/src/btserial.h index e3c1f54..7effd33 100644 --- a/src/btserial.h +++ b/src/btserial.h @@ -5,8 +5,14 @@ */ #include "defs.h" -void *bt_open(void); + +#ifdef _WIN32 +void *bt_open(const wchar_t *device); +#else +void *bt_open(const char *device); +#endif int bt_write(void* fd, const u8* buf, size_t count); int bt_read(void* fd, u8* buf, size_t count, int milliseconds); +void bt_close(void*); const wchar_t *bt_error(void* fd); diff --git a/src/btunix.c b/src/btunix.c index 3870f41..abe1a82 100644 --- a/src/btunix.c +++ b/src/btunix.c @@ -18,11 +18,11 @@ #define BT "/dev/cu.EV3-SerialPort" // ^ TODO: add ability to find differently named EV3's static void handle_sigint(int signo); -void *bt_open() +void *bt_open(const char *file) { - // signal(SIGINT, handle_sigint); + // signal(SIGINT, handle_sigint); int *fd = malloc(sizeof(int)); - *fd = open(BT, O_RDWR); + *fd = open(file ?: BT, O_RDWR); return *fd != -1 ? fd : NULL; } @@ -48,7 +48,7 @@ static void handle_alarm(int sig) (void)sig; longjmp(env, 1); } int bt_read(void* fd_, u8* buf, size_t count, int milliseconds) -{ // goto <3 +{ //FIXME: goto <3 (void)count; (void)milliseconds; int fd = *(int*)fd_; @@ -68,7 +68,7 @@ int bt_read(void* fd_, u8* buf, size_t count, int milliseconds) for (ssize_t ret=recvd; recvd < packet_len; recvd += ret) { if (milliseconds != -1) { - setitimer(ITIMER_REAL, &timer, NULL); + setitimer(ITIMER_REAL, &timer, NULL); //TODO: maybe move this out the loop? would handle diosconnects that way ret = read(fd, buf+recvd, packet_len-recvd); alarm(0); }else @@ -91,5 +91,9 @@ int bt_read(void* fd_, u8* buf, size_t count, int milliseconds) return recvd; } +void bt_close(void *handle) +{ + close(*(int*)handle); +} const wchar_t *bt_error(void* fd_) { (void)fd_; return L"Errors not implemented yet";} diff --git a/src/btwin.c b/src/btwin.c new file mode 100644 index 0000000..4f8a2cc --- /dev/null +++ b/src/btwin.c @@ -0,0 +1,45 @@ +/** + * @file io.c - Input/Output wrappers for Bluetooth (Win32) + * @author Ahmad Fatoum + * @license Code available under terms of the GNU General Public License + */ +#include +#include + +#include + +#include "defs.h" + +#define BT L"COM1" + +// ^ TODO: add multiple COM ports +void *bt_open(const wchar_t *device) +{ + HANDLE handle = CreateFileW(device ?: BT, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + return handle != INVALID_HANDLE_VALUE ? handle : NULL; +} + +int bt_write(void* handle, const u8* buf, size_t count) +{ + DWORD dwBytesWritten; + + buf++;count--; // omit HID report number + if (!WriteFile(handle, buf, count, &dwBytesWritten, NULL)) + return -1; + + return dwBytesWritten; +} +int bt_read(void *handle, u8* buf, size_t count, int milliseconds) +{ + (void) milliseconds; // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363190%28v=vs.85%29.aspx + DWORD dwBytesRead; + if (!ReadFile(handle, buf, count, &dwBytesRead, NULL)) + return -1; + return dwBytesRead; +} +void bt_close(void *handle) +{ + CloseHandle(handle); +} +const wchar_t *bt_error(void* fd_) { (void)fd_; return L"Errors not implemented yet";} + diff --git a/src/cat.c b/src/cat.c new file mode 100644 index 0000000..26d1244 --- /dev/null +++ b/src/cat.c @@ -0,0 +1,25 @@ +#include +#include +#include + +#include "ev3_io.h" + +#include "defs.h" +#include "systemcmd.h" +#include "error.h" +#include "funcs.h" + +/** + * @brief Concatenate files to the LCD screen. + * @param [in] path remote FILE*s + * @param [in] count number of FILE*s to cat + * + * @retval error according to enum #ERR + * @see http://topikachu.github.io/python-ev3/UIdesign.html + */ +#define MAX_READ 1024 +extern int cat(const char *rem, size_t count) +{ + + +} \ No newline at end of file diff --git a/src/ev3_io.h b/src/ev3_io.h index 953a3c5..cc9e15d 100644 --- a/src/ev3_io.h +++ b/src/ev3_io.h @@ -12,7 +12,7 @@ EXTERN int (*ev3_write)(void *, const u8*, size_t); EXTERN int (*ev3_read_timeout)(void *, u8*, size_t, int milliseconds); EXTERN const wchar_t* (*ev3_error)(void *); - +EXTERN void(*ev3_close)(void*); EXTERN void *handle; #endif diff --git a/src/funcs.h b/src/funcs.h index 6a8a244..fdd896d 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -14,6 +14,7 @@ #define EV3DUDER_FUNCS_H #include +#include /** * @name EV3 commands * @brief EV3 USB-served commands @@ -29,18 +30,28 @@ //! upload local file loc to remote destination rem extern int up(FILE* loc, const char *rem); + //! download remote source \p rem to local file \p loc extern int dl(const char *rem, FILE* loc); + //! print HID information, beep and exit extern int test(void); + //! run remote .rbf file \p rem via VM extern int run(const char *rem); + //! list contents of remote directory \p rem extern int ls(const char *rem); + +//! concatenate contents of \p count of \p rem FILEs to the EV3's LCD +extern int cat(const char *rem, size_t count); + //! remove remote file or directory \p rem extern int rm(const char *rem); + //! create directory \p rem on remote system extern int mkdir(const char *rem); + //! fill \p *buf with a rbf file executing \p cmd extern size_t mkrbf(char **buf, const char *cmd); #endif diff --git a/src/ls.c b/src/ls.c index 989106e..03be5fa 100644 --- a/src/ls.c +++ b/src/ls.c @@ -18,6 +18,7 @@ * @see http://topikachu.github.io/python-ev3/UIdesign.html * @bug Doesn't handle replies over 1000 byte in length. * implementation of \p CONTINUTE_LIST_FILES would be required + * EDIT: CONTINUE_LIST_FILES isn't even implemented in "firmware". */ #define MAX_READ 1024 int ls(const char *path) @@ -61,7 +62,7 @@ int ls(const char *path) errmsg = "`LIST_FILES` was denied."; return ERR_VM; } - fputs(listrep->list, stdout); + fwrite(listrep->list, 1, listrep->packetLen - 10, stdout); // No NUL Termination over Serial COM for whatever reason. // // From the LEGO docs: - LIST_FILES should work as long as list does not exceed 1014 bytes. CONTINUE_LISTFILES has NOT been implemented yet. #if !LEGO_FIXED_CONTINUE_LIST_FILES diff --git a/src/utf8.h b/src/utf8.h index ff786ad..12a9add 100644 --- a/src/utf8.h +++ b/src/utf8.h @@ -19,6 +19,7 @@ u8str[u8sz] = '\0'; \ WideCharToMultiByte(CP_UTF8, 0, wstr, len, u8str, u8sz, NULL, NULL); \ u8str; }) +#define fgetts fgetws #else #define tchar char @@ -28,6 +29,7 @@ #define tstrchr(str, chr) strchr(str, chr) #define tstrlen(str) strlen(str) #define tgetenv(str) getenv(str) +#define fgetts fgets #define PRIts "s" #define U8(path, len) ((void)len, path) #endif diff --git a/test.c b/test.c new file mode 100644 index 0000000..20e13c2 --- /dev/null +++ b/test.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +#include +#include "src/btserial.h" +static const unsigned char tone[] = "\x0\x0F\x00\0\0\x80\x00\x00\x94\x01\x81\x02\x82\xE8\x03\x82\xE8\x03"; + +#define MAX_STR 256 + +int main(int argc, char *argv[]) +{ + HANDLE handle = bt_open(L"COM3"); + int written = bt_write(handle, tone, sizeof tone - 1); + CloseHandle(handle); + printf("Wrote %d bytes of %u", written, sizeof tone-1); + return 0; +} +