diff --git a/Makefile b/Makefile index 206d0da..4018dd1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ STRIP=arm-linux-gnueabihf-strip CCFLAGS=-Ialsa/include -Lalsa/lib -Ofast -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -ftree-vectorize -funsafe-math-optimizations LDFLAGS=-lasound -lm -pthread all : - $(CC) $(CCFLAGS) $(LDFLAGS) main.c serial.c serial2.c misc.c udpsock.c tcpsock.c alsa.c ini.c directory.c modem_snd.c -o midilink + $(CC) $(CCFLAGS) $(LDFLAGS) main.c modem.c serial.c serial2.c misc.c udpsock.c tcpsock.c alsa.c ini.c directory.c modem_snd.c -o midilink $(STRIP) midilink $(CC) $(CCFLAGS) mlinkutil.c misc.c serial2.c tcpsock.c -o mlinkutil $(STRIP) mlinkutil diff --git a/config.h b/config.h index 1032072..986af5a 100644 --- a/config.h +++ b/config.h @@ -9,21 +9,20 @@ // Thanks to https://ccrma.stanford.edu/~craig/articles/linuxmidi/ for the // excellent MIDI programming examples. // -// "/dev/sequencer" does not seem to work for input -static char * midiLinkINI = "/media/fat/linux/MidiLink.INI"; -static char * midiLinkDIR = "/media/fat/linux/MidiLink.DIR"; -static char * serialDevice = "/dev/ttyS1"; -static char * serialDeviceUSB = "/dev/ttyUSB0"; -static char * helloStr = "MiSTer MidiLink 2.9d BB7"; +char * midiLinkINI = "/media/fat/linux/MidiLink.INI"; +char * midiLinkDIR = "/media/fat/linux/MidiLink.DIR"; +char * serialDevice = "/dev/ttyS1"; +char * helloStr = "MiSTer MidiLink 3.0 BB7"; +char * PCMDevice = "/dev/snd/pcmC0D0p"; +int CPUMASK = 1; +static char * MrAudioDevice = "/dev/MrAudio"; static unsigned char test_note[3] = {0x90, 60, 127}; static char * midiINDevice = "/dev/midi2"; static char * midiDevice = "/dev/midi1"; -static char * PCMDevice = "/dev/snd/pcmC0D0p"; -static char * MrAudioDevice = "/dev/MrAudio"; -static int CPUMASK = 1; - -static char all_notes_off[] = +static char * serialDeviceUSB = "/dev/ttyUSB0"; + +char all_notes_off[] = { 0xb0, 0x7b, 0x00, 0xb0, 0x40, 0x00, 0xb1, 0x7b, 0x00, 0xb1, 0x40, 0x00, 0xb2, 0x7b, 0x00, 0xb2, 0x40, 0x00, 0xb3, 0x7b, 0x00, 0xb3, 0x40, 0x00, 0xb4, 0x7b, 0x00, 0xb4, 0x40, 0x00, 0xb5, 0x7b, 0x00, 0xb5, 0x40, 0x00, @@ -33,6 +32,7 @@ static char all_notes_off[] = 0xbf, 0x7b, 0x00, 0xbf, 0x40, 0x00 }; +int sizeof_all_notes_off = sizeof(all_notes_off); diff --git a/ini.c b/ini.c index 78c6107..2608694 100644 --- a/ini.c +++ b/ini.c @@ -321,7 +321,7 @@ void ini_print_settings(int p) misc_print(p, " - FSYNTH_VOLUME --> %d%c\n", fsynthVolume, '%'); else misc_print(p, " - FSYNTH_VOLUME --> Default (don't set)\n"); - if(fsynthVolume != -1) + if(modemVolume != -1) misc_print(p, " - MODEM_VOLUME --> %d%c\n", modemVolume, '%'); else misc_print(p, " - MODEM_VOLUME --> Default (don't set)\n"); diff --git a/main.c b/main.c index cf412ab..2c8ee57 100644 --- a/main.c +++ b/main.c @@ -22,85 +22,62 @@ along with this program. If not, see . #include #include #include -#include #include #include #include "serial.h" #include "serial2.h" -#include "config.h" #include "misc.h" #include "udpsock.h" #include "tcpsock.h" #include "alsa.h" #include "ini.h" -#include "directory.h" -#include "modem_snd.h" - -#define DEFAULT_MODEMSOUND TRUE -#define DEFAULT_modemVolume -1 -#define DEFAULT_TCPAsciiTrans AsciiNoTrans -#define DEFAULT_TCPTermRows 22 -#define DEFAULT_TCPFlow -1 -#define DEFAULT_TCPDTR 1 -#define DEFAULT_TCPQuiet 0 +#include "modem.h" +#include "config.h" enum MODE {ModeUSBMIDI, ModeTCP, ModeUDP, ModeUSBSER, ModeMUNT, ModeMUNTGM, ModeFSYNTH, ModeUDPMUNT, ModeUDPMUNTGM, ModeUDPFSYNTH}; -int MIDI_DEBUG = TRUE; static enum MODE mode = ModeUSBMIDI; -static int fdSerial = -1; static int fdSerialUSB = -1; -static int fdMidi = -1; -static int fdMidiIN = -1; -static int socket_in = -1; -static int socket_out = -1; -static int socket_lst = -1; -static int baudRate = -1; -char MT32LCDMsg[21] = "MiSTer MidiLink! BB7"; -char MP3Path[500] = "/media/fat/MP3"; -char MIDIPath[500] = "/media/fat/MIDI"; -char downloadPath[500] = "/media/fat"; -char uploadPath[100] = "/media/fat/UPLOAD"; -char fsynthSoundFont [150] = "/media/fat/linux/soundfonts/SC-55.sf2"; -char MUNTRomPath[150] = "/media/fat/linux/mt32-rom-data"; -char modemConnectSndWAV[50] = ""; -char modemDialSndWAV[50] = ""; -char modemRingSndWAV[50] = ""; -char UDPServer [100] = ""; -char mixerControl[20] = "Master"; -char MUNTOptions[30] = ""; -int MP3Volume = -1; -int muntVolume = -1; -int fsynthVolume = -1; -int modemVolume = DEFAULT_modemVolume; -int midilinkPriority = 0; +static int fdMidi = -1; +static int fdMidiIN = -1; + +int MIDI_DEBUG = TRUE; +int socket_in = -1; +int socket_out = -1; +int socket_lst = -1; +int fdSerial = -1; +int baudRate = -1; +int muntVolume = -1; +int fsynthVolume = -1; +int midilinkPriority = 0; int UDPBaudRate = -1; int TCPBaudRate = -1; int UDPBaudRate_alt = -1; int TCPBaudRate_alt = -1; -int MIDIBaudRate = -1; +int MIDIBaudRate = -1; int USBSerBaudRate = -1; -char USBSerModule[100] = ""; -enum ASCIITRANS TCPAsciiTrans = DEFAULT_TCPAsciiTrans; -int TCPFlow = DEFAULT_TCPFlow; -int TCPDTR = DEFAULT_TCPDTR; +int TCPFlow = -1; +int TCPDTR = 1; int UDPFlow = -1; -int MODEMSOUND = DEFAULT_MODEMSOUND; -int TCPQuiet = DEFAULT_TCPQuiet; -int TCPATHDelay = 900; int MUNTCPUMask = -1; int FSYNTHCPUMask = -1; -enum SOFTSYNTH TCPSoftSynth = FluidSynth; -unsigned int TCPTermRows = DEFAULT_TCPTermRows; -unsigned int DELAYSYSEX = FALSE; -unsigned int UDPServerPort = 1999; -unsigned int TCPServerPort = 23; +unsigned int DELAYSYSEX = FALSE; +unsigned int UDPServerPort = 1999; +unsigned int TCPServerPort = 23; unsigned int UDPServerFilterIP = FALSE; -static pthread_t midiInThread; -static pthread_t midiINInThread; -static pthread_t socketInThread; +char MT32LCDMsg[21] = "MiSTer MidiLink! BB7"; +char fsynthSoundFont [150] = "/media/fat/linux/soundfonts/SC-55.sf2"; +char MUNTRomPath[150] = "/media/fat/linux/mt32-rom-data"; +char UDPServer [100] = ""; +char mixerControl[20] = "Master"; +char MUNTOptions[30] = ""; +char USBSerModule[100] = ""; + +static pthread_t midiInThread; +static pthread_t midiINInThread; +static pthread_t socketInThread; static pthread_t socketLstThread; -static pthread_t serialInThread; +static pthread_t serialInThread; /////////////////////////////////////////////////////////////////////////////////////// // @@ -187,42 +164,6 @@ int start_fsynth() return midiPort; } -/////////////////////////////////////////////////////////////////////////////////////// -// -// void killall_mpg123() -// -void killall_mpg123(int delay) -{ - misc_print(0, "Killing --> mpg123\n"); - system("killall -q mpg123"); - if(delay) - sleep(delay); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void killall_aplaymidi() -// -void killall_aplaymidi(int delay) -{ - misc_print(0, "Killing --> aplaymidi\n"); - system("killall -q aplaymidi"); - if(delay) - sleep(delay); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void killall_aplaymidi() -// -void killall_aplay(int delay) -{ - misc_print(0, "Killing --> aplay\n"); - system("killall -q aplay"); - if(delay) - sleep(delay); -} - /////////////////////////////////////////////////////////////////////////////////////// // // void show_debug_buf(char * descr, char * buf, int bufLen) @@ -244,78 +185,6 @@ void show_debug_buf(char * descr, char * buf, int bufLen) } } -/////////////////////////////////////////////////////////////////////////////////////// -// -// void play_conenct_sound(char * tmp) -// -// -void play_connect_sound(char * tmp) -{ - if (MODEMSOUND) - { - killall_aplaymidi(0); - killall_softsynth(0); - killall_mpg123(0); - killall_aplay(0); - if(strlen(modemConnectSndWAV) > 0 && misc_check_file(modemConnectSndWAV)) - { - misc_print(1, "Playing WAV --> '%s'\n", modemConnectSndWAV); - sprintf(tmp, "aplay %s", modemConnectSndWAV); - system(tmp); - } - else - modem_snd("C"); - } -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void play_conenct_sound(char * tmp) -// -// -void play_ring_sound(char * tmp) -{ - if (MODEMSOUND) - { - killall_aplaymidi(0); - killall_softsynth(0); - killall_mpg123(0); - killall_aplay(0); - if(strlen(modemRingSndWAV) > 0 && misc_check_file(modemRingSndWAV)) - { - misc_print(1, "Playing WAV --> '%s'\n", modemRingSndWAV); - sprintf(tmp, "aplay %s", modemRingSndWAV); - system(tmp); - } - else - modem_snd("R"); - } -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void play_dial_sound(char * tmp, char * ipAddr) -// -// -void play_dial_sound(char * tmp, char * ipAddr) -{ - if (MODEMSOUND) - { - killall_aplaymidi(0); - killall_softsynth(0); - killall_mpg123(0); - killall_aplay(0); - if (strlen(modemDialSndWAV) > 0 && misc_check_file(modemDialSndWAV)) - { - misc_print(1, "Playing WAV --> '%s'\n", modemDialSndWAV); - sprintf(tmp, "aplay %s", modemDialSndWAV); - system(tmp); - } - else - modem_snd(ipAddr); - } -} - /////////////////////////////////////////////////////////////////////////////////////// // // write_[sequencer]_packet() @@ -327,884 +196,6 @@ void write_alsa_packet(char * buf, int bufLen) show_debug_buf("SEQU OUT ", buf, bufLen); } -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * tcplst_thread_function(void * x) -// Thread function for TCP Listener input -// -void * tcplst_thread_function (void * x) -{ - unsigned char buf[100]; - int rdLen; - - do - { - socket_in = tcpsock_accept(socket_lst); - if(socket_in != -1) - { - tcpsock_set_tcp_nodelay(socket_in); - tcpsock_set_timeout(socket_in, 10); - misc_print(1,"Incomming connection\n"); - tcpsock_get_ip(socket_in, buf); - misc_print(1, "CONNECT --> %s\n", buf); - if(socket_out == -1) - { - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nRING"); - if(MODEMSOUND) - set_pcm_volume(modemVolume); - play_ring_sound(buf); - play_connect_sound(buf); - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nCONNECT %d\r\n", baudRate); - serial2_set_DCD(serialDevice, fdSerial, TRUE); - do - { - rdLen = read(socket_in, buf, sizeof(buf)); - if (rdLen > 0) - { - write(fdSerial, buf, rdLen); - show_debug_buf("TSERV IN", buf, rdLen); - } - else if (rdLen == 0) - { - if(socket_in != -1) - close(socket_in); - socket_in = -1; - misc_print(1, "tcplst_thread_function() --> Connection Closed.\n"); - } - } while (socket_in != -1); - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nNO CARRIER\r\n"); - serial2_set_DCD(serialDevice, fdSerial, FALSE); - } - else - { - char busyStr[] = "\r\nBUSY"; - misc_print(1, "Sending BUSY message and disconnecting.,\n"); - tcpsock_write(socket_in, busyStr, strlen(busyStr)); - sleep(2); - tcpsock_close(socket_in); - socket_in = -1; - } - } - else - { - sleep(5); - } - - } while(TRUE); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * socket_thread_function(void * x) -// Thread function for TCP input -// -void * tcpsock_thread_function (void * x) -{ - unsigned char buf[100]; - int rdLen; - do - { - rdLen = tcpsock_read(socket_out, (char *) buf, sizeof(buf)); - if (rdLen > 0) - { - write(fdSerial, buf, rdLen); - show_debug_buf("TSOCK IN ", buf, rdLen); - } - else if(rdLen < 1) - misc_print(1, "ERROR: tcpsock_thread_function() --> rdLen < 1\n"); - } while (rdLen > 0 && socket_out != -1); - if(socket_out != -1) - close(socket_out); - socket_out = -1; - if(MIDI_DEBUG) - misc_print(1, "TCPSOCK Thread fuction exiting.\n", socket_out); - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nNO CARRIER\r\n"); - pthread_exit(NULL); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * udpsock_thread_function(void * x) -// Thread function for UDP input -// -void * udpsock_thread_function (void * x) -{ - unsigned char buf[100]; - int rdLen; - do - { - rdLen = udpsock_read(socket_in, (char *) buf, sizeof(buf)); - if (rdLen > 0) - { - write(fdSerial, buf, rdLen); - show_debug_buf("USOCK IN ", buf, rdLen); - } - } while (TRUE); -} - - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * udpsock_thread_function2(void * x) -// Thread function for UDP input for external device like Raspberry Pi -// -void * udpsock_thread_function2 (void * x) -{ - unsigned char buf[100]; - int rdLen; - do - { - rdLen = udpsock_read(socket_in, (char *) buf, sizeof(buf)); - if (rdLen > 0) - { - write_alsa_packet(buf, rdLen); - //show_debug_buf("USOCK2 IN", buf, rdLen); - } - } while (TRUE); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void do_check_modem_hangup(char * buf, int bufLen) -// -// -void do_check_modem_hangup(int * socket, char * buf, int bufLen) -{ - static char lineBuf[6]; - static char iLineBuf = 0; - static int plusCount = 0; - static int NEEDSTOP = FALSE; - static struct timeval start; - static struct timeval stop; - char tmp[100] = ""; - - for (char * p = buf; bufLen-- > 0; p++) - { - switch(*p) - { - case '+': // RESET - gettimeofday(&start, NULL); - iLineBuf = 0; - lineBuf[iLineBuf] = 0x00; - plusCount++; - NEEDSTOP = TRUE; - break; - case 0x0D:// [RETURN] - if(plusCount >= 3 && iLineBuf >= 3 && memcmp(lineBuf, "ATH", 3) == 0) - { - int delay = misc_get_timeval_diff(&start, &stop); - if(TCPATHDelay == 0 || delay > TCPATHDelay) - { - tcpsock_close(*socket); - *socket = -1; - serial2_set_DCD(serialDevice, fdSerial, FALSE); - sprintf(tmp, "\r\nHANG-UP DETECTED\r\n"); - misc_print(1, "HANG-UP Detected --> %d\n", delay); - misc_swrite(fdSerial, tmp); - sleep(1); - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "OK\r\n"); - } - else - misc_print(1, "HANG-UP Rejected --> %d\n", delay); - } - iLineBuf = 0; - lineBuf[iLineBuf] = 0x00; - plusCount = 0; - break; - default: - if (plusCount >= 3 && iLineBuf < sizeof(lineBuf)-1) - { - if (NEEDSTOP) - { - gettimeofday(&stop, NULL); - NEEDSTOP = FALSE; - } - lineBuf[iLineBuf++] = *p; - lineBuf[iLineBuf] = 0x00; - } - else - plusCount = 0; - break; - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void do_telnet_negotiate() -// -// -#define DO 0xfd -#define WONT 0xfc -#define WILL 0xfb -#define DONT 0xfe -#define CMD 0xff -#define CMD_ECHO 1 -#define CMD_WINDOW_SIZE 31 - -void do_telnet_negotiate() -{ - char buf[3]; - int rdLen1; - int rdLen2; - int rdLen3; - int wrLen = 0; - unsigned char msg1[] = {0xff, 0xfb, 0x1f}; - unsigned char msg2[] = {0xff, 0xfa, 0x1f, 0x00, 0x50, 0x00, 0x18, 0xff, 0xf0}; - - tcpsock_set_timeout(socket_out, 3); - misc_print(1, "Telnet negotiation --> START\n"); - do - { - rdLen1 = tcpsock_read(socket_out, &buf[0], 1); - if (rdLen1 == 1 && buf[0] == CMD) - { - //misc_print(1, "Telnet negotiation --> CMD\n"); - rdLen2 = tcpsock_read(socket_out, &buf[1], 1); - rdLen3 = tcpsock_read(socket_out, &buf[2], 1); - if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) - { - //misc_print(1, "Telnet negotiation --> N1\n"); - wrLen = tcpsock_write(socket_out, msg1, sizeof(msg1)); - if (wrLen < 0) goto end; - wrLen = tcpsock_write(socket_out, msg2, sizeof(msg2)); - if (wrLen < 0) goto end; - } - else - { - //misc_print(1, "Telnet negotiation --> N2\n"); - for (int i = 0; i < sizeof(buf); i++) - { - if (buf[i] == DO) - buf[i] = WONT; - else if (buf[i] == WILL) - buf[i] = DO; - } - wrLen = tcpsock_write(socket_out, buf, sizeof(buf)); - if (wrLen < 0) goto end; - buf[0] = CMD; - } - } - else if(rdLen1 = 1) - write(fdSerial, &buf[0], 1); - } while (buf[0] == CMD && rdLen1 == 1); -end: - misc_print(1, "Telnet negotiation --> END\n"); - if (wrLen < 0) - { - misc_print(0, "ERROR: Telnet negotiation failed\n"); - } - tcpsock_set_timeout(socket_out, 0); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// BOOL do_file_picker(char * pathBuf, char * resultBuf) -// -// -int do_file_picker(char * pathBuf, char * fileNameBuf) -{ - int DIR = 0; - int result; - char * endPtr; - do - { - result = misc_list_files(pathBuf, fdSerial, TCPTermRows, fileNameBuf, &DIR); - if(result) - if (DIR) - { - if(strcmp(fileNameBuf, ".") == 0 || - strcmp(fileNameBuf, "..") == 0) - { - endPtr = strrchr(pathBuf, '/'); - if (endPtr != NULL && strlen(pathBuf) > 1) - *endPtr = (char) 0x00; - } - else - { - strcat(pathBuf, "/"); - strcat(pathBuf, fileNameBuf); - } - } - else - { - misc_swrite(fdSerial, "Selected file --> "); - misc_swrite(fdSerial, fileNameBuf); - } - } while (result && DIR); - return result; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// int get_softsynth_port(int softSynth) -// -// -int get_softsynth_port(int softSynth) -{ - int midiPort = alsa_get_midi_port("MT-32"); - if (midiPort == -1) - midiPort = alsa_get_midi_port("FLUID Synth"); - if (midiPort == -1) - { - switch(softSynth) - { - case MUNT: - midiPort = start_munt(); - break; - case FluidSynth: - midiPort = start_fsynth(); - break; - case -1: //do nothing. - break; - } - } - return midiPort; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// BOOL handle_at_command(char * lineBuf) -// -// -#define KILL_MP3_SLEEP if(MP3){killall_mpg123(1);MP3 = FALSE;} -int handle_at_command(char * lineBuf) -{ - static int TELNET_NEGOTIATE = TRUE; - static int MP3 = FALSE; - char tmp[1024] = ""; - char * endPtr; - char fileName [256]; - char audioError[] = "\r\nBad news, you have no audio device :( --> %s"; - - if(memcmp(lineBuf, "ATDT", 4) == 0) - { - char * ipAddr = &lineBuf[4]; - if(ipAddr[0] != (char) 0x00) - directory_search(midiLinkDIR, ipAddr, ipAddr); - char * prtSep = strchr(ipAddr, ':'); - if(prtSep == NULL) - prtSep = strchr(ipAddr, '*'); // with NCOMM? - char * port = (prtSep == NULL)?NULL:(prtSep + 1); - if (prtSep != NULL) *prtSep = 0x00; - if (strlen(ipAddr) < 3) - misc_show_atdt(fdSerial); - else - { - int ipError = FALSE; - int iPort = (port == NULL)?23:strtol(port, &endPtr, 10); - if (!misc_is_ip_addr(ipAddr)) - { - char domainName[30]; - getdomainname(domainName, sizeof(domainName)); - if(strcmp(domainName, "(none)") != 0 && misc_count_str_chr(ipAddr, '.') < 1) - { - strcat(ipAddr, "."); - strcat(ipAddr, domainName); - misc_print(1, "Doing domain name fix --> %s\n", ipAddr); - } - if(!misc_hostname_to_ip(ipAddr, ipAddr)) - { - misc_swrite(fdSerial, "\r\nERROR: Unable to convert hostname '%s' to IP address.", ipAddr); - ipError = TRUE; - } - } - if(!ipError) - { - misc_swrite(fdSerial, "\r\nDIALING %s:%d\r\n", ipAddr, iPort); - serial_do_tcdrain(fdSerial); - if(MODEMSOUND) - set_pcm_volume(modemVolume); - play_dial_sound(tmp, ipAddr); - serial_do_tcdrain(fdSerial); - if(MODEMSOUND) - sleep(1); - serial2_set_DCD(serialDevice, fdSerial, FALSE); - socket_out = tcpsock_client_connect(ipAddr, iPort, fdSerial); - } - if(socket_out > 0) - { - if (TELNET_NEGOTIATE) - do_telnet_negotiate(); - play_ring_sound(tmp); - play_connect_sound(tmp); - if(TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nCONNECT %d\r\n", baudRate); - serial_do_tcdrain(fdSerial); - sleep(1); - int status = pthread_create(&socketInThread, NULL, tcpsock_thread_function, NULL); - serial2_set_DCD(serialDevice, fdSerial, TRUE); - return TRUE; - } - } - } - else if (memcmp(lineBuf, "ATBAUD", 6) == 0) - { - char * baud = &lineBuf[6]; - int iBaud = strtol(baud, &endPtr, 10); - int iTemp = serial2_baud_at_index(iBaud); - iBaud = (misc_is_number(baud) && iTemp > 0)?iTemp:iBaud; - if (serial2_is_valid_rate (iBaud)) - { - int sec = 10; - misc_swrite(fdSerial, "\r\nSetting BAUD to %d in %d seconds...", iBaud, sec); - sleep(sec); - serial2_set_baud(serialDevice, fdSerial, iBaud); - baudRate = iBaud; - misc_swrite(fdSerial, "\r\nBAUD has been set to %d", iBaud); - } - else - { - if(baud[0] != 0x00) - misc_swrite(fdSerial, "\r\nBAUD rate '%s' is not valid.", baud); - serial2_show_menu(fdSerial); - } - } - else if (memcmp(lineBuf, "ATIP", 4) == 0) - { - misc_show_atip(fdSerial); - } - else if (memcmp(lineBuf, "ATK", 3) == 0) - { - char * hayesMode = &lineBuf[3]; - if(misc_is_number(hayesMode)) - { - int iHayesMode = strtol(hayesMode, &endPtr, 10); - serial_set_flow_control(fdSerial, iHayesMode); - } - else - serial_set_flow_control(fdSerial, -1); - } - else if (memcmp(lineBuf, "ATTEL", 5) == 0) - { - if (lineBuf[5] == '0') - TELNET_NEGOTIATE = FALSE; - else if (lineBuf[5] == '1') - TELNET_NEGOTIATE = TRUE; - misc_swrite(fdSerial, "\r\nTelnet Negotiations --> %s", TELNET_NEGOTIATE?"TRUE":"FALSE"); - } - else if (memcmp(lineBuf, "ATMP3", 5) == 0) - { - if (misc_check_device(PCMDevice)) - { - if(lineBuf[5] == '!') - { - misc_swrite(fdSerial, "\r\nMP3 --> OFF"); - killall_mpg123(0); - } - else if(do_file_picker(MP3Path, fileName)) - { - chdir("/root"); - set_pcm_volume(MP3Volume); - sprintf(tmp, "taskset %d mpg123 -o alsa \"%s/%s\" 2> /tmp/mpg123 & ", CPUMASK, MP3Path, fileName); - if(!MP3) - { - killall_aplaymidi(0); - killall_softsynth(3); - } - killall_mpg123(0); - misc_print(1, "Play MP3 --> %s\n", tmp); - system(tmp); - misc_swrite(fdSerial, "\r\n"); - sleep(1); - misc_file_to_serial(fdSerial, "/tmp/mpg123", TCPTermRows); - MP3 = TRUE; - } - } - else - misc_swrite(fdSerial, audioError, PCMDevice); - } - else if (memcmp(lineBuf, "ATMID", 5) == 0) - { - if (misc_check_device(PCMDevice)) - { - if(lineBuf[5] == '!') - { - killall_aplaymidi(0); - misc_swrite(fdSerial, "\r\nMIDI --> OFF"); - sleep(2); - int midiPort = get_softsynth_port(-1); - if(midiPort != -1) - { - alsa_open_seq(midiPort, 0); - alsa_send_midi_raw(all_notes_off, sizeof(all_notes_off)); - alsa_close_seq(); - } - } - else if(lineBuf[5] == '1') - { - KILL_MP3_SLEEP; - killall_aplaymidi(0); - misc_swrite(fdSerial, "\r\nLoading --> FluidSynth"); - killall_softsynth(3); - TCPSoftSynth = FluidSynth; - get_softsynth_port(TCPSoftSynth); - } - else if(lineBuf[5] == '2') - { - KILL_MP3_SLEEP; - killall_aplaymidi(0); - misc_swrite(fdSerial, "\r\nLoading --> MUNT"); - killall_softsynth(3); - TCPSoftSynth = MUNT; - get_softsynth_port(TCPSoftSynth); - } - else if(lineBuf[5] == 'S' && lineBuf[6] == 'F') - { - strcpy(tmp, fsynthSoundFont); - char * dir = strrchr(tmp, '/'); - if(dir != NULL) - *dir = (char) 0x00; - else - tmp[0] = (char) 0x00; - if (do_file_picker(tmp, fileName)) - { - strcpy(fsynthSoundFont, tmp); - strcat(fsynthSoundFont, "/"); - strcat(fsynthSoundFont, fileName); - misc_swrite(fdSerial, "\r\n SoundFont -->"); - misc_swrite(fdSerial, fsynthSoundFont); - sprintf(tmp,"sed -i '{s|^FSYNTH_SOUNDFONT[[:space:]]*=.*|FSYNTH_SOUNDFONT = %s|}' %s", - fsynthSoundFont, midiLinkINI); - system(tmp); - } - } - else if(do_file_picker(MIDIPath, fileName)) - { - KILL_MP3_SLEEP; - killall_aplaymidi(0); - int midiPort = get_softsynth_port(TCPSoftSynth); - chdir("/root"); - sprintf(tmp, "taskset %d aplaymidi --port %d \"%s/%s\" 2> /tmp/aplaymidi & ", CPUMASK, midiPort, MIDIPath, fileName);; - misc_print(1, "Play MIDI --> %s\n", tmp); - system(tmp); - misc_swrite(fdSerial, "\r\n"); - sleep(1); - misc_file_to_serial(fdSerial, "/tmp/aplaymidi", 0); - MP3 = FALSE; - } - } - else - { - misc_swrite(fdSerial, audioError, PCMDevice); - } - } - else if (memcmp(lineBuf, "ATSZ", 4) == 0) - { - if(do_file_picker(downloadPath, fileName)) - { - sprintf(tmp, "%s/%s", downloadPath, fileName); - misc_print(1, "Zmodem download --> %s\n", tmp); - serial_do_tcdrain(fdSerial); - misc_do_pipe(fdSerial, "/bin/sz","sz", tmp, NULL, NULL, NULL, NULL); - sleep(3); - } - } - else if (memcmp(lineBuf, "ATRZ", 4) == 0) - { - if(chdir (uploadPath) == 0) - { - misc_swrite(fdSerial, "\r\nUpload path --> '%s'", uploadPath); - misc_swrite(fdSerial, "\r\nUpload file using Zmodem protocol now...\r\n"); - serial_do_tcdrain(fdSerial); - misc_do_pipe(fdSerial, "/bin/rz", "rz", NULL, NULL, NULL, NULL, NULL); - chdir("/root"); - sleep(3); - } - else - misc_swrite(fdSerial, "\r\nERROR: Upload path invalid --> '%s'", uploadPath); - } - else if (memcmp(lineBuf, "ATROWS", 6) == 0) - { - char * strRows = &lineBuf[6]; - if(!misc_is_number(strRows)) - { - for (int i = 50; i > 1; i--) - misc_swrite(fdSerial, "\r\n%2d", i); - } - else - { - TCPTermRows = strtol(strRows, &endPtr, 10); - misc_swrite(fdSerial, "\r\nROWS --> %d", TCPTermRows); - serial_do_tcdrain(fdSerial); - } - } - else if (memcmp(lineBuf, "ATINI", 5) == 0) - { - misc_file_to_serial(fdSerial, midiLinkINI, TCPTermRows); - } - else if (memcmp(lineBuf, "ATDIR", 5) == 0) - { - misc_file_to_serial(fdSerial, midiLinkDIR, TCPTermRows); - } - else if (memcmp(lineBuf, "ATTRANS", 7) == 0) - { - char * validOptions = "\r\nValid options --> 0, 1, 2" - "\r\n-------------------------" - "\r\n0 = NONE" - "\r\n1 = PETSKII (C64)" - "\r\n2 = ATASCII (Atari 8-bit)" - "\r\n-------------------------"; - if(misc_is_number(&lineBuf[7])) - { - int tmpMode = strtol(&lineBuf[7], &endPtr, 10); - if (tmpMode >= 0 && tmpMode <= 2) - TCPAsciiTrans = tmpMode; - else - misc_swrite(fdSerial, validOptions); - } - else if(lineBuf[7] != (char) 0x00) - misc_swrite(fdSerial, validOptions); - misc_swrite(fdSerial, "\r\nASCII translation --> %s", - misc_trans_to_str(TCPAsciiTrans)); - } - else if (memcmp(lineBuf, "ATM", 3) == 0) - { - char * pct = strchr(&lineBuf[3], '%'); - if (pct != NULL) - *pct = (char) 0x00; - if(misc_is_number(&lineBuf[3])) - { - int tmpVol = strtol(&lineBuf[3], &endPtr, 10); - if(pct) - { - if(tmpVol <= 100) - { - modemVolume = tmpVol; - } - else - { - misc_swrite(fdSerial,"\r\nValid options --> 0-100%%"); - } - } - else - switch(tmpVol) - { - case 0: - MODEMSOUND = FALSE; - break; - case 1: - MODEMSOUND = TRUE; - break; - default: - misc_swrite(fdSerial,"\r\nUnsupported option --> '%s'", &lineBuf[3]); - break; - } - } - else - { - if(lineBuf[3] != (char) 0x00) - { - misc_swrite(fdSerial,"\r\nUnsupported option --> '%s'", &lineBuf[3]); - } - } - if(modemVolume != -1 && MODEMSOUND) - misc_swrite(fdSerial, "\r\nModem sounds = %s : volume = %d%%", MODEMSOUND?"ON":"OFF", modemVolume); - else - misc_swrite(fdSerial,"\r\nModem sounds = %s", MODEMSOUND?"ON":"OFF"); - } - else if (memcmp(lineBuf, "ATVER", 5) == 0) - { - misc_swrite(fdSerial, "\r\n"); - misc_swrite(fdSerial, helloStr); - } - else if (memcmp(lineBuf, "ATHELP", 6) == 0) - { - misc_show_at_commands(fdSerial, TCPTermRows); - } - else if (memcmp(lineBuf, "ATUARTTEST", 6) == 0) - { - if (lineBuf[10] == '!') - TCPTermRows = 0; - while (TRUE) - { - misc_show_at_commands(fdSerial, TCPTermRows); - misc_file_to_serial(fdSerial, midiLinkDIR, TCPTermRows); - } - } - else if (memcmp(lineBuf, "ATD", 3) == 0) - { - switch(lineBuf[3]) - { - case '0' : - case '1' : - TCPDTR = 1; - misc_print(1, "Setting DTR mode --> Normal\n"); - break; - case '2' : - TCPDTR = 2; - misc_print(1, "Setting DTR mode --> Hangup\n"); - break; - default: - misc_swrite(fdSerial,"\r\nUnsupported DTR option --> '%s'", &lineBuf[3]); - break; - } - } - else if (memcmp(lineBuf, "ATQ", 3) == 0) - { - switch(lineBuf[3]) - { - case '0' : - TCPQuiet = 0; - misc_print(1, "Setting result code mode --> Verbose\n"); - break; - case '1' : - TCPQuiet = 1; - misc_print(1, "Setting result code mode --> Quiet\n"); - break; - default: - misc_swrite(fdSerial,"\r\nUnsupported result code mode --> '%s'", &lineBuf[3]); - break; - } - } - else if (memcmp(lineBuf, "ATZ", 3) == 0) - { - misc_print(1, "Resetting TCP defaults...\n"); - MODEMSOUND = DEFAULT_MODEMSOUND; - modemVolume = DEFAULT_modemVolume; - TCPAsciiTrans = DEFAULT_TCPAsciiTrans; - TCPTermRows = DEFAULT_TCPTermRows; - TCPFlow = DEFAULT_TCPFlow; - TCPDTR = DEFAULT_TCPDTR; - TCPQuiet = DEFAULT_TCPQuiet; - TELNET_NEGOTIATE = TRUE; - misc_print(1, "Reloading INI defaults...\n"); - misc_get_core_name(tmp, sizeof(tmp)); - if(misc_check_file(midiLinkINI)) - ini_read_ini(midiLinkINI, tmp, 1); - } - else if (memcmp(lineBuf, "AT", 2) == 0) - { - if (lineBuf[2] != (char) 0x00) - { - misc_swrite(fdSerial, "\r\nUnknown Command '%s'", &lineBuf[2]); - misc_print(1, "ERROR : Unknown AT command --> '%s'\n", &lineBuf[2]); - } - } - - return FALSE; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void do_modem_emulation(char * buf, int bufLen) -// -// -void do_modem_emulation(char * buf, int bufLen) -{ - static char lineBuf[150] = ""; - static char iLineBuf = 0; - char * lbp; - - show_debug_buf("SER OUT ", buf, bufLen); - for (char * p = buf; bufLen-- > 0; p++) - { - *p = toupper(*p); - switch(*p) - { - case ' ': // [SPACE] no space - break; - case 0x08: // [DELETE] - case 0x14: // [PETSKII DELETE] - case 0xf8: // [BACKSPACE] - if (iLineBuf > 0) - { - lineBuf[--iLineBuf] = 0x00; - write(fdSerial, p, 1); - } - break; - case 0x0D: // [RETURN] - lbp = lineBuf; - int CONNECT = FALSE; - if(iLineBuf > 1 && lineBuf[0] == 'A' && lineBuf[1] == 'T') - { - while (lbp && !CONNECT) - { - char * amp = strchr(lbp, '&'); - if(amp) - *amp = 0x00; - CONNECT = handle_at_command(lbp); - if(amp) - { - lbp = amp-1; - lbp[0] = 'A'; - lbp[1] = 'T'; - } - else - lbp = NULL; - } - if (!CONNECT && TCPQuiet == 0) - misc_swrite_no_trans(fdSerial, "\r\nOK\r\n"); - } - else - misc_swrite(fdSerial, "\r\n"); - iLineBuf = 0; - lineBuf[iLineBuf] = 0x00; - break; - default: - if (iLineBuf < 80) - { - lineBuf[iLineBuf++] = *p; - write(fdSerial, p, 1); - lineBuf[iLineBuf] = 0x00; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * midi_thread_function(void * x) -// Thread function for /dev/midi input -// -void * midi_thread_function (void * x) -{ - unsigned char buf [100]; - int rdLen; - do - { - rdLen = read(fdMidi, &buf, sizeof(buf)); - if (rdLen > 0) - { - write(fdSerial, buf, rdLen); - show_debug_buf("MIDI IN ", buf, rdLen); - } - else - { - misc_print(1, "ERROR: midi_thread_function() reading %s --> %d : %s \n", midiDevice, rdLen, strerror(errno)); - } - } while (TRUE); -} - -/////////////////////////////////////////////////////////////////////////////////////// -// -// void * serial_thread_function(void * x) -// Thread function for /dev/ttyUSB input -// -void * serial_thread_function (void * x) -{ - unsigned char buf [100]; - int rdLen; - do - { - rdLen = read(fdSerialUSB, &buf, sizeof(buf)); - if (rdLen > 0) - { - write(fdSerial, buf, rdLen); - show_debug_buf("SERIAL IN ", buf, rdLen); - } - else - { - misc_print(1, "ERROR: serial_thread_function() reading %s --> %d : %s \n", serialDeviceUSB, rdLen, strerror(errno)); - } - } while (TRUE); -} - /////////////////////////////////////////////////////////////////////////////////////// // // write_midi_packet() @@ -1253,12 +244,87 @@ void write_midi_packet(char * buf, int bufLen) /////////////////////////////////////////////////////////////////////////////////////// // -// test_midi_device() -// Play a test note : this is for /dev/midi +// write_socket_packet() +// this is for TCP/IP // -void test_midi_device() +void write_socket_packet(int sock, char * buf, int bufLen) { - write_midi_packet(test_note, sizeof(test_note)); + if (mode == ModeTCP) + { + if(tcpsock_write(sock, buf, bufLen) < 1) + { + close(socket_out); + //tcpsock_close(socket_out); + socket_out = -1; + } + } + else + udpsock_write(sock, buf, bufLen); + + show_debug_buf("SOCK OUT ", buf, bufLen); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void * udpsock_thread_function(void * x) +// Thread function for UDP input +// +void * udpsock_thread_function (void * x) +{ + unsigned char buf[100]; + int rdLen; + do + { + rdLen = udpsock_read(socket_in, (char *) buf, sizeof(buf)); + if (rdLen > 0) + { + write(fdSerial, buf, rdLen); + show_debug_buf("USOCK IN ", buf, rdLen); + } + } while (TRUE); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void * udpsock_thread_function_ext(void * x) +// Thread function for UDP input for external device like Raspberry Pi +// +void * udpsock_thread_function_ext (void * x) +{ + unsigned char buf[100]; + int rdLen; + do + { + rdLen = udpsock_read(socket_in, (char *) buf, sizeof(buf)); + if (rdLen > 0) + { + write_alsa_packet(buf, rdLen); + } + } while (TRUE); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void * midi_thread_function(void * x) +// Thread function for /dev/midi input +// +void * midi_thread_function (void * x) +{ + unsigned char buf [100]; + int rdLen; + do + { + rdLen = read(fdMidi, &buf, sizeof(buf)); + if (rdLen > 0) + { + write(fdSerial, buf, rdLen); + show_debug_buf("MIDI IN ", buf, rdLen); + } + else + { + misc_print(1, "ERROR: midi_thread_function() reading %s --> %d : %s \n", midiDevice, rdLen, strerror(errno)); + } + } while (TRUE); } /////////////////////////////////////////////////////////////////////////////////////// @@ -1294,24 +360,36 @@ void * midiINin_thread_function (void * x) /////////////////////////////////////////////////////////////////////////////////////// // -// write_socket_packet() -// this is for TCP/IP +// void * serial_thread_function(void * x) +// Thread function for /dev/ttyUSB input // -void write_socket_packet(int sock, char * buf, int bufLen) +void * serial_thread_function (void * x) { - if (mode == ModeTCP) + unsigned char buf [100]; + int rdLen; + do { - if(tcpsock_write(sock, buf, bufLen) < 1) + rdLen = read(fdSerialUSB, &buf, sizeof(buf)); + if (rdLen > 0) { - close(socket_out); - //tcpsock_close(socket_out); - socket_out = -1; + write(fdSerial, buf, rdLen); + show_debug_buf("SERIAL IN ", buf, rdLen); } - } - else - udpsock_write(sock, buf, bufLen); + else + { + misc_print(1, "ERROR: serial_thread_function() reading %s --> %d : %s \n", serialDeviceUSB, rdLen, strerror(errno)); + } + } while (TRUE); +} - show_debug_buf("SOCK OUT ", buf, bufLen); +/////////////////////////////////////////////////////////////////////////////////////// +// +// test_midi_device() +// Play a test note : this is for /dev/midi +// +void test_midi_device() +{ + write_midi_packet(test_note, sizeof(test_note)); } /////////////////////////////////////////////////////////////////////////////////////// @@ -1352,8 +430,9 @@ void close_fd() void signal_handler(int signum, siginfo_t *info, void *ptr) { //write(STDERR_FILENO, SIGTERM_MSG, sizeof(SIGTERM_MSG)); - killall_mpg123(0); - killall_aplaymidi(0); + modem_killall_mpg123(0); + modem_killall_aplaymidi(0); + modem_killall_aplay(0); killall_softsynth(0); close_fd(); } @@ -1389,6 +468,7 @@ int main(int argc, char *argv[]) misc_print(0, "\e[2J\e[H"); misc_print(0, helloStr); misc_print(0, "\n"); + misc_get_core_name(coreName, sizeof(coreName)); misc_print(0, "CORE --> '%s'\n", coreName); @@ -1443,8 +523,8 @@ int main(int argc, char *argv[]) if(misc_check_args_option(argc, argv, "UDPFSYNTH")) mode = ModeUDPFSYNTH; } - killall_mpg123(0); - killall_aplaymidi(0); + modem_killall_mpg123(0); + modem_killall_aplaymidi(0); killall_softsynth(3); if (mode == ModeMUNT || mode == ModeMUNTGM || mode == ModeFSYNTH || @@ -1597,7 +677,7 @@ int main(int argc, char *argv[]) if(socket_in > 0) { misc_print(0, "Socket Listener created on port %d.\n", UDPServerPort); - status = pthread_create(&socketInThread, NULL, udpsock_thread_function2, NULL); + status = pthread_create(&socketInThread, NULL, udpsock_thread_function_ext, NULL); if (status == -1) { misc_print(0, "ERROR: unable to create UDP socket input thread.\n"); @@ -1668,6 +748,7 @@ int main(int argc, char *argv[]) break; case ModeTCP: { + modem_set_defaults(); if(TCPFlow > 0) serial_set_flow_control(fdSerial, TCPFlow); //serial2_set_DCD(sericlDevice, fdSerial, FALSE); @@ -1675,7 +756,7 @@ int main(int argc, char *argv[]) socket_lst = tcpsock_server_open(TCPServerPort); if(socket_lst != -1) { - status = pthread_create(&socketLstThread, NULL, tcplst_thread_function, NULL); + status = pthread_create(&socketLstThread, NULL, modem_tcplst_thread_function, NULL); if (status == -1) { misc_print(0, "ERROR: unable to create socket listener thread.\n"); @@ -1796,7 +877,7 @@ int main(int argc, char *argv[]) { case ModeUSBMIDI: misc_print(1, "Sending MIDI --> all-notes-off\n"); - write_midi_packet(all_notes_off, sizeof(all_notes_off)); + write_midi_packet(all_notes_off, sizeof_all_notes_off); if(strlen(MT32LCDMsg) > 0) { misc_print(1, "Sending MT-32 LCD --> '%s'\n", MT32LCDMsg); @@ -1842,7 +923,7 @@ int main(int argc, char *argv[]) if (socket_out != -1 && baudRate == 31250) { misc_print(1, "Sending UDP --> all-notes-off\n"); - write_socket_packet(socket_out, all_notes_off, sizeof(all_notes_off)); + write_socket_packet(socket_out, all_notes_off, sizeof_all_notes_off); if(strlen(MT32LCDMsg) > 0) { misc_print(1, "Sending UDP MT-32 LCD --> '%s'\n", MT32LCDMsg); @@ -1873,18 +954,18 @@ int main(int argc, char *argv[]) { if(socket_in != -1) { - do_check_modem_hangup(&socket_in, buf, rdLen); + modem_do_check_hangup(&socket_in, buf, rdLen); if(socket_in != -1) write_socket_packet(socket_in, buf, rdLen); } if(socket_out != -1) { - do_check_modem_hangup(&socket_out, buf, rdLen); + modem_do_check_hangup(&socket_out, buf, rdLen); if(socket_out != -1) write_socket_packet(socket_out, buf, rdLen); } else if (socket_in == -1) - do_modem_emulation(buf, rdLen); + modem_do_emulation(buf, rdLen); } else if (TCPDTR == 2 && rdLen == 0 && serial2_get_DSR(fdSerial) == FALSE) @@ -1907,4 +988,4 @@ int main(int argc, char *argv[]) } close_fd(); return 0; -} \ No newline at end of file +} diff --git a/midilink b/midilink index aad37f6..9463b36 100755 Binary files a/midilink and b/midilink differ diff --git a/misc.c b/misc.c index 601c8b9..9780282 100644 --- a/misc.c +++ b/misc.c @@ -34,45 +34,6 @@ static pthread_mutex_t swrite_lock; extern int MIDI_DEBUG; extern enum ASCIITRANS TCPAsciiTrans; -static char * athelp[] = -{ - "AT - Attention", - "ATBAUD# - Set baud rate", - "ATBAUD - Show baud rate menu", - "ATDIR - Show dialing MidiLink.DIR", - "ATDT - Dial 'ATDT192.168.1.131:23'", - "ATHELP - Show valid AT Comamnds", - "ATINI - Show MidiLink.INI", - "ATIP - Show IP address", - "ATMID1 - Switch synth to FluidSynth", - "ATMID2 - Switch synth to MUNT", - "ATMID - Play MIDI file", - "ATMIDSF - Select FluidSynth SoundFont", - "ATMID! - Stop currently playing MIDI", - "ATM0 - Disable modem sounds", - "ATM1 - Enable modem sounds", - "ATM###%% - Set modem volume [0-100%%]", - "ATMP3 - Play MP3 file", - "ATMP3! - Stop playing MP3 File", - "ATROWS - Do terminal row test", - "ATROWS## - Set number of terminal rows", - "ATRZ - Receive a file using Zmodem", - "ATSZ - Send a file via Zmodem", - "ATTEL0 - Disable telnet negotiation", - "ATTEL1 - Enable telnet negotiation", - "ATTRANS# - Set ASCII translation", - "ATQ0 - Verbose result codes", - "ATQ1 - Suppress result codes", - "ATVER - Show MidiLink version", - "ATZ - Reset modem", - "AT&D0 - DTR mode normal", - "AT&D2 - DTR drop causes hangup", - "AT&K0 - Disable flow control", - "AT&K3 - RTS/CTS flow control", - "AT&K4 - XON/XOFF flow control", - "+++ATH - Hang-up", - NULL -}; /////////////////////////////////////////////////////////////////////////////////////// // @@ -434,6 +395,7 @@ int misc_check_module_loaded (char * modName) } } +/* /////////////////////////////////////////////////////////////////////////////////////// // // int misc_get_midi_port(char * descr) @@ -477,6 +439,7 @@ int misc_get_midi_port(char * descr) return FALSE; } } +*/ /////////////////////////////////////////////////////////////////////////////////////// // @@ -842,27 +805,6 @@ void misc_do_rowcheck(int fdSerial, int rows, int * rowcount, char * c) } } -/////////////////////////////////////////////////////////////////////////////////////// -// -// void misc_show_at_commands(int fdSerial, int rows) -// -void misc_show_at_commands(int fdSerial, int rows) -{ - int index = 0; - int rowcount = 0; - char c = (char) 0x00; - - while(athelp[index] != NULL && c != 'Q') - { - misc_swrite(fdSerial, "\r"); - if (rowcount != 0 || index == 0) //rowcount not reset - misc_swrite(fdSerial, "\n"); - misc_swrite(fdSerial, athelp[index]); - index++; - misc_do_rowcheck(fdSerial, rows, &rowcount, &c); - } -} - /////////////////////////////////////////////////////////////////////////////////////// // // BOOL misc_do_pipe2(int fdSerial, char * command) @@ -993,3 +935,5 @@ char * misc_hayes_ATQ_to_str(int dtr) } } + + diff --git a/misc.h b/misc.h index 3f27750..0118513 100644 --- a/misc.h +++ b/misc.h @@ -1,45 +1,43 @@ -enum SOFTSYNTH { MUNT, FluidSynth}; +enum SOFTSYNTH { MUNT, FluidSynth}; enum ASCIITRANS { AsciiNoTrans, AsciiToPetskii, AsciiToAtascii}; -int misc_check_args_option (int argc, char *argv[], char * option); +int misc_check_args_option (int argc, char *argv[], char * option); char * misc_trans_to_str(enum ASCIITRANS mode); -int misc_str_to_trans(char * str); -void misc_str_to_upper(char *str); -int misc_check_file (char * fileName); -int misc_check_device (char * deviceName); -int misc_set_priority(int priority); -int misc_ipaddr_is_multicast(char * ipAddr); -void misc_print(int priority, const char* format, ... ); -void misc_swrite(int fdSerial, const char* format, ... ); -void misc_swrite_no_trans(int fdSerial, const char* format, ... ); -int misc_is_ip_addr(char *ipAddr); -int misc_hostname_to_ip(char * hostname , char* ipAddr); -int misc_get_ipaddr(char * interface, char * buf); -int misc_is_number(char *testStr); -void misc_show_atdt(int fdSerial); -void misc_show_atip(int fdSerial); -long misc_get_timeval_diff(struct timeval * start, struct timeval * stop); -int misc_check_module_loaded (char * modName); -int misc_get_midi_port(char * descr); -int misc_list_files(char * path, int fdSerial, int rows, char * fileName, int * DIR); -void misc_d_type_to_str(unsigned char type, char * buf); -int misc_file_to_serial(int fdSerial, char * fileName, int rows); -int misc_count_str_chr(char * str, char chr); -int misc_MT32_LCD(char * MT32Message, char * buf); -void misc_show_at_commands(int fdSerial, int rows); -void misc_do_rowcheck(int fdSerial, int rows, int * rowcount, char * c); -int misc_get_core_name(char * buf, int maxBuf); -char misc_replace_char(char * str, int strLen, char old, char new); -int misc_do_pipe(int fdSerial, char * path, char * command, - char * arg1, - char * arg2, - char * arg3, - char * arg4, - char * arg5); +int misc_str_to_trans(char * str); +void misc_str_to_upper(char *str); +int misc_check_file (char * fileName); +int misc_check_device (char * deviceName); +int misc_set_priority(int priority); +int misc_ipaddr_is_multicast(char * ipAddr); +void misc_print(int priority, const char* format, ... ); +void misc_swrite(int fdSerial, const char* format, ... ); +void misc_swrite_no_trans(int fdSerial, const char* format, ... ); +int misc_is_ip_addr(char *ipAddr); +int misc_hostname_to_ip(char * hostname , char* ipAddr); +int misc_get_ipaddr(char * interface, char * buf); +int misc_is_number(char *testStr); +void misc_show_atdt(int fdSerial); +void misc_show_atip(int fdSerial); +long misc_get_timeval_diff(struct timeval * start, struct timeval * stop); +int misc_check_module_loaded (char * modName); +int misc_list_files(char * path, int fdSerial, int rows, char * fileName, int * DIR); +void misc_d_type_to_str(unsigned char type, char * buf); +int misc_file_to_serial(int fdSerial, char * fileName, int rows); +int misc_count_str_chr(char * str, char chr); +int misc_MT32_LCD(char * MT32Message, char * buf); +void misc_do_rowcheck(int fdSerial, int rows, int * rowcount, char * c); +int misc_get_core_name(char * buf, int maxBuf); +char misc_replace_char(char * str, int strLen, char old, char new); +int misc_do_pipe(int fdSerial, char * path, char * command, + char * arg1, + char * arg2, + char * arg3, + char * arg4, + char * arg5); char * misc_hayes_flow_to_str(int flow); char * misc_hayes_DTR_to_str(int dtr); char * misc_hayes_ATQ_to_str(int dtr); char * misc_get_clrScr(); - +//int misc_get_midi_port(char * descr); #define TRUE 1 #define FALSE 0 diff --git a/mlinkutil b/mlinkutil index 244e02f..4c8fcff 100755 Binary files a/mlinkutil and b/mlinkutil differ diff --git a/modem.c b/modem.c new file mode 100644 index 0000000..d580640 --- /dev/null +++ b/modem.c @@ -0,0 +1,1039 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" +#include "tcpsock.h" +#include "modem_snd.h" +#include "alsa.h" +#include "ini.h" +#include "serial.h" +#include "serial2.h" +#include "directory.h" + +#define DEFAULT_MODEMSOUND TRUE +#define DEFAULT_modemVolume -1 +#define DEFAULT_TCPAsciiTrans AsciiNoTrans +#define DEFAULT_TCPTermRows 22 +#define DEFAULT_TCPFlow -1 +#define DEFAULT_TCPDTR 1 +#define DEFAULT_TCPQuiet 0 + +enum SOFTSYNTH TCPSoftSynth = FluidSynth; +enum ASCIITRANS TCPAsciiTrans = DEFAULT_TCPAsciiTrans; +char MP3Path[500] = "/media/fat/MP3"; +char MIDIPath[500] = "/media/fat/MIDI"; +char downloadPath[500] = "/media/fat"; +char uploadPath[100] = "/media/fat/UPLOAD"; +char modemConnectSndWAV[50] = ""; +char modemDialSndWAV[50] = ""; +char modemRingSndWAV[50] = ""; +int TCPATHDelay = 900; +int MP3Volume = -1; +unsigned int TCPTermRows = DEFAULT_TCPTermRows; +int modemVolume = DEFAULT_modemVolume; +int TCPQuiet = DEFAULT_TCPQuiet; +int MODEMSOUND = DEFAULT_MODEMSOUND; + +extern int MIDI_DEBUG; +extern int CPUMASK; +extern int MODEMSOUND; +extern int socket_in; +extern int socket_out; +extern int socket_lst; +extern int fdSerial; +extern int baudRate; +extern int TCPQuiet; +extern int modemVolume; +extern int sizeof_all_notes_off; +extern int TCPDTR; +extern int TCPFlow; +extern char all_notes_off[]; +extern char * midiLinkINI; +extern char * midiLinkDIR; +extern char * PCMDevice; +extern char * serialDevice; +extern char * helloStr; +extern char fsynthSoundFont[]; + +static pthread_t socketInThread; + +int start_munt(); +int start_fsynth(); +void show_debug_buf(char * descr, char * buf, int bufLen); +void killall_softsynth(int delay); +void set_pcm_volume(int value); + +static char * athelp[] = +{ + "AT - Attention", + "ATBAUD# - Set baud rate", + "ATBAUD - Show baud rate menu", + "ATDIR - Show dialing MidiLink.DIR", + "ATDT - Dial 'ATDT192.168.1.131:23'", + "ATHELP - Show valid AT Comamnds", + "ATINI - Show MidiLink.INI", + "ATIP - Show IP address", + "ATMID1 - Switch synth to FluidSynth", + "ATMID2 - Switch synth to MUNT", + "ATMID - Play MIDI file", + "ATMIDSF - Select FluidSynth SoundFont", + "ATMID! - Stop currently playing MIDI", + "ATM0 - Disable modem sounds", + "ATM1 - Enable modem sounds", + "ATM###%% - Set modem volume [0-100%%]", + "ATMP3 - Play MP3 file", + "ATMP3! - Stop playing MP3 File", + "ATROWS - Do terminal row test", + "ATROWS## - Set number of terminal rows", + "ATRZ - Receive a file using Zmodem", + "ATSZ - Send a file via Zmodem", + "ATTEL0 - Disable telnet negotiation", + "ATTEL1 - Enable telnet negotiation", + "ATTRANS# - Set ASCII translation", + "ATQ0 - Verbose result codes", + "ATQ1 - Suppress result codes", + "ATVER - Show MidiLink version", + "ATZ - Reset modem", + "AT&D0 - DTR mode normal", + "AT&D2 - DTR drop causes hangup", + "AT&K0 - Disable flow control", + "AT&K3 - RTS/CTS flow control", + "AT&K4 - XON/XOFF flow control", + "+++ATH - Hang-up", + NULL +}; + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_show_at_commands(int fdSerial, int rows) +// +void modem_show_at_commands(int fdSerial, int rows) +{ + int index = 0; + int rowcount = 0; + char c = (char) 0x00; + + while(athelp[index] != NULL && c != 'Q') + { + misc_swrite(fdSerial, "\r"); + if (rowcount != 0 || index == 0) //rowcount not reset + misc_swrite(fdSerial, "\n"); + misc_swrite(fdSerial, athelp[index]); + index++; + misc_do_rowcheck(fdSerial, rows, &rowcount, &c); + } +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_killall_mpg123() +// +void modem_killall_mpg123(int delay) +{ + misc_print(0, "Killing --> mpg123\n"); + system("killall -q mpg123"); + if(delay) + sleep(delay); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_killall_aplaymidi() +// +void modem_killall_aplaymidi(int delay) +{ + misc_print(0, "Killing --> aplaymidi\n"); + system("killall -q aplaymidi"); + if(delay) + sleep(delay); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_killall_aplay() +// +void modem_killall_aplay(int delay) +{ + misc_print(0, "Killing --> aplay\n"); + system("killall -q aplay"); + if(delay) + sleep(delay); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// int modem_get_softsynth_port(int softSynth) +// +// +int modem_get_softsynth_port(int softSynth) +{ + int midiPort = alsa_get_midi_port("MT-32"); + if (midiPort == -1) + midiPort = alsa_get_midi_port("FLUID Synth"); + if (midiPort == -1) + { + switch(softSynth) + { + case MUNT: + midiPort = start_munt(); + break; + case FluidSynth: + midiPort = start_fsynth(); + break; + case -1: //do nothing. + break; + } + } + return midiPort; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_play_conenct_sound(char * tmp) +// +// +void modem_play_connect_sound(char * tmp) +{ + if (MODEMSOUND) + { + modem_killall_aplaymidi(0); + killall_softsynth(0); + modem_killall_mpg123(0); + modem_killall_aplay(0); + if(strlen(modemConnectSndWAV) > 0 && misc_check_file(modemConnectSndWAV)) + { + misc_print(1, "Playing WAV --> '%s'\n", modemConnectSndWAV); + sprintf(tmp, "aplay %s", modemConnectSndWAV); + system(tmp); + } + else + modem_snd("C"); + } +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void play_conenct_sound(char * tmp) +// +// +void modem_play_ring_sound(char * tmp) +{ + if (MODEMSOUND) + { + modem_killall_aplaymidi(0); + killall_softsynth(0); + modem_killall_mpg123(0); + modem_killall_aplay(0); + if(strlen(modemRingSndWAV) > 0 && misc_check_file(modemRingSndWAV)) + { + misc_print(1, "Playing WAV --> '%s'\n", modemRingSndWAV); + sprintf(tmp, "aplay %s", modemRingSndWAV); + system(tmp); + } + else + modem_snd("R"); + } +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_play_dial_sound(char * tmp, char * ipAddr) +// +// +void modem_play_dial_sound(char * tmp, char * ipAddr) +{ + if (MODEMSOUND) + { + modem_killall_aplaymidi(0); + killall_softsynth(0); + modem_killall_mpg123(0); + modem_killall_aplay(0); + if (strlen(modemDialSndWAV) > 0 && misc_check_file(modemDialSndWAV)) + { + misc_print(1, "Playing WAV --> '%s'\n", modemDialSndWAV); + sprintf(tmp, "aplay %s", modemDialSndWAV); + system(tmp); + } + else + modem_snd(ipAddr); + } +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void * modem_socket_thread_function(void * x) +// Thread function for TCP input +// +void * modem_tcpsock_thread_function (void * x) +{ + unsigned char buf[100]; + int rdLen; + do + { + rdLen = tcpsock_read(socket_out, (char *) buf, sizeof(buf)); + if (rdLen > 0) + { + write(fdSerial, buf, rdLen); + show_debug_buf("TSOCK IN ", buf, rdLen); + } + else if(rdLen < 1) + misc_print(1, "ERROR: tcpsock_thread_function() --> rdLen < 1\n"); + } while (rdLen > 0 && socket_out != -1); + if(socket_out != -1) + close(socket_out); + socket_out = -1; + if(MIDI_DEBUG) + misc_print(1, "TCPSOCK Thread fuction exiting.\n", socket_out); + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nNO CARRIER\r\n"); + pthread_exit(NULL); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void * modem_tcplst_thread_function(void * x) +// Thread function for TCP Listener input +// +void * modem_tcplst_thread_function (void * x) +{ + unsigned char buf[100]; + int rdLen; + + do + { + socket_in = tcpsock_accept(socket_lst); + if(socket_in != -1) + { + tcpsock_set_tcp_nodelay(socket_in); + tcpsock_set_timeout(socket_in, 10); + misc_print(1,"Incomming connection\n"); + tcpsock_get_ip(socket_in, buf); + misc_print(1, "CONNECT --> %s\n", buf); + if(socket_out == -1) + { + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nRING"); + if(MODEMSOUND) + set_pcm_volume(modemVolume); + modem_play_ring_sound(buf); + modem_play_connect_sound(buf); + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nCONNECT %d\r\n", baudRate); + serial2_set_DCD(serialDevice, fdSerial, TRUE); + do + { + rdLen = read(socket_in, buf, sizeof(buf)); + if (rdLen > 0) + { + write(fdSerial, buf, rdLen); + show_debug_buf("TSERV IN", buf, rdLen); + } + else if (rdLen == 0) + { + if(socket_in != -1) + close(socket_in); + socket_in = -1; + misc_print(1, "tcplst_thread_function() --> Connection Closed.\n"); + } + } while (socket_in != -1); + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nNO CARRIER\r\n"); + serial2_set_DCD(serialDevice, fdSerial, FALSE); + } + else + { + char busyStr[] = "\r\nBUSY"; + misc_print(1, "Sending BUSY message and disconnecting.,\n"); + tcpsock_write(socket_in, busyStr, strlen(busyStr)); + sleep(2); + tcpsock_close(socket_in); + socket_in = -1; + } + } + else + { + sleep(5); + } + + } while(TRUE); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_set_defaults() +// +// +void modem_set_defaults() +{ + MODEMSOUND = DEFAULT_MODEMSOUND; + modemVolume = DEFAULT_modemVolume; + TCPAsciiTrans = DEFAULT_TCPAsciiTrans; + TCPTermRows = DEFAULT_TCPTermRows; + TCPFlow = DEFAULT_TCPFlow; + TCPDTR = DEFAULT_TCPDTR; + TCPQuiet = DEFAULT_TCPQuiet; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_do_check_hangup(char * buf, int bufLen) +// +// +void modem_do_check_hangup(int * socket, char * buf, int bufLen) +{ + static char lineBuf[6]; + static char iLineBuf = 0; + static int plusCount = 0; + static int NEEDSTOP = FALSE; + static struct timeval start; + static struct timeval stop; + char tmp[100] = ""; + + for (char * p = buf; bufLen-- > 0; p++) + { + switch(*p) + { + case '+': // RESET + gettimeofday(&start, NULL); + iLineBuf = 0; + lineBuf[iLineBuf] = 0x00; + plusCount++; + NEEDSTOP = TRUE; + break; + case 0x0D:// [RETURN] + if(plusCount >= 3 && iLineBuf >= 3 && memcmp(lineBuf, "ATH", 3) == 0) + { + int delay = misc_get_timeval_diff(&start, &stop); + if(TCPATHDelay == 0 || delay > TCPATHDelay) + { + tcpsock_close(*socket); + *socket = -1; + serial2_set_DCD(serialDevice, fdSerial, FALSE); + sprintf(tmp, "\r\nHANG-UP DETECTED\r\n"); + misc_print(1, "HANG-UP Detected --> %d\n", delay); + misc_swrite(fdSerial, tmp); + sleep(1); + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "OK\r\n"); + } + else + misc_print(1, "HANG-UP Rejected --> %d\n", delay); + } + iLineBuf = 0; + lineBuf[iLineBuf] = 0x00; + plusCount = 0; + break; + default: + if (plusCount >= 3 && iLineBuf < sizeof(lineBuf)-1) + { + if (NEEDSTOP) + { + gettimeofday(&stop, NULL); + NEEDSTOP = FALSE; + } + lineBuf[iLineBuf++] = *p; + lineBuf[iLineBuf] = 0x00; + } + else + plusCount = 0; + break; + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void do_telnet_negotiate() +// +// +#define DO 0xfd +#define WONT 0xfc +#define WILL 0xfb +#define DONT 0xfe +#define CMD 0xff +#define CMD_ECHO 1 +#define CMD_WINDOW_SIZE 31 + +void modem_do_telnet_negotiate() +{ + char buf[3]; + int rdLen1; + int rdLen2; + int rdLen3; + int wrLen = 0; + unsigned char msg1[] = {0xff, 0xfb, 0x1f}; + unsigned char msg2[] = {0xff, 0xfa, 0x1f, 0x00, 0x50, 0x00, 0x18, 0xff, 0xf0}; + + tcpsock_set_timeout(socket_out, 3); + misc_print(1, "Telnet negotiation --> START\n"); + do + { + rdLen1 = tcpsock_read(socket_out, &buf[0], 1); + if (rdLen1 == 1 && buf[0] == CMD) + { + //misc_print(1, "Telnet negotiation --> CMD\n"); + rdLen2 = tcpsock_read(socket_out, &buf[1], 1); + rdLen3 = tcpsock_read(socket_out, &buf[2], 1); + if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) + { + //misc_print(1, "Telnet negotiation --> N1\n"); + wrLen = tcpsock_write(socket_out, msg1, sizeof(msg1)); + if (wrLen < 0) goto end; + wrLen = tcpsock_write(socket_out, msg2, sizeof(msg2)); + if (wrLen < 0) goto end; + } + else + { + //misc_print(1, "Telnet negotiation --> N2\n"); + for (int i = 0; i < sizeof(buf); i++) + { + if (buf[i] == DO) + buf[i] = WONT; + else if (buf[i] == WILL) + buf[i] = DO; + } + wrLen = tcpsock_write(socket_out, buf, sizeof(buf)); + if (wrLen < 0) goto end; + buf[0] = CMD; + } + } + else if(rdLen1 = 1) + write(fdSerial, &buf[0], 1); + } while (buf[0] == CMD && rdLen1 == 1); +end: + misc_print(1, "Telnet negotiation --> END\n"); + if (wrLen < 0) + { + misc_print(0, "ERROR: Telnet negotiation failed\n"); + } + tcpsock_set_timeout(socket_out, 0); +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// BOOL do_file_picker(char * pathBuf, char * resultBuf) +// +// +int do_file_picker(char * pathBuf, char * fileNameBuf) +{ + int DIR = 0; + int result; + char * endPtr; + do + { + result = misc_list_files(pathBuf, fdSerial, TCPTermRows, fileNameBuf, &DIR); + if(result) + if (DIR) + { + if(strcmp(fileNameBuf, ".") == 0 || + strcmp(fileNameBuf, "..") == 0) + { + endPtr = strrchr(pathBuf, '/'); + if (endPtr != NULL && strlen(pathBuf) > 1) + *endPtr = (char) 0x00; + } + else + { + strcat(pathBuf, "/"); + strcat(pathBuf, fileNameBuf); + } + } + else + { + misc_swrite(fdSerial, "Selected file --> "); + misc_swrite(fdSerial, fileNameBuf); + } + } while (result && DIR); + return result; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// BOOL modem_handle_at_command(char * lineBuf) +// +// +#define KILL_MP3_SLEEP if(MP3){modem_killall_mpg123(1);MP3 = FALSE;} +int modem_handle_at_command(char * lineBuf) +{ + static int TELNET_NEGOTIATE = TRUE; + static int MP3 = FALSE; + char tmp[1024] = ""; + char * endPtr; + char fileName [256]; + char audioError[] = "\r\nBad news, you have no audio device :( --> %s"; + + if(memcmp(lineBuf, "ATDT", 4) == 0) + { + char * ipAddr = &lineBuf[4]; + if(ipAddr[0] != (char) 0x00) + directory_search(midiLinkDIR, ipAddr, ipAddr); + char * prtSep = strchr(ipAddr, ':'); + if(prtSep == NULL) + prtSep = strchr(ipAddr, '*'); // with NCOMM? + char * port = (prtSep == NULL)?NULL:(prtSep + 1); + if (prtSep != NULL) *prtSep = 0x00; + if (strlen(ipAddr) < 3) + misc_show_atdt(fdSerial); + else + { + int ipError = FALSE; + int iPort = (port == NULL)?23:strtol(port, &endPtr, 10); + if (!misc_is_ip_addr(ipAddr)) + { + char domainName[30]; + getdomainname(domainName, sizeof(domainName)); + if(strcmp(domainName, "(none)") != 0 && misc_count_str_chr(ipAddr, '.') < 1) + { + strcat(ipAddr, "."); + strcat(ipAddr, domainName); + misc_print(1, "Doing domain name fix --> %s\n", ipAddr); + } + if(!misc_hostname_to_ip(ipAddr, ipAddr)) + { + misc_swrite(fdSerial, "\r\nERROR: Unable to convert hostname '%s' to IP address.", ipAddr); + ipError = TRUE; + } + } + if(!ipError) + { + misc_swrite(fdSerial, "\r\nDIALING %s:%d\r\n", ipAddr, iPort); + serial_do_tcdrain(fdSerial); + if(MODEMSOUND) + set_pcm_volume(modemVolume); + modem_play_dial_sound(tmp, ipAddr); + serial_do_tcdrain(fdSerial); + if(MODEMSOUND) + sleep(1); + serial2_set_DCD(serialDevice, fdSerial, FALSE); + socket_out = tcpsock_client_connect(ipAddr, iPort, fdSerial); + } + if(socket_out > 0) + { + if (TELNET_NEGOTIATE) + modem_do_telnet_negotiate(); + modem_play_ring_sound(tmp); + modem_play_connect_sound(tmp); + if(TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nCONNECT %d\r\n", baudRate); + serial_do_tcdrain(fdSerial); + sleep(1); + int status = pthread_create(&socketInThread, NULL, modem_tcpsock_thread_function, NULL); + serial2_set_DCD(serialDevice, fdSerial, TRUE); + return TRUE; + } + } + } + else if (memcmp(lineBuf, "ATBAUD", 6) == 0) + { + char * baud = &lineBuf[6]; + int iBaud = strtol(baud, &endPtr, 10); + int iTemp = serial2_baud_at_index(iBaud); + iBaud = (misc_is_number(baud) && iTemp > 0)?iTemp:iBaud; + if (serial2_is_valid_rate (iBaud)) + { + int sec = 10; + misc_swrite(fdSerial, "\r\nSetting BAUD to %d in %d seconds...", iBaud, sec); + sleep(sec); + serial2_set_baud(serialDevice, fdSerial, iBaud); + baudRate = iBaud; + misc_swrite(fdSerial, "\r\nBAUD has been set to %d", iBaud); + } + else + { + if(baud[0] != 0x00) + misc_swrite(fdSerial, "\r\nBAUD rate '%s' is not valid.", baud); + serial2_show_menu(fdSerial); + } + } + else if (memcmp(lineBuf, "ATIP", 4) == 0) + { + misc_show_atip(fdSerial); + } + else if (memcmp(lineBuf, "ATK", 3) == 0) + { + char * hayesMode = &lineBuf[3]; + if(misc_is_number(hayesMode)) + { + int iHayesMode = strtol(hayesMode, &endPtr, 10); + serial_set_flow_control(fdSerial, iHayesMode); + } + else + serial_set_flow_control(fdSerial, -1); + } + else if (memcmp(lineBuf, "ATTEL", 5) == 0) + { + if (lineBuf[5] == '0') + TELNET_NEGOTIATE = FALSE; + else if (lineBuf[5] == '1') + TELNET_NEGOTIATE = TRUE; + misc_swrite(fdSerial, "\r\nTelnet Negotiations --> %s", TELNET_NEGOTIATE?"TRUE":"FALSE"); + } + else if (memcmp(lineBuf, "ATMP3", 5) == 0) + { + if (misc_check_device(PCMDevice)) + { + if(lineBuf[5] == '!') + { + misc_swrite(fdSerial, "\r\nMP3 --> OFF"); + modem_killall_mpg123(0); + } + else if(do_file_picker(MP3Path, fileName)) + { + chdir("/root"); + set_pcm_volume(MP3Volume); + sprintf(tmp, "taskset %d mpg123 -o alsa \"%s/%s\" 2> /tmp/mpg123 & ", CPUMASK, MP3Path, fileName); + if(!MP3) + { + modem_killall_aplaymidi(0); + killall_softsynth(3); + } + modem_killall_mpg123(0); + misc_print(1, "Play MP3 --> %s\n", tmp); + system(tmp); + misc_swrite(fdSerial, "\r\n"); + sleep(1); + misc_file_to_serial(fdSerial, "/tmp/mpg123", TCPTermRows); + MP3 = TRUE; + } + } + else + misc_swrite(fdSerial, audioError, PCMDevice); + } + else if (memcmp(lineBuf, "ATMID", 5) == 0) + { + if (misc_check_device(PCMDevice)) + { + if(lineBuf[5] == '!') + { + modem_killall_aplaymidi(0); + misc_swrite(fdSerial, "\r\nMIDI --> OFF"); + sleep(2); + int midiPort = modem_get_softsynth_port(-1); + if(midiPort != -1) + { + alsa_open_seq(midiPort, 0); + alsa_send_midi_raw(all_notes_off, sizeof_all_notes_off); + alsa_close_seq(); + } + } + else if(lineBuf[5] == '1') + { + KILL_MP3_SLEEP; + modem_killall_aplaymidi(0); + misc_swrite(fdSerial, "\r\nLoading --> FluidSynth"); + killall_softsynth(3); + TCPSoftSynth = FluidSynth; + modem_get_softsynth_port(TCPSoftSynth); + } + else if(lineBuf[5] == '2') + { + KILL_MP3_SLEEP; + modem_killall_aplaymidi(0); + misc_swrite(fdSerial, "\r\nLoading --> MUNT"); + killall_softsynth(3); + TCPSoftSynth = MUNT; + modem_get_softsynth_port(TCPSoftSynth); + } + else if(lineBuf[5] == 'S' && lineBuf[6] == 'F') + { + strcpy(tmp, fsynthSoundFont); + char * dir = strrchr(tmp, '/'); + if(dir != NULL) + *dir = (char) 0x00; + else + tmp[0] = (char) 0x00; + if (do_file_picker(tmp, fileName)) + { + strcpy(fsynthSoundFont, tmp); + strcat(fsynthSoundFont, "/"); + strcat(fsynthSoundFont, fileName); + misc_swrite(fdSerial, "\r\n SoundFont -->"); + misc_swrite(fdSerial, fsynthSoundFont); + sprintf(tmp,"sed -i '{s|^FSYNTH_SOUNDFONT[[:space:]]*=.*|FSYNTH_SOUNDFONT = %s|}' %s", + fsynthSoundFont, midiLinkINI); + system(tmp); + } + } + else if(do_file_picker(MIDIPath, fileName)) + { + KILL_MP3_SLEEP; + modem_killall_aplaymidi(0); + int midiPort = modem_get_softsynth_port(TCPSoftSynth); + chdir("/root"); + sprintf(tmp, "taskset %d aplaymidi --port %d \"%s/%s\" 2> /tmp/aplaymidi & ", CPUMASK, midiPort, MIDIPath, fileName);; + misc_print(1, "Play MIDI --> %s\n", tmp); + system(tmp); + misc_swrite(fdSerial, "\r\n"); + sleep(1); + misc_file_to_serial(fdSerial, "/tmp/aplaymidi", 0); + MP3 = FALSE; + } + } + else + { + misc_swrite(fdSerial, audioError, PCMDevice); + } + } + else if (memcmp(lineBuf, "ATSZ", 4) == 0) + { + if(do_file_picker(downloadPath, fileName)) + { + sprintf(tmp, "%s/%s", downloadPath, fileName); + misc_print(1, "Zmodem download --> %s\n", tmp); + serial_do_tcdrain(fdSerial); + misc_do_pipe(fdSerial, "/bin/sz","sz", tmp, NULL, NULL, NULL, NULL); + sleep(3); + } + } + else if (memcmp(lineBuf, "ATRZ", 4) == 0) + { + if(chdir (uploadPath) == 0) + { + misc_swrite(fdSerial, "\r\nUpload path --> '%s'", uploadPath); + misc_swrite(fdSerial, "\r\nUpload file using Zmodem protocol now...\r\n"); + serial_do_tcdrain(fdSerial); + misc_do_pipe(fdSerial, "/bin/rz", "rz", NULL, NULL, NULL, NULL, NULL); + chdir("/root"); + sleep(3); + } + else + misc_swrite(fdSerial, "\r\nERROR: Upload path invalid --> '%s'", uploadPath); + } + else if (memcmp(lineBuf, "ATROWS", 6) == 0) + { + char * strRows = &lineBuf[6]; + if(!misc_is_number(strRows)) + { + for (int i = 50; i > 1; i--) + misc_swrite(fdSerial, "\r\n%2d", i); + } + else + { + TCPTermRows = strtol(strRows, &endPtr, 10); + misc_swrite(fdSerial, "\r\nROWS --> %d", TCPTermRows); + serial_do_tcdrain(fdSerial); + } + } + else if (memcmp(lineBuf, "ATINI", 5) == 0) + { + misc_file_to_serial(fdSerial, midiLinkINI, TCPTermRows); + } + else if (memcmp(lineBuf, "ATDIR", 5) == 0) + { + misc_file_to_serial(fdSerial, midiLinkDIR, TCPTermRows); + } + else if (memcmp(lineBuf, "ATTRANS", 7) == 0) + { + char * validOptions = "\r\nValid options --> 0, 1, 2" + "\r\n-------------------------" + "\r\n0 = NONE" + "\r\n1 = PETSKII (C64)" + "\r\n2 = ATASCII (Atari 8-bit)" + "\r\n-------------------------"; + if(misc_is_number(&lineBuf[7])) + { + int tmpMode = strtol(&lineBuf[7], &endPtr, 10); + if (tmpMode >= 0 && tmpMode <= 2) + TCPAsciiTrans = tmpMode; + else + misc_swrite(fdSerial, validOptions); + } + else if(lineBuf[7] != (char) 0x00) + misc_swrite(fdSerial, validOptions); + misc_swrite(fdSerial, "\r\nASCII translation --> %s", + misc_trans_to_str(TCPAsciiTrans)); + } + else if (memcmp(lineBuf, "ATM", 3) == 0) + { + char * pct = strchr(&lineBuf[3], '%'); + if (pct != NULL) + *pct = (char) 0x00; + if(misc_is_number(&lineBuf[3])) + { + int tmpVol = strtol(&lineBuf[3], &endPtr, 10); + if(pct) + { + if(tmpVol <= 100) + { + modemVolume = tmpVol; + } + else + { + misc_swrite(fdSerial,"\r\nValid options --> 0-100%%"); + } + } + else + switch(tmpVol) + { + case 0: + MODEMSOUND = FALSE; + break; + case 1: + MODEMSOUND = TRUE; + break; + default: + misc_swrite(fdSerial,"\r\nUnsupported option --> '%s'", &lineBuf[3]); + break; + } + } + else + { + if(lineBuf[3] != (char) 0x00) + { + misc_swrite(fdSerial,"\r\nUnsupported option --> '%s'", &lineBuf[3]); + } + } + if(modemVolume != -1 && MODEMSOUND) + misc_swrite(fdSerial, "\r\nModem sounds = %s : volume = %d%%", MODEMSOUND?"ON":"OFF", modemVolume); + else + misc_swrite(fdSerial,"\r\nModem sounds = %s", MODEMSOUND?"ON":"OFF"); + } + else if (memcmp(lineBuf, "ATVER", 5) == 0) + { + misc_swrite(fdSerial, "\r\n"); + misc_swrite(fdSerial, helloStr); + } + else if (memcmp(lineBuf, "ATHELP", 6) == 0) + { + modem_show_at_commands(fdSerial, TCPTermRows); + } + else if (memcmp(lineBuf, "ATUARTTEST", 6) == 0) + { + if (lineBuf[10] == '!') + TCPTermRows = 0; + while (TRUE) + { + modem_show_at_commands(fdSerial, TCPTermRows); + misc_file_to_serial(fdSerial, midiLinkDIR, TCPTermRows); + } + } + else if (memcmp(lineBuf, "ATD", 3) == 0) + { + switch(lineBuf[3]) + { + case '0' : + case '1' : + TCPDTR = 1; + misc_print(1, "Setting DTR mode --> Normal\n"); + break; + case '2' : + TCPDTR = 2; + misc_print(1, "Setting DTR mode --> Hangup\n"); + break; + default: + misc_swrite(fdSerial,"\r\nUnsupported DTR option --> '%s'", &lineBuf[3]); + break; + } + } + else if (memcmp(lineBuf, "ATQ", 3) == 0) + { + switch(lineBuf[3]) + { + case '0' : + TCPQuiet = 0; + misc_print(1, "Setting result code mode --> Verbose\n"); + break; + case '1' : + TCPQuiet = 1; + misc_print(1, "Setting result code mode --> Quiet\n"); + break; + default: + misc_swrite(fdSerial,"\r\nUnsupported result code mode --> '%s'", &lineBuf[3]); + break; + } + } + else if (memcmp(lineBuf, "ATZ", 3) == 0) + { + misc_print(1, "Resetting TCP defaults...\n"); + modem_set_defaults(); + TELNET_NEGOTIATE = TRUE; + misc_print(1, "Reloading INI defaults...\n"); + misc_get_core_name(tmp, sizeof(tmp)); + if(misc_check_file(midiLinkINI)) + ini_read_ini(midiLinkINI, tmp, 1); + } + else if (memcmp(lineBuf, "AT", 2) == 0) + { + if (lineBuf[2] != (char) 0x00) + { + misc_swrite(fdSerial, "\r\nUnknown Command '%s'", &lineBuf[2]); + misc_print(1, "ERROR : Unknown AT command --> '%s'\n", &lineBuf[2]); + } + } + + return FALSE; +} + +/////////////////////////////////////////////////////////////////////////////////////// +// +// void modem_do_emulation(char * buf, int bufLen) +// +// +void modem_do_emulation(char * buf, int bufLen) +{ + static char lineBuf[150] = ""; + static char iLineBuf = 0; + char * lbp; + + show_debug_buf("SER OUT ", buf, bufLen); + for (char * p = buf; bufLen-- > 0; p++) + { + *p = toupper(*p); + switch(*p) + { + case ' ': // [SPACE] no space + break; + case 0x08: // [DELETE] + case 0x14: // [PETSKII DELETE] + case 0xf8: // [BACKSPACE] + if (iLineBuf > 0) + { + lineBuf[--iLineBuf] = 0x00; + write(fdSerial, p, 1); + } + break; + case 0x0D: // [RETURN] + lbp = lineBuf; + int CONNECT = FALSE; + if(iLineBuf > 1 && lineBuf[0] == 'A' && lineBuf[1] == 'T') + { + while (lbp && !CONNECT) + { + char * amp = strchr(lbp, '&'); + if(amp) + *amp = 0x00; + CONNECT = modem_handle_at_command(lbp); + if(amp) + { + lbp = amp-1; + lbp[0] = 'A'; + lbp[1] = 'T'; + } + else + lbp = NULL; + } + if (!CONNECT && TCPQuiet == 0) + misc_swrite_no_trans(fdSerial, "\r\nOK\r\n"); + } + else + misc_swrite(fdSerial, "\r\n"); + iLineBuf = 0; + lineBuf[iLineBuf] = 0x00; + break; + default: + if (iLineBuf < 80) + { + lineBuf[iLineBuf++] = *p; + write(fdSerial, p, 1); + lineBuf[iLineBuf] = 0x00; + } + } + } +} + diff --git a/modem.h b/modem.h new file mode 100644 index 0000000..a0b8e88 --- /dev/null +++ b/modem.h @@ -0,0 +1,19 @@ +void modem_play_connect_sound(char * tmp); +void modem_play_ring_sound(char * tmp); +void modem_play_dial_sound(char * tmp, char * ipAddr); +void modem_do_check_hangup(int * socket, char * buf, int bufLen); +void modem_do_telnet_negotiate(); +int modem_do_file_picker(char * pathBuf, char * fileNameBuf); +void modem_do_emulation(char * buf, int bufLen); +int modem_handle_at_command(char * lineBuf); +void modem_killall_aplay(int delay); +void modem_killall_aplaymidi(int delay); +void modem_killall_mpg123(int delay); +void * modem_tcplst_thread_function (void * x); +void * modem_tcpsock_thread_function (void * x); +int modem_get_softsynth_port(int softSynth); +void modem_set_defaults(); +void modem_show_at_commands(int fdSerial, int rows); + + +