cd to to the top of the lirc-0.9.0 tree (the directory containing
INSTALL etc.) and apply this patch by

patch -p1 < path_to_this_file

diff -Naur lirc-0.9.0_orig/daemons/lircd.c lirc-0.9.0_new/daemons/lircd.c
--- lirc-0.9.0_orig/daemons/lircd.c	2011-03-25 23:28:18.000000000 +0100
+++ lirc-0.9.0_new/daemons/lircd.c	2012-04-15 16:10:31.187897321 +0200
@@ -116,6 +116,8 @@
 	{"SEND_ONCE", send_once},
 	{"SEND_START", send_start},
 	{"SEND_STOP", send_stop},
+	{"SEND_CCF_ONCE", send_ccf_once},
+	{"SEND_CCF_START", send_ccf_start},
 	{"VERSION", version},
 	{"SET_TRANSMITTERS", set_transmitters},
 	{"SIMULATE", simulate},
@@ -184,6 +186,10 @@
 static sig_atomic_t term = 0, hup = 0, alrm = 0;
 static int termsig;
 
+static struct ir_remote ccf_remote;
+static struct ir_ncode  ccf_code;
+static lirc_t ccf_signal[PACKET_SIZE/5];
+
 static __u32 setup_min_freq = 0, setup_max_freq = 0;
 static lirc_t setup_max_gap = 0;
 static lirc_t setup_min_pulse = 0, setup_min_space = 0;
@@ -1367,6 +1373,17 @@
 	return (send_name(fd, message, code));
 }
 
+int ccfcode2freq(int freq)
+{
+	return (int) (1000000.0/(PRONTO_CONSTANT * (double) freq) + 0.5);
+}
+
+int ccftime2us(int ccftime, int freq)
+{
+	/* ccftime * pulsetime *10^6 = ccftime/freq * 10^6 */
+	return (int) ((double)ccftime*1000000.0/(double)freq + 0.5);
+}
+
 int set_transmitters(int fd, char *message, char *arguments)
 {
 	char *next_arg = NULL, *end_ptr;
@@ -1482,7 +1499,6 @@
 {
 	struct ir_remote *remote;
 	struct ir_ncode *code;
-	struct itimerval repeat_timer;
 	int reps;
 	int err;
 
@@ -1494,6 +1510,13 @@
 	if (err)
 		return 1;
 
+	return send_core_core(fd, message, remote, code, reps, once);
+}
+
+int send_core_core(int fd, char *message, struct ir_remote *remote,
+		   struct ir_ncode *code, int reps, int once)
+{
+	struct itimerval repeat_timer;
 	if (once) {
 		if (repeat_remote != NULL) {
 			return (send_error(fd, message, "busy: repeating\n"));
@@ -1548,6 +1571,85 @@
 	}
 }
 
+unsigned int eat_int_aux(char **p, char *format)
+{
+	unsigned int result;
+	if (*p == NULL)
+		return -1;
+	sscanf(*p, format, &result);
+	*p = strchr(*p, ' ');
+	if (*p)
+		for (;**p == ' '; (*p)++)
+			;
+	return result;
+}
+
+unsigned int eat_hex_int(char **p)
+{
+	return eat_int_aux(p, "%x");
+}
+
+unsigned int eat_decimal_int(char **p)
+{
+	return eat_int_aux(p, "%d");
+}
+
+int send_ccf_once(int fd, char *message, char *arguments)
+{
+	return send_ccf_core(fd, message, arguments, 1);
+}
+
+int send_ccf_start(int fd, char *message, char *arguments)
+{
+	return send_ccf_core(fd, message, arguments, 0);
+}
+
+int send_ccf_core(int fd, char *message, char *arguments, int once)
+{
+	int reps = 0;
+	int ccf_type;		/* in the CCF sense */
+	int ccf_freq_code;	/* in the CCF sense */
+	int intro_length;	/* in the CCF sense */
+	int repetition_length;	/* in the CCF sense */
+	int i;
+
+	if (hw.send_mode==0)
+		return(send_error(fd, message,
+				  "hardware does not support sending\n"));
+	
+	if (once)
+		reps=eat_decimal_int(&arguments);
+	if (reps < 0 || reps > repeat_max || !once)
+		reps = repeat_max;
+
+	memset(&ccf_remote, 0, sizeof(struct ir_remote));
+	ccf_remote.name = "ccf_remote";
+	ccf_remote.flags = RAW_CODES; 
+	memset(&ccf_code, 0, sizeof(struct ir_ncode));
+	ccf_code.name = "ccf_code";
+	ccf_code.signals = ccf_signal;
+
+	ccf_type = eat_hex_int(&arguments);
+	if (ccf_type != CCF_LEARNED_CODE)
+		return(send_error(fd, message,
+				  "Can only handle CCF codes of type 0000\n"));
+
+	ccf_freq_code = eat_hex_int(&arguments);
+	ccf_remote.freq = ccfcode2freq(ccf_freq_code);
+	intro_length = eat_hex_int(&arguments);
+	repetition_length = eat_hex_int(&arguments);
+	ccf_code.length = 2*(intro_length + repetition_length) - 1;
+
+	/* Simply assume that the stated length is correct, do not check */
+	for (i = 0; i < ccf_code.length; i++)
+		ccf_signal[i] = ccftime2us(eat_hex_int(&arguments),
+					    ccf_remote.freq);
+	
+	ccf_remote.gap = ccftime2us(eat_hex_int(&arguments),
+				    ccf_remote.freq);
+	return send_core_core(fd, message, &ccf_remote, &ccf_code, reps, once);
+}
+
 int send_stop(int fd, char *message, char *arguments)
 {
 	struct ir_remote *remote;
diff -Naur lirc-0.9.0_orig/daemons/lircd.h lirc-0.9.0_new/daemons/lircd.h
--- lirc-0.9.0_orig/daemons/lircd.h	2011-03-25 23:28:18.000000000 +0100
+++ lirc-0.9.0_new/daemons/lircd.h	2012-04-15 16:10:37.740952367 +0200
@@ -14,9 +14,13 @@
 
 #include "ir_remote.h"
 
-#define PACKET_SIZE (256)
+/* Packet size needs to be larger if accepting CCF signals */
+#define PACKET_SIZE 1000
 #define WHITE_SPACE " \t"
 
+#define CCF_LEARNED_CODE 0
+#define PRONTO_CONSTANT 0.241246
+
 struct peer_connection {
 	char *host;
 	unsigned short port;
@@ -81,6 +85,11 @@
 int waitfordata(long maxusec);
 void loop(void);
 
+int send_ccf_core(int fd, char *message, char *arguments, int once);
+int send_ccf_once(int fd, char *message, char *arguments);
+int send_ccf_start(int fd, char *message, char *arguments);
+int send_core_core(int fd, char *message, struct ir_remote*, struct ir_ncode*, int reps,int once);
+
 struct protocol_directive {
 	char *name;
 	int (*function) (int fd, char *message, char *arguments);
diff -Naur lirc-0.9.0_orig/tools/irsend.c lirc-0.9.0_new/tools/irsend.c
--- lirc-0.9.0_orig/tools/irsend.c	2011-03-25 23:28:18.000000000 +0100
+++ lirc-0.9.0_new/tools/irsend.c	2012-04-15 16:10:58.309125149 +0200
@@ -48,7 +48,7 @@
 typedef uint32_t __u32;
 #endif
 
-#define PACKET_SIZE 256
+#define PACKET_SIZE 1024
 /* three seconds */
 #define TIMEOUT 3
 
@@ -392,6 +392,24 @@
 		if (send_packet(fd, buffer) == -1) {
 			exit(EXIT_FAILURE);
 		}
+	} else if (strcasecmp(directive,"send_ccf_once") == 0
+		  || strcasecmp(directive,"send_ccf_start") == 0) {
+               if (strcasecmp(directive,"send_ccf_once") == 0)
+                       sprintf(buffer,"send_ccf_once %lu", count - 1);
+               else
+                       strcpy(buffer,"send_ccf_start");
+               for (;optind<argc; optind++) {
+                       if (strlen(buffer)+strlen(argv[optind])+2>PACKET_SIZE) {
+                               fprintf(stderr,"%s: input too long\n",progname);
+                               exit(EXIT_FAILURE);
+                       }
+                       strcat(buffer, " ");
+                       strcat(buffer, argv[optind]);
+               }
+               strcat(buffer, "\n");
+               if(send_packet(fd,buffer)==-1) {
+                       exit(EXIT_FAILURE);
+               }
 	} else {
 		remote = argv[optind++];
 
