Hardware

This project used a few I/O devices:

  • A BeagleBone green;
  • A potentiometer on a custom beagleboard cape;
  • USB headset managed through PortAudio;
  • LED lights connected to I/O pins;
  • A 12 digit keypad connected to I/O pins; and
  • Ethernet connection between beagleboards;
  • diagram of I/O devices
    fig: A Fritzing schematic outlining the use of GPIO pins
    Project Overview

    The overall architecture of the program is fairly simple. Once main is launched it launches functions that launches threads for polling the keypad, checking/updating LEDs as well as checking for incoming calls. Once an outgoing or an incoming call is made, seperate threads also manage the polling for audio input, audio output and audio signal transmission. Clearly, the audio and networking portions are both the most essential and most complicated part of this program. Fittingly there are 6 separate C files to manage these functions. The goal was to keep the 'main' file relatively clean and leave the individual thread management in separate purpose specific C files. This is shown in the code and diagram below:

              
                int main(int argc, char* argv[]) {
                 if (argc < 3) {
                     fprintf(stderr, "Please provide the input audio device index, then output device index.\n");
                     return 1;
                 }
    
                 printf("hello Bryce \n");
                 int inputDeviceIndex = atoi(argv[1]);
                 int outputDeviceIndex = atoi(argv[2]);
    
                 printf("Audio input bound to device %d and output to device %d.\nPress Ctrl-C to quit.\n", 
                 inputDeviceIndex, outputDeviceIndex);
    
                 // Signal handling stuff...
                 sigset_t signalSet;
                 int signalNumber;
                 sigemptyset(&signalSet);
                 sigaddset(&signalSet, SIGINT);
                 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
    
                 KEYPAD_init();
                 Audio_init(inputDeviceIndex, outputDeviceIndex);
    
                 LED_init();
                 AddressBook_init();
                 DialService_start(onDial);
                 VoiceServer_start(handleIncomingCall);
    
                 // Wait for SIGINT to arrive.
                 sigwait(&signalSet, &signalNumber);
    
                 printf("\nSIGINT received by main thread. Stopping program...\n");
    
                 VoiceServer_stop();
                 DialService_stop();
                 printf("Audio_stop TEARDOWN\n");
                 Audio_stop();
                 Audio_teardown();
    
                 printf("Bye.\n");
    
                 return 0;
                }
              
            

    The above is the main function in its entirety. It checks the initial parameters, then calls functions to launch threads for all the functionality. Finally, it will shut down the threads and close the program.

    A diagram showing how the varying proccesses are managed
    fig: map of the system

    Note: Execept for the potentiometer, which is controled by systemd, all the other processes are essentially threads called from main.

    Acknowledgements

    This project was completed with: Jeffrey Leung, Paymon Jalali, and Rulai Hu

    An image of the Beagleboard with keypad.