/* * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem. * * Copyright (C) 1999,2000 Andreas Bombe * * This library is licensed under the GNU Lesser General Public License (LGPL), * version 2.1 or later. See the file COPYING.LIB in the distribution for * details. */ #include #include #include #include #include #include #include #include "../src/raw1394.h" #define BUFFER 1000 #define PACKET_MAX 4096 unsigned long which_port; char *filename; unsigned long loopcount = 1; unsigned int speed; void usage_exit(int exitcode) { fprintf(stderr, "Usage: sendiso [opts] FILE\n" "Send IEEE 1394 isochronous packets from dump file FILE.\n" "\n" "-l --loop COUNT Repeat sending data COUNT times.\n" "-i --infinite Repeat sending data infinitely.\n" "-s --speed SPEED Send data at SPEED (valid values are 100, 200, 400 or\n" " alternatively 1, 2, 4). (default: 100)\n" "\n" "-p --port PORT Choose 1394 chip PORT. (default: 0)\n" "-h --help Show this help.\n" ); exit(exitcode); } void parse_args(int argc, char **argv) { char *tail; int c; int index; static struct option opts[] = { { "file", required_argument, NULL, 'f' }, { "loop", required_argument, NULL, 'l' }, { "infinite", no_argument, NULL, 'i' }, { "speed", required_argument, NULL, 's' }, { "port", required_argument, NULL, 'p' }, { "help", no_argument, NULL, 'h' }, { 0 } }; while (1) { c = getopt_long(argc, argv, "f:l:is:p:h", opts, &index); if (c == -1) break; switch (c) { case 'f': filename = optarg; break; case 'l': loopcount = strtoul(optarg, &tail, 10); if (*tail) { fprintf(stderr, "invalid argument to loop: %s\n", optarg); usage_exit(1); } break; case 'i': loopcount = 0; break; case 's': speed = strtoul(optarg, &tail, 10); if (*tail) speed = -1; switch (speed) { case 1: case 100: speed = RAW1394_ISO_SPEED_100; break; case 2: case 200: speed = RAW1394_ISO_SPEED_200; break; case 4: case 400: speed = RAW1394_ISO_SPEED_400; break; default: fprintf(stderr, "invalid argument to speed: %s\n", optarg); usage_exit(1); } break; case 'p': which_port = strtoul(optarg, &tail, 10); if (*tail) { fprintf(stderr, "invalid argument to port: %s\n", optarg); usage_exit(1); } break; case 'h': usage_exit(0); case '?': usage_exit(1); case 0: break; default: abort(); } } argv += optind; argc -= optind; if (argc > 1) { fprintf(stderr, "Too many arguments.\n"); usage_exit(1); } if (argc) filename = *argv; } #define BUF_SIZE 4096 #define BUF_HEAD 8 void send_file_once(raw1394handle_t handle, int file) { int count, i, ret; unsigned channel, tag, sy; size_t length; static unsigned char buffer[BUF_SIZE + BUF_HEAD]; static unsigned int counter = 0; static int inited = 0; while (1) { count = read(file, buffer, BUF_HEAD); if (count < 0) { perror("read"); exit(1); } if (count < BUF_HEAD) return; i = 0; length = ((unsigned int *)buffer)[i]; channel = buffer[i + 4]; tag = buffer[i + 5]; sy = buffer[i + 6]; i += BUF_HEAD; while (count < length + BUF_HEAD) { ret = read(file, buffer + count, length - count + BUF_HEAD); if (ret < 0) { perror("read"); exit(1); } if (ret == 0) return; count += ret; } if (inited == 0) { /* fprintf(stderr, "transmitting first packet with length " "%d on channel %d with tag %d and sy %d\n", length, channel, tag, sy); */ ret = raw1394_iso_xmit_init(handle, NULL, BUFFER, PACKET_MAX, channel, speed, -1); if (ret < 0) { perror("raw1394_iso_xmit_init"); exit(1); } raw1394_iso_xmit_start(handle, -1, -1); inited = 1; } if (++counter % 1000 == 0) fprintf(stderr, "\r%uK packets", counter/1000); ret = raw1394_iso_xmit_write(handle, &buffer[i], length, tag, sy); if (ret < 0) { perror("\nraw1394_iso_xmit_write"); exit(1); } } } void send_iso_file(raw1394handle_t handle) { int file; int count, ret; char buffer[32]; if (filename[0] == '-' && filename[1] == '\0') { file = fileno(stdin); } else { file = open(filename, O_RDONLY, 0); if (file < 0) { perror("open"); exit(1); } } count = 32; while (count) { ret = read(file, buffer, count); if (!ret) goto bad_format; if (ret < 0) { perror("read"); exit(1); } count -= ret; } if (memcmp("1394 isodump v", buffer, 14)) goto bad_format; if (buffer[14] != '2') goto wrong_version; while (1) { send_file_once(handle, file); if (!loopcount) { if (lseek(file, 32, SEEK_SET) < 0) { perror("lseek"); exit(1); } continue; } if (!(--loopcount)) break; if (lseek(file, 32, SEEK_SET) < 0) { perror("lseek"); exit(1); } } return; bad_format: fprintf(stderr, "Input file format not recognized.\n"); exit(1); wrong_version: fprintf(stderr, "Format version of input file not supported.\n"); exit(1); } int main(int argc, char **argv) { raw1394handle_t handle; int ret; parse_args(argc, argv); fprintf(stderr, "port: %ld\nloops: %ld\nfile: %s\n", which_port, loopcount, filename); handle = raw1394_new_handle(); if (!handle) { if (!errno) fprintf(stderr, "No working kernel driver found.\n"); else perror("raw1394_get_handle"); exit(1); } do { if (raw1394_get_port_info(handle, NULL, 0) <= which_port) { fprintf(stderr, "Port %ld does not exist.\n", which_port); exit(1); } ret = raw1394_set_port(handle, which_port); } while (ret < 0 && errno == ESTALE); if (ret < 0) { perror("raw1394_set_port"); exit(1); } if (filename) send_iso_file(handle); fprintf(stderr, "\n"); raw1394_iso_shutdown(handle); raw1394_destroy_handle(handle); return 0; }