LinHES Forums
http://forum.linhes.org/

firewire_tester -Helps test and fix your firewire connection
http://forum.linhes.org/viewtopic.php?f=2&t=11826
Page 1 of 1

Author:  ed3120 [ Mon Sep 25, 2006 3:10 pm ]
Post subject:  firewire_tester -Helps test and fix your firewire connection

Someone pointed this out to me and I wanted to let everyone here know about it. It is a script that makes testing your firewire connection a little easier.

Full credit goes to Jim Westfall for writing it. (Thanks Jim!) I'm just pointing it out.

source: http://threebit.net/mail-archive/mythtv ... 05659.html

Here are the options. Running firewire_tester -B -n <node#> helps "prime the pump" after a reboot and helps get your firewire connection running again. It's been working for me.

Code:
firewire_tester <action> -n <node> [-P <port>] [-v]
 Actions: (one is required)
    -b          - test broadcast connection
    -p          - test p2p connection
    -B          - attempt to fix/stabilize broadcast connection
 Options
    -n <node>   - required
    -P <port>   - default 0
    -v          - verbose


Here is the script:

Code:
/*
 *  firewire_tester
 *  Copyright (c) 2006 by Jim Westfall
 *  Distributed as part of MythTV under GPL v2 and later.
 *
 *  $ gcc -o firewire_tester firewire_tester.c  -liec61883 -lraw1394
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <libraw1394/raw1394.h>
#include <libiec61883/iec61883.h>

#define ACTION_NONE        -1
#define ACTION_TEST_BCAST   0
#define ACTION_TEST_P2P     1
#define ACTION_FIX_BCAST    2

#define SYNC_BYTE           0x47
#define MIN_PACKETS         25

int verbose = 0;

static int read_packet (unsigned char *tspacket, int len,
                        unsigned int dropped, void *callback_data)
{
    int *count = (int *)callback_data;

    if (dropped)
    {
        printf("Dropped %d packet(s).\n", dropped);
        return 0;
    }

    if (tspacket[0] != SYNC_BYTE)
    {
        printf("TS packet out of sync.\n");
        // reset count
        *count = 0;
        return 1;
    }
    *count = *count + 1;
    return 1;
}

int test_connection(raw1394handle_t handle, int channel)
{
    int count = 0;
    int retry = 0;
    int fd = raw1394_get_fd(handle);
    iec61883_mpeg2_t mpeg;
    struct timeval tv;
    fd_set rfds;

    mpeg = iec61883_mpeg2_recv_init(handle, read_packet, (void*) &count);
    iec61883_mpeg2_recv_start(mpeg, channel);
    while(count < MIN_PACKETS && retry < 2)
    {
        FD_ZERO(&rfds);
        FD_SET(fd, &rfds);
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        if (select(fd + 1, &rfds, NULL, NULL, &tv) > 0)
        {
             raw1394_loop_iterate(handle);
        }
        else
        {
            retry++;
        }
    }
    iec61883_mpeg2_recv_stop(mpeg);
    iec61883_mpeg2_close(mpeg);
    return count;
}

// create and test a p2p connection
// returns 1 on success, 0 on failure
int test_p2p(raw1394handle_t handle, nodeid_t node) {
    int channel, count;
    channel = node;

    printf("p2p: ");
    fflush(stdout);
 
    // make connection
    if (iec61883_cmp_create_p2p_output(handle, node | 0xffc0, 0, channel,
                                       1 /* fix me, speed */ ) != 0)
    {
        printf("iec61883_cmp_create_p2p_output failed\n");
        return 0;
    }
    count = test_connection(handle, channel);
    iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
                            raw1394_get_local_id (handle),
                            -1, channel, 0);
    if (count >= MIN_PACKETS)
    {
        printf("success, %d packets received\n", count);
        return 1;
    }
    printf("failed\n");
    return 0;
}


// create and test a broadcast connection
// returns 1 on success, 0 on failure
int test_broadcast(raw1394handle_t handle, nodeid_t node) {
    int channel, count;
    channel = 63 - node;

    printf("broadcast: ");
    fflush(stdout);

    // open connection
    if (iec61883_cmp_create_bcast_output(handle, node | 0xffc0, 0, channel,
                                         1 /* fix me, speed */ ) != 0)
    {
        printf("iec61883_cmp_create_bcast_output failed\n");
        return 0;
    }
    count = test_connection(handle, channel);
    iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
                            raw1394_get_local_id (handle),
                            -1, channel, 0);
    if (count >= MIN_PACKETS)
    {
        printf("success, %d packets\n", count);
        return 1;
    }
    printf("failed\n");
    return 0;


/*
 *  Attempt to get a reliable broadcast connection initialized
 *  This is done by first attempting multiple p2p connections until data is
 *  received, once data is seen we then attempt multiple broadcast
 *  connections to verify the connection is stable.
 *  returns 1 on success, 0 on fail.
 */
int fix_broadcast(raw1394handle_t handle, nodeid_t node) {
    int total_retries = 0;
    int p2p_retries;
    int bcast_success = 0;

    // see if we even need to fix it
    while (test_broadcast(handle, node))
    {
        bcast_success++;
        if (bcast_success == 5)
        {
            printf("fix bcast success (already stable)\n");
            return 1;
        }
    }

    while (total_retries < 3)
    {
        p2p_retries = 0;
        // attempt upto 5 p2p connections looking for data
        while (p2p_retries < 5)
        {

            if (test_p2p(handle, node))
            {
                bcast_success = 0;
                // got data from p2p, try a few bcast connections
                while (test_broadcast(handle, node))
                {
                    bcast_success++;
                    if (bcast_success == 5)
                    {
                        printf("fix bcast success\n");
                        return 1;
                    }
                }
            }
            p2p_retries++;
        }
        total_retries++;
    }
    printf("fix bcast failed\n");
    return 0;
}

void usage(void) {
    printf("firewire_tester <action> -n <node> [-P <port>] [-v]\n");
    printf(" Actions: (one is required)\n");
    printf("    -b          - test broadcast connection\n");
    printf("    -p          - test p2p connection\n");
    printf("    -B          - attempt to fix/stabilize broadcast connection\n");
    printf(" Options\n");
    printf("    -n <node>   - required\n");
    printf("    -P <port>   - default 0\n");
    printf("    -v          - verbose\n");
}

int main(int argc, char **argv) {
    raw1394handle_t handle;
    int node = -1;
    int port = 0;
    int c, success;
    int action = ACTION_NONE;

    opterr = 0;
    while ((c = getopt(argc, argv, "Bbn:pP:v")) != -1)
    {
        switch (c)
        {

            // attempt to get a reliable bcast connection initialize
            case 'B':
                if (action != ACTION_NONE)
                {
                    printf("Invalid command line\n");
                    usage();
                    exit(1);
                }
                action = ACTION_FIX_BCAST;
                break;

            // test broadcast connection
            case 'b':
                if (action != ACTION_NONE)
                {
                    printf("Invalid command line\n");
                    usage();
                    exit(1);
                }
                action = ACTION_TEST_BCAST;
                break;

            // set the node, required
            case 'n':
                node = atoi(optarg);
                if (node < 0 || node > 63)
                {
                    printf("Invalid node: %d\n");
                    exit(1);
                }
                break;

            // set the port, optional
            case 'P':
                port = atoi(optarg);
                if (port < 0)
                {
                    printf("Invalid port: %d\n");
                    exit(1);
                }
                break;

            // test a p2p connection
            case 'p':
                if (action != ACTION_NONE)
                {
                    printf("Invalid command line\n");
                    usage();
                    exit(1);
                }
                action = ACTION_TEST_P2P;
                break;

            // verbose
            case 'v':
                verbose = 1;
                break;

            // bad option
            default:
                printf("invalid command line\n");
                usage();
               
        }
    }

    if (action == ACTION_NONE)
    {
        printf("No action on command line\n");
        usage();
        exit(1);
    }

    if (node == -1)
    {
        printf("node is a required option\n");
        usage();
        exit(1);
    }

    handle = raw1394_new_handle_on_port(port);
    if (!handle)
    {
        printf("Failed to create new raw1394 handle on port %d\n", port);
        exit(1);
    }

    switch (action)
    {
        case ACTION_TEST_BCAST:
            printf("Testing broadcast connection, node %d, channel %d\n",
                   node, 63 - node);
            success = test_broadcast(handle, node);
            break;
        case ACTION_TEST_P2P:
            printf("Testing P2P connection, node %d, channel %d\n",
                   node, node);
            success = test_p2p(handle, node);
            break;
        case ACTION_FIX_BCAST:
            printf("Attempting to fixup broadcast connection on node %d\n",
                   node);
            success = fix_broadcast(handle, node);
            break;
    }

    raw1394_destroy_handle(handle);
    exit(!success);
}


Save it as firewire_tester.c - then run the following command:

Code:
gcc -o firewire_tester firewire_tester.c  -liec61883 -lraw1394
./firewire_tester

Author:  marc.aronson [ Sat Dec 02, 2006 11:03 am ]
Post subject: 

When I try to run this program I get the following error:
Code:
p2p: firewire_tester: symbol lookup error: /usr/lib/libiec61883.so.0: undefined symbol: raw1394_channel_modify


From what I can see,Knoppmyth R5D1 releases with an older version of libiec61883 and libraw1394. Can anyone tell me if it is safe to simply download and install the latest version of these libraries? I was planning to do this by running "./configure", "make" and "make install" in the download directories. Is there a better way?

THanks!


Marc

Author:  marc.aronson [ Sat Dec 02, 2006 5:04 pm ]
Post subject: 

Problem solved -- I added "-static" to the compile command and it both builds & runs properly. ie

Code:
gcc -o firewire_tester firewire_tester.c  -static -liec61883 -lraw1394


Also, I got the latest version of firewire_tester.c from http://svn.mythtv.org/svn/trunk/mythtv/contrib/ -- it has some nice improvements.

Marc

Author:  ed3120 [ Tue Dec 05, 2006 9:36 am ]
Post subject: 

I'll check it the new version....I've been running a cron job that runs:

Code:
firewire_tester -n 0 -B

((assuming the cable box is on node 0)

at X:28, X:29, X:58, X:59 for every hour. This way it runs twice right before a record would start on the half hour or hour mark just to ensure that everything is working properly. It doesn't seem to hurt anything if things are working properly (even if a recording is going on), so I run it twice just to be safe. (Sometimes onces doesn't fix it, but the second run does.)

Author:  marc.aronson [ Wed Dec 06, 2006 1:52 am ]
Post subject: 

I ran a quick experiment and running the new version while a recording is going on creates a large number of the following errors in the backend log
Code:
Firewire: Got out of sync TS Packet

Author:  ed3120 [ Thu Dec 07, 2006 1:04 pm ]
Post subject: 

Do you notice any issues in the recording when you play it back, or are these just moot messages?

Author:  marc.aronson [ Thu Dec 07, 2006 10:27 pm ]
Post subject: 

I didn't test the recording. The presence of over 70,000 of these messages in the back end log file was sufficient reason for me to not do this.

Marc

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/