module Peak

Constants

BUILTIN_PLUGINS
VERSION

Public Class Methods

all_plugins(extra_plugins=[]) click to toggle source
# File lib/peak/plugin_loader.rb, line 6
def self.all_plugins(extra_plugins=[])
    return BUILTIN_PLUGINS + extra_plugins
end
config_lookup_enforce(config_map, key) click to toggle source
# File lib/peak/config_loader.rb, line 28
def self.config_lookup_enforce(config_map, key)
    unless config_map.key?(key)
        echo_colorized_error('Invalid configuration, could not find an ' + key + ' attribute in section')
        return false
    end
    return true
end
echo_color_frame(frame, port_name, direction_in) click to toggle source
# File lib/peak/echo.rb, line 4
def self.echo_color_frame(frame, port_name, direction_in)
    formatted_aprs = [frame[:source].colorize(:green), frame[:destination].colorize(:blue)].join('>')
    paths = []
    frame[:path].each do |path|
        paths << path.colorize(:cyan)
    end
    paths = paths.join(',')
    if frame[:path] and frame[:path].length > 0
        formatted_aprs = [formatted_aprs, paths].join(',')
    end
    formatted_aprs += ':'
    formatted_aprs += frame[:text]
    if direction_in
        puts (port_name + ' << ').colorize(:magenta) + formatted_aprs
    else
        # TODO : make this bold and/or blink
        puts (port_name + ' >> ').colorize(:color => :magenta, :mode => :bold) + formatted_aprs
    end
end
echo_colorized_error(text) click to toggle source
# File lib/peak/echo.rb, line 24
def self.echo_colorized_error(text)
    puts 'Error: '.colorize(:color => :red, :mode => [:bold, :blink]) + text.colorize(:bold)
end
echo_colorized_warning(text) click to toggle source
# File lib/peak/echo.rb, line 28
def self.echo_colorized_warning(text)
    puts 'Warning: '.colorize(:color => :yellow) + text
end
find_config(verbose, config_paths=[]) click to toggle source
# File lib/peak/config_loader.rb, line 7
def self.find_config(verbose, config_paths=[])
    config_file = 'peak.conf'
    rc_file = '.peakrc'
    cur_path = config_file
    home_path = File.join(Dir.home, rc_file)
    etc_path = File.join('', 'etc', config_file)
    config_paths = [cur_path, home_path, etc_path] + config_paths
    
    if verbose
        puts 'Searching for configuration file in the following locations: ' + config_paths.inspect
    end
    
    config_paths.each do |config_path|
        if File.file?(config_path)
            return YAML::load_file(config_path)
        end
    end
    
    return nil
end
init_port_map(config) click to toggle source
# File lib/peak/config_loader.rb, line 36
def self.init_port_map(config)
    port_map = {}
    
    config.each do |section_name, section_content|
        if section_name.start_with?('TNC ')
            tnc_name = section_name.strip.split(' ')[1].strip
            if tnc_name == 'IGATE'
                echo_colorized_error('IGATE was used as the name for a TNC in the configuration, this name is reserved')
                return nil
            end
        
            kiss_tnc = nil
            if config_lookup_enforce(section_content, 'com_port') and config_lookup_enforce(section_content, 'baud')
                com_port = section_content['com_port']
                baud = section_content['baud']
                kiss_tnc = Apex::AprsKiss.new(Kiss::KissSerial.new(com_port, baud))
            else
                return nil
            end
            
            if section_content.key?('kiss_init')
                kiss_init_string = section_content['kiss_init']
                if kiss_init_string == 'MODE_INIT_W8DED'
                    kiss_tnc.connect(Kiss::MODE_INIT_W8DED)
                elsif kiss_init_string == 'MODE_INIT_KENWOOD_D710'
                    kiss_tnc.connect(Kiss::MODE_INIT_KENWOOD_D710)
                elsif kiss_init_string == 'NONE'
                    kiss_tnc.connect
                else
                    echo_colorized_error('Invalid configuration, value assigned to kiss_init was not recognized: ' + kiss_init_string)
                    return nil
                end
            else
                kiss_tnc.connect
            end

            unless config_lookup_enforce(section_content, 'port_count')
                return nil
            end
            
            port_count = section_content['port_count']
            
            (1..port_count).each do |port|
                port_name = tnc_name + '-' + port.to_s
                port_section_name = 'PORT ' + port_name
                
                unless config_lookup_enforce(config, port_section_name)
                    return nil
                end
                port_section = config[port_section_name]
                
                unless config_lookup_enforce(port_section, 'identifier')
                    return nil
                end
                port_identifier = port_section['identifier']

                unless config_lookup_enforce(port_section, 'net')
                    return nil
                end
                port_net = port_section['net']

                unless config_lookup_enforce(port_section, 'tnc_port')
                    return nil
                end
                tnc_port = port_section['tnc_port']
                
                unless config_lookup_enforce(port_section, 'echo')
                    return nil
                end
                echo_state = port_section['echo']
                
                port_map[port_name] = TncPort.new(kiss_tnc, port_name, port_identifier, port_net, echo_state, tnc_port)
            end
        end
    end
    
    return port_map
end
load_plugins(plugins=BUILTIN_PLUGINS) click to toggle source
# File lib/peak/plugin_loader.rb, line 10
def self.load_plugins(plugins=BUILTIN_PLUGINS)
    plugins.each do |plugin|
        require plugin
    end
    return Plugins::PluginFactory.get_registered_plugins
end
main() click to toggle source
# File lib/peak.rb, line 8
def self.main
    config = find_config(true)
    unless config
        echo_colorized_error('Could not find a valid configuration file in any of the default locations')
        return
    end

    port_map = init_port_map(config)
    unless port_map
        echo_colorized_error('Configuration could not be loaded,  format was invalid.')
        return
    end

    Signal.trap('INT') { throw :sig }
    Signal.trap('TERM') { throw :sig }
    
    active_plugins = {}
    plugins = load_plugins
    plugins.each do |plugin|
        active_plugin = plugin.new(config, port_map, nil)
        active_plugin_thread = Thread.new {
            active_plugin.run
        }
        active_plugins[active_plugin] = active_plugin_thread
    end

    # Handle any packets we read in.
    catch (:sig) do
        while true
            something_read = false
            port_map.values.each do |tnc_port|
                frame = tnc_port.read
                if frame
                    something_read = true
                    routed_frame = Routing::Route.handle_frame(frame, config, true, tnc_port.name)
                    if routed_frame
                        if routed_frame[:output_target]
                            port_map[routed_frame[:output_target]].write(routed_frame[:frame])
                        else
                            active_plugins.each_key do |plugin|
                                plugin.handle_packet(routed_frame[:frame], tnc_port)
                            end
                        end
                    end
                end
            end
            unless something_read
                sleep(1)
            end
        end
    end

    puts
    puts 'Shutdown signal caught, shutting down...'

    # Let's cleanup some stuff before exiting.
    active_plugins.keys.each do |plugin|
        plugin.stop
    end
    active_plugins.values.each do |plugin_thread|
        plugin_thread.join
    end
    port_map.values.each do |port|
        port.close
    end
    
    puts 'Peak successfully shutdown.'
end