This repository has been archived on 2022-09-20. You can view files and clone it, but cannot push or open issues or pull requests.
libraw1394/tools/sendiso.c
Stefan Richter ba8d2119ba tools: Fix startup of dumpiso and sendiso on juju
Quoting the errno manual:

"[errno] is set by system calls and some library functions in the
event of an error to indicate  what went wrong.  Its value is
significant only when the return value of the call indicated an
error (i.e., -1 from most system calls; -1 or NULL from most library
functions); a function that succeeds is allowed to change errno.
Valid error numbers are all nonzero; errno is never set to zero by
any system call or library function."

Dumpiso and sendiso checked for raw1394_set_port() failure by
looking at errno rather than by looking at the function's return
code.  This happened to work on top of raw1394 by lucky incident but
no longer works on top of firewire-core.

Reported-by: Vladimir Romanov <blueboar2@gmail.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
2013-08-24 11:51:11 +02:00

316 lines
9.3 KiB
C

/*
* 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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#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;
}