1 /*
2  * vim:tw=80:ai:tabstop=4:softtabstop=4:shiftwidth=4:expandtab
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * (C) Copyright Kevin Timmerman 2007
19  * (C) Copyright Phil Dibowitz 2007
20  */
21 
22 #ifndef REMOTE_H
23 #define REMOTE_H
24 
25 #include "lc_internal.h"
26 #include "libconcord.h"
27 
28 #define SERIAL_SIZE 48
29 #define FIRMWARE_MAX_SIZE 64*1024
30 /* Largest packet size for HID-UDP is 4 bytes (header) + 64 bytes (data) */
31 #define HID_UDP_MAX_PACKET_SIZE 68
32 #define HID_UDP_HDR_SIZE 2
33 #define HID_TCP_HDR_SIZE 4
34 /* Largest packet size for usbnet is the COMMAND_WRITE_UPDATE_DATA
35    which is 1 (num params) + 3 (3 parameter size bytes) + 1 (param 1)
36    + 1024 (param 2) + 4 (param 3) = 1033. */
37 #define USBNET_MAX_PACKET_SIZE 1033
38 const uint8_t MH_EOF_BYTES[] = { 0x50, 0x54, 0x59, 0x59 };
39 
40 /*
41  * limits for IR signal learning, stop when any is reached:
42  * timeouts in milliseconds, length in number of mark/space durations
43  */
44 #define IR_LEARN_START_TIMEOUT 5000
45 #define MAX_IR_SIGNAL_DURATION 5000
46 #define IR_LEARN_DONE_TIMEOUT 500
47 #define MAX_IR_SIGNAL_LENGTH 1000
48 
49 /*
50  * WARNING: Do not change this!
51  * These values have special meaning to the Z-Wave remotes
52  */
53 enum TRegion {
54     REGION_BOOTLOADER=0,        // 0
55     REGION_SAFEMODE,            // 1
56     REGION_APPLICATION,         // 2
57     REGION_EMBEDDING_CONFIG,    // 3
58     REGION_USER_CONFIG,         // 4
59     REGION_PIC_REGION,          // 5
60     REGION_SPARE1,              // 6
61     REGION_ZWAVE,               // 7
62     REGION_BLASTER_CONFIG,      // 8
63     REGION_STATE_VARIABLE,      // 9
64     REGION_LOGGING_REGION,      // 10
65     REGION_SPARE2,              // 11
66     REGION_SPARE3,              // 12
67     REGION_SPARE4,              // 13
68     REGION_SPARE5,              // 14
69     REGION_SPARE6               // 15
70 };
71 
72 struct TModel {
73     const char *mfg;
74     const char *model;
75     const char *code_name;
76 };
77 
78 struct TFlash {
79     uint8_t mfg;
80     uint8_t id;
81     uint32_t size;
82     unsigned int bits;
83     const uint32_t *sectors;
84     const char *part;
85 };
86 
87 #define SERIAL_LOCATION_EEPROM 1
88 #define SERIAL_LOCATION_FLASH  2
89 struct TArchInfo {
90     int serial_location;
91     uint32_t serial_address;
92     uint32_t flash_base;
93     uint32_t firmware_base;
94     uint32_t config_base;
95     uint32_t firmware_update_base;
96     uint32_t firmware_4847_offset;
97     uint32_t cookie;
98     uint32_t cookie_size;
99     uint32_t end_vector;
100     const char *micro;
101     uint32_t flash_size;
102     uint32_t ram_size;
103     uint32_t eeprom_size;
104     const char *usb;
105 };
106 
107 struct TRemoteInfo {
108     uint16_t hw_ver_major;
109     uint16_t hw_ver_minor;
110     uint16_t hw_ver_micro;
111     uint16_t fw_ver_major;
112     uint16_t fw_ver_minor;
113     uint8_t fw_type;
114     uint8_t flash_mfg;
115     uint8_t flash_id;
116     const TFlash *flash;
117     uint16_t architecture;
118     const TArchInfo *arch;
119     uint8_t skin;
120     uint8_t protocol;
121     const TModel *model;
122     char *serial1;
123     char *serial2;
124     char *serial3;
125     bool valid_config;
126     uint32_t config_bytes_used;
127     uint32_t max_config_size;
128     /* usbnet only from here down */
129     uint8_t num_regions;
130     uint8_t *region_ids;
131     char **region_versions;
132     uint32_t home_id;
133     uint8_t node_id;
134     char *tid;
135     char *xml_user_rf_setting;
136     /* Special serial number that some MH remotes use */
137     string mh_serial;
138 };
139 
140 struct THarmonyTime {
141     unsigned int second;
142     unsigned int minute;
143     unsigned int hour;
144     unsigned int dow;
145     unsigned int day;
146     unsigned int month;
147     unsigned int year;
148     int utc_offset;
149     string timezone;
150 };
151 
152 
153 void setup_ri_pointers(TRemoteInfo &ri);
154 void make_serial(uint8_t *ser, TRemoteInfo &ri);
155 int LearnIRInnerLoop(uint32_t *freq, uint32_t **ir_signal,
156     uint32_t *ir_signal_length, uint8_t seq);
157 uint16_t mh_get_checksum(uint8_t* rd, const uint32_t len);
158 
159 class CRemoteBase            // Base class for all remotes
160 {
161 public:
CRemoteBase()162     CRemoteBase() {};
~CRemoteBase()163     virtual ~CRemoteBase() {};
164     virtual int Reset(uint8_t kind)=0;
165     virtual int GetIdentity(TRemoteInfo &ri, struct THIDINFO &hid,
166         lc_callback cb=NULL, void *cb_arg=NULL,
167         uint32_t cb_stage=0)=0;
168 
169     virtual int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
170         unsigned int protocol, bool verify=false,
171         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0)=0;
172     virtual int InvalidateFlash(lc_callback cb=NULL, void *cb_arg=NULL,
173         uint32_t cb_stage=0)=0;
174     virtual int EraseFlash(uint32_t addr, uint32_t len,
175         const TRemoteInfo &ri, lc_callback cb=NULL,
176         void *cb_arg=NULL, uint32_t cb_stage=0)=0;
177     virtual int WriteFlash(uint32_t addr, const uint32_t len,
178         const uint8_t *wr, unsigned int protocol, lc_callback cb=NULL,
179         void *cb_arg=NULL, uint32_t cb_stage=0)=0;
180     virtual int WriteRam(uint32_t addr, const uint32_t len, uint8_t *wr)=0;
181     virtual int ReadRam(uint32_t addr, const uint32_t len, uint8_t *rd)=0;
182     virtual int PrepFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
183         void *cb_arg=NULL, uint32_t cb_stage=0) = 0;
184     virtual int FinishFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
185         void *cb_arg=NULL, uint32_t cb_stage=0) = 0;
186     virtual int PrepConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
187         void *cb_arg=NULL, uint32_t cb_stage=0)=0;
188     virtual int FinishConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
189         void *cb_arg=NULL, uint32_t cb_stage=0)=0;
190     virtual int UpdateConfig(const uint32_t len,
191         const uint8_t *wr, lc_callback cb, void *cb_arg,
192         uint32_t cb_stage, uint32_t xml_size=0,
193         uint8_t *xml=NULL)=0;
194     virtual int GetTime(const TRemoteInfo &ri, THarmonyTime &ht)=0;
195     virtual int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
196         lc_callback cb=NULL, void *cb_arg=NULL,
197         uint32_t cb_stage=0)=0;
198     virtual int LearnIR(uint32_t *freq, uint32_t **ir_signal,
199         uint32_t *ir_signal_length, lc_callback cb=NULL,
200         void *cb_arg=NULL, uint32_t cb_stage=0)=0;
201     virtual int IsZRemote()=0;
202     virtual int IsUSBNet()=0;
203     virtual int IsMHRemote()=0;
204 
205     virtual int ReadFile(const char *filename, uint8_t *rd,
206         const uint32_t rdlen, uint32_t *data_read, uint8_t start_seq,
207         lc_callback cb, void *cb_arg, uint32_t cb_stage)=0;
208     virtual int WriteFile(const char *filename, uint8_t *wr,
209         const uint32_t wrlen)=0;
210 };
211 
212 class CRemote : public CRemoteBase    // All non-Z-Wave remotes
213 {
214 private:
215     int ReadMiscByte(uint8_t addr, uint32_t len, uint8_t kind,
216         uint8_t *rd);
217     int ReadMiscWord(uint16_t addr, uint32_t len, uint8_t kind,
218         uint16_t *rd);
219     int WriteMiscByte(uint8_t addr, uint32_t len, uint8_t kind,
220         uint8_t *wr);
221     int WriteMiscWord(uint16_t addr, uint32_t len, uint8_t kind,
222         uint16_t *wr);
223 
224 public:
CRemote()225     CRemote() {};
~CRemote()226     virtual ~CRemote() {};
227     int Reset(uint8_t kind);
228     int GetIdentity(struct TRemoteInfo &ri, struct THIDINFO &hid,
229         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
230 
231     int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
232         unsigned int protocol, bool verify=false,
233         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
234     int InvalidateFlash(lc_callback cb=NULL, void *cb_arg=NULL,
235         uint32_t cb_stage=0);
236     int EraseFlash(uint32_t addr, uint32_t len, const TRemoteInfo &ri,
237         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
238     int WriteFlash(uint32_t addr, const uint32_t len, const uint8_t *wr,
239         unsigned int protocol, lc_callback cb=NULL, void *cb_arg=NULL,
240         uint32_t cb_stage=0);
241     int WriteRam(uint32_t addr, const uint32_t len, uint8_t *wr);
242     int ReadRam(uint32_t addr, const uint32_t len, uint8_t *rd);
243     int PrepFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
244         void *cb_arg=NULL, uint32_t cb_stage=0);
245     int FinishFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
246         void *cb_arg=NULL, uint32_t cb_stage=0);
247     int PrepConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
248         void *cb_arg=NULL, uint32_t cb_stage=0);
249     int FinishConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
250         void *cb_arg=NULL, uint32_t cb_stage=0);
251     virtual int UpdateConfig(const uint32_t len,
252         const uint8_t *wr, lc_callback cb, void *cb_arg,
253         uint32_t cb_stage=0, uint32_t xml_size=0,
254         uint8_t *xml=NULL) {return 0;};
255 
256     int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
257     int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
258         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
259 
260     int LearnIR(uint32_t *freq, uint32_t **ir_signal,
261         uint32_t *ir_signal_length, lc_callback cb=NULL,
262         void *cb_arg=NULL, uint32_t cb_stage=0);
IsZRemote()263     int IsZRemote() {return false;}
IsUSBNet()264     int IsUSBNet() {return false;}
IsMHRemote()265     int IsMHRemote() {return false;}
266 
267     int ReadFile(const char *filename, uint8_t *rd, const uint32_t rdlen,
268         uint32_t *data_read, uint8_t start_seq, lc_callback cb, void *cb_arg,
269         uint32_t cb_stage);
270     int WriteFile(const char *filename, uint8_t *wr, const uint32_t wrlen);
271 };
272 
273 // Base class for all Z-Wave remotes
274 class CRemoteZ_Base : public CRemoteBase
275 {
276 protected:
277     struct TParamList {
278         uint32_t count;
279         uint8_t *p[32];
280     };
281     virtual int Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
282         uint8_t *data=NULL)=0;
283     virtual int Read(uint8_t &status, uint32_t &len, uint8_t *data)=0;
284     virtual int ParseParams(uint32_t len, uint8_t *data,
285         TParamList &pl)=0;
286     virtual uint16_t GetWord(uint8_t *x)=0;
287     virtual int ReadRegion(uint8_t region, uint32_t &len, uint8_t *rd,
288         lc_callback cb, void *cb_arg, uint32_t cb_stage)=0;
289 
290 public:
CRemoteZ_Base()291     CRemoteZ_Base() {};
~CRemoteZ_Base()292     virtual ~CRemoteZ_Base() {};
293     int Reset(uint8_t kind);
294     int GetIdentity(struct TRemoteInfo &ri, struct THIDINFO &hid,
295         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
296 
297     int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
298         unsigned int protocol, bool verify=false,
299         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
300     int InvalidateFlash(lc_callback cb=NULL, void *cb_arg=NULL,
301         uint32_t cb_stage=0);
302     int EraseFlash(uint32_t addr, uint32_t len, const TRemoteInfo &ri,
303         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
304     int WriteFlash(uint32_t addr, const uint32_t len, const uint8_t *wr,
305         unsigned int protocol, lc_callback cb=NULL, void *cb_arg=NULL,
306         uint32_t cb_stage=0);
307     int WriteRam(uint32_t addr, const uint32_t len, uint8_t *wr);
308     int ReadRam(uint32_t addr, const uint32_t len, uint8_t *rd);
309     int PrepFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
310         void *cb_arg=NULL, uint32_t cb_stage=0);
311     int FinishFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
312         void *cb_arg=NULL, uint32_t cb_stage=0);
313     int PrepConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
314         void *cb_arg=NULL, uint32_t cb_stage=0);
315     int FinishConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
316         void *cb_arg=NULL, uint32_t cb_stage=0);
317 
318     int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
319     int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
320         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
321 
IsZRemote()322     int IsZRemote() {return true;}
IsMHRemote()323     int IsMHRemote() {return false;}
324 
325     int ReadFile(const char *filename, uint8_t *rd, const uint32_t rdlen,
326         uint32_t *data_read, uint8_t start_seq, lc_callback cb, void *cb_arg,
327         uint32_t cb_stage);
328     int WriteFile(const char *filename, uint8_t *wr, const uint32_t wrlen);
329 };
330 
331 // 890, 890Pro, AVL-300, RF Extender
332 class CRemoteZ_HID : public CRemoteZ_Base
333 {
334 private:
335     uint8_t m_tx_seq;
336     uint8_t m_rx_seq;
337     int UDP_Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
338         uint8_t *data=NULL);
339     int UDP_Read(uint8_t &status, uint32_t &len, uint8_t *data);
340     int TCP_Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
341         uint8_t *data=NULL);
342     int TCP_Read(uint8_t &status, uint32_t &len, uint8_t *data);
343 
344 protected:
345     int TCPSendAndCheck(uint8_t cmd, uint32_t len=0, uint8_t *data=NULL,
346         bool ackonly=false);
347     virtual int Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
348         uint8_t *data=NULL);
349     virtual int Read(uint8_t &status, uint32_t &len, uint8_t *data);
350     virtual int ParseParams(uint32_t len, uint8_t *data,
351         TParamList &pl);
GetWord(uint8_t * x)352     virtual uint16_t GetWord(uint8_t *x) { return x[1]<<8 | x[0]; };
353 
354 public:
CRemoteZ_HID()355     CRemoteZ_HID() {};
~CRemoteZ_HID()356     virtual ~CRemoteZ_HID() {};
357     int UpdateConfig(const uint32_t len, const uint8_t *wr,
358         lc_callback cb, void *cb_arg, uint32_t cb_stage,
359         uint32_t xml_size=0, uint8_t *xml=NULL);
360     int LearnIR(uint32_t *freq, uint32_t **ir_signal,
361         uint32_t *ir_signal_length, lc_callback cb=NULL,
362         void *cb_arg=NULL, uint32_t cb_stage=0);
IsUSBNet()363     int IsUSBNet() {return false;}
364     virtual int ReadRegion(uint8_t region, uint32_t &len, uint8_t *rd,
365         lc_callback cb, void *cb_arg, uint32_t cb_stage);
366 };
367 
368 // 1000, 1000i
369 class CRemoteZ_USBNET : public CRemoteZ_Base
370 {
371 protected:
372     int TCPSendAndCheck(uint8_t cmd, uint32_t len=0, uint8_t *data=NULL);
373     virtual int Write(uint8_t typ, uint8_t cmd, uint32_t len=0,
374         uint8_t *data=NULL);
375     virtual int Read(uint8_t &status, uint32_t &len, uint8_t *data);
376     virtual int ParseParams(uint32_t len, uint8_t *data,
377         TParamList &pl);
GetWord(uint8_t * x)378     virtual uint16_t GetWord(uint8_t *x) { return x[0]<<8 | x[1]; };
GetWord32(uint8_t * x)379     virtual uint32_t GetWord32(uint8_t *x) { return x[0]<<24 | x[1]<<16
380         | x[2]<<8 | x[3]; };
381     virtual int ReadRegion(uint8_t region, uint32_t &len, uint8_t *rd,
382         lc_callback cb, void *cb_arg, uint32_t cb_stage);
383 
384 public:
CRemoteZ_USBNET()385     CRemoteZ_USBNET() {};
~CRemoteZ_USBNET()386     virtual ~CRemoteZ_USBNET() {};
387     int UpdateConfig(const uint32_t len, const uint8_t *wr,
388         lc_callback cb, void *cb_arg, uint32_t cb_stage,
389         uint32_t xml_size=0, uint8_t *xml=NULL);
390     int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
391     int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
392         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
393     int LearnIR(uint32_t *freq, uint32_t **ir_signal,
394         uint32_t *ir_signal_length, lc_callback cb=NULL,
395         void *cb_arg=NULL, uint32_t cb_stage=0);
IsUSBNet()396     int IsUSBNet() {return true;}
397 };
398 
399 class CRemoteMH : public CRemoteBase    // "My Harmony" remotes
400 {
401 private:
402     int ReadMiscByte(uint8_t addr, uint32_t len, uint8_t kind,
403         uint8_t *rd);
404     int ReadMiscWord(uint16_t addr, uint32_t len, uint8_t kind,
405         uint16_t *rd);
406     int WriteMiscByte(uint8_t addr, uint32_t len, uint8_t kind,
407         uint8_t *wr);
408     int WriteMiscWord(uint16_t addr, uint32_t len, uint8_t kind,
409         uint16_t *wr);
410 
411 public:
CRemoteMH()412     CRemoteMH() {};
~CRemoteMH()413     virtual ~CRemoteMH() {};
414     int Reset(uint8_t kind);
415     int GetIdentity(struct TRemoteInfo &ri, struct THIDINFO &hid,
416         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
417 
418     int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
419         unsigned int protocol, bool verify=false,
420         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
421     int InvalidateFlash(lc_callback cb=NULL, void *cb_arg=NULL,
422         uint32_t cb_stage=0);
423     int EraseFlash(uint32_t addr, uint32_t len, const TRemoteInfo &ri,
424         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
425     int WriteFlash(uint32_t addr, const uint32_t len, const uint8_t *wr,
426         unsigned int protocol, lc_callback cb=NULL, void *cb_arg=NULL,
427         uint32_t cb_stage=0);
428     int WriteRam(uint32_t addr, const uint32_t len, uint8_t *wr);
429     int ReadRam(uint32_t addr, const uint32_t len, uint8_t *rd);
430     int PrepFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
431         void *cb_arg=NULL, uint32_t cb_stage=0);
432     int FinishFirmware(const TRemoteInfo &ri, lc_callback cb=NULL,
433         void *cb_arg=NULL, uint32_t cb_stage=0);
434     int PrepConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
435         void *cb_arg=NULL, uint32_t cb_stage=0);
436     int FinishConfig(const TRemoteInfo &ri, lc_callback cb=NULL,
437         void *cb_arg=NULL, uint32_t cb_stage=0);
438     virtual int UpdateConfig(const uint32_t len, const uint8_t *wr,
439         lc_callback cb,    void *cb_arg, uint32_t cb_stage=0,
440         uint32_t xml_size=0, uint8_t *xml=NULL);
441 
442     int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
443     int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht,
444         lc_callback cb=NULL, void *cb_arg=NULL, uint32_t cb_stage=0);
445 
446     int LearnIR(uint32_t *freq, uint32_t **ir_signal,
447         uint32_t *ir_signal_length, lc_callback cb=NULL,
448         void *cb_arg=NULL, uint32_t cb_stage=0);
IsZRemote()449     int IsZRemote() {return false;}
IsUSBNet()450     int IsUSBNet() {return false;}
IsMHRemote()451     int IsMHRemote() {return true;}
452 
453     int ReadFile(const char *filename, uint8_t *rd, const uint32_t rdlen,
454         uint32_t *data_read, uint8_t start_seq, lc_callback cb, void *cb_arg,
455         uint32_t cb_stage);
456     int WriteFile(const char *filename, uint8_t *wr, const uint32_t wrlen);
457 };
458 
459 #endif //REMOTE_H
460