23 #define LIRCD_EXACT_GAP_THRESHOLD 10000 
   25 #include "media/lirc.h" 
   27 #include "lirc/lirc_log.h" 
   28 #include "lirc/transmit.h" 
   38         lirc_t  _data[WBUF_SIZE]; 
 
   48 static void send_signals(lirc_t* signals, 
int n);
 
   49 static int init_send_or_sim(
struct ir_remote* remote, 
struct ir_ncode* code, 
int sim, 
int repeat_preset);
 
   60         memset(&send_buffer, 0, 
sizeof(send_buffer));
 
   63 static void clear_send_buffer(
void)
 
   67         send_buffer.too_long = 0;
 
   68         send_buffer.is_biphase = 0;
 
   69         send_buffer.pendingp = 0;
 
   70         send_buffer.pendings = 0;
 
   74 static void add_send_buffer(lirc_t data)
 
   76         if (send_buffer.wptr < WBUF_SIZE) {
 
   77                 log_trace2(
"adding to transmit buffer: %u", data);
 
   78                 send_buffer.sum += data;
 
   79                 send_buffer._data[send_buffer.wptr] = data;
 
   82                 send_buffer.too_long = 1;
 
   86 static void send_pulse(lirc_t data)
 
   88         if (send_buffer.pendingp > 0) {
 
   89                 send_buffer.pendingp += data;
 
   91                 if (send_buffer.pendings > 0) {
 
   92                         add_send_buffer(send_buffer.pendings);
 
   93                         send_buffer.pendings = 0;
 
   95                 send_buffer.pendingp = data;
 
   99 static void send_space(lirc_t data)
 
  101         if (send_buffer.wptr == 0 && send_buffer.pendingp == 0) {
 
  105         if (send_buffer.pendings > 0) {
 
  106                 send_buffer.pendings += data;
 
  108                 if (send_buffer.pendingp > 0) {
 
  109                         add_send_buffer(send_buffer.pendingp);
 
  110                         send_buffer.pendingp = 0;
 
  112                 send_buffer.pendings = data;
 
  116 static int bad_send_buffer(
void)
 
  118         if (send_buffer.too_long != 0)
 
  120         if (send_buffer.wptr == WBUF_SIZE && send_buffer.pendingp > 0)
 
  125 static int check_send_buffer(
void)
 
  129         if (send_buffer.wptr == 0) {
 
  133         for (i = 0; i < send_buffer.wptr; i++) {
 
  134                 if (send_buffer.data[i] == 0) {
 
  147 static void flush_send_buffer(
void)
 
  149         if (send_buffer.pendingp > 0) {
 
  150                 add_send_buffer(send_buffer.pendingp);
 
  151                 send_buffer.pendingp = 0;
 
  153         if (send_buffer.pendings > 0) {
 
  154                 add_send_buffer(send_buffer.pendings);
 
  155                 send_buffer.pendings = 0;
 
  159 static void sync_send_buffer(
void)
 
  161         if (send_buffer.pendingp > 0) {
 
  162                 add_send_buffer(send_buffer.pendingp);
 
  163                 send_buffer.pendingp = 0;
 
  165         if (send_buffer.wptr > 0 && send_buffer.wptr % 2 == 0)
 
  169 static void send_header(
struct ir_remote* remote)
 
  171         if (has_header(remote)) {
 
  172                 send_pulse(remote->phead);
 
  173                 send_space(remote->
shead);
 
  177 static void send_foot(
struct ir_remote* remote)
 
  179         if (has_foot(remote)) {
 
  180                 send_space(remote->
sfoot);
 
  181                 send_pulse(remote->pfoot);
 
  185 static void send_lead(
struct ir_remote* remote)
 
  187         if (remote->
plead != 0)
 
  188                 send_pulse(remote->
plead);
 
  191 static void send_trail(
struct ir_remote* remote)
 
  194                 send_pulse(remote->
ptrail);
 
  197 static void send_data(
struct ir_remote* remote, 
ir_code data, 
int bits, 
int done)
 
  200         int all_bits = bit_count(remote);
 
  204         data = reverse(data, bits);
 
  205         if (is_rcmm(remote)) {
 
  206                 mask = 1 << (all_bits - 1 - done);
 
  207                 if (bits % 2 || done % 2) {
 
  211                 for (i = 0; i < bits; i += 2, mask >>= 2) {
 
  214                                 send_pulse(remote->pzero);
 
  215                                 send_space(remote->
szero);
 
  219                                 send_pulse(remote->pone);
 
  220                                 send_space(remote->
sone);
 
  223                                 send_pulse(remote->ptwo);
 
  224                                 send_space(remote->
stwo);
 
  227                                 send_pulse(remote->pthree);
 
  228                                 send_space(remote->
sthree);
 
  234         } 
else if (is_xmp(remote)) {
 
  235                 if (bits % 4 || done % 4) {
 
  239                 for (i = 0; i < bits; i += 4) {
 
  242                         nibble = reverse(data & 0xf, 4);
 
  243                         send_pulse(remote->pzero);
 
  244                         send_space(remote->
szero + nibble * remote->
sone);
 
  250         mask = ((
ir_code)1) << (all_bits - 1 - done);
 
  251         for (i = 0; i < bits; i++, mask >>= 1) {
 
  253                         if (toggle_bit_mask_bits == 1) {
 
  256                                 if (remote->toggle_bit_mask_state & mask)
 
  259                                 if (remote->toggle_bit_mask_state & mask)
 
  263                 if (has_toggle_mask(remote) && mask & remote->
toggle_mask && remote->toggle_mask_state % 2)
 
  266                         if (is_biphase(remote)) {
 
  268                                         send_space(2 * remote->
sone);
 
  269                                         send_pulse(2 * remote->pone);
 
  271                                         send_space(remote->
sone);
 
  272                                         send_pulse(remote->pone);
 
  274                         } 
else if (is_space_first(remote)) {
 
  275                                 send_space(remote->
sone);
 
  276                                 send_pulse(remote->pone);
 
  278                                 send_pulse(remote->pone);
 
  279                                 send_space(remote->
sone);
 
  283                                 send_pulse(2 * remote->pzero);
 
  284                                 send_space(2 * remote->
szero);
 
  285                         } 
else if (is_space_first(remote)) {
 
  286                                 send_space(remote->
szero);
 
  287                                 send_pulse(remote->pzero);
 
  289                                 send_pulse(remote->pzero);
 
  290                                 send_space(remote->
szero);
 
  297 static void send_pre(
struct ir_remote* remote)
 
  299         if (has_pre(remote)) {
 
  301                 if (remote->pre_p > 0 && remote->
pre_s > 0) {
 
  302                         send_pulse(remote->pre_p);
 
  303                         send_space(remote->
pre_s);
 
  308 static void send_post(
struct ir_remote* remote)
 
  310         if (has_post(remote)) {
 
  311                 if (remote->post_p > 0 && remote->
post_s > 0) {
 
  312                         send_pulse(remote->post_p);
 
  313                         send_space(remote->
post_s);
 
  319 static void send_repeat(
struct ir_remote* remote)
 
  322         send_pulse(remote->prepeat);
 
  340                 send_buffer.sum -= remote->phead + remote->
shead;
 
  343 static void send_signals(lirc_t* signals, 
int n)
 
  347         for (i = 0; i < n; i++)
 
  348                 add_send_buffer(signals[i]);
 
  353         return init_send_or_sim(remote, code, 0, 0);
 
  362         return init_send_or_sim(remote, code, 1, repeat_preset);
 
  371         return send_buffer.wptr;
 
  377         return send_buffer.data;
 
  382         return send_buffer.sum;
 
  385 static int init_send_or_sim(
struct ir_remote* remote, 
struct ir_ncode* code, 
int sim, 
int repeat_preset)
 
  387         int i, repeat = repeat_preset;
 
  389         if (is_grundig(remote) || is_serial(remote) || is_bo(remote)) {
 
  391                         log_error(
"sorry, can't send this protocol yet");
 
  395         if (strcmp(remote->
name, 
"lirc") == 0) {
 
  396                 send_buffer.data[send_buffer.wptr] = 
LIRC_EOF | 1;
 
  397                 send_buffer.wptr += 1;
 
  401         if (is_biphase(remote))
 
  402                 send_buffer.is_biphase = 1;
 
  405                         remote->repeat_countdown = remote->
min_repeat;
 
  411         if (repeat && has_repeat(remote)) {
 
  416                 if (!is_raw(remote)) {
 
  419                         if (sim || code->transmit_state == NULL)
 
  420                                 next_code = code->code;
 
  422                                 next_code = code->transmit_state->code;
 
  424                         if (repeat && has_repeat_mask(remote))
 
  427                         send_code(remote, next_code, repeat);
 
  428                         if (!sim && has_toggle_mask(remote)) {
 
  429                                 remote->toggle_mask_state++;
 
  430                                 if (remote->toggle_mask_state == 4)
 
  431                                         remote->toggle_mask_state = 2;
 
  433                         send_buffer.data = send_buffer._data;
 
  435                         if (code->signals == NULL) {
 
  440                         if (send_buffer.wptr > 0) {
 
  441                                 send_signals(code->signals, code->length);
 
  443                                 send_buffer.data = code->signals;
 
  444                                 send_buffer.wptr = code->length;
 
  445                                 for (i = 0; i < code->length; i++)
 
  446                                         send_buffer.sum += code->signals[i];
 
  451         if (bad_send_buffer()) {
 
  459         if (has_repeat_gap(remote) && repeat && has_repeat(remote)) {
 
  462         } 
else if (is_const(remote)) {
 
  463                 if (min_gap(remote) > send_buffer.sum) {
 
  477         if (code->next != NULL) {
 
  478                 if (code->transmit_state == NULL) {
 
  479                         code->transmit_state = code->next;
 
  481                         code->transmit_state = code->transmit_state->next;
 
  482                         if (is_xmp(remote) && code->transmit_state == NULL)
 
  483                                 code->transmit_state = code->next;
 
  486         if ((remote->repeat_countdown > 0 || code->transmit_state != NULL)
 
  488                 if (send_buffer.data != send_buffer._data) {
 
  492                         log_trace(
"unrolling raw signal optimisation");
 
  493                         signals = send_buffer.data;
 
  494                         n = send_buffer.wptr;
 
  495                         send_buffer.data = send_buffer._data;
 
  496                         send_buffer.wptr = 0;
 
  498                         send_signals(signals, n);
 
  500                 log_trace(
"concatenating low gap signals");
 
  501                 if (code->next == NULL || code->transmit_state == NULL)
 
  502                         remote->repeat_countdown--;
 
  513         if (!check_send_buffer()) {
 
  516                         log_error(
"this remote configuration cannot be used to transmit");
 
int send_buffer_put(struct ir_remote *remote, struct ir_ncode *code)
Initializes the global send buffer for transmitting the code in the second argument,...
const lirc_t * send_buffer_data(void)
lirc_t send_buffer_sum(void)
struct ir_remote * repeat_remote
Global pointer to the remote that contains the code currently repeating.
void send_buffer_init(void)
Initializes the global sending buffer.
int send_buffer_length(void)
Do not document this function.
#define REPEAT_HEADER
header is also sent before repeat code
uint64_t ir_code
Denotes an internal coded representation for an IR transmission.
#define NO_FOOT_REP
no foot for key repeats
#define NO_HEAD_REP
no header for key repeats
#define CONST_LENGTH
signal length+gap is always constant
#define LIRC_EOF
Bit manipulator in lirc_t, see lirc.h .
#define log_trace(fmt,...)
Log a trace message.
#define log_trace2(fmt,...)
Log a trace2 message.
#define log_error(fmt,...)
Log an error message.
logchannel_t
Log channels used to filter messages.
IR Command, corresponding to one (command defining) line of the configuration file.
One remote as represented in the configuration file.
uint32_t repeat_gap
time between two repeat codes if different from gap
lirc_t stwo
2 (only used for RC-MM)
ir_code rc6_mask
RC-6 doubles signal length of some bits.
lirc_t max_remaining_gap
gap range
lirc_t ptrail
trailing pulse
ir_code repeat_mask
mask defines which bits are inverted for repeats
lirc_t srepeat
indicate repeating
ir_code pre_data
data which the remote sends before actual keycode
int bits
bits (length of code)
int post_data_bits
length of post_data
lirc_t plead
leading pulse
lirc_t sthree
3 (only used for RC-MM)
ir_code post_data
data which the remote sends after actual keycode
ir_code toggle_mask
Sharp (?) error detection scheme.
int min_repeat
code is repeated at least x times code sent once -> min_repeat=0
lirc_t post_s
signal between keycode and post_code
lirc_t pre_s
signal between pre_data and keycode
uint32_t gap
time between signals in usecs
const char * name
name of remote control
ir_code toggle_bit_mask
previously only one bit called toggle_bit
int pre_data_bits
length of pre_data
lirc_t min_remaining_gap
remember gap for CONST_LENGTH remotes