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 > concordance-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/concordance-devel > -- Phil Dibowitz p...@ipom.com 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 concordance-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/concordance-devel