static int master(void) { modem_t modem[10]; char buf[1024]; int len; int i; for (i = 0; i < 10; i++) { if (psuedo_terminal_create(&modem[i])) { printf("Failure\n"); exit(2); } printf("%s %s\n", modem[i].devlink, modem[i].stty); } for (;;) { for (i = 0; i < 10; i++) { len = read(modem[i].master, buf, 4); if (len >= 0) { buf[len] = '\0'; printf("%d %d '%s' %s\n", i, len, buf, strerror(errno)); } } } for (i = 0; i < 10; i++) { if (psuedo_terminal_close(&modem[i])) { printf("Failure\n"); exit(2); } } return 0; }
int psuedo_terminal_create(modem_t *modem) { #if defined(WIN32) COMMTIMEOUTS timeouts = {0}; #endif memset(modem, 0, sizeof(*modem)); span_log_init(&modem->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&modem->logging, "PTY"); span_log_set_level(&modem->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); span_log_set_tag(&modem->logging, "PTY"); modem->master = -1; modem->slave = -1; #if USE_OPENPTY if (openpty(&modem->master, &modem->slave, NULL, NULL, NULL)) { span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to initialize pty\n"); return -1; } modem->stty = ttyname(modem->slave); #else #if defined(WIN32) modem->slot = 4 + next_id++; /* need work here we start at COM4 for now*/ snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot); modem->master = CreateFile(modem->devlink, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (modem->master == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: Serial port does not exist\n"); else span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: Serial port open error\n"); return -1; } #elif !defined(HAVE_POSIX_OPENPT) modem->master = open("/dev/ptmx", O_RDWR); #else modem->master = posix_openpt(O_RDWR | O_NOCTTY); #endif #if !defined(WIN32) if (modem->master < 0) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to initialize UNIX98 master pty\n"); if (grantpt(modem->master) < 0) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to grant access to slave pty\n"); if (unlockpt(modem->master) < 0) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to unlock slave pty\n"); if ((modem->stty = ptsname(modem->master)) == NULL) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to obtain slave pty filename\n"); if ((modem->slave = open(modem->stty, O_RDWR)) < 0) span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to open slave pty %s\n", modem->stty); #endif #if defined(SOLARIS) ioctl(modem->slave, I_PUSH, "ptem"); ioctl(modem->slave, I_PUSH, "ldterm"); #endif #endif #if defined(WIN32) timeouts.ReadIntervalTimeout = 50; timeouts.ReadTotalTimeoutConstant = 50; timeouts.ReadTotalTimeoutMultiplier = 10; timeouts.WriteTotalTimeoutConstant = 50; timeouts.WriteTotalTimeoutMultiplier = 10; SetCommMask(modem->master, EV_RXCHAR); if (!SetCommTimeouts(modem->master, &timeouts)) { span_log(&modem->logging, SPAN_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink); psuedo_terminal_close(modem); return -1; } modem->threadAbort = CreateEvent(NULL, true, false, NULL); #else modem->slot = next_id++; snprintf(modem->devlink, sizeof(modem->devlink), "%s/%d", device_root_name, modem->slot); /* Remove any stale link which might be present */ unlink(modem->devlink); if (symlink(modem->stty, modem->devlink)) { span_log(&modem->logging, SPAN_LOG_ERROR, "Fatal error: failed to create %s symbolic link\n", modem->devlink); psuedo_terminal_close(modem); return -1; } if (fcntl(modem->master, F_SETFL, fcntl(modem->master, F_GETFL, 0) | O_NONBLOCK)) { span_log(&modem->logging, SPAN_LOG_ERROR, "Cannot set up non-blocking read on %s\n", ttyname(modem->master)); psuedo_terminal_close(modem); return -1; } #endif return 0; }
int main(int argc, char *argv[]) { int log_audio; int t38_mode; int test_sending; int use_ecm; int use_gui; int g1050_model_no; int g1050_speed_pattern_no; int opt; #if !defined(WIN32) int tioflags; #endif decode_test_file = NULL; log_audio = FALSE; test_sending = FALSE; t38_mode = FALSE; use_ecm = FALSE; use_gui = FALSE; g1050_model_no = 0; g1050_speed_pattern_no = 1; while ((opt = getopt(argc, argv, "d:eglM:rS:st")) != -1) { switch (opt) { case 'd': decode_test_file = optarg; break; case 'e': use_ecm = TRUE; break; case 'g': #if defined(ENABLE_GUI) use_gui = TRUE; #else fprintf(stderr, "Graphical monitoring not available\n"); exit(2); #endif break; case 'l': log_audio = TRUE; break; case 'M': g1050_model_no = optarg[0] - 'A' + 1; break; case 'r': test_sending = FALSE; break; case 'S': g1050_speed_pattern_no = atoi(optarg); break; case 's': test_sending = TRUE; break; case 't': t38_mode = TRUE; break; default: //usage(); exit(2); break; } } if (psuedo_terminal_create(&modem[0])) printf("Failure\n"); #if !defined(WIN32) ioctl(modem[0].slave, TIOCMGET, &tioflags); tioflags |= TIOCM_RI; ioctl(modem[0].slave, TIOCMSET, &tioflags); #endif t30_tests(t38_mode, use_ecm, use_gui, log_audio, test_sending, g1050_model_no, g1050_speed_pattern_no); if (psuedo_terminal_close(&modem[0])) printf("Failure\n"); printf("Tests passed\n"); return 0; }