FreeCalypso > hg > freecalypso-tools
view rvinterf/lowlevel/rvifmain.c @ 867:dfd98dd46068
ringtools: fc-pwt-comp utility written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 28 Mar 2022 05:45:31 +0000 |
parents | 32031c18cc25 |
children | a1065c17429c |
line wrap: on
line source
/* * This module contains the main() function for rvinterf */ #include <sys/types.h> #include <sys/errno.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <time.h> #include "../include/pktmux.h" #include "../include/localsock.h" #include "client.h" extern int target_fd, listener; extern char *extlcd_program; extern u_char rxpkt[]; extern size_t rxpkt_len; struct client *client_head; int socketpair_fd; char *logfname; FILE *logF; time_t logtime; int background, no_output; int max_fd; char *socket_pathname = "/tmp/rvinterf_socket"; int wakeup_after_sec = 7; static char *baudrate = "115200"; static char keepalive_msg[] = "Received keepalive query, responding with keepalive answer"; static u_char keepalive_answer[2] = {RVT_KEEPALIVE_HEADER, 'A'}; write_pid_file(pid) { static char pid_filename[] = "/tmp/rvinterf.pid"; FILE *of; of = fopen(pid_filename, "w"); if (!of) { fprintf(stderr, "warning: unable to write %s\n", pid_filename); return(-1); } fprintf(of, "%d\n", pid); fclose(of); return(0); } main(argc, argv) char **argv; { extern char *optarg; extern int optind; int c; fd_set fds; struct client *cli, **clip; while ((c = getopt(argc, argv, "bB:d:l:nP:s:S:w:X:")) != EOF) switch (c) { case 'b': background++; /* FALL THRU */ case 'n': no_output++; continue; case 'B': baudrate = optarg; continue; case 'd': target_fd = atoi(optarg); continue; case 'l': logfname = optarg; continue; case 'P': if (find_bootctrl_entry(optarg) < 0) exit(1); /* error msg already printed */ continue; case 's': socket_pathname = optarg; continue; case 'S': socketpair_fd = atoi(optarg); continue; case 'w': wakeup_after_sec = strtoul(optarg, 0, 0); continue; case 'X': extlcd_program = optarg; continue; case '?': default: usage: fprintf(stderr, "usage: %s [options] ttyport\n", argv[0]); exit(1); } if (target_fd <= 0) { if (argc - optind != 1) goto usage; open_serial_port(argv[optind]); set_fixed_baudrate(baudrate); } max_fd = target_fd; if (extlcd_program) open_extlcd_pipe(); set_serial_nonblock(0); setlinebuf(stdout); if (logfname) { logF = fopen(logfname, "w"); if (!logF) { perror(logfname); exit(1); } setlinebuf(logF); fprintf(logF, "*** Log of rvinterf session ***\n"); } if (socketpair_fd) create_socketpair_client(); else create_listener_socket(); if (background) { c = fork(); if (c < 0) { perror("fork"); exit(1); } if (c) { printf("rvinterf forked into background (pid %d)\n", c); write_pid_file(c); exit(0); } } signal(SIGPIPE, SIG_IGN); pwon_if_needed(); for (;;) { FD_ZERO(&fds); FD_SET(target_fd, &fds); if (listener) FD_SET(listener, &fds); for (clip = &client_head; cli = *clip; ) { if (cli->rx_state == 2) { close(cli->fd); *clip = cli->next; free(cli); continue; } FD_SET(cli->fd, &fds); clip = &cli->next; } if (socketpair_fd && !client_head) exit(0); c = select(max_fd+1, &fds, 0, 0, 0); time(&logtime); if (c < 0) { if (errno == EINTR) continue; perror("select"); exit(1); } if (FD_ISSET(target_fd, &fds)) process_serial_rx(); if (listener && FD_ISSET(listener, &fds)) handle_listener_select(); for (cli = client_head; cli; cli = cli->next) if (FD_ISSET(cli->fd, &fds)) handle_client_select(cli); } } handle_rx_packet() { switch (rxpkt[0]) { case RVT_RV_HEADER: if (rxpkt_len < 6) goto unknown; if (!no_output || logF) print_rv_trace(); if (client_head) forward_rv_trace(); return; case RVT_L1_HEADER: if (!no_output || logF) print_l1_trace(); if (client_head) forward_nonrvt_pkt(); return; case RVT_L23_HEADER: if (!no_output || logF) print_g23_trace(); if (client_head) forward_nonrvt_pkt(); return; case RVT_TM_HEADER: if (!no_output || logF) print_tm_output_raw(); if (client_head) forward_nonrvt_pkt(); return; case RVT_AT_HEADER: if (!no_output || logF) print_ati_output(); if (client_head) forward_nonrvt_pkt(); return; case RVT_EXTUI_HEADER: if (rxpkt_len < 5 || !(rxpkt_len & 1)) goto unknown; if (extlcd_program) output_to_extlcd(); else report_extui_packet(); return; case RVT_TCH_HEADER: if (!no_output || logF) print_tch_output_raw(); if (client_head) forward_nonrvt_pkt(); return; case RVT_KEEPALIVE_HEADER: if (rxpkt_len != 2 || rxpkt[1] != 'Q') goto unknown; output_line(keepalive_msg); send_pkt_to_target(keepalive_answer, 2); return; case '*': print_fc_lld_msg(); return; default: unknown: print_unknown_packet(); } }