00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <unistd.h>
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <sys/select.h>
00014 #include <libraw1394/raw1394.h>
00015 #include <libiec61883/iec61883.h>
00016
00017 #define ACTION_NONE -1
00018 #define ACTION_TEST_BCAST 0
00019 #define ACTION_TEST_P2P 1
00020 #define ACTION_FIX_BCAST 2
00021 #define ACTION_RESET_BUS 3
00022
00023 #define SYNC_BYTE 0x47
00024 #define MIN_PACKETS 25
00025 #define MAX_NODATA 10
00026
00027 #define VERBOSE(args...) do { if (verbose) printf(args); } while (0)
00028
00029 int verbose = 0;
00030 int sync_failed = 0;
00031 int nodata = 0;
00032
00033 static int read_packet (unsigned char *tspacket, int len,
00034 unsigned int dropped, void *callback_data)
00035 {
00036 int *count = (int *)callback_data;
00037
00038 if (dropped)
00039 {
00040 printf("Dropped %d packet(s).\n", dropped);
00041 return 0;
00042 }
00043
00044 if (tspacket[0] != SYNC_BYTE)
00045 {
00046 sync_failed = 1;
00047 return 0;
00048 }
00049 nodata = 0;
00050 *count = *count + 1;
00051 return 1;
00052 }
00053
00054 int test_connection(raw1394handle_t handle, int channel)
00055 {
00056 int count = 0;
00057 int retry = 0;
00058 int fd = raw1394_get_fd(handle);
00059 iec61883_mpeg2_t mpeg;
00060 struct timeval tv;
00061 fd_set rfds;
00062
00063 sync_failed = 0;
00064 mpeg = iec61883_mpeg2_recv_init(handle, read_packet, (void*) &count);
00065 iec61883_mpeg2_recv_start(mpeg, channel);
00066 while(count < MIN_PACKETS && retry < 2 && !sync_failed
00067 && nodata < MAX_NODATA)
00068 {
00069 FD_ZERO(&rfds);
00070 FD_SET(fd, &rfds);
00071 tv.tv_sec = 1;
00072 tv.tv_usec = 0;
00073
00074 if (select(fd + 1, &rfds, NULL, NULL, &tv) > 0)
00075 {
00076 nodata++;
00077 raw1394_loop_iterate(handle);
00078 }
00079 else
00080 {
00081 retry++;
00082 }
00083 }
00084 iec61883_mpeg2_recv_stop(mpeg);
00085 iec61883_mpeg2_close(mpeg);
00086
00087 if (sync_failed)
00088 return 0;
00089
00090 return count;
00091 }
00092
00093
00094
00095 int test_p2p(raw1394handle_t handle, nodeid_t node) {
00096 int channel, count, success = 0;
00097 channel = node;
00098
00099
00100 VERBOSE("P2P: Creating, node %d, channel %d\n", node, channel);
00101
00102 printf("P2P: Testing...");
00103 fflush(stdout);
00104
00105
00106 if (iec61883_cmp_create_p2p_output(handle, node | 0xffc0, 0, channel,
00107 1 ) != 0)
00108 {
00109 printf("iec61883_cmp_create_p2p_output failed\n");
00110 return 0;
00111 }
00112
00113 count = test_connection(handle, channel);
00114 if (count >= MIN_PACKETS)
00115 {
00116 printf("Success, %d packets received\n", count);
00117 success = 1;
00118 }
00119 else
00120 {
00121 printf("Failed%s\n", (sync_failed ? " (sync failed)":""));
00122 }
00123
00124 VERBOSE("P2P: Disconnecting.\n");
00125 iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
00126 raw1394_get_local_id (handle),
00127 -1, channel, 0);
00128 return success;
00129 }
00130
00131
00132
00133 int test_broadcast(raw1394handle_t handle, nodeid_t node) {
00134 int channel, count, success = 0;
00135 channel = 63 - node;
00136
00137 VERBOSE("Broadcast: Creating, node %d, channel %d\n", node, channel);
00138
00139 printf("Broadcast: Testing...");
00140 fflush(stdout);
00141
00142
00143 if (iec61883_cmp_create_bcast_output(handle, node | 0xffc0, 0, channel,
00144 1 ) != 0)
00145 {
00146 printf("iec61883_cmp_create_bcast_output failed\n");
00147 return 0;
00148 }
00149 count = test_connection(handle, channel);
00150
00151 if (count >= MIN_PACKETS)
00152 {
00153 printf("Success, %d packets\n", count);
00154 success = 1;
00155 }
00156 else
00157 {
00158 printf("Failed%s\n", (sync_failed ? " (sync failed)":""));
00159 }
00160
00161 VERBOSE("Broadcast: Disconnecting.\n");
00162 iec61883_cmp_disconnect(handle, node | 0xffc0, 0,
00163 raw1394_get_local_id (handle),
00164 -1, channel, 0);
00165 return success;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 int fix_broadcast(raw1394handle_t handle, nodeid_t node) {
00176 int p2p_retries = 0;
00177 int bcast_success = 0;
00178
00179
00180 while (test_broadcast(handle, node))
00181 {
00182 bcast_success++;
00183 if (bcast_success == 5)
00184 {
00185 printf("Broadcast Fix: Success (already stable)\n");
00186 return 1;
00187 }
00188 }
00189
00190
00191 while (p2p_retries < 10)
00192 {
00193 if (test_p2p(handle, node))
00194 {
00195
00196 bcast_success = 0;
00197 while (test_broadcast(handle, node))
00198 {
00199 bcast_success++;
00200 if (bcast_success == 5)
00201 {
00202 printf("Broadcast Fix: Success\n");
00203 return 1;
00204 }
00205 }
00206 }
00207 p2p_retries++;
00208 }
00209 printf("Broadcast Fix: Failed\n");
00210 return 0;
00211 }
00212
00213 void usage(void) {
00214 printf("firewire_tester <action> -n <node> [-P <port>] [-r <n>] [-v]\n");
00215 printf(" Actions: (one is required)\n");
00216 printf(" -b - test broadcast connection\n");
00217 printf(" -p - test p2p connection\n");
00218 printf(" -B - attempt to fix/stabilize broadcast connection\n");
00219 printf(" -R - reset the firewire bus\n");
00220 printf(" Options\n");
00221 printf(" -n <node> - firewire node, required\n");
00222 printf(" -P <port> - firewire port, default 0\n");
00223 printf(" -r <n> - run action <n> times, default 1\n");
00224 printf(" -v - verbose\n");
00225 exit(1);
00226 }
00227
00228 int main(int argc, char **argv) {
00229 raw1394handle_t handle;
00230 int node = -1;
00231 int port = 0;
00232 int runs = 1;
00233 int c, i, success;
00234 int action = ACTION_NONE;
00235
00236 opterr = 0;
00237 while ((c = getopt(argc, argv, "Bbn:pP:r:Rv")) != -1)
00238 {
00239 switch (c)
00240 {
00241
00242
00243 case 'B':
00244 if (action != ACTION_NONE)
00245 {
00246 printf("Invalid command line\n");
00247 usage();
00248 }
00249 action = ACTION_FIX_BCAST;
00250 break;
00251
00252
00253 case 'b':
00254 if (action != ACTION_NONE)
00255 {
00256 printf("Invalid command line\n");
00257 usage();
00258 }
00259 action = ACTION_TEST_BCAST;
00260 break;
00261
00262
00263 case 'n':
00264 node = atoi(optarg);
00265 if (node < 0 || node > 63)
00266 {
00267 printf("Invalid node: %d\n", node);
00268 exit(1);
00269 }
00270 break;
00271
00272
00273 case 'P':
00274 port = atoi(optarg);
00275 if (port < 0)
00276 {
00277 printf("Invalid port: %d\n", port);
00278 }
00279 break;
00280
00281
00282 case 'p':
00283 if (action != ACTION_NONE)
00284 {
00285 printf("Invalid command line\n");
00286 usage();
00287 }
00288 action = ACTION_TEST_P2P;
00289 break;
00290
00291 case 'R':
00292 action = ACTION_RESET_BUS;
00293 break;
00294
00295
00296 case 'r':
00297 runs = atoi(optarg);
00298 if (runs <= 0)
00299 {
00300 printf("Run amount <= 0\n");
00301 usage();
00302 }
00303 break;
00304
00305
00306 case 'v':
00307 verbose = 1;
00308 break;
00309
00310
00311 default:
00312 printf("Invalid command line\n");
00313 usage();
00314
00315 }
00316 }
00317
00318 if (action == ACTION_NONE)
00319 {
00320 usage();
00321 }
00322
00323 if (action != ACTION_RESET_BUS && node == -1)
00324 {
00325 printf("-n <node> is a required option\n");
00326 usage();
00327 }
00328
00329 VERBOSE("raw1394: Allocating handle, port %d.\n", port);
00330 handle = raw1394_new_handle_on_port(port);
00331 if (!handle)
00332 {
00333 printf("Failed to create new raw1394 handle on port %d\n", port);
00334 exit(1);
00335 }
00336
00337 success = 0;
00338 switch (action)
00339 {
00340 case ACTION_TEST_BCAST:
00341 printf("Action: Test broadcast %d times, node %d, channel %d\n",
00342 runs, node, 63 - node);
00343 for (i = 0;i < runs;i++)
00344 success += test_broadcast(handle, node);
00345 break;
00346 case ACTION_TEST_P2P:
00347 printf("Action: Test P2P connection %d times, node %d, channel %d\n",
00348 runs, node, node);
00349 for (i = 0;i < runs;i++)
00350 success += test_p2p(handle, node);
00351 break;
00352 case ACTION_FIX_BCAST:
00353 printf("Action: Attempt to fix broadcast connection %d times, node %d\n",
00354 runs, node);
00355 for (i = 0;i < runs;i++)
00356 success += fix_broadcast(handle, node);
00357 break;
00358 case ACTION_RESET_BUS:
00359 runs = 1;
00360 printf("Action: Resetting the firewire bus\n");
00361 if (raw1394_reset_bus_new(handle, RAW1394_LONG_RESET) == 0)
00362 {
00363 printf("Bus reset succeeded\n");
00364 success = 1;
00365 }
00366 else
00367 {
00368 printf("Bus reset failed: %d\n", errno);
00369 }
00370 break;
00371 }
00372
00373 VERBOSE("raw1394: Releasing handle.\n");
00374 raw1394_destroy_handle(handle);
00375 exit(!(success == runs));
00376 }