mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-13 00:55:42 +01:00
Bug fixes and modifications for the recent change of sequencer API.
This commit is contained in:
parent
c786b1b6d5
commit
1e5289de13
3 changed files with 45 additions and 31 deletions
|
@ -46,7 +46,8 @@ sending signal to them. The server will automatically quit.
|
||||||
The available options are:
|
The available options are:
|
||||||
|
|
||||||
-p port : specify the TCP port number or TCP service name.
|
-p port : specify the TCP port number or TCP service name.
|
||||||
Default value is 9009 (I don't know it's allowed..)
|
Default value is 40002.
|
||||||
-s addr : explicit read-subscription to the given address
|
-s addr : explicit read-subscription to the given address
|
||||||
(client:addr).
|
(client:addr).
|
||||||
-d addr : explicit write-subscription to the given address.
|
-d addr : explicit write-subscription to the given address.
|
||||||
|
-v : verbose mode.
|
||||||
|
|
|
@ -70,9 +70,12 @@ Subscribe to the given address for read automatically.
|
||||||
.TP
|
.TP
|
||||||
.B \-d addr
|
.B \-d addr
|
||||||
Subscribe to the given address for write automatically.
|
Subscribe to the given address for write automatically.
|
||||||
|
.TP
|
||||||
|
.B \-v
|
||||||
|
Verbose mode.
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
aconnect(1), pmidi(1)
|
aconnect(1), pmidi(1)
|
||||||
|
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Takashi Iwai <iwai@ww.uni-erlangen.de>.
|
Takashi Iwai <tiwai@suse.de>.
|
||||||
|
|
|
@ -43,7 +43,7 @@ static int copy_remote_to_local(int fd);
|
||||||
/*
|
/*
|
||||||
* default TCP port number
|
* default TCP port number
|
||||||
*/
|
*/
|
||||||
#define DEFAULT_PORT 9009
|
#define DEFAULT_PORT 40002
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* local input buffer
|
* local input buffer
|
||||||
|
@ -63,6 +63,7 @@ static int cur_connected;
|
||||||
static int seq_port;
|
static int seq_port;
|
||||||
|
|
||||||
static int server_mode;
|
static int server_mode;
|
||||||
|
static int verbose = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -74,6 +75,7 @@ static struct option long_option[] = {
|
||||||
{"source", 1, NULL, 's'},
|
{"source", 1, NULL, 's'},
|
||||||
{"dest", 1, NULL, 'd'},
|
{"dest", 1, NULL, 'd'},
|
||||||
{"help", 0, NULL, 'h'},
|
{"help", 0, NULL, 'h'},
|
||||||
|
{"verbose", 0, NULL, 'v'},
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ int main(int argc, char **argv)
|
||||||
int port = DEFAULT_PORT;
|
int port = DEFAULT_PORT;
|
||||||
char *source = NULL, *dest = NULL;
|
char *source = NULL, *dest = NULL;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "p:s:d:", long_option, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "p:s:d:v", long_option, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'p':
|
case 'p':
|
||||||
if (isdigit(*optarg))
|
if (isdigit(*optarg))
|
||||||
|
@ -97,6 +99,9 @@ int main(int argc, char **argv)
|
||||||
case 'd':
|
case 'd':
|
||||||
dest = optarg;
|
dest = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -141,6 +146,7 @@ static void usage(void)
|
||||||
fprintf(stderr, " -p,--port # : sepcify TCP port (digit or service name)\n");
|
fprintf(stderr, " -p,--port # : sepcify TCP port (digit or service name)\n");
|
||||||
fprintf(stderr, " -s,--source addr : read from given addr (client:port)\n");
|
fprintf(stderr, " -s,--source addr : read from given addr (client:port)\n");
|
||||||
fprintf(stderr, " -d,--dest addr : write to given addr (client:port)\n");
|
fprintf(stderr, " -d,--dest addr : write to given addr (client:port)\n");
|
||||||
|
fprintf(stderr, " -v, --verbose : print verbose messages\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,6 +191,7 @@ static int parse_addr(snd_seq_addr_t *addr, char *arg)
|
||||||
static void close_files(void)
|
static void close_files(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
if (verbose)
|
||||||
fprintf(stderr, "closing files..\n");
|
fprintf(stderr, "closing files..\n");
|
||||||
for (i = 0; i < max_connection; i++) {
|
for (i = 0; i < max_connection; i++) {
|
||||||
if (netfd[i] >= 0)
|
if (netfd[i] >= 0)
|
||||||
|
@ -226,6 +233,7 @@ static void init_seq(char *source, char *dest)
|
||||||
perror("create seq port");
|
perror("create seq port");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (verbose)
|
||||||
fprintf(stderr, "sequencer opened: %d:%d\n",
|
fprintf(stderr, "sequencer opened: %d:%d\n",
|
||||||
snd_seq_client_id(handle), seq_port);
|
snd_seq_client_id(handle), seq_port);
|
||||||
|
|
||||||
|
@ -263,7 +271,7 @@ static int get_port(char *service)
|
||||||
struct servent *sp;
|
struct servent *sp;
|
||||||
|
|
||||||
if ((sp = getservbyname(service, "tcp")) == NULL){
|
if ((sp = getservbyname(service, "tcp")) == NULL){
|
||||||
fprintf(stderr, "%s is not found in /etc/services\n", service);
|
fprintf(stderr, "service '%s' is not found in /etc/services\n", service);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sp->s_port;
|
return sp->s_port;
|
||||||
|
@ -285,6 +293,7 @@ static void sigterm_exit(int sig)
|
||||||
static void init_server(int port)
|
static void init_server(int port)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int curstate = 1;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
@ -295,17 +304,19 @@ static void init_server(int port)
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (sockfd < 0) {
|
if (sockfd < 0) {
|
||||||
fprintf(stderr, "can't create a socket\n");
|
perror("create socket");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate));
|
||||||
|
/* the return value is ignored.. */
|
||||||
|
|
||||||
if (bind(sockfd, &addr, sizeof(addr)) < 0) {
|
if (bind(sockfd, &addr, sizeof(addr)) < 0) {
|
||||||
fprintf(stderr, "can't bind address\n");
|
perror("can't bind");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(sockfd, 5) < 0) {
|
if (listen(sockfd, 5) < 0) {
|
||||||
fprintf(stderr, "can't listen on socket\n");
|
perror("can't listen");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,9 +346,10 @@ static void start_connection(void)
|
||||||
addr_len = sizeof(addr);
|
addr_len = sizeof(addr);
|
||||||
netfd[i] = accept(sockfd, (struct sockaddr *)&addr, &addr_len);
|
netfd[i] = accept(sockfd, (struct sockaddr *)&addr, &addr_len);
|
||||||
if (netfd[i] < 0) {
|
if (netfd[i] < 0) {
|
||||||
fprintf(stderr, "can't accept\n");
|
perror("accept");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (verbose)
|
||||||
fprintf(stderr, "accepted[%d]\n", netfd[i]);
|
fprintf(stderr, "accepted[%d]\n", netfd[i]);
|
||||||
cur_connected++;
|
cur_connected++;
|
||||||
}
|
}
|
||||||
|
@ -349,10 +361,15 @@ static void init_client(char *server, int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
struct hostent *host;
|
struct hostent *host;
|
||||||
|
int curstate = 1;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
|
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
|
||||||
fprintf(stderr, "can't create socket\n");
|
perror("create socket");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) {
|
||||||
|
perror("setsockopt");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if ((host = gethostbyname(server)) == NULL){
|
if ((host = gethostbyname(server)) == NULL){
|
||||||
|
@ -363,9 +380,10 @@ static void init_client(char *server, int port)
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
|
memcpy(&addr.sin_addr, host->h_addr, host->h_length);
|
||||||
if (connect(fd, &addr, sizeof(addr)) < 0) {
|
if (connect(fd, &addr, sizeof(addr)) < 0) {
|
||||||
fprintf(stderr,"can't connect\n");
|
perror("connect");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (verbose)
|
||||||
fprintf(stderr, "ok.. connected\n");
|
fprintf(stderr, "ok.. connected\n");
|
||||||
netfd[0] = fd;
|
netfd[0] = fd;
|
||||||
cur_connected = 1;
|
cur_connected = 1;
|
||||||
|
@ -464,7 +482,8 @@ static int copy_local_to_remote(void)
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
while ((rc = snd_seq_event_input(handle, &ev)) >= 0 && ev) {
|
while ((rc = snd_seq_event_input(handle, &ev)) >= 0 && ev) {
|
||||||
if (ev->type >= SND_SEQ_EVENT_CLIENT_START) {
|
if (ev->type >= SND_SEQ_EVENT_CLIENT_START &&
|
||||||
|
! snd_seq_ev_is_variable_type(ev)) {
|
||||||
snd_seq_free_event(ev);
|
snd_seq_free_event(ev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -478,6 +497,7 @@ static int copy_local_to_remote(void)
|
||||||
buf = get_writebuf(sizeof(snd_seq_event_t));
|
buf = get_writebuf(sizeof(snd_seq_event_t));
|
||||||
memcpy(buf, ev, sizeof(snd_seq_event_t));
|
memcpy(buf, ev, sizeof(snd_seq_event_t));
|
||||||
}
|
}
|
||||||
|
snd_seq_free_event(ev);
|
||||||
}
|
}
|
||||||
flush_writebuf();
|
flush_writebuf();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -496,26 +516,17 @@ static int copy_remote_to_local(int fd)
|
||||||
buf = readbuf;
|
buf = readbuf;
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
|
if (verbose)
|
||||||
fprintf(stderr, "disconnected\n");
|
fprintf(stderr, "disconnected\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
ev = snd_seq_create_event();
|
ev = (snd_seq_event_t*)buf;
|
||||||
if (ev == NULL) {
|
|
||||||
fprintf(stderr, "can't malloc\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memcpy(ev, buf, sizeof(snd_seq_event_t));
|
|
||||||
buf += sizeof(snd_seq_event_t);
|
buf += sizeof(snd_seq_event_t);
|
||||||
count -= sizeof(snd_seq_event_t);
|
count -= sizeof(snd_seq_event_t);
|
||||||
if (snd_seq_ev_is_variable(ev) && ev->data.ext.len > 0) {
|
if (snd_seq_ev_is_variable(ev) && ev->data.ext.len > 0) {
|
||||||
ev->data.ext.ptr = malloc(ev->data.ext.len);
|
ev->data.ext.ptr = buf;
|
||||||
if (ev->data.ext.ptr == NULL) {
|
|
||||||
fprintf(stderr, "can't malloc\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memcpy(ev->data.ext.ptr, buf, ev->data.ext.len);
|
|
||||||
buf += ev->data.ext.len;
|
buf += ev->data.ext.len;
|
||||||
count -= ev->data.ext.len;
|
count -= ev->data.ext.len;
|
||||||
}
|
}
|
||||||
|
@ -523,7 +534,6 @@ static int copy_remote_to_local(int fd)
|
||||||
snd_seq_ev_set_source(ev, seq_port);
|
snd_seq_ev_set_source(ev, seq_port);
|
||||||
snd_seq_ev_set_subs(ev);
|
snd_seq_ev_set_subs(ev);
|
||||||
snd_seq_event_output(handle, ev);
|
snd_seq_event_output(handle, ev);
|
||||||
snd_seq_free_event(ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_seq_flush_output(handle);
|
snd_seq_flush_output(handle);
|
||||||
|
|
Loading…
Reference in a new issue