diff --git a/LICENSE b/LICENSE
index 353e988b0f7cb3db920a4af611e32fc1e1a4d865..4c8225b9d2ee683106e884502c077311771ba7c5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2013 OnBeep, Inc.
+Copyright 2015 Orion Labs, Inc.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
diff --git a/Makefile b/Makefile
index b2fd593b431060572167910abe4d6ba644fa62a9..38ec6b297feb78eee46c263466fdd27ee8224828 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # Makefile for APRS Python Module.
 #
 # Source:: https://github.com/ampledata/aprs
-# Author:: Greg Albrecht W2GMD <gba@onbeep.com>
-# Copyright:: Copyright 2013 OnBeep, Inc.
+# Author:: Greg Albrecht W2GMD <gba@orionlabs.co>
+# Copyright:: Copyright 2015 Orion Labs, Inc.
 # License:: Apache License, Version 2.0
 #
 
diff --git a/README.rst b/README.rst
index 4cd263537220ac9a79978cccd15f142df85c5210..f3937ba8abdc51d662429340fef8f26e3935cc80 100644
--- a/README.rst
+++ b/README.rst
@@ -15,12 +15,13 @@ sent to my callback *my_cb* and printed.
 
     import aprs
 
-    a = aprs.APRS('W2GMD')
-
-    def my_cb(line):
+    def my_callback(line):
         print line
 
-    a.receive(callback=my_cb)
+    a = aprs.APRS('W2GMD', '12345')
+    a.connect()
+    a.send('W2GMD>APRS:>Test!')
+    a.receive(callback=my_callback)
 
 
 Example output:
@@ -33,12 +34,12 @@ Github: https://github.com/ampledata/aprs
 
 Author
 ======
-Greg Albrecht W2GMD <gba@gregalbrecht.com>
+Greg Albrecht W2GMD <gba@orionlabs.co>
 
 Copyright
 =========
-Copyright 2013 Greg Albrecht
+Copyright 2015 Orion Labs, Inc.
 
 License
 =======
-Creative Commons Attribution 3.0 Unported License
+Apache License, Version 2.0
diff --git a/aprs/__init__.py b/aprs/__init__.py
index c89c4799580cfea8dae3913364ca43bf23eccf39..c9c0b3fa570ced895f893277dc10644d7af320d7 100644
--- a/aprs/__init__.py
+++ b/aprs/__init__.py
@@ -8,8 +8,8 @@ APRS Python Module.
 ~~~~
 
 
-:author: Greg Albrecht W2GMD <gba@onbeep.com>
-:copyright: Copyright 2013 OnBeep, Inc.
+:author: Greg Albrecht W2GMD <gba@orionlabs.co>
+:copyright: Copyright 2015 Orion Labs, Inc.
 :license: Apache License, Version 2.0
 :source: <https://github.com/ampledata/aprs>
 
diff --git a/aprs/classes.py b/aprs/classes.py
index 491ef3fe6da9c5f16c83d25e017ae46523ded849..9147b6c67d10954c5e41ab6cdb34cf2dd094774a 100755
--- a/aprs/classes.py
+++ b/aprs/classes.py
@@ -3,15 +3,14 @@
 
 """APRS Class Definitions"""
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import logging
 import logging.handlers
 import socket
-import time
 
 import requests
 
@@ -37,30 +36,21 @@ class APRS(object):
     def __init__(self, user, password='-1', input_url=None):
         self.user = user
         self._url = input_url or aprs.constants.APRSIS_URL
-        self._auth = ' '.join(['user', user, 'pass', password])
+        self._auth = ' '.join(
+            ['user', user, 'pass', password, 'vers', 'APRS Python Module v2'])
+        self.aprsis_sock = None
 
-    def send(self, message, headers=None):
+    def connect(self, server=None, port=None, filter=None):
         """
-        Sends message to APRS-IS send-only interface.
-
-        :param message: Message to send to APRS-IS.
-        :param headers: Optional headers to post.
-        :type message: str
-        :type headers: dict
-
-        :return: True on 204 success, False otherwise.
-        :rtype: bool
+        Connects & logs in to APRS-IS.
+
+        :param server: Optional alternative APRS-IS erver.
+        :param port: Optional APRS-IS port.
+        :param filter: Optional filter to use.
+        :type server: str
+        :type port: int
+        :type filte: str
         """
-        self.logger.debug('message=%s headers=%s', message, headers)
-
-        headers = headers or aprs.constants.APRSIS_HTTP_HEADERS
-        content = "\n".join([self._auth, message])
-
-        result = requests.post(self._url, data=content, headers=headers)
-
-        return result.status_code == 204
-
-    def receive(self, server=None, port=None, filter=None, callback=None):
         if not server:
             server = aprs.constants.APRSIS_SERVER
         if not port:
@@ -68,19 +58,60 @@ class APRS(object):
         if not filter:
             filter = "p/%s" % self.user
 
-        full_auth = ' '.join([self._auth, 'vers omg 1.0', 'filter', filter])
+        full_auth = ' '.join([self._auth, 'filter', filter])
 
-        recvd_data = ''
-
-        aprsis_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        aprsis_sock.connect((server, int(port)))
+        self.aprsis_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.aprsis_sock.connect((server, int(port)))
         self.logger.info('Connected to server=%s port=%s', server, port)
         self.logger.debug('Sending full_auth=%s', full_auth)
-        aprsis_sock.sendall(full_auth + '\n\r')
+        self.aprsis_sock.sendall(full_auth + '\n\r')
+
+    def send(self, message, headers=None, protocol='TCP'):
+        """
+        Sends message to APRS-IS.
+
+        :param message: Message to send to APRS-IS.
+        :param headers: Optional HTTP headers to post.
+        :param protocol: Protocol to use: One of TCP, HTTP or UDP.
+        :type message: str
+        :type headers: dict
+
+        :return: True on success, False otherwise.
+        :rtype: bool
+        """
+        self.logger.debug(
+            'message=%s headers=%s protocol=%s', message, headers, protocol)
+
+        if protocol == 'TCP':
+            self.logger.debug('sending message=%s', message)
+            self.aprsis_sock.sendall(message + '\n\r')
+            return True
+        elif protocol == 'HTTP':
+            content = "\n".join([self._auth, message])
+            headers = headers or aprs.constants.APRSIS_HTTP_HEADERS
+            result = requests.post(self._url, data=content, headers=headers)
+            return result.status_code == 204
+        elif protocol == 'UDP':
+            content = "\n".join([self._auth, message])
+            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+            sock.sendto(
+                content,
+                (aprs.constants.APRSIS_SERVER, aprs.constants.APRSIS_RX_PORT)
+            )
+            return True
+
+    def receive(self, callback=None):
+        """
+        Receives from APRS-IS.
+
+        :param callback: Optional callback to deliver data to.
+        :type callback: func
+        """
+        recvd_data = ''
 
         try:
             while 1:
-                recv_data = aprsis_sock.recv(aprs.constants.RECV_BUFFER)
+                recv_data = self.aprsis_sock.recv(aprs.constants.RECV_BUFFER)
 
                 if not recv_data:
                     break
diff --git a/aprs/constants.py b/aprs/constants.py
index 185e7f888ab6550ef5ed24234f7a945c9ce5aaec..37b7117528e9a317daf061dcb66349f1168e4587 100644
--- a/aprs/constants.py
+++ b/aprs/constants.py
@@ -5,9 +5,9 @@
 Constants for APRS Module.
 """
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import logging
@@ -20,6 +20,7 @@ APRSIS_HTTP_HEADERS = {
 }
 APRSIS_SERVER = 'rotate.aprs.net'
 APRSIS_FILTER_PORT = 14580
+APRSIS_RX_PORT = 8080
 
 RECV_BUFFER = 1024
 
diff --git a/aprs/util.py b/aprs/util.py
index 7e904e72c7667a48ae555491232b787ea655b84b..f03810f2204f4bcc8d695878c8fe577581a59a6b 100755
--- a/aprs/util.py
+++ b/aprs/util.py
@@ -3,9 +3,9 @@
 
 """Utilities for the APRS Python Module."""
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import logging
@@ -15,16 +15,6 @@ import aprs.decimaldegrees
 import kiss.constants
 
 
-logger = logging.getLogger(__name__)
-logger.setLevel(aprs.constants.LOG_LEVEL)
-console_handler = logging.StreamHandler()
-console_handler.setLevel(aprs.constants.LOG_LEVEL)
-console_handler.setFormatter(
-    logging.Formatter(aprs.constants.LOG_FORMAT))
-logger.addHandler(console_handler)
-logger.propagate = False
-
-
 def dec2dm_lat(dec):
     """Converts DecDeg to APRS Coord format.
     See: http://ember2ash.com/lat.htm
@@ -83,15 +73,15 @@ def decode_aprs_ascii_frame(ascii_frame):
     :returns: Dictionary of APRS Frame parts: source, destination, path, text.
     :rtype: dict
     """
-    logger.debug('frame=%s', ascii_frame)
+    logging.debug('frame=%s', ascii_frame)
     decoded_frame = {}
     frame_so_far = ''
 
     for char in ascii_frame:
-        if '>' in char and not 'source' in decoded_frame:
+        if '>' in char and 'source' not in decoded_frame:
             decoded_frame['source'] = frame_so_far
             frame_so_far = ''
-        elif ':' in char and not 'path' in decoded_frame:
+        elif ':' in char and 'path' not in decoded_frame:
             decoded_frame['path'] = frame_so_far
             frame_so_far = ''
         else:
@@ -162,7 +152,7 @@ def valid_callsign(callsign):
     :returns: True if valid, False otherwise.
     :rtype: bool
     """
-    logger.debug('callsign=%s', callsign)
+    logging.debug('callsign=%s', callsign)
 
     if '-' in callsign:
         if not callsign.count('-') == 1:
@@ -172,7 +162,7 @@ def valid_callsign(callsign):
     else:
         ssid = 0
 
-    logger.debug('callsign=%s ssid=%s', callsign, ssid)
+    logging.debug('callsign=%s ssid=%s', callsign, ssid)
 
     if (len(callsign) < 2 or len(callsign) > 6 or len(str(ssid)) < 1 or
             len(str(ssid)) > 2):
@@ -327,7 +317,7 @@ def decode_frame(raw_frame):
 def run_doctest():  # pragma: no cover
     """Runs doctests for this module."""
     import doctest
-    import aprs.util  # pylint: disable=W0406
+    import aprs.util  # pylint: disable=W0406,W0621
     return doctest.testmod(aprs.util)
 
 
diff --git a/requirements.txt b/requirements.txt
index 1396a2d55928fc1bcb8c65f1810e00765d240f3f..184270861d51c5d986852ca79eadc2979eca553f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,8 +1,8 @@
 # Python Distribution Package Requirements for APRS.
 #
 # Source:: https://github.com/ampledata/aprs
-# Author:: Greg Albrecht W2GMD <gba@onbeep.com>
-# Copyright:: Copyright 2013 OnBeep, Inc. and Contributors
+# Author:: Greg Albrecht W2GMD <gba@orionlabs.co>
+# Copyright:: Copyright 2015 Orion Labs, Inc.
 # License:: Apache License, Version 2.0
 
 
diff --git a/setup.cfg b/setup.cfg
index 828204dda494d29ae36cf35c9b06e8fff692228a..771109304582af55b26225c5eb4a1257ac738d91 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,8 +1,8 @@
 # Nosetests configuration for APRS.
 #
 # Source:: https://github.com/ampledata/aprs
-# Author:: Greg Albrecht W2GMD <gba@onbeep.com>
-# Copyright:: Copyright 2013 OnBeep, Inc.
+# Author:: Greg Albrecht W2GMD <gba@orionlabs.co>
+# Copyright:: Copyright 2015 Orion Labs, Inc.
 # License:: Apache License, Version 2.0
 #
 
diff --git a/setup.py b/setup.py
index 9533632b7ff4e4955cced9e3315f200b6996d607..4ead7bfe31e6636bea50dc1214ecf419f52e3289 100644
--- a/setup.py
+++ b/setup.py
@@ -10,9 +10,9 @@ Source:: https://github.com/ampledata/aprs
 
 __title__ = 'aprs'
 __version__ = '2.2.0'
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2014 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import os
@@ -39,7 +39,7 @@ setup(
     version=__version__,
     description='Python Bindings for APRS-IS API.',
     author='Greg Albrecht',
-    author_email='gba@onbeep.com',
+    author_email='gba@orionlabs.co',
     packages=['aprs'],
     package_data={'': ['LICENSE']},
     license=open('LICENSE').read(),
diff --git a/tests/constants.py b/tests/constants.py
index d97eb5efc1b98b7988c84b6d199487d98198f2c5..01db6f7e2c023c0f7e83c53912a7cf4b5a40ccb3 100644
--- a/tests/constants.py
+++ b/tests/constants.py
@@ -3,9 +3,9 @@
 
 """Constants for APRS Module Tests."""
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 TEST_FRAMES = 'tests/test_frames.log'
diff --git a/tests/context.py b/tests/context.py
index a9ab68e5b0afe32be888a18a567acdb6c943e6ec..37f3193a10a7f53373409f66ebecda4e91d0c9c5 100644
--- a/tests/context.py
+++ b/tests/context.py
@@ -3,6 +3,10 @@
 
 """Context for tests for APRS Python Module."""
 
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
+__license__ = 'Apache License, Version 2.0'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
+
 
 import os
 import sys
diff --git a/tests/test_aprs.py b/tests/test_aprs.py
index 33ff8e01414ac0da970cb8ab17d7dd676be4114b..be9c476e2a52192f5f2d8e6e6dd2060d7c0f6475 100644
--- a/tests/test_aprs.py
+++ b/tests/test_aprs.py
@@ -3,9 +3,9 @@
 
 """Tests for Python APRS-IS Bindings."""
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import random
@@ -36,7 +36,8 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
     logger.addHandler(console_handler)
     logger.propagate = False
 
-    def random(self, length=8, alphabet=ALPHANUM):
+    @classmethod
+    def random(cls, length=8, alphabet=ALPHANUM):
         """
         Generates a random string for test cases.
 
@@ -65,8 +66,11 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
         self.real_server = 'http://localhost:14580'
         self.real_callsign = '-'.join(['W2GMD', self.random(1, '123456789')])
 
-        self.logger.debug("fake_server=%s fake_callsign=%s"
-                          % (self.fake_server, self.fake_callsign))
+        self.logger.debug(
+            "fake_server=%s fake_callsign=%s",
+            self.fake_server,
+            self.fake_callsign
+        )
 
     @httpretty.httprettified
     def test_fake_good_auth(self):
@@ -83,6 +87,7 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
             user=self.fake_callsign,
             input_url=self.fake_server
         )
+        aprs_conn.connect()
 
         msg = '>'.join([
             self.fake_callsign,
@@ -95,7 +100,7 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
         self.assertTrue(result)
 
     @httpretty.httprettified
-    def test_fake_bad_auth(self):
+    def test_fake_bad_auth_http(self):
         """
         Tests authenticating against APRS-IS using an invalid call+pass.
         """
@@ -109,6 +114,7 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
             user=self.fake_callsign,
             input_url=self.fake_server
         )
+        aprs_conn.connect()
 
         msg = '>'.join([
             self.fake_callsign,
@@ -116,7 +122,7 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
         ])
         self.logger.debug(locals())
 
-        result = aprs_conn.send(msg)
+        result = aprs_conn.send(msg, protocol='HTTP')
 
         self.assertFalse(result)
 
@@ -129,6 +135,7 @@ class APRSTest(unittest.TestCase):  # pylint: disable=R0904
             user=self.real_callsign,
             input_url=self.real_server
         )
+        aprs_conn.connect()
 
         msg = '>'.join([
             self.real_callsign,
diff --git a/tests/test_util.py b/tests/test_util.py
index 8fba5ba52fd0a81a79cb4a53061e419fd733b2b4..04c8aff5fd87f52606158de6565bbb9c4697e59b 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -3,9 +3,9 @@
 
 """Tests for Python APRS util methods."""
 
-__author__ = 'Greg Albrecht W2GMD <gba@onbeep.com>'
-__copyright__ = 'Copyright 2013 OnBeep, Inc.'
+__author__ = 'Greg Albrecht W2GMD <gba@orionlabs.co>'
 __license__ = 'Apache License, Version 2.0'
+__copyright__ = 'Copyright 2015 Orion Labs, Inc.'
 
 
 import unittest
@@ -72,7 +72,7 @@ class APRSUtilTestCase(unittest.TestCase):  # pylint: disable=R0904
         self.logger.debug('aprs_lat=%s', aprs_lat)
 
         lat_deg = int(aprs_lat.split('.')[0][:1])
-        #lat_hsec = aprs_lat.split('.')[1]
+        # lat_hsec = aprs_lat.split('.')[1]
 
         self.assertTrue(len(aprs_lat) == 8)
         self.assertTrue(lat_deg >= 00)
@@ -103,7 +103,7 @@ class APRSUtilTestCase(unittest.TestCase):  # pylint: disable=R0904
         self.logger.debug('aprs_lat=%s', aprs_lat)
 
         lat_deg = int(aprs_lat.split('.')[0][:1])
-        #lat_hsec = aprs_lat.split('.')[1]
+        # lat_hsec = aprs_lat.split('.')[1]
 
         self.assertTrue(len(aprs_lat) == 8)
         self.assertTrue(lat_deg >= 00)
@@ -136,7 +136,7 @@ class APRSUtilTestCase(unittest.TestCase):  # pylint: disable=R0904
         self.logger.debug('aprs_lng=%s', aprs_lng)
 
         lng_deg = int(aprs_lng.split('.')[0][:2])
-        #lng_hsec = aprs_lng.split('.')[1]
+        # lng_hsec = aprs_lng.split('.')[1]
 
         self.assertTrue(len(aprs_lng) == 9)
         self.assertTrue(lng_deg >= 000)
@@ -169,7 +169,7 @@ class APRSUtilTestCase(unittest.TestCase):  # pylint: disable=R0904
         self.logger.debug('aprs_lng=%s', aprs_lng)
 
         lng_deg = int(aprs_lng.split('.')[0][:2])
-        #lng_hsec = aprs_lng.split('.')[1]
+        # lng_hsec = aprs_lng.split('.')[1]
 
         self.assertTrue(len(aprs_lng) == 9)
         self.assertTrue(lng_deg >= 000)