attachment:firewire_tester.c of MythTV_Firewire


Attachment 'firewire_tester.c'

Download

Toggle line numbers
   1 /*
   2  *  firewire_tester
   3  *  Copyright (c) 2006 by Jim Westfall
   4  *  Distributed as part of MythTV under GPL v2 and later.
   5  *
   6  *  $ gcc -Wall -o firewire_tester firewire_tester.c -liec61883 -lraw1394
   7  */
   8 
   9 #include <unistd.h>
  10 #include <stdlib.h>
  11 #include <stdio.h>
  12 #include <sys/select.h>
  13 #include <libraw1394/raw1394.h>
  14 #include <libiec61883/iec61883.h>
  15 
  16 #define ACTION_NONE        -1
  17 #define ACTION_TEST_BCAST   0
  18 #define ACTION_TEST_P2P     1
  19 #define ACTION_FIX_BCAST    2
  20 
  21 #define SYNC_BYTE           0x47
  22 #define MIN_PACKETS         25
  23 
  24 #define VERBOSE(args...)    do { if (verbose) printf(args); } while (0)
  25 
  26 int verbose = 0;
  27 int sync_failed = 0;
  28 
  29 static int read_packet (unsigned char *tspacket, int len, 
  30                         unsigned int dropped, void *callback_data)
  31 {
  32     int *count = (int *)callback_data;
  33 
  34     if (dropped)
  35     {
  36         printf("Dropped %d packet(s).\n", dropped);
  37         return 0;
  38     }
  39 
  40     if (tspacket[0] != SYNC_BYTE)
  41     {
  42         sync_failed = 1;
  43         return 0;
  44     }
  45     *count = *count + 1;
  46     return 1;
  47 }
  48 
  49 int test_connection(raw1394handle_t handle, int channel)
  50 {
  51     int count = 0;
  52     int retry = 0;
  53     int fd = raw1394_get_fd(handle);
  54     iec61883_mpeg2_t mpeg;
  55     struct timeval tv;
  56     fd_set rfds;
  57 
  58     sync_failed = 0;
  59     mpeg = iec61883_mpeg2_recv_init(handle, read_packet, (void*) &count);
  60     iec61883_mpeg2_recv_start(mpeg, channel);
  61     while(count < MIN_PACKETS && retry < 2 && !sync_failed)
  62     {
  63         FD_ZERO(&rfds);
  64         FD_SET(fd, &rfds);
  65         tv.tv_sec = 1;
  66         tv.tv_usec = 0;
  67 
  68         if (select(fd + 1, &rfds, NULL, NULL, &tv) > 0)
  69         {
  70              raw1394_loop_iterate(handle);
  71         }
  72         else
  73         {
  74             retry++;
  75         }
  76     }
  77     iec61883_mpeg2_recv_stop(mpeg);
  78     iec61883_mpeg2_close(mpeg);
  79 
  80     if (sync_failed)
  81         return 0;
  82 
  83     return count;
  84 }
  85 
  86 // create and test a p2p connection
  87 // returns 1 on success, 0 on failure
  88 int test_p2p(raw1394handle_t handle, nodeid_t node) {
  89     int channel, count, success = 0;
  90     channel = node;
  91 
  92 
  93     VERBOSE("P2P: Creating, node %d, channel %d\n", node, channel);
  94 
  95     printf("P2P: Testing...");
  96     fflush(stdout);
  97  
  98     // make connection
  99     if (iec61883_cmp_create_p2p_output(handle, node | 0xffc0, 0, channel,
 100                                        1 /* fix me, speed */ ) != 0)
 101     {
 102         printf("iec61883_cmp_create_p2p_output failed\n");
 103         return 0;
 104     }
 105 
 106     count = test_connection(handle, channel);
 107     if (count >= MIN_PACKETS)
 108     {
 109         printf("Success, %d packets received\n", count);
 110         success = 1;
 111     }
 112     else
 113     {
 114         printf("Failed%s\n", (sync_failed ? " (sync failed)":""));
 115     }
 116 
 117     VERBOSE("P2P: Disconnecting.\n");
 118     iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
 119                             raw1394_get_local_id (handle),
 120                             -1, channel, 0);
 121     return success;
 122 }
 123 
 124 // create and test a broadcast connection
 125 // returns 1 on success, 0 on failure
 126 int test_broadcast(raw1394handle_t handle, nodeid_t node) {
 127     int channel, count, success = 0;
 128     channel = 63 - node;
 129 
 130     VERBOSE("Broadcast: Creating, node %d, channel %d\n", node, channel);
 131 
 132     printf("Broadcast: Testing...");
 133     fflush(stdout);
 134 
 135     // open connection
 136     if (iec61883_cmp_create_bcast_output(handle, node | 0xffc0, 0, channel, 
 137                                          1 /* fix me, speed */ ) != 0)
 138     {
 139         printf("iec61883_cmp_create_bcast_output failed\n");
 140         return 0;
 141     }
 142     count = test_connection(handle, channel);
 143 
 144     if (count >= MIN_PACKETS)
 145     {
 146         printf("Success, %d packets\n", count);
 147         success = 1;
 148     }
 149     else
 150     {
 151         printf("Failed%s\n", (sync_failed ? " (sync failed)":""));
 152     }
 153 
 154     VERBOSE("Broadcast: Disconnecting.\n");
 155     iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
 156                             raw1394_get_local_id (handle),
 157                             -1, channel, 0);
 158     return success;
 159 }  
 160 
 161 /* 
 162  *  Attempt to get a reliable broadcast connection initialized
 163  *  This is done by first attempting multiple p2p connections until data is 
 164  *  received, once data is seen we then attempt multiple (5) broadcast 
 165  *  connections to verify the connection is stable.
 166  *  returns 1 on success, 0 on fail.
 167  */
 168 int fix_broadcast(raw1394handle_t handle, nodeid_t node) {
 169     int p2p_retries = 0;
 170     int bcast_success = 0;
 171 
 172     // see if we even need to fix it
 173     while (test_broadcast(handle, node))
 174     {
 175         bcast_success++;
 176         if (bcast_success == 5)
 177         {
 178             printf("Broadcast Fix: Success (already stable)\n");
 179             return 1;
 180         }
 181     }
 182 
 183     // attempt upto 10 p2p connections looking for data
 184     while (p2p_retries < 10)
 185     { 
 186         if (test_p2p(handle, node))
 187         {
 188             // got data from p2p, try a few bcast connections
 189             bcast_success = 0;
 190             while (test_broadcast(handle, node))
 191             {
 192                 bcast_success++;
 193                 if (bcast_success == 5)
 194                 {
 195                     printf("Broadcast Fix: Success\n");
 196                     return 1;
 197                 }
 198             }
 199         }
 200         p2p_retries++;
 201     }
 202     printf("Broadcast Fix: Failed\n");
 203     return 0;
 204 }
 205 
 206 void usage(void) {
 207     printf("firewire_tester <action> -n <node> [-P <port>] [-r <n>] [-v]\n");
 208     printf(" Actions: (one is required)\n");
 209     printf("    -b          - test broadcast connection\n");
 210     printf("    -p          - test p2p connection\n");
 211     printf("    -B          - attempt to fix/stabilize broadcast connection\n");
 212     printf(" Options\n");
 213     printf("    -n <node>   - firewire node, required\n");
 214     printf("    -P <port>   - firewire port, default 0\n");
 215     printf("    -r <n>      - run action <n> times, default 1\n");
 216     printf("    -v          - verbose\n");
 217     exit(1);
 218 }
 219 
 220 int main(int argc, char **argv) {
 221     raw1394handle_t handle;
 222     int node = -1;
 223     int port = 0;
 224     int runs = 1;
 225     int c, i, success;
 226     int action = ACTION_NONE;
 227 
 228     opterr = 0;
 229     while ((c = getopt(argc, argv, "Bbn:pP:r:v")) != -1)
 230     {
 231         switch (c) 
 232         {
 233 
 234             // attempt to get a reliable bcast connection initialize
 235             case 'B':
 236                 if (action != ACTION_NONE)
 237                 {
 238                     printf("Invalid command line\n");
 239                     usage();
 240                 }
 241                 action = ACTION_FIX_BCAST;
 242                 break;
 243 
 244             // test broadcast connection
 245             case 'b':
 246                 if (action != ACTION_NONE)
 247                 {
 248                     printf("Invalid command line\n");
 249                     usage();
 250                 }
 251                 action = ACTION_TEST_BCAST;
 252                 break;
 253 
 254             // set the node, required
 255             case 'n':
 256                 node = atoi(optarg);
 257                 if (node < 0 || node > 63)
 258                 {
 259                     printf("Invalid node: %d\n", node);
 260                     exit(1);
 261                 }
 262                 break;
 263 
 264             // set the port, optional
 265             case 'P':
 266                 port = atoi(optarg);
 267                 if (port < 0)
 268                 {
 269                     printf("Invalid port: %d\n", port);
 270                 }
 271                 break;
 272 
 273             // test a p2p connection
 274             case 'p':
 275                 if (action != ACTION_NONE)
 276                 {
 277                     printf("Invalid command line\n");
 278                     usage();
 279                 }
 280                 action = ACTION_TEST_P2P;
 281                 break;
 282 
 283             // number of runs
 284             case 'r':
 285                 runs = atoi(optarg);
 286                 if (runs <= 0)
 287                 {
 288                     printf("Run amount <= 0\n");
 289                     usage();
 290                 }
 291                 break;
 292 
 293             // verbose
 294             case 'v':
 295                 verbose = 1;
 296                 break;
 297 
 298             // bad option
 299             default:
 300                 printf("Invalid command line\n");
 301                 usage();
 302                 
 303         }
 304     }
 305 
 306     if (action == ACTION_NONE)
 307     {
 308         usage();
 309     }
 310 
 311     if (node == -1)
 312     {
 313         printf("-n <node> is a required option\n");
 314         usage();
 315     }
 316 
 317     VERBOSE("raw1394: Allocating handle, port %d.\n", port);
 318     handle = raw1394_new_handle_on_port(port);
 319     if (!handle)
 320     {
 321         printf("Failed to create new raw1394 handle on port %d\n", port);
 322         exit(1);
 323     }
 324 
 325     success = 0;
 326     switch (action)
 327     {
 328         case ACTION_TEST_BCAST:
 329             printf("Action: Test broadcast %d times, node %d, channel %d\n", 
 330                    runs, node, 63 - node);
 331             for (i = 0;i < runs;i++) 
 332                 success += test_broadcast(handle, node);
 333             break;
 334         case ACTION_TEST_P2P:
 335             printf("Action: Test P2P connection %d times, node %d, channel %d\n",
 336                    runs, node, node);
 337             for (i = 0;i < runs;i++)
 338                 success += test_p2p(handle, node);
 339             break;
 340         case ACTION_FIX_BCAST:
 341             printf("Action: Attempt to fix broadcast connection %d times, node %d\n", 
 342                    runs, node);
 343             for (i = 0;i < runs;i++)
 344                 success += fix_broadcast(handle, node);
 345             break;
 346     }
 347 
 348     VERBOSE("raw1394: Releasing handle.\n");
 349     raw1394_destroy_handle(handle);
 350     exit(!(success == runs));
 351 }

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2008-04-10 19:58:41, 0.6 KB) [[attachment:55b.changelog]]
  • [get | view] (2007-03-30 04:59:59, 334.3 KB) [[attachment:connectsource2.png]]
  • [get | view] (2007-04-13 16:45:18, 186.1 KB) [[attachment:connectsource2_2.png]]
  • [get | view] (2008-03-12 15:52:13, 9.2 KB) [[attachment:firewire_tester.c]]
  • [get | view] (2007-03-30 04:59:40, 377.0 KB) [[attachment:fwcapcard2.png]]
  • [get | view] (2007-04-13 16:44:58, 212.3 KB) [[attachment:fwcapcard2_2.png]]
  • [get | view] (2007-03-30 05:13:32, 5.7 KB) [[attachment:myth_prime.c]]
  • [get | view] (2007-03-30 05:15:09, 1.4 KB) [[attachment:myth_prime_p2p]]
  • [get | view] (2008-03-12 16:01:57, 1.5 KB) [[attachment:myth_prime_p2p_r2]]
  • [get | view] (2008-04-10 19:57:55, 19.0 KB) [[attachment:mythprime.AMD64]]
  • [get | view] (2008-04-10 19:58:08, 15.3 KB) [[attachment:mythprime.i386]]
  • [get | view] (2007-04-13 17:44:21, 3.3 KB) [[attachment:mythtv-backend]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.