X10 Automation for Linux, Unix, and Mac OS X is an open source project powered by Assembla

Assembla offers free public and private SVN/Git repositories and project hosting with bug/issue tracking and collaboration tools.

Commit 8c5e0e64e3ad86ff5f176c787803fecc00a1d5e8

User picture

Relay: Prevent incoming powerline signals from being destroyed by other signals

In its current form, the heyu_relay puts an incomming poll request (0x5a) byte
and a following signal(s) byte sequence into the spool file in two separate
write() calls. Since this procedure doesn't respect spool file locks, it may
happen that another signal, whether a command line, heyu_aux or whatever its
source can be, gets inserted into the spool file inbetween, effectivelly
destroying the full byte sequence required by the heyu_engine to actually
recognize an incomming signal(s) sequence. This results in powerline signals
happening to get lost, with the infamous "Poll received unknown value ..."
error message being displayed.

This patch tries to correct the problem by first collecting the whole
sequence, consisting of one poll request (0x5a) byte and a subsequent
incomming command(s) bytes, and then putting it into the spool file with one
atomic write() call.

I have initially created this patch against heyu-2.3.0 and tested extensively
since then. The below version is refershed against current official release
(2.9.0).

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>

Files Affected

 
055a676c537da3c635b8b1b0978fd73514f4fc9f8c5e0e64e3ad86ff5f176c787803fecc00a1d5e8
367
        /* just write any unknown data */
367
        /* just write any unknown data */
368
        ignoret = write(outfd,ibuff, 1);
368
        ignoret = write(outfd,ibuff, 1);
369
        }
369
        }
370
 
370
#if 0
371
    if ( ibuff[0] == 0x5a && (count_5a == 0 || in_sync == 1 ) )  {
371
    if ( ibuff[0] == 0x5a && (count_5a == 0 || in_sync == 1 ) )  {
372
        /* write the first 0x5a that's seen */
372
        /* write the first 0x5a that's seen */
373
        ignoret = write(outfd,ibuff, 1);
373
        ignoret = write(outfd,ibuff, 1);
...
 
...
 
377
         * let's try that next time that I'm deep into the code.
377
         * let's try that next time that I'm deep into the code.
378
         */
378
         */
379
    }
379
    }
380
 
380
#endif
381
    if ( ibuff[0] == 0x5a && count == 1)  {
381
    if ( ibuff[0] == 0x5a && count == 1)  {
382
 
382
 
383
            /* CM11A has a character to read */
383
            /* CM11A has a character to read */
384
        if ( ++count_5a > 1 || (count_5a == 1 && in_sync == 1) )  {
384
        if ( ++count_5a > 1 || (count_5a == 1 && in_sync == 1) )  {
385
                /* After a (configurable) short delay, tell the CM11A to send it */
385
                /* After a (configurable) short delay, tell the CM11A to send it */
386
                millisleep(configp->cm11a_query_delay);
386
                millisleep(configp->cm11a_query_delay);
387
        ibuff[0] = 0xC3;
387
        ibuff[1] = 0xC3;
388
 
388
 
389
        /* if( lock_for_write() == 0 ) */
389
        /* if( lock_for_write() == 0 ) */
390
        {
390
        {
391
            port_locked = 1;
391
            port_locked = 1;
392
            ignoret = write(tty,ibuff, 1);
392
            ignoret = write(tty,ibuff + 1, 1);
393
            munlock(writefilename);
393
            munlock(writefilename);
394
                    port_locked = 0;
394
                    port_locked = 0;
395
        }
395
        }
...
 
...
 
401
         * Like power fail or hail request.
401
         * Like power fail or hail request.
402
         */
402
         */
403
 
403
 
404
             count = sxread(tty, ibuff, 1, 5);      /* Get number of bytes which follow */
404
             count = sxread(tty, ibuff + 1, 1, 5);     /* Get number of bytes which follow */
405
 
405
 
406
             if ( count == 1 ) {
406
             if ( count == 1 ) {
407
                     /* so far so good */
407
                     /* so far so good */
408
 
408
 
409
             expected = ibuff[0];
409
             expected = ibuff[1];
410
 
410
 
411
                     if ( expected == 0x5a ) {
411
                     if ( expected == 0x5a ) {
412
                        /* CM11A quirk - sometimes send 0xC3, get nothing */
412
                        /* CM11A quirk - sometimes send 0xC3, get nothing */
...
 
...
 
417
                     }
417
                     }
418
 
418
 
419
             if ( expected > 20 )  {
419
             if ( expected > 20 )  {
420
                         ignoret = write(outfd,ibuff, 1);
420
                         ignoret = write(outfd,ibuff, 2);
421
                         /* Too many. We must not be synced. */
421
                         /* Too many. We must not be synced. */
422
                 in_sync = 0;
422
                 in_sync = 0;
423
                 continue; /* go to outer while to grab this */
423
                 continue; /* go to outer while to grab this */
424
             }
424
             }
425
 
425
 
426
                     count = sxread(tty, ibuff + 1, expected, 5);
426
                     count = sxread(tty, ibuff + 2, expected, 5);
427
 
427
 
428
             if ( count != expected )  {
428
             if ( count != expected )  {
429
                 /* This should be too few. so we aren't in sync yet. */
429
                 /* This should be too few. so we aren't in sync yet. */
430
                         ibuff[0] = count;
430
                         ibuff[1] = count;
431
                 ignoret = write(outfd,ibuff, count + 1);
431
                 ignoret = write(outfd,ibuff, count + 2);
432
                 in_sync = 0;
432
                 in_sync = 0;
433
                 continue; /* go to outer while to grab this */
433
                 continue; /* go to outer while to grab this */
434
             }
434
             }
435
             if ( count == expected )  {
435
             if ( count == expected )  {
436
            count_5a = 0;
436
            count_5a = 0;
437
            in_sync = 1;
437
            in_sync = 1;
438
            ignoret = write(outfd,ibuff, count + 1);
438
            ignoret = write(outfd,ibuff, count + 2);
439
                     }
439
                     }
440
 
440
 
441
             }
441
             }