diff --git a/.autotools b/.autotools deleted file mode 100644 index 39db8f3..0000000 --- a/.autotools +++ /dev/null @@ -1,42 +0,0 @@ - - - - - diff --git a/.gitignore b/.gitignore index 0df5f09..9341548 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ *.dylib # Executables +umtool *.exe *.out *.app @@ -57,6 +58,7 @@ config.guess config.sub depcomp ltmain.sh +.autotools m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 diff --git a/21-ultimarc.rules b/21-ultimarc.rules index 74688c5..c4c942b 100644 --- a/21-ultimarc.rules +++ b/21-ultimarc.rules @@ -8,6 +8,7 @@ ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="05 ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="0502", MODE:="666" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="0503", MODE:="666" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="0504", MODE:="666" +ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="1200", MODE:="666" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="1401", MODE:="666" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="1402", MODE:="666" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="1403", MODE:="666" diff --git a/README.md b/README.md index e2a0f79..e0db87d 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ This library and command line utility support 2012 through 2015 boards. If you #### Required Libraries To build this tool the following libraries need to be install on your system. -* json-c (0.11), -* libusb-dev (1.0.18) +* json-c (0.11), site +* libusb-1.0 (1.0.18), site * libtool #### UDEV Rule: @@ -28,7 +28,7 @@ If you need extra debug statements for the IPac boards then run the following * make The executable will be in src/umtool directory and named umtool.out. -* ./umtool.out ipac2.json +* ./umtool ipac2.json #### Donations: Click here to lend your support to: Ultimarc-Linux and make a donation at pledgie.com ! diff --git a/configure.ac b/configure.ac index 329cfd1..82cff4a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(Ultimarc-linux, 0.1) +AC_INIT(Ultimarc-linux, 1.0) AC_CANONICAL_HOST AM_INIT_AUTOMAKE() @@ -29,7 +29,7 @@ CPPFLAGS="-I$KERNEL_HEADERS_DIR/include" AX_PKG_CHECK_MODULES([JSON], [], [json-c >= 0.11]) AX_PKG_CHECK_MODULES([LIBUSB], [], [libusb-1.0 >= 1.0.18]) -AC_SUBST([ULTIMARC_LIB_VERSION], [0.1]) +AC_SUBST([ULTIMARC_LIB_VERSION], [1.0]) AC_CONFIG_FILES([Makefile src/libs/Makefile diff --git a/src/libs/Makefile.am b/src/libs/Makefile.am index c604c94..ddafbf2 100644 --- a/src/libs/Makefile.am +++ b/src/libs/Makefile.am @@ -4,9 +4,10 @@ AM_CFLAGS = $(JSON_CFLAGS) $(LIBUSB_CFLAGS) AM_LDFLAGS = $(JSON_LIBS) $(LIBUSB_LIBS) -lib_LTLIBRARIES = libultimarc-0.1.la -libultimarc_0_1_la_SOURCES = ultimarc.c ipac.c ultistik.c pacLED.c common.c pacdrive.c ipacultimate.c ipacseries.c +lib_LTLIBRARIES = libultimarc.la +libultimarc_la_SOURCES = ultimarc.c ipac.c ultistik.c pacLED.c common.c pacdrive.c ipacultimate.c ipacseries.c ulboard.c usbbutton.c ipac.h ultistik.h pacLED.h common.h pacdrive.h ipacultimate.h dbg.h ipacseries.h usbbutton.h +libultimarc_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 otherincludedir = $(includedir)/ultimarc -otherinclude_HEADERS = ultimarc.h ipac.h ultistik.h pacLED.h common.h pacdrive.h ipacultimate.h dbg.h ipacseries.h +otherinclude_HEADERS = ultimarc.h ulboard.h diff --git a/src/libs/dbg.h b/src/libs/dbg.h index fb1d57f..2b3f072 100644 --- a/src/libs/dbg.h +++ b/src/libs/dbg.h @@ -24,9 +24,9 @@ #define clean_errno() (errno == 0 ? "None" : strerror(errno)) -#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) +#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) -#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) +#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__) diff --git a/src/libs/ipac.c b/src/libs/ipac.c index 82182af..cf96044 100644 --- a/src/libs/ipac.c +++ b/src/libs/ipac.c @@ -18,44 +18,37 @@ #include /* Local */ +#include "ulboard.h" #include "common.h" #include "ipac.h" #include "ipacseries.h" #include "dbg.h" -struct ipac pIPAC; - -bool isIPACConfig (const char* prodStr, int version, json_object* jobj) +bool isIPACConfig (json_object* jobj, ulboard* board) { bool isBoardCfg = false; - pIPAC.version = version; - pIPAC.ipac2 = (strcmp(prodStr, IPAC_STR_2) == 0); - pIPAC.minipac = (strcmp(prodStr, IPAC_STR_M) == 0); - pIPAC.ipac4 = (strcmp(prodStr, IPAC_STR_4) == 0); - pIPAC.jpac = (strcmp(prodStr, JPAC_STR) == 0); - - if (pIPAC.ipac2) + if (board->type == ulboard_type_ipac2) { - isBoardCfg = validateIPACData(jobj, 32); + isBoardCfg = validateIPACData(jobj, 32, board); } - else if (pIPAC.ipac4) + else if (board->type == ulboard_type_ipac4) { - isBoardCfg = validateIPAC4Data(jobj); + isBoardCfg = validateIPAC4Data(jobj, board); } - else if (pIPAC.minipac) + else if (board->type == ulboard_type_minipac) { - isBoardCfg = validateIPACData(jobj, 32); + isBoardCfg = validateIPACData(jobj, 32, board); } - else if (pIPAC.jpac) + else if (board->type == ulboard_type_jpac) { - isBoardCfg = validateIPACData(jobj, 30); + isBoardCfg = validateIPACData(jobj, 30, board); } return isBoardCfg; } -bool validateIPACData(json_object* jobj, int size) +bool validateIPACData(json_object* jobj, int size, ulboard* board) { bool valid = true; json_object* tmp = NULL; @@ -119,12 +112,12 @@ bool validateIPACData(json_object* jobj, int size) } } - valid = validateIPACMacros(jobj, valid); + valid = validateIPACMacros(jobj, valid, board); return valid; } -bool validateIPAC4Data (json_object* jobj) +bool validateIPAC4Data (json_object* jobj, ulboard* board) { bool valid = true; @@ -203,12 +196,12 @@ bool validateIPAC4Data (json_object* jobj) } } - valid = validateIPACMacros(jobj, valid); + valid = validateIPACMacros(jobj, valid, board); return valid; } -bool validateIPACMacros(json_object* jobj, bool validState) +bool validateIPACMacros(json_object* jobj, bool validState, ulboard* board) { bool valid = validState; @@ -253,7 +246,7 @@ bool validateIPACMacros(json_object* jobj, bool validState) } else { - if (pIPAC.version == 1) + if (board->version == ulboard_version_pre2015) { if (json_object_array_length(macro) != maxKeyCount) { @@ -289,12 +282,12 @@ bool validateIPACMacros(json_object* jobj, bool validState) } } - if ((pIPAC.version == 1) && (macroCount > maxMacroCount)) + if ((board->version == ulboard_version_pre2015) && (macroCount > maxMacroCount)) { log_err("The number of macros defined is '%i'. 4 macro entries are allowed.", macroCount); valid = false; } - else if (pIPAC.version == 2) + else if (board->version == ulboard_version_2015) { if (macroCount2015 > maxMacroCount2015) { @@ -314,16 +307,16 @@ bool validateIPACMacros(json_object* jobj, bool validState) return valid; } -bool updateBoardIPAC (json_object *jobj) +bool updateBoardIPAC (json_object *jobj, ulboard *board) { bool result = false; int bprod = 0; unsigned char* barray = NULL; - switch (pIPAC.version) + switch (board->version) { - case 1: - if (pIPAC.ipac2) + case ulboard_version_pre2015: + if (board->type == ulboard_type_ipac2) { log_info ("Updating IPAC2 board..."); barray = calloc(IPAC_SIZE_PRE_2015, sizeof(unsigned char)); @@ -338,7 +331,7 @@ bool updateBoardIPAC (json_object *jobj) } } - if (pIPAC.minipac) + if (board->type == ulboard_type_minipac) { log_info ("Updating MinIPAC board..."); barray = calloc(IPAC_SIZE_PRE_2015, sizeof(unsigned char)); @@ -353,7 +346,7 @@ bool updateBoardIPAC (json_object *jobj) } } - if (pIPAC.ipac4) + if (board->type == ulboard_type_ipac4) { log_info ("Updating IPAC4 board..."); barray = calloc((IPAC_SIZE_PRE_2015 * 2), sizeof(unsigned char)); @@ -370,32 +363,32 @@ bool updateBoardIPAC (json_object *jobj) } break; - case 2: + case ulboard_version_2015: barray = calloc(IPACSERIES_SIZE, sizeof(unsigned char)); if (barray != NULL) { - if (pIPAC.ipac2) + if (board->type == ulboard_type_ipac2) { log_info ("Updating IPAC2 board..."); bprod = IPAC_2_PRODUCT; update2015IPAC2Board(jobj, barray); } - else if (pIPAC.minipac) + else if (board->type == ulboard_type_minipac) { log_info ("Updating MinIPAC board..."); bprod = IPAC_M_PRODUCT; update2015MinIPACBoard(jobj, barray); } - else if (pIPAC.ipac4) + else if (board->type == ulboard_type_ipac4) { log_info ("Updating IPAC4 board..."); bprod = IPAC_4_PRODUCT; update2015IPAC4Board(jobj, barray); } - else if (pIPAC.jpac) + else if (board->type == ulboard_type_jpac) { log_info ("Updating JPAC board..."); bprod = JPAC_PRODUCT; diff --git a/src/libs/ipac.h b/src/libs/ipac.h index eaac080..c89c174 100644 --- a/src/libs/ipac.h +++ b/src/libs/ipac.h @@ -17,12 +17,6 @@ extern "C" { #endif -/* Required items in the json file for IPAC2, MINIPAC, IPAC4 and JPAC cards */ -#define IPAC_STR_2 "ipac2" -#define IPAC_STR_M "minipac" -#define IPAC_STR_4 "ipac4" -#define JPAC_STR "jpac" - /* Required items for writing out through the USB port */ #define IPAC_VENDOR_PRE_2015 0xD208 #define IPAC_VENDOR_2015 0xD209 @@ -35,19 +29,11 @@ extern "C" { #define IPAC_INTERFACE 2 typedef struct json_object json_object; +typedef struct ulboard ulboard; -struct ipac -{ - int version; - bool minipac; - bool ipac2; - bool ipac4; - bool jpac; -}; - -bool isIPACConfig (const char* prodStr, int version, json_object* jobj); -bool validateIPACData(json_object* jobj, int size); -bool validateIPAC4Data(json_object* jobj); +bool isIPACConfig (json_object* jobj, ulboard* board); +bool validateIPACData(json_object* jobj, int size, ulboard* board); +bool validateIPAC4Data(json_object* jobj, ulboard* board); /* * macros are optional. @@ -59,12 +45,12 @@ bool validateIPAC4Data(json_object* jobj); * limit of 85 bytes for the complete macro group (2015 boards) * */ -bool validateIPACMacros(json_object* jobj, bool valid); +bool validateIPACMacros(json_object* jobj, bool valid, ulboard* board); /* * Writes the data out to the board. */ -bool updateBoardIPAC (json_object *jobj); +bool updateBoardIPAC (json_object *jobj, ulboard* board); void updatePre2015IPAC2Board (json_object *jobj, unsigned char* barray); diff --git a/src/libs/ipacseries.c b/src/libs/ipacseries.c index 610b257..832abd6 100644 --- a/src/libs/ipacseries.c +++ b/src/libs/ipacseries.c @@ -142,6 +142,8 @@ convertIPACSeries (json_object* jobj) retval = 0x2F; if (!strcasecmp(str, "]")) retval = 0x30; + if (!strcasecmp(str, "non US #")) + retval = 0x32; if (!strcasecmp(str, "'")) retval = 0x34; if (!strcasecmp(str, "`")) @@ -238,7 +240,7 @@ convertIPACSeries (json_object* jobj) retval = 0x62; if (!strcasecmp(str, "KP .")) retval = 0x63; - if (!strcasecmp(str, "\\")) + if (!strcasecmp(str, "\\") || !strcasecmp(str, "NON US \\")) retval = 0x64; if (!strcasecmp(str, "APP")) retval = 0x65; @@ -252,6 +254,8 @@ convertIPACSeries (json_object* jobj) retval = 0x71; if (!strcasecmp(str, "ALT L")) retval = 0x72; + if (!strcasecmp(str, "WIN L")) + retval = 0x73; if (!strcasecmp(str, "CTRL R")) retval = 0x74; if (!strcasecmp(str, "SHIFT R")) @@ -376,15 +380,15 @@ convertIPACSeries (json_object* jobj) retval = 0xe0; if (!strcasecmp(str, "m2")) retval = 0xe1; - if (!strcasecmp(str, "m3")) + if (!strcasecmp(str, "m3") || !strcasecmp(str, "MUTE")) retval = 0xe2; - if (!strcasecmp(str, "m4")) + if (!strcasecmp(str, "m4") || !strcasecmp(str, "PLAY/PAUSE")) retval = 0xe3; - if (!strcasecmp(str, "m5")) + if (!strcasecmp(str, "m5") || !strcasecmp(str, "NEXT")) retval = 0xe4; - if (!strcasecmp(str, "m6")) + if (!strcasecmp(str, "m6") || !strcasecmp(str, "PREV")) retval = 0xe5; - if (!strcasecmp(str, "m7")) + if (!strcasecmp(str, "m7") || !strcasecmp(str, "STOP")) retval = 0xe6; if (!strcasecmp(str, "m8")) retval = 0xe7; @@ -404,35 +408,35 @@ convertIPACSeries (json_object* jobj) retval = 0xee; if (!strcasecmp(str, "m16")) retval = 0xef; - if (!strcasecmp(str, "m17")) + if (!strcasecmp(str, "m17") || !strcasecmp(str, "EMAIL")) retval = 0xf0; - if (!strcasecmp(str, "m18")) + if (!strcasecmp(str, "m18") || !strcasecmp(str, "SEARCH")) retval = 0xf1; - if (!strcasecmp(str, "m19")) + if (!strcasecmp(str, "m19") || !strcasecmp(str, "BOOKMARKS")) retval = 0xf2; - if (!strcasecmp(str, "m20")) + if (!strcasecmp(str, "m20") || !strcasecmp(str, "OPEN BROWSER")) retval = 0xf3; - if (!strcasecmp(str, "m21")) + if (!strcasecmp(str, "m21") || !strcasecmp(str, "WEB BACK")) retval = 0xf4; - if (!strcasecmp(str, "m22")) + if (!strcasecmp(str, "m22") || !strcasecmp(str, "WEB FORWARD")) retval = 0xf5; - if (!strcasecmp(str, "m23")) + if (!strcasecmp(str, "m23") || !strcasecmp(str, "WEB STOP")) retval = 0xf6; - if (!strcasecmp(str, "m24")) + if (!strcasecmp(str, "m24") || !strcasecmp(str, "WEB REFRESH")) retval = 0xf7; - if (!strcasecmp(str, "m25")) + if (!strcasecmp(str, "m25") || !strcasecmp(str, "MEDIA PLAYER")) retval = 0xf8; if (!strcasecmp(str, "m26")) retval = 0xf9; - if (!strcasecmp(str, "m27")) + if (!strcasecmp(str, "m27") || !strcasecmp(str, "CALCULATOR")) retval = 0xfa; if (!strcasecmp(str, "m28")) retval = 0xfb; - if (!strcasecmp(str, "m29")) + if (!strcasecmp(str, "m29") || !strcasecmp(str, "EXPLORER")) retval = 0xfc; if (!strcasecmp(str, "m30")) retval = 0xfd; - if (!strcasecmp(str, "m31")) + if (!strcasecmp(str, "m31") || !strcasecmp(str, "WAIT 3 SEC")) retval = 0xfe; } diff --git a/src/libs/ipacultimate.c b/src/libs/ipacultimate.c index 884b361..c573e78 100644 --- a/src/libs/ipacultimate.c +++ b/src/libs/ipacultimate.c @@ -20,39 +20,22 @@ #include "ipacultimate.h" #include "ipacseries.h" #include "dbg.h" +#include "ulboard.h" struct ipacultimate pLED; -bool isIPACUltimateConfig(const char* prodStr, int version, json_object* jobj) +bool isIPACUltimateConfig(json_object* jobj, ulboard* board) { bool isBoardCfg = false; - if (strcmp(prodStr, IPACULTIMATE_PRODUCT_STR) == 0 || - strcmp(prodStr, IPACULTIMATE_STR) == 0) + if (board->type == ulboard_type_ultimate) { - if (version >= IPACULTIMATE_VERSION_MIN && - version <= IPACULTIMATE_VERSION_MAX) - { - if (version == 1) - { - isBoardCfg = validateIPacUltimateData(jobj); - } - } + isBoardCfg = validateIPacUltimateData(jobj); } return isBoardCfg; } -const char* getIPacUltimateProductStr () -{ - return IPACULTIMATE_PRODUCT_STR; -} - -int getIPacUltimateVersion() -{ - return IPACULTIMATE_VERSION_MIN; -} - bool validateIPacUltimateData(json_object* jobj) { const char invalidKey = 0x00; diff --git a/src/libs/ipacultimate.h b/src/libs/ipacultimate.h index a3108c3..5a3cc3e 100644 --- a/src/libs/ipacultimate.h +++ b/src/libs/ipacultimate.h @@ -17,11 +17,6 @@ extern "C" { #endif -#define IPACULTIMATE_VERSION_MIN 1 -#define IPACULTIMATE_VERSION_MAX 2 -#define IPACULTIMATE_PRODUCT_STR "0410" -#define IPACULTIMATE_STR "ULTIMATE" - /* Required items for writing out through the USB port */ #define IPACULTIMATE_VENDOR 0xD209 #define IPACULTIMATE_PRODUCT 0x0410 @@ -31,6 +26,7 @@ extern "C" { #define IPACULTIMATE_DATA_SIZE 260 typedef struct json_object json_object; +typedef struct ulboard ulboard; struct ipacultimate { @@ -45,9 +41,7 @@ struct ipacultimate /* * Determine if the json file is an IPac Ultimate configuration */ -bool isIPACUltimateConfig(const char* prodStr, int version, json_object* jobj); -const char* getIPacUltimateProductStr (); -int getIPacUltimateVersion(); +bool isIPACUltimateConfig(json_object* jobj, ulboard* board); bool validateIPacUltimateData(json_object* jobj); /** populates the data array from the json configuration file */ diff --git a/src/libs/pacLED.c b/src/libs/pacLED.c index 8111d99..f35f713 100644 --- a/src/libs/pacLED.c +++ b/src/libs/pacLED.c @@ -20,35 +20,22 @@ #include "common.h" #include "pacLED.h" #include "dbg.h" +#include "ulboard.h" struct pacLED pLED; -bool isPACLED64Config(const char* prodStr, int version, json_object* jobj) +bool isPACLED64Config(json_object* jobj, ulboard* board) { bool isBoardCfg = false; - if (strcmp(prodStr, PACLED_PRODUCT_STR) == 0 || - strcmp(prodStr, PACLED_STR) == 0) + if (board->type == ulboard_type_pacLED) { - if (version == PACLED_VERSION) - { - isBoardCfg = validatePacLED64Data(jobj); - } + isBoardCfg = validatePacLED64Data(jobj); } return isBoardCfg; } -const char* getPacLED64ProductStr () -{ - return PACLED_PRODUCT_STR; -} - -int getPacLED64Version() -{ - return PACLED_VERSION; -} - bool validatePacLED64Data(json_object* jobj) { bool valid = false; diff --git a/src/libs/pacLED.h b/src/libs/pacLED.h index 15336cd..6ed22ab 100644 --- a/src/libs/pacLED.h +++ b/src/libs/pacLED.h @@ -17,10 +17,6 @@ extern "C" { #endif -#define PACLED_VERSION 1 -#define PACLED_PRODUCT_STR "1401" -#define PACLED_STR "PACLED64" - /* Required items for writing out through the USB port */ #define PACLED_VENDOR 0xD209 #define PACLED_PRODUCT 0x1401 @@ -34,6 +30,7 @@ extern "C" { #define PACLED_FADE_ALL_BASE 4 typedef struct json_object json_object; +typedef struct ulboard ulboard; struct pacLED { @@ -48,9 +45,7 @@ struct pacLED /* * Determine if the json file is an pacLED configuration */ -bool isPACLED64Config(const char* prodStr, int version, json_object* jobj); -const char* getPacLED64ProductStr (); -int getPacLED64Version(); +bool isPACLED64Config(json_object* jobj, ulboard* board); bool validatePacLED64Data(json_object* jobj); bool updateBoardPacLED (json_object* jobj); diff --git a/src/libs/pacdrive.c b/src/libs/pacdrive.c index 3f71db8..34b7e62 100644 --- a/src/libs/pacdrive.c +++ b/src/libs/pacdrive.c @@ -21,33 +21,19 @@ /* Local */ #include "common.h" #include "dbg.h" +#include "ulboard.h" -bool isPACDriveConfig(const char* prodStr, int version, json_object* jobj) +bool isPACDriveConfig(json_object* jobj, ulboard* board) { bool isBoardCfg = false; - - if (strcmp(prodStr, PACDRIVE_PRODUCT_STR) == 0 || - strcmp(prodStr, PACDRIVE_STR) == 0) + if (board->type == ulboard_type_pacDrive) { - if (version == PACDRIVE_VERSION) - { - isBoardCfg = validatePacDriveData(jobj); - } + isBoardCfg = validatePacDriveData(jobj); } return isBoardCfg; } -const char* getPacDriveProductStr () -{ - return PACDRIVE_PRODUCT_STR; -} - -int getPacDriveVersion() -{ - return PACDRIVE_VERSION; -} - bool validatePacDriveData(json_object* jobj) { bool valid = true; diff --git a/src/libs/pacdrive.h b/src/libs/pacdrive.h index 0d26056..50ff39c 100644 --- a/src/libs/pacdrive.h +++ b/src/libs/pacdrive.h @@ -17,10 +17,6 @@ extern "C" { #endif -#define PACDRIVE_VERSION 1 -#define PACDRIVE_PRODUCT_STR "1500" -#define PACDRIVE_STR "PACDrive" - /* Required items for writing out through the USB port */ #define PACDRIVE_VENDOR 0xD209 #define PACDRIVE_PRODUCT 0x1500 @@ -32,13 +28,12 @@ extern "C" { #define PACDRIVE_INTERFACE 0 typedef struct json_object json_object; +typedef struct ulboard ulboard; /* * Determine if the json file is an PAC drive configuration */ -bool isPACDriveConfig(const char* prodStr, int version, json_object* jobj); -const char* getPacDriveProductStr (); -int getPacDriveVersion(); +bool isPACDriveConfig(json_object* jobj, ulboard* board); bool validatePacDriveData(json_object* jobj); bool updateBoardPacDrive (json_object* jobj); diff --git a/src/libs/ulboard.c b/src/libs/ulboard.c new file mode 100644 index 0000000..cb99205 --- /dev/null +++ b/src/libs/ulboard.c @@ -0,0 +1,65 @@ +/* + ============================================================================ + Name : ulboard.c + Author : Katie Snow + Version : + Copyright : Copyright 2014 Robert Abram, Katie Snow + Description : Ultimarc board type and version + ============================================================================ + */ +#include + +#include "ulboard.h" +#include "dbg.h" + +#define ULSIZE(a) (sizeof(a)/sizeof(a[0])) +const char* ulBoardTypeName[] = + { "null", "IPAC2", "IPAC4", "JPAC", "MINIPAC", "ULTIMATE", + "PACDRIVE", "PACLED64", "ULTISTIK", "USBBUTTON" }; + +const char* ulBoardVersionName[] = + { "null", "PRE2015", "2015" }; + +const char* +ulBoardTypeToString (ulboard_type bType) +{ + int _bType = (int) bType; + + if (_bType < 0 || _bType >= (int)ULSIZE(ulBoardTypeName)) + { + log_err ("Board type %d is out of range [0,%d]", bType, + (int)ULSIZE(ulBoardTypeName)); + return NULL; + } + + return ulBoardTypeName[_bType]; +} + +ulboard_type +ulStringToBoardType (const char* bStr) +{ + int pos = 0; + for (pos = 0; pos < (int)ULSIZE(ulBoardTypeName); pos++) + { + debug ("'%s' = '%s'", bStr, ulBoardTypeName[pos]); + if (!strcasecmp (bStr, ulBoardTypeName[pos])) + { + return (ulboard_type) pos; + } + } + + return ulboard_type_null; +} + +ulboard_version +ulIntToBoardVersion (int bVersion) +{ + if (bVersion < 0 || bVersion >= (int)ULSIZE(ulBoardVersionName)) + { + log_err ("Board version %d is out of range [0,%d]", bVersion, + (int)ULSIZE(ulBoardVersionName)); + return ulboard_version_null; + } + + return (ulboard_version) bVersion; +} diff --git a/src/libs/ulboard.h b/src/libs/ulboard.h new file mode 100644 index 0000000..f1c210a --- /dev/null +++ b/src/libs/ulboard.h @@ -0,0 +1,60 @@ +/* + ============================================================================ + Name : ulboard.h + Author : Katie Snow + Version : + Copyright : Copyright 2014 Robert Abram, Katie Snow + Description : Ultimarc board types and structures + ============================================================================ + */ + +#ifndef ULTIMARCBOARD_H_ +#define ULTIMARCBOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* All the supported board types */ +typedef enum ulboard_type +{ + ulboard_type_null, + ulboard_type_ipac2, + ulboard_type_ipac4, + ulboard_type_jpac, + ulboard_type_minipac, + ulboard_type_ultimate, + ulboard_type_pacDrive, + ulboard_type_pacLED, + ulboard_type_ultistik, + ulboard_type_usbbutton +} ulboard_type; + +/* Supported versions */ +typedef enum ulboard_version +{ + ulboard_version_null, + ulboard_version_pre2015, + ulboard_version_2015 +} ulboard_version; + +/* Data structure */ +typedef struct ulboard +{ + ulboard_type type; + ulboard_version version; +} ulboard; + +extern const char* ulBoardTypeToString (ulboard_type bType); + +extern ulboard_type ulStringToBoardType (const char* bStr); + +extern ulboard_version ulIntToBoardVersion (int bVersion); + +#ifdef __cplusplus +} +#endif + + +#endif /* ULTIMARCBOARD_H_ */ diff --git a/src/libs/ultimarc.c b/src/libs/ultimarc.c index 6a6d99c..b48d312 100644 --- a/src/libs/ultimarc.c +++ b/src/libs/ultimarc.c @@ -6,7 +6,7 @@ Copyright : Copyright 2014 Robert Abram, Katie Snow Description : Ultimarc main configuration library ============================================================================ -*/ + */ /* Unix */ #include @@ -17,141 +17,241 @@ #include #include "ultimarc.h" +#include "ulboard.h" #include "ipac.h" #include "pacLED.h" #include "ultistik.h" #include "pacdrive.h" #include "ipacultimate.h" +#include "usbbutton.h" #include "dbg.h" +int +ulValidateConfig (json_object* bcfg, ulboard* ulcfg) +{ + int retCode = 0; + + if (bcfg && ulcfg) + { + retCode = ulGetProdAndVersion (bcfg, ulcfg); -void loadUltimarcConfigurations (int argc, char **argv) + if (retCode == 0) + { + if (isIPACConfig (bcfg, ulcfg) + || isIPACUltimateConfig (bcfg, ulcfg) + || isPACDriveConfig (bcfg, ulcfg) + || isPACLED64Config (bcfg, ulcfg) + || isUltistikConfig (bcfg, ulcfg) + || isUSBButtonConfig(bcfg, ulcfg)) + { + log_info("Configuration is %s. [Validated]", ulBoardTypeToString(ulcfg->type)); + } + else + { + retCode = -1; + log_err("Configuration is '%s'. [Not validated].", ulBoardTypeToString(ulcfg->type)); + } + } + else + { + retCode = -1; + log_err("Configuration is '%s'. [Not validated].", ulBoardTypeToString(ulcfg->type)); + } + } + else + { + retCode = -1; + log_err("JSON format invalid"); + } + + return retCode; +} + +int +ulValidateConfigFileStr (const char* file, ulboard* board) { - int idx; - int inner_idx; + json_object *bcfg = json_object_from_file (file); - const char* fileStr = NULL; + return ulValidateConfig (bcfg, board); +} - json_object *jobj = NULL; - json_object *innerobj = NULL; - json_object *item = NULL; +int +ulWriteToBoard (json_object* bcfg, ulboard* board) +{ + int retCode = 0; - for (idx = 1; idx < argc; ++idx) + if (bcfg && board) { - jobj = json_object_from_file (argv[idx]); - if (jobj) + if (board->type == ulboard_type_ipac2 || + board->type == ulboard_type_ipac4 || + board->type == ulboard_type_jpac || + board->type == ulboard_type_minipac) + { + retCode = updateBoardIPAC (bcfg, board); + } + else if (board->type == ulboard_type_ultimate) + { + log_info("Updating IPAC Ultimate board..."); + retCode = updateBoardIPacUltimate (bcfg); + } + else if (board->type == ulboard_type_pacDrive) + { + log_info("Updating PAC Drive board..."); + retCode = updateBoardPacDrive (bcfg); + } + else if (board->type == ulboard_type_pacLED) + { + log_info("Updating PAC LED 64 board..."); + retCode = updateBoardPacLED (bcfg); + } + else if (board->type == ulboard_type_ultistik) { - log_info ("Loading %s...", argv[idx]); + log_info("Updating Ultistik board..."); + retCode = updateBoardULTISTIK (bcfg, board); + } + else if (board->type == ulboard_type_usbbutton) + { + log_info("Updating USBButton..."); + retCode = updateUSBButton (bcfg, board); + } - if (json_object_object_get_ex(jobj, "configurations", &innerobj)) + if (retCode) + { + log_info("Board update successful."); + } + else + { + log_info("Board update failed."); + } + } + else + { + retCode = -1; + log_info("Board update failed."); + } + + return retCode; +} + +int +ulWriteToBoardFileStr (const char* file, ulboard* board) +{ + json_object *bcfg = json_object_from_file (file); + + return ulWriteToBoard (bcfg, board); +} + +void +ulMultiConfigurationsFileStr (const char* file) +{ + ulboard board; + + json_object *bcfg = NULL; + json_object *jobj = NULL; + json_object *mcfg = json_object_from_file (file); + + int valid = true; + int idx = 0; + + const char* fileStr = NULL; + + if (mcfg) + { + if (json_object_object_get_ex(mcfg, "list", &bcfg)) + { + if (!json_object_is_type(bcfg, json_type_array)) + { + log_err ("'list' needs to be of type array"); + valid = false; + } + else { - printf ("\n"); - for (inner_idx = 0; inner_idx < json_object_array_length(innerobj); ++ inner_idx) + for (idx = 0; idx < json_object_array_length(bcfg); ++ idx) { - item = json_object_array_get_idx(innerobj, inner_idx); - fileStr = json_object_get_string(item); - item = json_object_from_file (fileStr); + log_info ("-------"); + jobj = json_object_array_get_idx(bcfg, idx); + fileStr = json_object_get_string (jobj); + jobj = json_object_from_file (fileStr); - if (item) + if (jobj) { log_info ("Loading %s...", fileStr); - updateUltimarcBoard(item); - } - else - { - log_err ("%s. Format invalid\n", fileStr); + if (ulValidateConfig(jobj, &board) == 0) + { + ulWriteToBoard(jobj, &board); + } } } } - else - { - updateUltimarcBoard(jobj); - } } else { - log_err ("%s. Format invalid\n", argv[idx]); + log_err ("'list' is not defined in the configuration"); + valid = false; + } + + if (!valid) + { + log_err ("Configuration. [Not validated]"); } } } -bool updateUltimarcBoard (json_object* jobj) +int +ulGetProdAndVersion (json_object* jobj, ulboard* ulcfg) { - bool ret = false; - - const char* prodstr = NULL; + int retCode = 0; int version = 0; json_object* prodobj = NULL; json_object* verobj = NULL; - if (json_object_object_get_ex(jobj, "product", &prodobj) && - json_object_get_type(prodobj) == json_type_string) + if (jobj && ulcfg) { - if (json_object_object_get_ex(jobj, "version", &verobj) && - json_object_get_type(verobj) == json_type_int) + if (json_object_object_get_ex (jobj, "product", &prodobj)) { - prodstr = json_object_get_string(prodobj); - version = json_object_get_int(verobj); - - if (isIPACConfig(prodstr, version, jobj)) - { - ret = updateBoardIPAC(jobj); - } - else if (isIPACUltimateConfig(prodstr, version, jobj)) + if (json_object_get_type (prodobj) == json_type_string) { - log_info ("Updating IPAC Ultimate board..."); - ret = updateBoardIPacUltimate(jobj); + ulcfg->type = ulStringToBoardType(json_object_get_string (prodobj)); } - else if (isPACDriveConfig(prodstr, version, jobj)) - { - log_info ("Updating PAC Drive board..."); - ret = updateBoardPacDrive(jobj); - } - else if (isPACLED64Config(prodstr, version, jobj)) - { - log_info ("Updating PAC LED 64 board..."); - ret = updateBoardPacLED(jobj); - } - else if (isUltistikConfig(prodstr, version, jobj)) + else { - log_info ("Updating Ultistik board..."); - ret = updateBoardULTISTIK(jobj); + log_err("'product' is not defined as a string"); + ulcfg->type = ulboard_type_null; + retCode = 1; } } else { - if (json_object_object_get_ex(jobj, "version", &verobj)) + log_err("'product' is not defined in the configuration file"); + ulcfg->type = ulboard_type_null; + retCode = 1; + } + + if (json_object_object_get_ex (jobj, "version", &verobj)) + { + if (json_object_get_type (verobj) == json_type_int) { - log_err ("'version' is not defined as a integer"); + ulcfg->version = ulIntToBoardVersion(json_object_get_int (verobj)); } else { - log_err ("'version' is not defined in the configuration file"); + log_err("'version' is not defined as a integer"); + ulcfg->version = ulboard_version_null; + retCode = 1; } } - } - else - { - if (json_object_object_get_ex(jobj, "product", &prodobj)) - { - log_err ("'product' is not defined as a string"); - } else { - log_err ("'product' is not defined in the configuration file"); + log_err("'version' is not defined in the configuration file"); + ulcfg->version = ulboard_version_null; + retCode = 1; } } - - if (ret) - { - log_info ("Update done.\n"); - } else { - log_info ("Update failed!\n"); + log_err("JSON_Object is null"); } - json_object_put(jobj); - return ret; + return retCode; } diff --git a/src/libs/ultimarc.h b/src/libs/ultimarc.h index 9d8031c..8496873 100644 --- a/src/libs/ultimarc.h +++ b/src/libs/ultimarc.h @@ -6,30 +6,55 @@ Copyright : Copyright 2014 Robert Abram, Katie Snow Description : Ultimarc main configuration library ============================================================================ -*/ + */ #ifndef __ULTIMARC_H_ #define __ULTIMARC_H_ - /* Unix */ #include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif typedef struct json_object json_object; -extern void loadUltimarcConfigurations(int argc, char **argv); +typedef struct ulboard ulboard; -/* - * updateUltimarcBoard - * Updates a board. The board is selected based on the json file contents - * Paramter: json object - * Returns: true if successfully updated a board, false otherwise +/** + * ulValidateConfig + * Validates the configuration. + * Populates ulboard structure + */ +extern int +ulValidateConfig (json_object* bcfg, ulboard* ulobj); +extern int +ulValidateConfigFileStr (const char* file, ulboard* ulobj); + +/** + * ulWriteToBoard + * Writes the configuration provided out to the Ultimarc hardware + */ +extern int +ulWriteToBoard (json_object* bcfg, ulboard* ulobj); +extern int +ulWriteToBoardFileStr (const char* file, ulboard* ulobj); + +/** + * ulMultiConfigurationsFileStr + * Loads multiple configuration. + * Performs both validate and write functions. + */ +void +ulMultiConfigurationsFileStr (const char* file); + +/** + * Populates the ulobj with the product and version in the json_object */ -bool updateUltimarcBoard(json_object* jobj); +int +ulGetProdAndVersion (json_object* jobj, ulboard* ulobj); #ifdef __cplusplus } diff --git a/src/libs/ultistik.c b/src/libs/ultistik.c index 34493c4..ccf616c 100644 --- a/src/libs/ultistik.c +++ b/src/libs/ultistik.c @@ -20,25 +20,21 @@ #include "common.h" #include "ultistik.h" #include "dbg.h" +#include "ulboard.h" -struct Ultistik ustik; - -bool isUltistikConfig (const char* prodStr, int version, json_object* jobj) +bool isUltistikConfig (json_object* jobj, ulboard* board) { bool isBoardCfg = false; - ustik.version = version; - - if (strcmp(prodStr, USTIK_PRODUCT_STR) == 0 || - strcmp(prodStr, USTIK_STR) == 0) + if (board->type == ulboard_type_ultistik) { - isBoardCfg = validateUltistikData(jobj); + isBoardCfg = validateUltistikData(jobj, board); } return isBoardCfg; } -bool validateUltistikData(json_object* jobj) +bool validateUltistikData(json_object* jobj, ulboard* board) { int idx = 0; bool valid = false; @@ -49,8 +45,6 @@ bool validateUltistikData(json_object* jobj) json_object* tmp = NULL; json_object* key = NULL; - ustik.controllerIDUpdate = false; - if (checkBoardID(jobj, "controller id")) { /* Must have a valid controller id in the configuration file to even attempt to say @@ -170,7 +164,6 @@ bool validateUltistikData(json_object* jobj) { if (checkBoardID(jobj, "new controller id")) { - ustik.controllerIDUpdate = true; valid = true; } else @@ -226,7 +219,7 @@ convertULTISTIK (json_object *jobj) return retval; } -bool updateBoardULTISTIK (json_object* jobj) +bool updateBoardULTISTIK (json_object* jobj, ulboard* board) { int idx = 0; int itemidx = 0; @@ -248,7 +241,7 @@ bool updateBoardULTISTIK (json_object* jobj) memset(data, 0, sizeof(data)); - if (ustik.controllerIDUpdate == false) + if (json_object_object_get_ex(jobj, "controller id", &innerobj)) { data[0] = 0x50; @@ -261,13 +254,13 @@ bool updateBoardULTISTIK (json_object* jobj) /* Flash: false RAM(0xFF), true FLASH(0x00) */ json_object_object_get_ex(jobj, "flash", &innerobj); - switch (ustik.version) + switch (board->version) { - case 1: + case ulboard_version_pre2015: data[95] = (json_object_get_boolean(innerobj)? 0x00 : 0xFF); break; - case 2: + case ulboard_version_2015: /* 2015 and newer boards this value is zero */ data[95] = 0; break; @@ -297,9 +290,9 @@ bool updateBoardULTISTIK (json_object* jobj) json_object_object_get_ex(jobj, "controller id", &innerobj); controlCur = json_object_get_int(innerobj); - switch (ustik.version) + switch (board->version) { - case 1: + case ulboard_version_pre2015: product = USTIK_PRODUCT_PRE_2015; product += (controlCur - 1); @@ -354,7 +347,7 @@ bool updateBoardULTISTIK (json_object* jobj) closeUSB(ctx, handle, USTIK_INTERFACE_PRE_2015); break; - case 2: + case ulboard_version_2015: product = USTIK_PRODUCT; product += (controlCur - 1); @@ -397,9 +390,9 @@ bool updateBoardULTISTIK (json_object* jobj) json_object_object_get_ex(jobj, "current controller id", &innerobj); controlCur = json_object_get_int(innerobj); - switch (ustik.version) + switch (board->version) { - case 1: + case ulboard_version_pre2015: product = USTIK_PRODUCT_PRE_2015; product += (controlCur - 1); @@ -450,7 +443,7 @@ bool updateBoardULTISTIK (json_object* jobj) closeUSB(ctx, handle, USTIK_INTERFACE_PRE_2015); break; - case 2: + case ulboard_version_2015: product = USTIK_PRODUCT; product += (controlCur - 1); diff --git a/src/libs/ultistik.h b/src/libs/ultistik.h index 7597021..6dd5c2c 100644 --- a/src/libs/ultistik.h +++ b/src/libs/ultistik.h @@ -17,12 +17,6 @@ extern "C" { #endif -/* Required items in the json file for Ultistik card*/ -#define USTIK_VERSION 1 -#define USTIK_CONFIG_VERSION 2 -#define USTIK_PRODUCT_STR "0501" -#define USTIK_STR "ultistik" - /* Required items for writing out through the USB port */ #define USTIK_VENDOR 0xD209 #define USTIK_PRODUCT_PRE_2015 0x0501 @@ -42,24 +36,19 @@ extern "C" { #define USTIK_CONFIG_BASE 0x51 typedef struct json_object json_object; +typedef struct ulboard ulboard; -struct Ultistik -{ - int version; - bool controllerIDUpdate; -}; - -bool isUltistikConfig (const char* prodStr, int version, json_object* jobj); +bool isUltistikConfig (json_object* jobj, ulboard* board); -bool validateUltistikData(json_object* jobj); +bool validateUltistikData(json_object* jobj, ulboard* board); /* - * Convert the JSON keys data into IPAC data + * Convert the JSON keys data into Ultistik data * This is done one array element at a time */ char convertULTISTIK (json_object* jobj); -bool updateBoardULTISTIK (json_object* jobj); +bool updateBoardULTISTIK (json_object* jobj, ulboard* board); #ifdef __cplusplus } diff --git a/src/libs/usbbutton.c b/src/libs/usbbutton.c new file mode 100644 index 0000000..3d24126 --- /dev/null +++ b/src/libs/usbbutton.c @@ -0,0 +1,472 @@ +/* + ============================================================================ + Name : usbbutton.c + Author : Katie Snow + Version : + Copyright : Copyright 2014 Robert Abram, Katie Snow + Description : USBButton configuration library + ============================================================================ + */ + +/* C */ +#include +#include +#include + +/* Unix */ +#include +#include + +/* Local */ +#include "ulboard.h" +#include "common.h" +#include "usbbutton.h" +#include "dbg.h" + +bool isUSBButtonConfig(json_object *jobj, ulboard* board) +{ + bool result = false; + + if (board->type == ulboard_type_usbbutton) + { + result = validateUSBButtonData(jobj, board); + } + + return result; +} + +bool validateUSBButtonData(json_object* jobj, ulboard* board) +{ + bool result = true; + json_object* tmp = NULL; + json_object* color = NULL; + json_object* entries = NULL; + json_object* row = NULL; + + /* Required */ + if (json_object_object_get_ex(jobj, "action", &tmp)) + { + if (!json_object_is_type(tmp, json_type_string)) + { + log_err("'action' needs to be of type string"); + result = false; + } + } + else + { + log_err("'action' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(jobj, "pressed", &tmp)) + { + if (!json_object_is_type(tmp, json_type_object)) + { + log_err("'pressed' needs to be of type object"); + result = false; + } + else + { + if (json_object_object_get_ex(tmp, "red", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'red' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'red' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(tmp, "green", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'green' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'green' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(tmp, "blue", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'blue' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'blue' is not defined in the configuration"); + result = false; + } + } + } + else + { + log_err("'pressed' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(jobj, "released", &tmp)) + { + if (!json_object_is_type(tmp, json_type_object)) + { + log_err("'released' needs to be of type object"); + result = false; + } + else + { + if (json_object_object_get_ex(tmp, "red", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'red' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'red' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(tmp, "green", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'green' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'green' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(tmp, "blue", &color)) + { + if(!json_object_is_type(color, json_type_int)) + { + log_err("'blue' needs to be of type integer"); + result = false; + } + } + else + { + log_err("'blue' is not defined in the configuration"); + result = false; + } + } + } + else + { + log_err("'released' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(jobj, "keys", &tmp)) + { + if (!json_object_is_type(tmp, json_type_object)) + { + log_err("'keys' needs to be of type object"); + result = false; + } + else + { + if (json_object_object_get_ex(tmp, "primary", &entries)) + { + if (!json_object_is_type(entries, json_type_object)) + { + log_err("'primary' needs to be of type object"); + result = false; + } + else + { + result = validateUSBButtonRowData (entries, "row 1", result); + result = validateUSBButtonRowData (entries, "row 2", result); + result = validateUSBButtonRowData (entries, "row 3", result); + result = validateUSBButtonRowData (entries, "row 4", result); + } + } + else + { + log_err("'primary' is not defined in the configuration"); + result = false; + } + + if (json_object_object_get_ex(tmp, "secondary", &entries)) + { + if (!json_object_is_type(entries, json_type_object)) + { + log_err("'secondary' needs to be of type object"); + result = false; + } + else + { + result = validateUSBButtonRowData (entries, "row 1", result); + result = validateUSBButtonRowData (entries, "row 2", result); + result = validateUSBButtonRowData (entries, "row 3", result); + result = validateUSBButtonRowData (entries, "row 4", result); + } + } + else + { + log_err("'secondary' is not defined in the configuration"); + result = false; + } + } + } + else + { + log_err("'keys' is not defined in the configuration"); + result = false; + } + + return result; +} + +#define USBBTN_ROW_SIZE 6 + +bool validateUSBButtonRowData(json_object* entries, const char* rowStr, bool curResult) +{ + bool result = curResult; + + int pos = 0; + + json_object* row = NULL; + json_object* item = NULL; + + if (json_object_object_get_ex(entries, rowStr, &row)) + { + if (!json_object_is_type(row, json_type_array)) + { + log_err("'%s' needs to be of type array", rowStr); + result = false; + } + else + { + if (json_object_array_length(row) != USBBTN_ROW_SIZE) + { + log_err("'%s' array size was %i, but needs to be %i", + rowStr, json_object_array_length(row), + USBBTN_ROW_SIZE); + result = false; + } + else + { + for (pos = 0; pos < USBBTN_ROW_SIZE; ++pos) + { + item = json_object_array_get_idx(row, pos); + + if (!json_object_is_type(item, json_type_string)) + { + log_err("'%s' 'index %i' needs to be of type string", + rowStr, pos); + result = false; + } + } + } + } + } + else + { + log_err("'%s' is not defined in the configuration", + rowStr); + result = false; + } + + return result; +} + +int usbKeyLookupTable[8][6] = { +/* Primary */ +/* Row 1 */ +{10, 11, 12, 13, 14, 15}, +/* Row 2 */ +{16, 17, 18, 19, 20, 21}, +/* Row 3 */ +{22, 23, 24, 25, 26, 27}, +/* Row 4 */ +{28, 29, 30, 31, 32, 33}, + +/* Secondary */ +/* Row 1 */ +{34, 35, 36, 37, 38, 39}, +/* Row 2 */ +{40, 41, 42, 43, 44, 45}, +/* Row 3 */ +{46, 47, 48, 49, 50, 51}, +/* Row 4 */ +{52, 53, 54, 55, 56, 57} + +}; + +bool updateUSBButton (json_object* bcfg, ulboard* board) +{ + bool result = false; + + json_object* val = NULL; + json_object* tmp = NULL; + json_object* keys = NULL; + json_object* color = NULL; + + const char* str = NULL; + + unsigned char barray[USBBTN_SIZE]; + memset (&barray, 0, sizeof(barray)); + + /* Header */ + barray[0] = 0x50; + barray[1] = 0xdd; + + /* Action */ + json_object_object_get_ex(bcfg, "action", &val); + str = json_object_get_string(val); + if (!strcasecmp(str, "alternate")) + { + barray[2] = 0; + } + else if (!strcasecmp(str, "extended")) + { + barray[2] = 0x01; + } + else if (!strcasecmp(str, "both")) + { + barray[2] = 0x02; + } + + /* Release Colors */ + json_object_object_get_ex(bcfg, "released", &val); + json_object_object_get_ex(val, "red", &color); + barray[4] = convertDecimalToHex(json_object_get_int(color)); + + json_object_object_get_ex(val, "green", &color); + barray[5] = convertDecimalToHex(json_object_get_int(color)); + + json_object_object_get_ex(val, "blue", &color); + barray[6] = convertDecimalToHex(json_object_get_int(color)); + + /* Press Colors */ + json_object_object_get_ex(bcfg, "pressed", &val); + json_object_object_get_ex(val, "red", &color); + barray[7] = convertDecimalToHex(json_object_get_int(color)); + + json_object_object_get_ex(val, "green", &color); + barray[8] = convertDecimalToHex(json_object_get_int(color)); + + json_object_object_get_ex(val, "blue", &color); + barray[9] = convertDecimalToHex(json_object_get_int(color)); + + json_object_object_get_ex(bcfg, "keys", &tmp); + + /* Primary Keys*/ + json_object_object_get_ex(tmp, "primary", &val); + json_object_object_get_ex(val, "row 1", &keys); + populateUSBKeys(keys, 0, barray); + + json_object_object_get_ex(val, "row 2", &keys); + populateUSBKeys(keys, 1, barray); + + json_object_object_get_ex(val, "row 3", &keys); + populateUSBKeys(keys, 2, barray); + + json_object_object_get_ex(val, "row 4", &keys); + populateUSBKeys(keys, 3, barray); + + /* Secondary Keys */ + json_object_object_get_ex(tmp, "secondary", &val); + json_object_object_get_ex(val, "row 1", &keys); + populateUSBKeys(keys, 4, barray); + + json_object_object_get_ex(val, "row 2", &keys); + populateUSBKeys(keys, 5, barray); + + json_object_object_get_ex(val, "row 3", &keys); + populateUSBKeys(keys, 6, barray); + + json_object_object_get_ex(val, "row 4", &keys); + populateUSBKeys(keys, 7, barray); + + result = writeUSBButton(barray, 1, true); + + return result; +} + +void populateUSBKeys(json_object* keys, int row, unsigned char* barray) +{ + int pos = 0; + json_object* key = NULL; + + for(; pos < json_object_array_length(keys); ++pos) + { + key = json_object_array_get_idx(keys, pos); + barray[usbKeyLookupTable[row][pos]] = convertIPACSeries(key); + } +} + +bool writeUSBButton(unsigned char* barray, int autoconnect, bool transfer) +{ + libusb_context *ctx = NULL; + struct libusb_device_handle *handle = NULL; + unsigned char mesg[USBBTN_MESG_LENGTH] = {0,0,0,0}; + + bool result = true; + + int pos = 0; + int ret = 0; + + if (transfer) + { + handle = openUSB(ctx, USBBTN_VENDOR, USBBTN_PRODUCT, USBBTN_INTERFACE, autoconnect); + + if (!handle) + { + result = false; + goto error; + } + } + + while (pos < USBBTN_SIZE) + { + memcpy(&mesg[0], &barray[pos], 4); + + debug ("Writing (%i): %x, %x, %x, %x", pos, mesg[0], mesg[1], mesg[2], mesg[3]); + if (transfer) + { + ret = libusb_control_transfer(handle, + UM_REQUEST_TYPE, + UM_REQUEST, + USBBTN_VALUE, + USBBTN_INTERFACE, + mesg, + USBBTN_MESG_LENGTH, + UM_TIMEOUT); + debug ("Write result: %i", ret); + } + pos+=USBBTN_MESG_LENGTH; + } + +exit: + if (transfer) + { + closeUSB(ctx, handle, USBBTN_INTERFACE); + } + else + { + log_info ("board array was not written out!!!"); + } + return result; + +error: + return result; +} diff --git a/src/libs/usbbutton.h b/src/libs/usbbutton.h new file mode 100644 index 0000000..6545f8b --- /dev/null +++ b/src/libs/usbbutton.h @@ -0,0 +1,42 @@ +/* + ============================================================================ + Name : usbbutton.h + Author : Katie Snow + Version : + Copyright : Copyright 2015 Robert Abram, Katie Snow + Description : USB Button configuration library + ============================================================================ + */ + +#ifndef USBBUTTON_H_ +#define USBBUTTON_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define USBBTN_VENDOR 0xD209 +#define USBBTN_PRODUCT 0x1200 +#define USBBTN_INTERFACE 0 +#define USBBTN_VALUE 0x0200 +#define USBBTN_MESG_LENGTH 4 +#define USBBTN_SIZE 64 + +typedef struct json_object json_object; +typedef struct ulboard ulboard; + +bool isUSBButtonConfig(json_object *jobj, ulboard* board); +bool validateUSBButtonData(json_object* jobj, ulboard* board); +bool validateUSBButtonRowData(json_object* entries, const char* rowStr, bool curResult); + +bool updateUSBButton(json_object* bcfg, ulboard* board); +void populateUSBKeys(json_object* keys, int row, unsigned char* barray); + +bool writeUSBButton(unsigned char* barray, int autoconnect, bool transfer); +#ifdef __cplusplus +} +#endif + +#endif /* USBBUTTON_H_ */ diff --git a/src/umtool/Makefile.am b/src/umtool/Makefile.am index 61aee7a..dada4f4 100644 --- a/src/umtool/Makefile.am +++ b/src/umtool/Makefile.am @@ -4,8 +4,8 @@ AM_CFLAGS = $(JSON_CFLAGS) $(LIBUSB_CFLAGS) AM_LDFLAGS = $(JSON_LIBS) $(LIBUSB_LIBS) -bin_PROGRAMS=umtool.out -umtool_out_SOURCES=main.c -umtool_out_CPPFLAGS = -I$(top_srcdir)/src -umtool_out_LDADD = ../libs/libultimarc-0.1.la +bin_PROGRAMS=umtool +umtool_SOURCES=main.c +umtool_CPPFLAGS = -I$(top_srcdir)/src +umtool_LDADD = ../libs/libultimarc.la diff --git a/src/umtool/ipacultimate_config.json b/src/umtool/ipacultimate_config.json index 01e325f..12afc54 100644 --- a/src/umtool/ipacultimate_config.json +++ b/src/umtool/ipacultimate_config.json @@ -1,6 +1,6 @@ { "version" : 1, - "product" : "0410", + "product" : "ultimate", "current board id" : 1, "new board id" : 2 } \ No newline at end of file diff --git a/src/umtool/ipacultimate_led.json b/src/umtool/ipacultimate_led.json index 86a29b2..4e8dbb4 100644 --- a/src/umtool/ipacultimate_led.json +++ b/src/umtool/ipacultimate_led.json @@ -1,6 +1,6 @@ { "version": 1, - "product": "0410", + "product": "ultimate", "board id" : 1, "LED states random" : true, "intensity" : [ diff --git a/src/umtool/ipacultimate_pins.json b/src/umtool/ipacultimate_pins.json index 92a76ea..9d75987 100644 --- a/src/umtool/ipacultimate_pins.json +++ b/src/umtool/ipacultimate_pins.json @@ -1,6 +1,6 @@ { "version": 1, - "product": "0410", + "product": "ultimate", "board id" : 1, "intensity" : [ {"led": 0, "intensity" : 10 }, @@ -58,4 +58,4 @@ ], "x threshold" : 15, "y threshold" : 127 -} \ No newline at end of file +} diff --git a/src/umtool/main.c b/src/umtool/main.c index f303f32..ef807db 100644 --- a/src/umtool/main.c +++ b/src/umtool/main.c @@ -13,26 +13,67 @@ #include #include +#include -int main(int argc, char **argv) { - int idx; - int retVal; - - for (idx = 1; idx < argc; ++idx) - { - if (strcmp(argv[idx], "-h") == 0 || - strcmp(argv[idx], "--help") == 0) - { - printf ("umtool [-h] [--help] [config files...]\n"); - printf ("-h | --help\t\t Prints this information\n"); - printf ("config files\t\t JSON Configuration files to be processed\n"); - retVal = EXIT_SUCCESS; - goto exit; - } - } - - loadUltimarcConfigurations(argc, argv); - - exit: - return retVal; +typedef struct args +{ + int help; + int multi; +} args; + +int +main (int argc, char **argv) +{ + int idx; + int retVal; + + ulboard board; + + args args; + args.help = 0; + args.multi = 0; + + if (argc == 1) + { + args.help = 1; + } + + for (idx = 1; idx < argc; ++idx) + { + if (strcmp (argv[idx], "-h") == 0 || strcmp (argv[idx], "--help") == 0) + args.help = 1; + if (strcmp (argv[idx], "-m") == 0 || strcmp (argv[idx], "--multi") == 0) + args.multi = 1; + } + + if (args.help) + { + printf ("umtool [-h] [--help] [-m config file] [--multi config file] [config files...]\n"); + printf ("-h | --help\t Prints this information\n"); + printf ("-m | --multi\t File provided has multiple configuration\n"); + printf ("config files\t JSON Configuration files to be processed\n"); + retVal = EXIT_SUCCESS; + goto exit; + } + + if (args.multi) + { + printf ("Loading multiple configurations from file %s...\n", argv[2]); + ulMultiConfigurationsFileStr(argv[2]); + retVal = EXIT_SUCCESS; + goto exit; + } + + for (idx = 1; idx < argc; ++idx) + { + printf ("Loading %s...\n", argv[idx]); + retVal = ulValidateConfigFileStr (argv[idx], &board); + + if (retVal == 0) + { + retVal = ulWriteToBoardFileStr(argv[idx], &board); + } + } + + exit: return retVal; } diff --git a/src/umtool/multiple.json b/src/umtool/multiple.json index 1d2e198..f722786 100644 --- a/src/umtool/multiple.json +++ b/src/umtool/multiple.json @@ -1,6 +1,6 @@ { - "configurations" : [ + "list" : [ "pacLED.json", - "ultistik.json" + "ultistik_2015_map2way.json" ] -} \ No newline at end of file +} diff --git a/src/umtool/pacLED.json b/src/umtool/pacLED.json index b786cf1..217bdd8 100644 --- a/src/umtool/pacLED.json +++ b/src/umtool/pacLED.json @@ -1,6 +1,6 @@ { "version": 1, - "product": "1401", + "product": "pacled64", "board id" : 1, "fade" : [ {"led": 0, "fade" : 4 }, diff --git a/src/umtool/pacLED_all.json b/src/umtool/pacLED_all.json index 984c45b..1149bea 100644 --- a/src/umtool/pacLED_all.json +++ b/src/umtool/pacLED_all.json @@ -1,7 +1,7 @@ { "version": 1, - "product": "1401", + "product": "PACLED64", "board id" : 1, "LED fade all" : 4, "LED intensity all" : 255 -} \ No newline at end of file +} diff --git a/src/umtool/pacLED_config.json b/src/umtool/pacLED_config.json index 81c261d..939a6ef 100644 --- a/src/umtool/pacLED_config.json +++ b/src/umtool/pacLED_config.json @@ -1,6 +1,6 @@ { "version" : 1, - "product" : "1401", + "product" : "pacled64", "current board id" : 1, "new board id" : 3 } \ No newline at end of file diff --git a/src/umtool/pacdrive.json b/src/umtool/pacdrive.json index ac4bc24..357ffa2 100644 --- a/src/umtool/pacdrive.json +++ b/src/umtool/pacdrive.json @@ -1,6 +1,6 @@ { "version": 1, - "product": "1500", + "product": "pacdrive", "board id" : 1, "led" : [1, 3, 9, 11] -} \ No newline at end of file +} diff --git a/src/umtool/usbbutton.json b/src/umtool/usbbutton.json new file mode 100644 index 0000000..a97741a --- /dev/null +++ b/src/umtool/usbbutton.json @@ -0,0 +1,30 @@ +{ + "version" : 1, + "product" : "usbbutton", + "board id" : 1, + "action" : "alternate", + "pressed" : { + "red" : 255, + "green" : 0, + "blue" : 0 + }, + "released" : { + "red" : 0, + "green" : 0, + "blue" : 255 + }, + "keys" : { + "primary" : { + "row 1" : ["U", "l", "t", "i", "m", "a"], + "row 2" : ["r", "c", "-", "l", "i", "n"], + "row 3" : ["u", "x", "space", "l", "i", "b"], + "row 4" : ["r", "a", "r", "y", "space", ""] + }, + "secondary" : { + "row 1" : ["shift l", "u", "s", "b", "b", ""], + "row 2" : ["u", "t", "t", "o", "n", "space"], + "row 3" : ["", "", "", "", "", ""], + "row 4" : ["", "", "", "", "", ""] + } + } +}