On 03/10/2012 06:01 PM, Scott Talbert wrote: > This update predominantly adds comments to explain some of the changes > better.
I went to apply this patch to a fresh export to start testing other hardware
against it, but it won't come close to applying:
[phil@rider 900support]$ patch -p0 < /tmp/900.patch
patching file concordance/concordance.c
Hunk #1 FAILED at 922.
1 out of 1 hunk FAILED -- saving rejects to file concordance/concordance.c.rej
patching file libconcord/configure.ac
Hunk #1 succeeded at 11 with fuzz 1.
patching file libconcord/lc_internal.h
patching file libconcord/libconcord.cpp
Hunk #2 succeeded at 105 with fuzz 1.
Hunk #3 succeeded at 213 with fuzz 1.
Hunk #4 FAILED at 610.
Hunk #5 FAILED at 646.
Hunk #6 FAILED at 1085.
3 out of 6 hunks FAILED -- saving rejects to file libconcord/libconcord.cpp.rej
patching file libconcord/libconcord.h
patching file libconcord/operationfile.cpp
Hunk #1 FAILED at 113.
Hunk #2 FAILED at 159.
Hunk #3 FAILED at 186.
3 out of 3 hunks FAILED -- saving rejects to file
libconcord/operationfile.cpp.rej
patching file libconcord/operationfile.h
Hunk #1 FAILED at 29.
1 out of 1 hunk FAILED -- saving rejects to file libconcord/operationfile.h.rej
patching file libconcord/remote.cpp
Hunk #1 FAILED at 52.
Hunk #2 FAILED at 112.
2 out of 2 hunks FAILED -- saving rejects to file libconcord/remote.cpp.rej
patching file libconcord/remote.h
Hunk #1 FAILED at 100.
Hunk #2 FAILED at 117.
Hunk #3 FAILED at 177.
Hunk #4 FAILED at 230.
Hunk #5 FAILED at 313.
Hunk #6 FAILED at 329.
6 out of 6 hunks FAILED -- saving rejects to file libconcord/remote.h.rej
patching file libconcord/remote_info.h
Hunk #1 FAILED at 92.
Hunk #2 FAILED at 416.
2 out of 2 hunks FAILED -- saving rejects to file libconcord/remote_info.h.rej
patching file libconcord/remote_z.cpp
Hunk #1 FAILED at 271.
Hunk #2 FAILED at 279.
Hunk #3 succeeded at 343 with fuzz 1.
Hunk #4 FAILED at 647.
Hunk #5 FAILED at 661.
Hunk #6 FAILED at 690.
Hunk #7 FAILED at 704.
Hunk #8 FAILED at 720.
7 out of 8 hunks FAILED -- saving rejects to file libconcord/remote_z.cpp.rej
patching file libconcord/usblan.cpp
Hunk #1 succeeded at 48 with fuzz 1.
Hunk #2 succeeded at 133 with fuzz 2.
patching file libconcord/usblan.h
patching file libconcord/web.cpp
Hunk #1 succeeded at 256 with fuzz 1.
Hunk #2 FAILED at 314.
Hunk #3 FAILED at 324.
2 out of 3 hunks FAILED -- saving rejects to file libconcord/web.cpp.rej
patching file libconcord/xml_headers.h
patching file libconcord/libusb/libusbhid.cpp
Hunk #1 FAILED at 135.
1 out of 1 hunk FAILED -- saving rejects to file
libconcord/libusb/libusbhid.cpp.rej
>
> Index: concordance/concordance.c
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
> retrieving revision 1.41.2.20
> diff -u -p -r1.41.2.20 concordance.c
> --- concordance/concordance.c 20 Feb 2011 00:57:18 -0000 1.41.2.20
> +++ concordance/concordance.c 11 Mar 2012 01:54:59 -0000
> @@ -922,8 +922,8 @@ int print_version_info(struct options_t
> if ((*options).verbose)
> printf(" Firmware Type: %i\n", get_fw_type());
>
> - printf(" Hardware Version: %i.%i\n", get_hw_ver_maj(),
> - get_hw_ver_min());
> + printf(" Hardware Version: %i.%i.%i\n", get_hw_ver_maj(),
> + get_hw_ver_min(), get_hw_ver_mic());
>
> if ((*options).verbose) {
> int size = get_flash_size();
> Index: libconcord/configure.ac
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/configure.ac,v
> retrieving revision 1.7.2.2
> diff -u -p -r1.7.2.2 configure.ac
> --- libconcord/configure.ac 11 Aug 2011 05:46:45 -0000 1.7.2.2
> +++ libconcord/configure.ac 11 Mar 2012 01:54:59 -0000
> @@ -11,7 +11,7 @@ then
> AC_MSG_ERROR([Error, libusb is missing!])
> fi
> AC_CHECK_HEADER(zzip/lib.h, [], [a=0])
> -AC_CHECK_LIB(zzip, zzip_dir_open, [] [a=0])
> +AC_CHECK_LIB(zzip, zzip_dir_open, [], [a=0])
> if test $a == 0
> then
> AC_MSG_ERROR([Error, libzzip is missing!])
> Index: libconcord/lc_internal.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/lc_internal.h,v
> retrieving revision 1.2.2.1
> diff -u -p -r1.2.2.1 lc_internal.h
> --- libconcord/lc_internal.h 19 Sep 2010 16:06:25 -0000 1.2.2.1
> +++ libconcord/lc_internal.h 11 Mar 2012 01:54:59 -0000
> @@ -59,5 +59,6 @@ using namespace std;
> void report_net_error(const char *msg);
> /* NOTE: 1 for yes, 0 for no, unlike some other functions. */
> int is_z_remote();
> +int is_usbnet_remote();
>
> #endif // ifndef LC_INTERNAL_H
> Index: libconcord/libconcord.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.cpp,v
> retrieving revision 1.42.2.18
> diff -u -p -r1.42.2.18 libconcord.cpp
> --- libconcord/libconcord.cpp 11 Aug 2011 05:46:45 -0000 1.42.2.18
> +++ libconcord/libconcord.cpp 11 Mar 2012 01:54:59 -0000
> @@ -47,7 +47,8 @@
> #define ZWAVE_HID_PID_MIN 0xC112
> #define ZWAVE_HID_PID_MAX 0xC115
>
> -#define MAX_WAIT_FOR_BOOT 5
> +// Certain remotes (e.g., 900) take longer to reboot, so extend wait time.
> +#define MAX_WAIT_FOR_BOOT 10
> #define WAIT_FOR_BOOT_SLEEP 5
>
> static class CRemoteBase *rmt;
> @@ -104,6 +105,11 @@ int get_hw_ver_min()
> return ri.hw_ver_minor;
> }
>
> +int get_hw_ver_mic()
> +{
> + return ri.hw_ver_micro;
> +}
> +
> int get_flash_size()
> {
> return ri.flash->size;
> @@ -207,6 +213,11 @@ int is_z_remote()
> return rmt->IsZRemote() ? 1 : 0;
> }
>
> +int is_usbnet_remote()
> +{
> + return rmt->IsUSBNet() ? 1 : 0;
> +}
> +
> int get_time_second()
> {
> return rtime.second;
> @@ -599,15 +610,11 @@ int init_concord()
> if ((err = FindRemote(hid_info))) {
> hid_info.pid = 0;
>
> -#ifdef WIN32
> if ((err = FindUsbLanRemote())) {
> return LC_ERROR_CONNECT;
> }
>
> rmt = new CRemoteZ_TCP;
> -#else
> - return LC_ERROR_CONNECT;
> -#endif
> }
>
> /*
> @@ -635,8 +642,11 @@ int init_concord()
> int deinit_concord()
> {
> ShutdownUSB();
> - if (of)
> - delete of;
> + // Do not delete the OperationFile here. It is used again in
> + // concordance after deinit_concord() is called. Deleting it causes
> + // the final website check to fail in update config operations.
> + //if (of)
> + //delete of;
> if (rmt)
> delete rmt;
> return 0;
> @@ -1074,7 +1084,7 @@ int update_configuration(lc_callback cb,
> if (err != 0)
> return err;
>
> - if (noreset || is_z_remote())
> + if (noreset || (is_z_remote() && !is_usbnet_remote()))
> return 0;
>
> if ((err = reset_remote(cb, cb_arg)))
> Index: libconcord/libconcord.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.h,v
> retrieving revision 1.22.2.14
> diff -u -p -r1.22.2.14 libconcord.h
> --- libconcord/libconcord.h 20 Feb 2011 00:27:19 -0000 1.22.2.14
> +++ libconcord/libconcord.h 11 Mar 2012 01:54:59 -0000
> @@ -132,6 +132,7 @@ int get_fw_ver_min();
> int get_fw_type();
> int get_hw_ver_maj();
> int get_hw_ver_min();
> +int get_hw_ver_mic();
> int get_flash_size();
> int get_flash_mfg();
> int get_flash_id();
> Index: libconcord/operationfile.cpp
> ===================================================================
> RCS file:
> /cvsroot/concordance/concordance/libconcord/Attic/operationfile.cpp,v
> retrieving revision 1.1.2.1
> diff -u -p -r1.1.2.1 operationfile.cpp
> --- libconcord/operationfile.cpp 19 Sep 2010 16:09:29 -0000 1.1.2.1
> +++ libconcord/operationfile.cpp 11 Mar 2012 01:54:59 -0000
> @@ -113,6 +113,7 @@ int OperationFile::ReadZipFile(char *fil
> } else {
> data_size = dirent.st_size;
> data = new uint8_t[data_size];
> + data_alloc = true;
> zzip_size_t len = zzip_file_read(fh, data,
> data_size);
> }
> @@ -159,11 +160,12 @@ OperationFile::OperationFile()
> {
> data_size = xml_size = 0;
> data = xml = NULL;
> + data_alloc = false;
> }
>
> OperationFile::~OperationFile()
> {
> - if (data)
> + if (data && data_alloc)
> delete data;
> if (xml)
> delete xml;
> @@ -186,6 +188,7 @@ int OperationFile::_ExtractFirmwareBinar
> debug("extracting firmware binary");
> uint32_t o_size = FIRMWARE_MAX_SIZE;
> data = new uint8_t[o_size];
> + data_alloc = true;
> uint8_t *o = data;
>
> uint8_t *x = xml;
> Index: libconcord/operationfile.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/Attic/operationfile.h,v
> retrieving revision 1.1.2.1
> diff -u -p -r1.1.2.1 operationfile.h
> --- libconcord/operationfile.h 19 Sep 2010 16:09:29 -0000 1.1.2.1
> +++ libconcord/operationfile.h 11 Mar 2012 01:54:59 -0000
> @@ -29,6 +29,7 @@ class OperationFile {
> private:
> uint8_t *data;
> uint32_t data_size;
> + bool data_alloc;
> uint8_t *xml;
> uint32_t xml_size;
> int ReadPlainFile(char *file_name);
> Index: libconcord/remote.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/remote.cpp,v
> retrieving revision 1.40.2.7
> diff -u -p -r1.40.2.7 remote.cpp
> --- libconcord/remote.cpp 20 Feb 2011 00:27:19 -0000 1.40.2.7
> +++ libconcord/remote.cpp 11 Mar 2012 01:54:59 -0000
> @@ -52,10 +52,19 @@ void setup_ri_pointers(TRemoteInfo &ri)
> void make_guid(const uint8_t * const in, char*&out)
> {
> char x[48];
> - sprintf(x,
> -
> "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
> - in[3], in[2], in[1], in[0], in[5], in[4], in[7], in[6],
> - in[8], in[9], in[10], in[11], in[12], in[13], in[14], in[15]);
> + // usbnet remotes seem to use a more normal byte ordering for serial #'s
> + if (is_usbnet_remote()) {
> + sprintf(x,
> +
> "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
> + in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7],
> + in[8], in[9], in[10], in[11], in[12], in[13], in[14],
> in[15]);
> + }
> + else {
> + sprintf(x,
> +
> "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
> + in[3], in[2], in[1], in[0], in[5], in[4], in[7], in[6],
> + in[8], in[9], in[10], in[11], in[12], in[13], in[14],
> in[15]);
> + }
> out = strdup(x);
> }
>
> @@ -112,6 +121,7 @@ int CRemote::GetIdentity(TRemoteInfo &ri
> ri.fw_ver_minor = rsp[1] & 0x0F;
> ri.hw_ver_major = rsp[2] >> 4;
> ri.hw_ver_minor = rsp[2] & 0x0F;
> + ri.hw_ver_micro = 0; /* usbnet remotes have a non-zero micro version */
> ri.flash_id = rsp[3];
> ri.flash_mfg = rsp[4];
> ri.architecture = rx_len < 6 ? 2 : rsp[5] >> 4;
> Index: libconcord/remote.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/remote.h,v
> retrieving revision 1.20.2.8
> diff -u -p -r1.20.2.8 remote.h
> --- libconcord/remote.h 19 Sep 2010 16:06:25 -0000 1.20.2.8
> +++ libconcord/remote.h 11 Mar 2012 01:54:59 -0000
> @@ -100,6 +100,7 @@ struct TArchInfo {
> struct TRemoteInfo {
> uint16_t hw_ver_major;
> uint16_t hw_ver_minor;
> + uint16_t hw_ver_micro;
> uint16_t fw_ver_major;
> uint16_t fw_ver_minor;
> uint8_t fw_type;
> @@ -117,6 +118,13 @@ struct TRemoteInfo {
> bool valid_config;
> uint32_t config_bytes_used;
> uint32_t max_config_size;
> + uint8_t num_regions; /* usbnet only from here down */
> + uint8_t *region_ids;
> + char **region_versions;
> + uint32_t home_id;
> + uint8_t node_id;
> + char *tid;
> + char *xml_user_rf_setting;
> };
>
> struct THarmonyTime {
> @@ -177,6 +185,7 @@ public:
> uint32_t *ir_signal_length, lc_callback cb=NULL,
> void *cb_arg=NULL, uint32_t cb_stage=NULL)=0;
> virtual int IsZRemote()=0;
> + virtual int IsUSBNet()=0;
> };
>
> class CRemote : public CRemoteBase // All non-Z-Wave remotes
> @@ -230,6 +239,7 @@ public:
> uint32_t *ir_signal_length, lc_callback cb=NULL,
> void *cb_arg=NULL, uint32_t cb_stage=NULL);
> int IsZRemote() {return false;}
> + int IsUSBNet() {return false;}
> };
>
> // Base class for all Z-Wave remotes
> @@ -313,12 +323,14 @@ public:
> virtual ~CRemoteZ_HID() {};
> int UpdateConfig(const uint32_t len, const uint8_t *wr,
> lc_callback cb, void *cb_arg, uint32_t cb_stage);
> + int IsUSBNet() {return false;}
> };
>
> // 1000, 1000i
> class CRemoteZ_TCP : public CRemoteZ_Base
> {
> protected:
> + int TCPSendAndCheck(uint8_t cmd, uint32_t len=0, uint8_t *data=NULL);
> virtual int Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
> uint8_t *data=NULL);
> virtual int Read(uint8_t &status, uint32_t &len, uint8_t *data);
> @@ -329,6 +341,12 @@ protected:
> public:
> CRemoteZ_TCP() {};
> virtual ~CRemoteZ_TCP() {};
> + int UpdateConfig(const uint32_t len, const uint8_t *wr,
> + lc_callback cb, void *cb_arg, uint32_t cb_stage);
> + int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
> + int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
> + lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=NULL);
> + int IsUSBNet() {return true;}
> };
>
> #endif //REMOTE_H
> Index: libconcord/remote_info.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/remote_info.h,v
> retrieving revision 1.12.2.1
> diff -u -p -r1.12.2.1 remote_info.h
> --- libconcord/remote_info.h 13 Mar 2011 09:40:50 -0000 1.12.2.1
> +++ libconcord/remote_info.h 11 Mar 2012 01:54:59 -0000
> @@ -92,7 +92,7 @@ static const TModel ModelList[]={
> { MFG_UNK, "Unknown", NULL },
> { MFG_UNK, "Unknown", NULL },
> { MFG_UNK, "Unknown", NULL },
> // 60
> - { MFG_UNK, "Unknown", NULL },
> + { MFG_HAR, "Harmony 900", NULL },
> { MFG_UNK, "Unknown", NULL },
> { MFG_UNK, "Unknown", NULL },
> { MFG_UNK, "Unknown", NULL },
> @@ -416,6 +416,24 @@ static const TArchInfo ArchList[]={
> 0, // ram_size
> 0, // eeprom_size
> "Internal", // usb
> + },
> + /* arch 15 - usbnet (e.g., 900) */
> + {
> + 0, // serial_location
> + 0, // serial_address
> + 0, // flash_base
> + 0, // firmware_base
> + 0, // config_base
> + 0, // firmware_update_base
> + 0, // firmware_4847_offset
> + 0x1, /* hack to make config test pass */ // cookie
> + 0, // cookie_size
> + 0, // end_vector
> + "", // micro
> + 0, // flash_size
> + 0, // ram_size
> + 0, // eeprom_size
> + "", // usb
> }
> };
>
> Index: libconcord/remote_z.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/remote_z.cpp,v
> retrieving revision 1.25.2.14
> diff -u -p -r1.25.2.14 remote_z.cpp
> --- libconcord/remote_z.cpp 19 Sep 2010 16:06:25 -0000 1.25.2.14
> +++ libconcord/remote_z.cpp 11 Mar 2012 01:54:59 -0000
> @@ -271,7 +271,10 @@ int CRemoteZ_HID::ParseParams(uint32_t l
> int CRemoteZ_TCP::Write(uint8_t typ, uint8_t cmd, uint32_t len,
> uint8_t *data)
> {
> - if (len > 60) {
> + /* Largest packet size for usbnet is the COMMAND_WRITE_UPDATE_DATA
> + which is 1 (num params) + 3 (3 parameter size bytes) + 1 (param 1)
> + + 1024 (param 2) + 4 (param 3) = 1033. */
> + if (len > 1033) {
> return LC_ERROR;
> }
>
> @@ -279,7 +282,7 @@ int CRemoteZ_TCP::Write(uint8_t typ, uin
> const bool request = (typ == TYPE_REQUEST);
> const uint8_t status = STATUS_OK;
>
> - uint8_t pkt[68];
> + uint8_t pkt[1036]; /* largest packet (1033) + standard 3-byte header */
> pkt[0] = service_type << 4 | (cmd >> 8) & 0x0F;
> pkt[1] = cmd & 0xFF;
> pkt[2] = request ? 0x80 : (status & 0x7F);
> @@ -343,6 +346,239 @@ int CRemoteZ_TCP::ParseParams(uint32_t l
> return 0;
> }
>
> +int CRemoteZ_TCP::TCPSendAndCheck(uint8_t cmd, uint32_t len, uint8_t *data)
> +{
> + int err = 0;
> + uint8_t status;
> + unsigned int rlen;
> + uint8_t rsp[60];
> +
> + if ((err = Write(TYPE_REQUEST, cmd, len, data))) {
> + debug("Failed to send request %02X", cmd);
> + return LC_ERROR_WRITE;
> + }
> +
> + if ((err = Read(status, rlen, rsp))) {
> + debug("Failed to read from remote");
> + return LC_ERROR_READ;
> + }
> +
> + if (rsp[2] != TYPE_RESPONSE) {
> + debug("Packet didn't have response bit!");
> + return LC_ERROR;
> + }
> +
> + if (rsp[1] != cmd) {
> + debug("The cmd bit didn't match our request packet");
> + return LC_ERROR;
> + }
> +
> + return 0;
> +}
> +
> +int CRemoteZ_TCP::UpdateConfig(const uint32_t len, const uint8_t *wr,
> + lc_callback cb, void *arg, uint32_t cb_stage)
> +{
> + int err = 0;
> + int cb_count = 0;
> + uint8_t rsp[60];
> + unsigned int rlen;
> + uint8_t status;
> +
> + cb(LC_CB_STAGE_INITIALIZE_UPDATE, cb_count++, 0, 2,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + /* ACK it with a command to start an update */
> + debug("START_UPDATE");
> + // 2 parameters, each 1 byte.
> + // 1st parameter "flags" seems to always be 0.
> + uint8_t cmd[60] = { 0x02, 0x01, 0x00, 0x01, REGION_USER_CONFIG };
> + if ((err = TCPSendAndCheck(COMMAND_START_UPDATE, 5, cmd))) {
> + return err;
> + }
> +
> + cb(LC_CB_STAGE_INITIALIZE_UPDATE, cb_count++, 1, 2,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + /* write update-header */
> + debug("UPDATE_HEADER");
> + cmd[0] = 0x02; // 2 parameters
> + cmd[1] = 0x04; // 1st parameter 4 bytes (size)
> + cmd[2] = (len & 0xFF000000) >> 24;
> + cmd[3] = (len & 0x00FF0000) >> 16;
> + cmd[4] = (len & 0x0000FF00) >> 8;
> + cmd[5] = (len & 0x000000FF);
> + cmd[6] = 0x01; // 2nd parameter 1 byte (region id)
> + cmd[7] = REGION_USER_CONFIG;
> + if ((err = TCPSendAndCheck(COMMAND_WRITE_UPDATE_HEADER, 8, cmd))) {
> + return err;
> + }
> +
> + cb(LC_CB_STAGE_INITIALIZE_UPDATE, cb_count++, 2, 2,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> + cb_count = 0;
> +
> + /* write data */
> + debug("UPDATE_DATA");
> + uint32_t pkt_len;
> + int tlen = len;
> + int bytes_written = 0;
> + uint8_t *wr_ptr = const_cast<uint8_t*>(wr);
> + uint8_t tmp_pkt[1033];
> + tmp_pkt[0] = 0x03; // 3 parameters
> + tmp_pkt[1] = 0x01; // 1st parameter, 1 byte (region id)
> + tmp_pkt[2] = REGION_USER_CONFIG;
> + tmp_pkt[3] = 0xC2; // 2nd parameter, 1024 bytes (data)
> + tmp_pkt[1028] = 0x04; // 3rd parameter, 4 bytes (length)
> + while (tlen) {
> + pkt_len = 1024; // max packet length seems to be 1024
> + if (tlen < pkt_len) {
> + pkt_len = tlen;
> + }
> + tlen -= pkt_len;
> +
> + memcpy(&tmp_pkt[4], wr_ptr, pkt_len);
> + tmp_pkt[1029] = (pkt_len & 0xFF000000) >> 24;
> + tmp_pkt[1030] = (pkt_len & 0x00FF0000) >> 16;
> + tmp_pkt[1031] = (pkt_len & 0x0000FF00) >> 8;
> + tmp_pkt[1032] = (pkt_len & 0x000000FF);
> +
> + debug("DATA %d, sending %d bytes, %d bytes left", cb_count,
> + pkt_len, tlen);
> +
> + if ((err = TCPSendAndCheck(COMMAND_WRITE_UPDATE_DATA, 1033,
> + tmp_pkt))) {
> + return err;
> + }
> + wr_ptr += pkt_len;
> +
> + if (cb) {
> + cb(LC_CB_STAGE_WRITE_CONFIG, cb_count++,
> + (int)(wr_ptr - wr), len,
> + LC_CB_COUNTER_TYPE_BYTES, arg);
> + }
> + }
> +
> + /* write update-done */
> + cb_count = 0;
> + cb(LC_CB_STAGE_FINALIZE_UPDATE, cb_count++, 0, 3,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + debug("UPDATE_DATA_DONE");
> + cmd[0] = 0x01; // 1 parameter
> + cmd[1] = 0x01; // 1st parameter 1 byte (region id)
> + cmd[2] = REGION_USER_CONFIG;
> + if ((err = TCPSendAndCheck(COMMAND_WRITE_UPDATE_DATA_DONE, 3, cmd))) {
> + return err;
> + }
> +
> + cb(LC_CB_STAGE_FINALIZE_UPDATE, cb_count++, 1, 3,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + /* send get-cheksum */
> + debug("GET_CHECKSUM");
> + cmd[0] = 0x02; // 2 parameters
> + cmd[1] = 0x02; // 1st parameter 2 bytes (seed)
> + cmd[2] = 0xFF; // seed seems to always be FF
> + cmd[3] = 0xFF; // seed seems to always be FF
> + cmd[4] = 0x01; // 2nd parameter 1 byte (region id)
> + cmd[5] = REGION_USER_CONFIG;
> + if ((err = TCPSendAndCheck(COMMAND_GET_UPDATE_CHECKSUM, 6, cmd))) {
> + return err;
> + }
> +
> + cb(LC_CB_STAGE_FINALIZE_UPDATE, cb_count++, 2, 3,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + /* send finish-update */
> + debug("FINISH_UPDATE");
> + cmd[0] = 0x02; // 2 parameters
> + cmd[1] = 0x01; // 1st parameter 1 byte (validate)
> + cmd[2] = 0x01; // validate?
> + cmd[3] = 0x01; // 2nd parameter 1 byte (region id)
> + cmd[4] = REGION_USER_CONFIG;
> + if ((err = TCPSendAndCheck(COMMAND_FINISH_UPDATE, 5, cmd))) {
> + return err;
> + }
> +
> + cb(LC_CB_STAGE_FINALIZE_UPDATE, cb_count++, 3, 3,
> + LC_CB_COUNTER_TYPE_STEPS, arg);
> +
> + return 0;
> +}
> +
> +int CRemoteZ_TCP::GetTime(const TRemoteInfo &ri, THarmonyTime &ht)
> +{
> + int err = 0;
> + if ((err = Write(TYPE_REQUEST, COMMAND_GET_CURRENT_TIME))) {
> + debug("Failed to write to remote");
> + return LC_ERROR_WRITE;
> + }
> + uint8_t time[60];
> + unsigned int len;
> + uint8_t status;
> + if ((err = Read(status, len, time))) {
> + debug("Failed to read to remote");
> + return LC_ERROR_READ;
> + }
> +
> + if (time[2] != TYPE_RESPONSE || time[1] != COMMAND_GET_CURRENT_TIME) {
> + debug("Incorrect response type from Get Time");
> + return LC_ERROR_INVALID_DATA_FROM_REMOTE;
> + }
> +
> + CRemoteZ_Base::TParamList pl;
> + ParseParams(len, time, pl);
> +
> + ht.year = GetWord(pl.p[0]);
> + ht.month = *pl.p[1];
> + ht.day = *pl.p[2];
> + ht.hour = *pl.p[3];
> + ht.minute = *pl.p[4];
> + ht.second = *pl.p[5];
> + ht.dow = *pl.p[6]&7;
> + ht.utc_offset = static_cast<int16_t>(GetWord(pl.p[7]));
> + if (pl.count > 11) {
> + ht.timezone = reinterpret_cast<char*>(pl.p[11]);
> + ht.timezone[3] = '\0';
> + } else {
> + ht.timezone = "";
> + }
> +
> + return 0;
> +}
> +
> +int CRemoteZ_TCP::SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
> + lc_callback cb, void *cb_arg, uint32_t cb_stage)
> +{
> + debug("SetTime");
> + int err = 0;
> +
> + uint8_t tsv[32] = {
> + 0x0C, // 12 parameters
> + 0x02, ht.year >> 8, ht.year, // 2 bytes
> + 0x01, ht.month,
> + 0x01, ht.day,
> + 0x01, ht.hour,
> + 0x01, ht.minute,
> + 0x01, ht.second,
> + 0x01, ht.dow,
> + // utcOffset
> + 0x02, 0, 0, // 2 bytes - 900 doesn't seem to accept this
> + // 0s
> + 0x02, 0, 0, // 2 bytes
> + 0x02, 0, 0, // 2 bytes
> + 0x02, 0, 0, // 2 bytes
> + 0x83, 0, 0, 0 // 900 doesn't seem to accept this, don't bother
> + };
> +
> + if ((err = TCPSendAndCheck(COMMAND_UPDATE_TIME, 32, tsv))) {
> + debug("Failed to write to remote");
> + return err;
> + }
> +
> + return 0;
> +}
>
> int CRemoteZ_Base::Reset(uint8_t kind)
> {
> @@ -414,8 +650,8 @@ int CRemoteZ_Base::GetIdentity(TRemoteIn
> hid.frl = 0;
> hid.mfg = "Logitech";
> hid.prod = "Harmony 1000";
> - ri.flash_mfg = 0; // todo
> - ri.flash_id = 0; // todo
> + ri.flash_mfg = 0x01; // Seems to be the same as regular zwave
> + ri.flash_id = 0x49; // Seems to be the same as regular zwave
> } else { // Not 1000
> ri.flash_mfg = 0x01;// todo
> ri.flash_id = 0x49; // todo
> @@ -428,10 +664,10 @@ int CRemoteZ_Base::GetIdentity(TRemoteIn
> const unsigned int hw = GetWord(pl.p[7]);
> ri.hw_ver_major = hw >> 8; // ???
> ri.hw_ver_minor = (hw >> 4) & 0x0F; // ???
> - // hw_ver_micro = hw & 0x0F // ???
> + ri.hw_ver_micro = hw & 0x0F; // 900 has this and is non-zero
> //ri.hw_ver_major = hw >> 4;
> //ri.hw_ver_minor = hw & 0x0F;
> - ri.protocol = 0;
> + ri.protocol = GetWord(pl.p[2]); // Seems to be the same as arch?
>
> setup_ri_pointers(ri);
>
> @@ -457,7 +693,12 @@ int CRemoteZ_Base::GetIdentity(TRemoteIn
> ri.max_config_size = 1;
> ri.valid_config = 1;
>
> -#if 0 // Get region info - 1000 only!
> + if (!IsUSBNet()) {
> + return 0;
> + }
> +
> + // Get region info - everything below is extra stuff that only the
> + // usbnet remotes seem to use.
> uint8_t rr[] = { 1, 1, 1 }; // AddByteParam(1);
> if ((err = Write(TYPE_REQUEST, COMMAND_GET_REGION_IDS, 3, rr))) {
> debug("Failed to write to remote");
> @@ -471,9 +712,33 @@ int CRemoteZ_Base::GetIdentity(TRemoteIn
> ParseParams(len, rgn, pl);
> if (pl.count == 1) {
> const unsigned int rc = *(pl.p[0]-1) & 0x3F;
> + ri.num_regions = rc + 1;
> + ri.region_ids = new uint8_t[ri.num_regions];
> + ri.region_versions = new char*[ri.num_regions];
> +
> + // There seems to be an implied Region 0 that the Windows
> + // software requests but it is not listed in the Region IDs.
> + uint8_t rz[] = { 1, 1, 0 }; // 1 parameter, 1 byte, value = 0
> + if ((err = Write(TYPE_REQUEST,
> + COMMAND_GET_REGION_VERSION, 3, rz))) {
> + debug("Failed to write to remote");
> + return LC_ERROR;
> + }
> + uint8_t rgz[64];
> + if ((err = Read(status, len, rgz))) {
> + debug("Failed to read from remote");
> + return LC_ERROR;
> + }
> + CRemoteZ_Base::TParamList rzp;
> + ParseParams(len, rgz, rzp);
> + ri.region_ids[0] = 0x00; // Store region 0.
> + ri.region_versions[0] = new char[4];
> + snprintf(ri.region_versions[0], 4, "%d.%d", *(rzp.p[0]+1),
> + *rzp.p[0]);
> +
> for(unsigned int r = 0; r < rc; ++r) {
> const uint8_t rn = *(pl.p[0]+r);
> - printf("Region %i\n", rn);
> + debug("Region %i", rn);
> uint8_t rv[] = { 1, 1, rn }; // AddByteParam(rn);
> if ((err = Write(TYPE_REQUEST,
> COMMAND_GET_REGION_VERSION, 3, rv))) {
> @@ -487,10 +752,61 @@ int CRemoteZ_Base::GetIdentity(TRemoteIn
> }
> CRemoteZ_Base::TParamList rp;
> ParseParams(len, rgv, rp);
> + ri.region_ids[r+1] = rn;
> + ri.region_versions[r+1] = new char[4];
> + snprintf(ri.region_versions[r+1], 4, "%d.%d",
> + *(rp.p[0]+1), *rp.p[0]);
> }
> }
> -#endif
>
> + // Get HOMEID, NODEID, TID
> + if ((err = Write(TYPE_REQUEST, COMMAND_GET_HOME_ID))) {
> + debug("Failed to write to remote");
> + return LC_ERROR;
> + }
> + if ((err = Read(status, len, rsp))) {
> + debug("Failed to read from remote");
> + return LC_ERROR;
> + }
> + ParseParams(len, rsp, pl);
> + ri.home_id = (*pl.p[0] << 24) + (*(pl.p[0]+1) << 16) +
> + (*(pl.p[0]+2) << 8) + *(pl.p[0]+3);
> + if ((err = Write(TYPE_REQUEST, COMMAND_GET_NODE_ID))) {
> + debug("Failed to write to remote");
> + return LC_ERROR;
> + }
> + if ((err = Read(status, len, rsp))) {
> + debug("Failed to read from remote");
> + return LC_ERROR;
> + }
> + ParseParams(len, rsp, pl);
> + ri.node_id = *pl.p[0];
> + // Get the "TID" - not entirely sure what this is, but it appears to be
> + // contained in the INTERFACE_LIST.
> + if ((err = Write(TYPE_REQUEST, COMMAND_GET_INTERFACE_LIST))) {
> + debug("Failed to write to remote");
> + return LC_ERROR;
> + }
> + if ((err = Read(status, len, rsp))) {
> + debug("Failed to read from remote");
> + return LC_ERROR;
> + }
> + ParseParams(len, rsp, pl);
> + ri.tid = new char[21];
> + ri.tid[0] = '0';
> + ri.tid[1] = 'x';
> + // "TID" appears to be contained in the middle of the INTERFACE_LIST.
> + for (int i=0; i<9; i++)
> + snprintf(&ri.tid[(i*2)+2], 3, "%02X", *(pl.p[1]+i+2));
> + ri.tid[20] = '\0';
> +
> + // Get the "XMLUserRFSetting" - the usbnet remote appears to have a web
> + // server running where the Windows driver grabs this data.
> + if (err = GetXMLUserRFSetting(&ri.xml_user_rf_setting)) {
> + debug("Failed to read XML User RF Settings");
> + return LC_ERROR;
> + }
> +
> return 0;
> }
>
> Index: libconcord/usblan.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/usblan.cpp,v
> retrieving revision 1.13.2.1
> diff -u -p -r1.13.2.1 usblan.cpp
> --- libconcord/usblan.cpp 19 Sep 2010 16:06:25 -0000 1.13.2.1
> +++ libconcord/usblan.cpp 11 Mar 2012 01:54:59 -0000
> @@ -48,6 +48,12 @@ static SOCKET sock = SOCKET_ERROR;
> const char * const remote_ip_address = "169.254.1.2";
> const u_short remote_port = 3074;
>
> +const char * const http_get_cmd = "\
> +GET /xmluserrfsetting HTTP/1.1\r\n\
> +User-Agent: Jakarta Commons-HttpClient/3.1\r\n\
> +Host: 169.254.1.2\r\n\
> +\r\n";
> +
> int InitializeUsbLan(void)
> {
> return 0;
> @@ -127,3 +133,63 @@ int UsbLan_Read(unsigned int &len, uint8
>
> return 0;
> }
> +
> +int GetXMLUserRFSetting(char **data)
> +{
> + int err;
> + int web_sock;
> + char buf[4096];
> +
> + hostent* addr = gethostbyname(remote_ip_address);
> +
> + if (!addr) {
> + report_net_error("gethostbyname()");
> + return LC_ERROR_OS_NET;
> + }
> +
> + sockaddr_in sa;
> + memcpy(&(sa.sin_addr), addr->h_addr, addr->h_length);
> + sa.sin_family = AF_INET; // TCP/IP
> + sa.sin_port = htons(80); // Web Server port
> +
> + web_sock = socket(sa.sin_family, SOCK_STREAM, 0); // TCP
> +
> + if ((err = connect(web_sock,(struct sockaddr*)&sa,sizeof(sa)))) {
> + report_net_error("connect()");
> + return LC_ERROR_OS_NET;
> + }
> + debug("Connected to USB LAN web server!");
> +
> + err = send(web_sock, http_get_cmd, strlen(http_get_cmd), 0);
> + if (err == SOCKET_ERROR) {
> + report_net_error("send()");
> + return LC_ERROR_OS_NET;
> + }
> + debug("%i bytes sent", err);
> +
> + unsigned int len = 0;
> + char* buf_ptr = buf;
> + do {
> + err = recv(web_sock, buf_ptr, sizeof(buf)-len, 0);
> + if (err == SOCKET_ERROR) {
> + report_net_error("recv()");
> + len = 0;
> + return LC_ERROR_OS_NET;
> + }
> + len += err;
> + buf_ptr += err;
> + debug("%i bytes received", err);
> + } while (err > 0); // recv will return 0 when the message is done.
> + buf[len] = '\0';
> +
> + buf_ptr = strstr(buf, "\r\n\r\n"); // search for end of the http header
> + if (buf_ptr == NULL) {
> + report_net_error("strstr()");
> + return LC_ERROR_OS_NET;
> + }
> + buf_ptr += 4;
> + *data = new char[strlen(buf_ptr)+1];
> + strncpy(*data, buf_ptr, strlen(buf_ptr)+1);
> +
> + return 0;
> +}
> Index: libconcord/usblan.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/usblan.h,v
> retrieving revision 1.5.2.1
> diff -u -p -r1.5.2.1 usblan.h
> --- libconcord/usblan.h 19 Sep 2010 16:06:25 -0000 1.5.2.1
> +++ libconcord/usblan.h 11 Mar 2012 01:54:59 -0000
> @@ -30,5 +30,6 @@ int ShutdownUsbLan(void);
> int FindUsbLanRemote(void);
> int UsbLan_Write(unsigned int len, uint8_t *data);
> int UsbLan_Read(unsigned int &len, uint8_t *data);
> +int GetXMLUserRFSetting(char **data);
>
> #endif
> Index: libconcord/web.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/web.cpp,v
> retrieving revision 1.27.2.2
> diff -u -p -r1.27.2.2 web.cpp
> --- libconcord/web.cpp 18 Sep 2010 14:14:54 -0000 1.27.2.2
> +++ libconcord/web.cpp 11 Mar 2012 01:54:59 -0000
> @@ -256,6 +256,19 @@ int encode_ir_signal(uint32_t carrier_cl
> return 0;
> }
>
> +int add_usbnet_headers(char *post_data, TRemoteInfo &ri)
> +{
> + sprintf(post_data+strlen(post_data), post_xml_usbnet1, ri.home_id,
> + ri.node_id, ri.tid);
> + for (int i=0; i<ri.num_regions; i++) {
> + sprintf(post_data+strlen(post_data),
> + post_xml_usbnet_region, ri.region_ids[i],
> + ri.region_versions[i]);
> + }
> + sprintf(post_data+strlen(post_data), "%s", post_xml_usbnet2);
> + sprintf(post_data+strlen(post_data), "%s", ri.xml_user_rf_setting);
> + sprintf(post_data+strlen(post_data), "%s", post_xml_usbnet3);
> +}
>
> int Post(uint8_t *xml, uint32_t xml_size, const char *root, TRemoteInfo &ri,
> bool has_userid, bool add_cookiekeyval, bool z_post,
> @@ -301,7 +314,7 @@ int Post(uint8_t *xml, uint32_t xml_size
> if (learn_seq == NULL) {
> char serial[144];
> sprintf(serial, "%s%s%s", ri.serial1, ri.serial2, ri.serial3);
> - char post_data[2000];
> + char post_data[4000]; // large enough for extra usbnet headers
> if (z_post) {
> sprintf(post_data, z_post_xml,
> ri.hw_ver_major, ri.hw_ver_minor,
> @@ -311,8 +324,14 @@ int Post(uint8_t *xml, uint32_t xml_size
> sprintf(post_data, post_xml,
> ri.fw_ver_major, ri.fw_ver_minor, ri.fw_type,
> serial, ri.hw_ver_major, ri.hw_ver_minor,
> - ri.flash_mfg, ri.flash_id, ri.protocol,
> - ri.architecture, ri.skin);
> + ri.hw_ver_micro, ri.flash_mfg, ri.flash_id,
> + ri.protocol, ri.architecture, ri.skin);
> + if (is_usbnet_remote()) {
> + add_usbnet_headers(post_data, ri);
> + } else {
> + sprintf(post_data+strlen(post_data), "%s",
> + post_xml_trailer);
> + }
> }
>
> debug("post data: %s",post_data);
> Index: libconcord/xml_headers.h
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/xml_headers.h,v
> retrieving revision 1.7.2.1
> diff -u -p -r1.7.2.1 xml_headers.h
> --- libconcord/xml_headers.h 25 Aug 2010 22:27:22 -0000 1.7.2.1
> +++ libconcord/xml_headers.h 11 Mar 2012 01:54:59 -0000
> @@ -153,16 +153,36 @@ const char *post_xml="\
> <SOFTWARE>%i.%i</SOFTWARE>\
> <SOFTWARETYPE>%i</SOFTWARETYPE>\
> <ID>%s</ID>\
> -<BOARD>%i.%i.0</BOARD>\
> +<BOARD>%i.%i.%i</BOARD>\
> <FLASH>0x%02X:0x%02X</FLASH>\
> <PROTOCOL>%i</PROTOCOL>\
> <ARCHITECTURE>%i</ARCHITECTURE>\
> -<SKIN>%i</SKIN>\
> +<SKIN>%i</SKIN>";
> +
> +const char *post_xml_trailer="\
> <REGIONS/>\
> </VERSION>\
> </VERSIONINFORMATION>\
> </EASYZAPPERDATA>\r\n";
>
> +const char *post_xml_usbnet1="\
> +<HOMEID>0x%08X</HOMEID>\
> +<NODEID>%i</NODEID>\
> +<TID>%s</TID>\
> +<FIRMWARE>";
> +
> +const char *post_xml_usbnet_region="\
> +<REGION ID=\"%i\">%s</REGION>";
> +
> +const char *post_xml_usbnet2="\
> +</FIRMWARE>\
> +<REGIONS/>\
> +</VERSION>\
> +</VERSIONINFORMATION>";
> +
> +const char *post_xml_usbnet3="\
> +</EASYZAPPERDATA>";
> +
> const char *z_post_xml="\
> <DATA>\
> <STATUS>Success</STATUS>\
> Index: libconcord/libusb/libusbhid.cpp
> ===================================================================
> RCS file: /cvsroot/concordance/concordance/libconcord/libusb/libusbhid.cpp,v
> retrieving revision 1.19
> diff -u -p -r1.19 libusbhid.cpp
> --- libconcord/libusb/libusbhid.cpp 17 Jul 2010 22:17:37 -0000 1.19
> +++ libconcord/libusb/libusbhid.cpp 11 Mar 2012 01:54:59 -0000
> @@ -135,6 +135,11 @@ int FindRemote(THIDINFO &hid_info)
> }
>
> #ifdef linux
> + /* If this is a usbnet remote, abort before trying to detach drivers */
> + if (h_dev && (h_dev->descriptor.idProduct == 0xC11F)) {
> + return LC_ERROR_CONNECT;
> + }
> +
> /*
> * Before we attempt to claim the interface, lets go ahead and get
> * the kernel off of it, in case it claimed it already.
>
> ------------------------------------------------------------------------------
> Virtualization & Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> concordance-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/concordance-devel
>
--
Phil Dibowitz [email protected]
Open Source software and tech docs Insanity Palace of Metallica
http://www.phildev.net/ http://www.ipom.com/
"Be who you are and say what you feel, because those who mind don't matter
and those who matter don't mind."
- Dr. Seuss
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________ concordance-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/concordance-devel
