Here come the first patches for libconcord and concordance,
providing resp. using the new IR learning API.

Patches are against the current (2008-06-06) CVS versions.

Regards, Andreas Schulz


Index: concordance.1
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.1,v
retrieving revision 1.9
diff -u -3 -p -u -p -r1.9 concordance.1
--- concordance.1	15 Apr 2008 02:32:32 -0000	1.9
+++ concordance.1	6 Jun 2008 21:05:25 -0000
@@ -60,7 +60,7 @@ Get time from the remote
 Set the time on the remote
 .TP
 .B \-l, \-\-learn-ir <filename>
-Learn IR from other remotes. Use <filename>.
+Learn IR from other remotes. Use <filename>. Current version also supports files with multiple codes, i.e. when you checked multiple commands on the Logitech website.
 .TP
 .B \-r, \-\-reset
 Reset (power-cycle) the remote control
@@ -97,6 +97,6 @@ Please file all bug reports in the bugs 
 .SH NOTES
 This software is not supported, affiliated, or controlled by Logitech in any way.
 .SH AUTHOR
-\fBconcordance\fP was written by Kevin Timmerman and Phil Dibowitz
+\fBconcordance\fP was written by Kevin Timmerman and Phil Dibowitz; IR learning update by Andreas Schulz
 .br
 http://www.phildev.net/concordance/
Index: concordance.c
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
retrieving revision 1.32
diff -u -3 -p -u -p -r1.32 concordance.c
--- concordance.c	15 Apr 2008 06:17:02 -0000	1.32
+++ concordance.c	6 Jun 2008 21:05:26 -0000
@@ -140,6 +140,101 @@ void cb_print_percent_status(uint32_t co
 	fflush(stdout);
 }
 
+void _printburst(uint32_t length)
+{
+	if (length < 250) {
+		printf("|");
+	} else if (length < 1000) {
+		printf("#");
+	} else {
+		printf("##");
+	}
+}
+
+void _printspace(uint32_t length)
+{
+	if (length < 250) {
+		printf(".");
+	} else if (length < 1000) {
+		printf("_");
+	} else if (length < 10000) {
+		printf("__");
+	} else {
+		printf("\n");
+	}
+}
+
+void _dump_new_code(uint32_t carrier_clock, uint32_t *pulses, 
+	uint32_t pulse_count, struct options_t *options)
+{
+	uint32_t index;
+	printf("ASCII-graph of received IR signal:\n");
+	for (index=0; index < pulse_count; index += 2){
+		_printburst(pulses[index]);
+		_printspace(pulses[index+1]);
+	}
+	printf("\n");
+	if ((*options).verbose) {
+		/*
+		 * full dump of new IR signal:
+		 */
+		printf("Carrier clock            : %u Hz\n", carrier_clock);
+		printf("Total pulse/space pairs  : %u\n", pulse_count/2);
+		for (index=0; index < pulse_count; index += 2){
+			printf("\tP:%6u\tS:%6u\n", pulses[index],
+				pulses[index+1]);
+		}
+	}
+}
+
+int _learn_ir_commands(uint8_t *data, uint32_t size, struct options_t *options)
+{
+	int err = 0;
+	uint32_t carrier_clock = 0;
+	uint32_t *pulses = NULL;
+	uint32_t pulse_count = 0;
+	int next_index = 1;
+	char *key_name = NULL;
+	char *post_string = NULL;
+
+	while ((key_name = get_key_name(data, size, next_index++)) != NULL) {
+		printf("Next key : <%s> : ", key_name);
+		err = 1; /* have no code yet */
+
+		/* learn from remote: */
+		printf("press <enter>, then related ");
+		printf("key on original remote:");
+		getchar();
+		err = learn_from_remote(&carrier_clock, &pulses,
+				&pulse_count);
+
+		if ( err != 0 ) {
+			printf("Failed to get IR code, ");
+			printf("continue with next key...\n");
+			continue;
+		}
+		/* have new IR code: */
+		_dump_new_code(carrier_clock, pulses, pulse_count, options);
+
+		post_string = encode_for_posting(carrier_clock, pulses,
+				pulse_count);
+
+		if ( post_string != NULL ) {
+			if ((*options).verbose) {
+				printf("%s\n\n", post_string );
+			}
+			if (!(*options).noweb) {
+				err = post_new_code(data, size, 
+					key_name, post_string);
+			}
+		} else {
+			printf("Failed to encode new code, ");
+			printf("continue with next key...\n");
+		}
+	}
+	return err;
+}
+
 /*
  * Start helper functions
  */
@@ -479,7 +574,6 @@ int dump_firmware(struct options_t *opti
 	return 0;
 }
 
-
 /*
  * Parse our options.
  */
@@ -923,7 +1017,7 @@ int main(int argc, char *argv[])
 
 	err = 0;
 
-	err = init_concord();
+	err = init_concord(); 
 	if (err != 0) {
 		printf("Error initializing libconcord: %s\n",
 			lc_strerror(err));
@@ -1032,7 +1126,7 @@ int main(int argc, char *argv[])
 			break;
 
 		case MODE_LEARN_IR:
-			err = learn_ir_commands(data, size, !options.noweb);
+			err = _learn_ir_commands(data, size, &options);
 			break;
 
 		case MODE_GET_TIME:
Index: libconcord.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.cpp,v
retrieving revision 1.35
diff -u -3 -p -u -p -r1.35 libconcord.cpp
--- libconcord.cpp	14 Apr 2008 07:27:58 -0000	1.35
+++ libconcord.cpp	6 Jun 2008 21:04:04 -0000
@@ -1224,42 +1224,154 @@ int extract_firmware_binary(uint8_t *xml
  * IR stuff
  */
 
-int learn_ir_commands(uint8_t *data, uint32_t size, int post)
+/*
+ * Static buffer to maintain the scanning status when searching
+ * the received XML file for key names between subsequent calls
+ * of get_key_name:
+ */
+
+static struct {
+	uint8_t *data;
+	uint32_t size;
+	uint8_t *cursor;
+	uint8_t *ip_end;
+	uint32_t previous_index;
+	string previous_name;
+} XMLBuffer;
+
+/*
+ * List of key names to be learned is passed in section INPUTPARMS
+ * as e.g.:
+ * <PARAMETER><KEY>KeyName</KEY><VALUE>PowerToggle</VALUE></PARAMETER>
+ * First of these is repeated in section PARAMETERS, so we must
+ * concentrate on INPUTPARMS to avoid duplication.
+ */
+
+int _next_key_name()
 {
 	int err;
-
-	if (data) {
-		uint8_t *t = data;
-		string keyname;
-		do {
-			err = GetTag("KEY", t, size - (t - data), t, &keyname);
-			if (err != 0) {
-				return err;
-			}
-		} while (keyname != "KeyName");
-		uint8_t *n = 0;
-		err = GetTag("VALUE", t, size, n, &keyname);
+	string keyname;
+	/*
+	 * Assuming XMLBuffer.cursor and XMLBuffer.data 
+	 * are already set by caller:
+	 */
+	if (XMLBuffer.cursor == XMLBuffer.data) {
+		/* starting scan : locating "INPUTPARMS" */
+		err = GetTag("INPUTPARMS", XMLBuffer.data, 
+				XMLBuffer.size, XMLBuffer.cursor);
+		if (err == 0) {
+			err = GetTag("/INPUTPARMS", XMLBuffer.cursor, 
+				XMLBuffer.size - (XMLBuffer.cursor-XMLBuffer.data),
+				XMLBuffer.ip_end);
+		}
 		if (err != 0) {
 			return err;
 		}
-		printf("Key Name: %s\n",keyname.c_str());
+	}
+	/*
+	 * to be really paranoid, we would narrow the search range
+	 * further down to next <PARAMETER>...</PARAMETER>, but IMHO it
+	 * should be safe to assume that Logitech always sends sane files:
+	 */
+	do {
+		err = GetTag("KEY", XMLBuffer.cursor,
+				XMLBuffer.ip_end - XMLBuffer.cursor,
+				XMLBuffer.cursor, &keyname);
+		if (err != 0) {
+			return err;
+		}
+	} while (keyname != "KeyName");
+
+	err = GetTag("VALUE", XMLBuffer.cursor, 
+		(XMLBuffer.ip_end - XMLBuffer.cursor), 
+		XMLBuffer.cursor, &keyname);
+
+	if (err == 0) {
+		/* found next key : save name and index; cursor set already */
+		debug("Key Name: %s\n",keyname.c_str());
+		XMLBuffer.previous_name = keyname;
+	}
+	return err;
+}
+
+
+char *get_key_name(uint8_t *data, uint32_t size, uint32_t index)
+{
+	/*
+	 * No need to provide means for input of a different keyname:
+	 * Logitech will only accept keynames already present in the
+	 * database or user-defined via 'Learn new Key' web page.
+	 */
+	int current;
 
-		string ls;
-		rmt->LearnIR(&ls);
-		debug("Learned code: %s",ls.c_str());
-
-		if (post) {
-			Post(data, size, "POSTOPTIONS", ri, true, false, &ls,
-				&keyname);
+	if (!data || size == 0 || index == 0) {
+		return NULL;
+	}
+	if ((index == 1) || (data != XMLBuffer.data)) {
+		/* initialize XMLbuffer : */
+		XMLBuffer.data = data;
+		XMLBuffer.size = size;
+		XMLBuffer.cursor = data;
+		XMLBuffer.previous_index = 0;
+	}
+	if (index < XMLBuffer.previous_index) {
+		/* moving back : reset cursor and start from beginning */
+		XMLBuffer.cursor = data;
+		XMLBuffer.previous_index = 0;		
+	}
+	/* now scan for name at requested index:
+	 * return NULL as soon as no more key is found */
+	while (XMLBuffer.previous_index < index) {
+		if (_next_key_name() != 0) {
+			return NULL;
 		}
+		XMLBuffer.previous_index++;	
+	}
+	/* found key : name in XMLBuffer.previous_name */
+	return strdup(XMLBuffer.previous_name.c_str());
+}
+
+int learn_from_remote(uint32_t *carrier_clock, uint32_t **pulses,
+	uint32_t *pulse_count)
+{
+	int err = 0;
+	if (rmt == NULL){
+		err = LC_ERROR_CONNECT;
 	} else {
-		rmt->LearnIR();
+		/* try to learn code via Harmony from original remote: */
+		err = rmt->LearnIR(carrier_clock, pulses, pulse_count);
+		if (*pulse_count == 0) err = -1;
+	}
+	return err;
+}
+
+
+char *encode_for_posting(uint32_t carrier_clock, uint32_t *pulses,
+	uint32_t pulse_count)
+{
+	string ls;
+	if (!pulses) {
+		return NULL;	/* cannot do anything without */
 	}
+	encode_ir_signal(pulses, pulse_count, carrier_clock, &ls);
+	debug("Learned code: %s",ls.c_str());
+	return strdup(ls.c_str());
+}
 
+int post_new_code(uint8_t *data, uint32_t size, char *key_name, 
+	char *code)
+{
+	string keyname = key_name;
+	string ls = code;
+
+	if (!(key_name && code && data)) {
+		return -1;	/* cannot do anything without */
+	}
+	Post(data, size, "POSTOPTIONS", ri, true, false,
+		&ls, &keyname);
 	return 0;
 }
 
-
 /*
  * PRIVATE-SHARED INTERNAL FUNCTIONS
  * These are functions used by the whole library but are NOT part of the API
Index: libconcord.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.h,v
retrieving revision 1.19
diff -u -3 -p -u -p -r1.19 libconcord.h
--- libconcord.h	11 Apr 2008 05:05:26 -0000	1.19
+++ libconcord.h	6 Jun 2008 21:04:04 -0000
@@ -382,10 +382,65 @@ int extract_firmware_binary(uint8_t *xml
 	uint32_t *size);
 
 /*
- * IR-stuff. This stuff hasn't yet been cleaned up, you'll have to
- * dig in yourself.
+ * IR-stuff
  */
-int learn_ir_commands(uint8_t *data, uint32_t size, int post);
+
+/*
+ * Data structure information:
+ *
+ * carrier_clock  : in Hz, usually ~36000..40000
+ * pulses : IR pulse/space durations (alternating) in microsconds
+ * pulse_count : total number of pulse and space durations in pulses
+ *      pulses should start with a pulse and end with a space duration,
+ *      hence pulse_count will always be an even number.
+ * 
+ * They are usually filled in by calling learn_from_remote(...),
+ * to learn IR signals from an existing other remote.
+ * They can also be set by the application, without calling 
+ * learn_from_remote(...), e.g. be derived from Pilips Pronto Hex
+ * codes or RC5/NEC/... command codes (separate conversion required).
+ *
+ * encoded posting format : IR code data converted to Logitech 
+ *     posting string format, returned by encode_for_posting.
+ *     Having the encoding separate from the posting keeps the
+ *     parameter list of post_new_code() tidy and allows the
+ *     application to display the encoded signal when desired.
+ */
+
+/*
+ * Scans the contents of the received LearnIR.EZTut file
+ * (read into *data[size]) for the index'th key name
+ * to learn (index starting at 1 for '1'st entry).
+ *
+ * Returns found name or NULL for no key found at index.
+ */
+char *get_key_name(uint8_t *data, uint32_t size, uint32_t index);
+
+/*
+ * Fills ir_data with IR code learned from other remote
+ * via Harmony IR receiver. Allocates storage for *pulses;
+ * caller is responsible for deallocation after use.
+ *
+ * Returns 0 for success, error code for failure.
+ */
+int learn_from_remote(uint32_t *carrier_clock, uint32_t **pulses,
+	uint32_t *pulse_count);
+
+/*
+ * Encodes IR code in to Logitech posting string format.
+ *
+ * Returns encoded string or NULL in case of failure.
+ */
+char *encode_for_posting(uint32_t carrier_clock, uint32_t *pulses,
+	uint32_t pulse_count);
+
+/*
+ * Posts encoded IR-code with key_name and additional 
+ * information from XML data[size] to Logitech.
+ *
+ * Returns 0 for success, error code for failure.
+ */
+int post_new_code(uint8_t *data, uint32_t size, char *key_name, char *code);
 
 #ifdef __cplusplus
 }
Index: remote.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/remote.cpp,v
retrieving revision 1.34
diff -u -3 -p -u -p -r1.34 remote.cpp
--- remote.cpp	14 Apr 2008 08:07:07 -0000	1.34
+++ remote.cpp	6 Jun 2008 21:04:04 -0000
@@ -643,14 +643,14 @@ bool check_seq(int received_seq, uint8_t
 	}
 }
 
-int handle_ir_response(uint8_t rsp[64], unsigned int &ir_word,
-	unsigned int &t_on, unsigned int &t_off, unsigned int &pulse_count,
-	unsigned int *&pulses, unsigned int &freq)
+int _handle_ir_response(uint8_t rsp[64], uint32_t &ir_word,
+	uint32_t &t_on, uint32_t &t_off, uint32_t &pulse_count,
+	uint32_t *&pulses, uint32_t &freq)
 {
-	const unsigned int len = rsp[63];
+	const uint32_t len = rsp[63];
 	if ((len & 1) == 0) {
-		for (unsigned int u = 2; u < len; u += 2) {
-			const unsigned int t = rsp[u] << 8 | rsp[1+u];
+		for (uint32_t u = 2; u < len; u += 2) {
+			const uint32_t t = rsp[u] << 8 | rsp[1+u];
 			if (ir_word > 2) {
 				/*
 				 * For ODD words, t is the total time, we'll
@@ -710,7 +710,8 @@ int handle_ir_response(uint8_t rsp[64], 
 						// pulse count of
 						// first burst
 						if (t_on) {
-							freq = static_cast<unsigned int>(static_cast<uint64_t>(t)*1000000/t_on);
+							freq = static_cast<uint32_t>(
+								static_cast<uint64_t>(t)*1000000/(t_on));
 							debug("%i Hz",freq);
 							debug("+%i",t_on);
 							pulses[pulse_count++] =
@@ -728,7 +729,8 @@ int handle_ir_response(uint8_t rsp[64], 
 	return 0;
 }
 
-int CRemote::LearnIR(string *learn_string)
+
+int CRemote::LearnIR(uint32_t *freq, uint32_t **pulses, uint32_t *pulse_count)
 {
 	int err = 0;
 	uint8_t rsp[68];
@@ -739,18 +741,16 @@ int CRemote::LearnIR(string *learn_strin
 
 	uint8_t seq = 0;
 	// Count of how man IR words we've received.
-	unsigned int ir_word = 0;
+	uint32_t ir_word = 0;
 	// Time button is on and off
-	unsigned int t_on = 0;
-	unsigned int t_off = 0;
-
-	// Frequency button emits
-	unsigned int freq = 0;
-	// Pulse map
-	unsigned int *pulses = new unsigned int[MAX_PULSE_COUNT];
-	unsigned int pulse_count = 0;
+	uint32_t t_on = 0;
+	uint32_t t_off = 0;
 
+	*pulse_count = 0;
+	*pulses = new uint32_t[MAX_PULSE_COUNT];
 	/*
+	 * Caller is responsible for deallocation of *pulses after use.
+	 *
 	 * Loop while we have no error and we haven't had 500,000us of
 	 * any pulses
 	 */
@@ -769,8 +769,8 @@ int CRemote::LearnIR(string *learn_strin
 			 * t_off so we can exit the loop if long enough time
 			 * goes by without action.
 			 */
-			err = handle_ir_response(rsp, ir_word, t_on, t_off,
-				pulse_count, pulses, freq);
+			err = _handle_ir_response(rsp, ir_word, t_on, t_off,
+				*pulse_count, *pulses, *freq);
 			if (err != 0) {
 				break;
 			}
@@ -786,8 +786,8 @@ int CRemote::LearnIR(string *learn_strin
 		debug("-%i", t_off);
 
 	/* make sure we record a final off? */
-	if (pulse_count < MAX_PULSE_COUNT)
-		pulses[pulse_count++] = t_off;
+	if (*pulse_count < MAX_PULSE_COUNT)
+		(*pulses)[*pulse_count++] = t_off;
 
 	const static uint8_t stop_ir_learn[] = { COMMAND_STOP_IRCAP };
 	HID_WriteReport(stop_ir_learn);
@@ -800,20 +800,5 @@ int CRemote::LearnIR(string *learn_strin
 		}
 	}
 
-	/*
-	 * Encode our pulses into string
-	 */
-	if (err == 0 && learn_string != NULL) {
-		char s[32];
-		sprintf(s, "F%04X", freq);
-		*learn_string = s;
-		for (unsigned int n = 0; n < pulse_count; ) {
-			sprintf(s, "P%04X", pulses[n++]);
-			*learn_string += s;
-			sprintf(s, "S%04X", pulses[n++]);
-			*learn_string += s;
-		}
-	}
-	
 	return err;
 }
Index: remote.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/remote.h,v
retrieving revision 1.17
diff -u -3 -p -u -p -r1.17 remote.h
--- remote.h	11 Apr 2008 05:05:26 -0000	1.17
+++ remote.h	6 Jun 2008 21:04:05 -0000
@@ -147,7 +147,8 @@ public:
 	virtual int GetTime(const TRemoteInfo &ri, THarmonyTime &ht)=0;
 	virtual int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht)=0;
 
-	virtual int LearnIR(string *learn_string=NULL)=0;
+	virtual int LearnIR(uint32_t *freq, uint32_t **pulses, 
+		uint32_t *pulse_count)=0;
 };
 
 class CRemote : public CRemoteBase	// All non-Z-Wave remotes
@@ -171,7 +172,7 @@ public:
 
 	int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
 		unsigned int protocol, bool verify=false,
-		lc_callback cb=0, void *cb_arg=NULL);
+		lc_callback cb=NULL, void *cb_arg=NULL);
 	int InvalidateFlash(void);
 	int EraseFlash(uint32_t addr, uint32_t len, const TRemoteInfo &ri,
 		lc_callback cb=NULL, void *cb_arg=NULL);
@@ -185,7 +186,7 @@ public:
 	int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
 	int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht);
 
-	int LearnIR(string *learn_string=NULL);
+	int LearnIR(uint32_t *freq, uint32_t **pulses, uint32_t *pulse_count);
 };
 
 // Base class for all Z-Wave remotes
@@ -212,7 +213,7 @@ public:
 
 	int ReadFlash(uint32_t addr, const uint32_t len, uint8_t *rd,
 		unsigned int protocol, bool verify=false,
-		lc_callback cb=0, void *cb_arg=NULL);
+		lc_callback cb=NULL, void *cb_arg=NULL);
 	int InvalidateFlash(void);
 	int EraseFlash(uint32_t addr, uint32_t len, const TRemoteInfo &ri,
 		lc_callback cb=NULL, void *cb_arg=NULL);
@@ -226,7 +227,7 @@ public:
 	int GetTime(const TRemoteInfo &ri, THarmonyTime &ht);
 	int SetTime(const TRemoteInfo &ri, const THarmonyTime &ht);
 
-	int LearnIR(string *learn_string=NULL);
+	int LearnIR(uint32_t *freq, uint32_t **pulses, uint32_t *pulse_count);
 };
 
 // 890, 890Pro, AVL-300, RF Extender
Index: remote_z.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/remote_z.cpp,v
retrieving revision 1.18
diff -u -3 -p -u -p -r1.18 remote_z.cpp
--- remote_z.cpp	11 Apr 2008 05:05:26 -0000	1.18
+++ remote_z.cpp	6 Jun 2008 21:04:05 -0000
@@ -353,7 +353,8 @@ int CRemoteZ_Base::SetTime(const TRemote
 	return 1;
 }
 
-int CRemoteZ_Base::LearnIR(string *learn_string)
+int CRemoteZ_Base::LearnIR(uint32_t *freq, uint32_t **pulses, 
+	uint32_t *pulse_count)
 {
 	return 0;
 }
Index: web.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/web.cpp,v
retrieving revision 1.26
diff -u -3 -p -u -p -r1.26 web.cpp
--- web.cpp	14 Apr 2008 02:32:00 -0000	1.26
+++ web.cpp	6 Jun 2008 21:04:05 -0000
@@ -215,6 +215,37 @@ int GetTag(const char *find, uint8_t* da
 	}
 }
 
+void encode_ir_signal(uint32_t *pulses, uint32_t pulse_count,
+	uint32_t freq, string *learn_seq)
+{	/*
+	 * Encode our pulses into string
+	 */
+	if (learn_seq != NULL) {
+		char s[32];
+		if (freq > 0xFFFF) {
+			sprintf(s, "F%08X", freq);
+		} else {
+			sprintf(s, "F%04X", freq);
+		}
+		*learn_seq = s;
+		for (unsigned int n = 0; n < pulse_count; ) {
+			if (pulses[n] > 0xFFFF) {
+				sprintf(s, "P%08X", pulses[n++]);
+			} else {
+				sprintf(s, "P%04X", pulses[n++]);
+			}
+			*learn_seq += s;
+			if (pulses[n] > 0xFFFF) {
+				sprintf(s, "S%08X", pulses[n++]);
+			} else {
+				sprintf(s, "S%04X", pulses[n++]);
+			}
+			*learn_seq += s;
+		}
+	}
+}
+
+
 int Post(uint8_t *xml, uint32_t xml_size, const char *root, TRemoteInfo &ri,
 	bool has_userid, bool add_cookiekeyval = false,
 	string *learn_seq = NULL, string *learn_key = NULL)
Index: web.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/web.h,v
retrieving revision 1.10
diff -u -3 -p -u -p -r1.10 web.h
--- web.h	14 Apr 2008 02:32:00 -0000	1.10
+++ web.h	6 Jun 2008 21:04:05 -0000
@@ -25,6 +25,10 @@
 
 int GetTag(const char *find, uint8_t* data, uint32_t data_size,
 	uint8_t *&found, string *s = NULL);
+
+void encode_ir_signal(uint32_t *pulses, uint32_t pulse_count,
+	uint32_t freq, string *learn_seq=NULL);
+
 int Post(uint8_t *xml, uint32_t xml_size, const char *root, TRemoteInfo &ri,
 	bool has_userid, bool add_cookiekeyval = false,
 	string *learn_seq=NULL, string *learn_key=NULL);
Index: bindings/python/libconcord.py
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/bindings/python/libconcord.py,v
retrieving revision 1.1
diff -u -3 -p -u -p -r1.1 libconcord.py
--- bindings/python/libconcord.py	8 Apr 2008 09:50:29 -0000	1.1
+++ bindings/python/libconcord.py	6 Jun 2008 21:04:05 -0000
@@ -23,6 +23,16 @@ from ctypes import *
 import platform
 import sys
 
+verbose = False
+
+def set_verbose(To):
+    global verbose
+    verbose = To
+    
+def vprint(text, result):
+    if verbose:
+        print "function %s returned %s" % (text, str(result))
+
 # Internal DLL handle
 if platform.system() == 'Windows':
     _dll = cdll.LoadLibrary('libconcord.dll')
@@ -53,9 +63,16 @@ class _CheckRetCode(object):
 
     def __call__(self, *args):
         result = args[0]
+        vprint(self.func_name, result)
         if result != 0:
             raise LibConcordException(self.func_name, result)
-        
+        return result
+
+class _Trace(_CheckRetCode):
+    def __call__(self, *args):
+        vprint(self.func_name, args[0])
+        return args[0]
+
 # Internal ctypes function wrapper creation
 def _create_func(
     func_name,
@@ -74,161 +91,161 @@ callback_type = CFUNCTYPE(None, c_uint, 
 # const char *get_mfg();
 get_mfg = _create_func(
     'get_mfg',
-    None,
+    _Trace,
     c_char_p
 )
 
 # const char *get_model();
 get_model = _create_func(
     'get_model',
-    None,
+    _Trace,
     c_char_p
 )
 
 # const char *get_codename();
 get_codename = _create_func(
     'get_codename',
-    None,
+    _Trace,
     c_char_p
 )
 
 # int get_skin();
 get_skin = _create_func(
     'get_skin',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_fw_ver_maj();
 get_fw_ver_maj = _create_func(
     'get_fw_ver_maj',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_fw_ver_min();
 get_fw_ver_min = _create_func(
     'get_fw_ver_min',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_fw_type();
 get_fw_type = _create_func(
     'get_fw_type',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_hw_ver_maj();
 get_hw_ver_maj = _create_func(
     'get_hw_ver_maj',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_hw_ver_min();
 get_hw_ver_min = _create_func(
     'get_hw_ver_min',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_flash_size();
 get_flash_size = _create_func(
     'get_flash_size',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_flash_mfg();
 get_flash_mfg = _create_func(
     'get_flash_mfg',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_flash_id();
 get_flash_id = _create_func(
     'get_flash_id',
-    None,
+    _Trace,
     c_int
 )
 
 # const char *get_flash_part_num();
 get_flash_part_num = _create_func(
     'get_flash_part_num',
-    None,
+    _Trace,
     c_char_p
 )
 
 # int get_arch();
 get_arch = _create_func(
     'get_arch',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_proto();
 get_proto = _create_func(
     'get_proto',
-    None,
+    _Trace,
     c_int
 )
 
 # const char *get_hid_mfg_str();
 get_hid_mfg_str = _create_func(
     'get_hid_mfg_str',
-    None,
+    _Trace,
     c_char_p
 )
 
 # const char *get_hid_prod_str();
 get_hid_prod_str = _create_func(
     'get_hid_prod_str',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_hid_irl();
 get_hid_irl = _create_func(
     'get_hid_irl',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_hid_orl();
 get_hid_orl = _create_func(
     'get_hid_orl',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_hid_frl();
 get_hid_frl = _create_func(
     'get_hid_frl',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_usb_vid();
 get_usb_vid = _create_func(
     'get_usb_vid',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_usb_pid();
 get_usb_pid = _create_func(
     'get_usb_pid',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_usb_bcd();
 get_usb_bcd = _create_func(
     'get_usb_bcd',
-    None,
+    _Trace,
     c_int
 )
 
@@ -239,7 +256,7 @@ SERIAL_COMPONENT_3 = 3
 # char *get_serial(int p);
 get_serial = _create_func(
     'get_serial',
-    None,
+    _Trace,
     c_char_p,
     c_int
 )
@@ -247,77 +264,77 @@ get_serial = _create_func(
 # int get_config_bytes_used();
 get_config_bytes_used = _create_func(
     'get_config_bytes_used',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_config_bytes_total();
 get_config_bytes_total = _create_func(
     'get_config_bytes_total',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_second();
 get_time_second = _create_func(
     'get_time_second',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_minute();
 get_time_minute = _create_func(
     'get_time_minute',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_hour();
 get_time_hour = _create_func(
     'get_time_hour',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_day();
 get_time_day = _create_func(
     'get_time_day',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_dow();
 get_time_dow = _create_func(
     'get_time_dow',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_month();
 get_time_month = _create_func(
     'get_time_month',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_year();
 get_time_year = _create_func(
     'get_time_year',
-    None,
+    _Trace,
     c_int
 )
 
 # int get_time_utc_offset();
 get_time_utc_offset = _create_func(
     'get_time_utc_offset',
-    None,
+    _Trace,
     c_int
 )
 
 # const char *get_time_timezone();
 get_time_timezone = _create_func(
     'get_time_timezone',
-    None,
+    _Trace,
     c_char_p
 )
 
@@ -545,7 +562,7 @@ write_safemode_to_file = _create_func(
 # int is_fw_update_supported(int direct);
 is_fw_update_supported = _create_func(
     'is_fw_update_supported',
-    None,
+    _Trace,
     c_int,
     c_int
 )
@@ -553,7 +570,7 @@ is_fw_update_supported = _create_func(
 # int is_config_safe_after_fw();
 is_config_safe_after_fw = _create_func(
     'is_config_safe_after_fw',
-    None,
+    _Trace,
     c_int
 )
 
@@ -630,13 +647,51 @@ extract_firmware_binary = _create_func(
     POINTER(c_uint)
 )
 
-# int learn_ir_commands(uint8_t *data, uint32_t size, int post);
-learn_ir_commands = _create_func(
-    'learn_ir_commands',
+
+# char *get_key_name(uint8_t *data, uint32_t size, uint32_t index);
+
+get_key_name = _create_func(
+    'get_key_name',
+    _Trace,
+    c_char_p,
+    POINTER(c_ubyte),
+    c_uint,
+    c_uint
+)
+
+# int learn_from_remote(uint32_t *carrier_clock, uint32_t **pulses,
+	# uint32_t *pulse_count);
+
+learn_from_remote = _create_func(
+    'learn_from_remote',
     _CheckRetCode,
     c_int,
-    POINTER(c_ubyte),
+    POINTER(c_uint),
+    POINTER(POINTER(c_uint)),
+    POINTER(c_uint)
+)
+
+# char *encode_for_posting(uint32_t carrier_clock, uint32_t *pulses,
+	# uint32_t pulse_count);
+
+encode_for_posting = _create_func(
+    'encode_for_posting',
+    _Trace,
+    c_char_p,
     c_uint,
-    c_int
+    POINTER(c_uint),
+    c_uint
 )
 
+
+# int post_new_code(uint8_t *data, uint32_t size, char *key_name, char *code);
+
+post_new_code = _create_func(
+    'post_new_code',
+    _CheckRetCode,
+    c_int,
+    POINTER(c_ubyte),
+    c_uint,
+    c_char_p,
+    c_char_p
+)
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to