diff --git a/api_app.py b/api_app.py
index 0b117ca..338662b 100644
--- a/api_app.py
+++ b/api_app.py
@@ -6,6 +6,7 @@ import csv
 import ast
 import glob
 import json
+import sqlite3
 api_app = Flask(__name__)
 api = Api(api_app)
 
@@ -42,16 +43,45 @@ def read_logs(log_folder):
 
     return(json_array)
 
+def dict_factory(cursor, row):
+    d = {}
+    for idx, col in enumerate(cursor.description):
+        d[col[0]] = row[idx]
+    return d
+
+def get_db_connection():
+    conn = sqlite3.connect('database.db')
+    #conn.row_factory = sqlite3.Row
+    conn.row_factory = dict_factory
+    return conn
+
+def select_all_frames(conn):
+    """
+    Query all rows in the frames table
+    :param conn: the Connection object
+    :return:
+    """
+    cur = conn.cursor()
+    cur.execute("SELECT * FROM frames")
+    rows = cur.fetchall()
+    return rows
+
 class Packets(Resource):
     def get(self):
-        data = read_logs(log_folder)
+        #data = read_logs(log_folder)
+        conn = get_db_connection()
+        data = select_all_frames(conn)
         return {'data': data}, 200  # return data and 200 OK code
 
 # Read config
 config = read_config()
 log_folder = config['Settings']['log_folder']
 # Load logs first (just to check for errors before page loads)
-data = read_logs(log_folder)
+#data = read_logs(log_folder)
+
+# Start subprocess to watch KISS connection
+import subprocess
+subprocess.Popen(["python3","kiss_and_db.py"])
 
 api.add_resource(Packets, '/packets')  # and '/locations' is our entry point for Locations
 
diff --git a/api_waitress.py b/api_waitress.py
index 015c602..126faf7 100644
--- a/api_waitress.py
+++ b/api_waitress.py
@@ -9,4 +9,4 @@ os.chdir(this_files_dir)
 
 # `url_prefix` is optional, but useful if you are serving app on a sub-dir
 # behind a reverse-proxy.
-serve(api_app, host='127.0.0.1', port=5001)
+serve(api_app, host='0.0.0.0', port=5001)
diff --git a/config.ini b/config.ini
index 61ac29d..647b245 100644
--- a/config.ini
+++ b/config.ini
@@ -7,3 +7,13 @@ log_folder = logs/
 station_call = W1CDN-1
 station_lat = 47.941500
 station_lon = -97.027000
+
+# How long to keep packets (frames) e.g., "2 days", "5 minutes"
+keep_time = "2 days"
+
+# KISS settings
+kiss_host = 192.168.0.30
+kiss_port = 8001
+
+# Development settings (not operational yet)
+mycall = W1CDN-15
diff --git a/init_db.py b/init_db.py
new file mode 100644
index 0000000..cf2eaf7
--- /dev/null
+++ b/init_db.py
@@ -0,0 +1,19 @@
+import sqlite3
+
+connection = sqlite3.connect('database.db')
+
+with open('schema.sql') as f:
+    connection.executescript(f.read())
+
+cur = connection.cursor()
+
+# cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
+#             ('First Post', 'Content for the first post')
+#             )
+#
+# cur.execute("INSERT INTO posts (title, content) VALUES (?, ?)",
+#             ('Second Post', 'Content for the second post')
+#             )
+
+connection.commit()
+connection.close()
diff --git a/kiss_and_db.py b/kiss_and_db.py
new file mode 100644
index 0000000..a8c7072
--- /dev/null
+++ b/kiss_and_db.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python3
+import os
+import sqlite3
+import aprs
+import json
+import aprslib
+import configparser
+
+db_fields = ("id",
+"addresse",
+"alive",
+"altitude",
+"comment",
+"course",
+"created",
+"format",
+"frame",
+"from",
+"gpsfixstatus",
+"latitude",
+"longitude",
+"mbits",
+"messagecapable",
+"message_text",
+"mtype",
+"object_format",
+"object_name",
+"path",
+"phg",
+"phg_dir",
+"phg_gain",
+"phg_height",
+"phg_power",
+"phg_range",
+"posambiguity",
+"raw",
+"raw_timestamp",
+"speed",
+"station_call",
+"station_lat",
+"station_lon",
+"status",
+"subpacket",
+"symbol",
+"symbol_table",
+"telemetry",
+"timestamp",
+"to",
+"tEQNS",
+"tPARM",
+"tUNIT",
+"via",
+"weather",
+"wx_raw_timestamp")
+
+def read_config():
+    config = configparser.ConfigParser()
+    config.read('config.ini')
+    return config
+
+def get_db_connection():
+    conn = sqlite3.connect('database.db')
+    conn.row_factory = sqlite3.Row
+    return conn
+
+def main():
+
+    # Add the call and location of this station to the packet info
+    config = read_config()
+    # MYCALL = os.environ.get("MYCALL", "W1CDN")
+    # KISS_HOST = os.environ.get("KISS_HOST", "192.168.0.30")
+    # KISS_PORT = os.environ.get("KISS_PORT", "8001")
+
+
+    ki = aprs.TCPKISS(host=config['Settings']['kiss_host'], port=int(config['Settings']['kiss_port']))
+    ki.start()
+
+    # Make a simple frame and send it
+    frame = aprs.APRSFrame.ui(
+        destination="APZ001",
+        source=config['Settings']['mycall'],
+        path=["WIDE1-1"],
+        info=b">Hello World!",
+    )
+    ki.write(frame)
+
+    # Watch for new packets to come in
+    while True:
+        conn = get_db_connection()
+        for frame in ki.read(min_frames=1):
+            a = aprslib.parse(str(frame))
+            a['station_call'] = config['Settings']['station_call']
+            a['station_lat'] = config['Settings']['station_lat']
+            a['station_lon'] = config['Settings']['station_lon']
+            print(a)
+            # Make this a string and deal with it later (probably a mistake)
+            a['path'] = str(a['path'])
+            # Store true/false as 1/0
+            if 'alive' in a:
+                if a['alive'] == True:
+                    a['alive'] = 1
+                else:
+                    a['alive'] = 0
+            # Build an INSERT statement based on the fields we have from the frame
+            attrib_names = ', '.join('"%s"' % w for w in a.keys())
+            attrib_values = ", ".join("?" * len(a.keys()))
+            sql = "INSERT INTO frames ("+attrib_names+") VALUES ("+attrib_values+")"
+            try:
+                # Insert data
+                conn.execute(sql, list(a.values()))
+                conn.commit()
+
+                # TODO remove packets that are older ('created') than a limit set in config.ini
+                # "5 minutes" also works
+                conn.execute("DELETE FROM frames WHERE created < DATETIME('now', '"+config['Settings']['keep_time']+"')")
+                conn.commit()
+            except:
+                print("Error with SQLite!")
+
+        conn.close()
+
+
+
+if __name__ == "__main__":
+    main()
diff --git a/requirements.txt b/requirements.txt
index baf9fc7..85407aa 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
 flask
 flask_restful
-pandas
-numpy
+aprs
+aprslib
diff --git a/schema.sql b/schema.sql
new file mode 100644
index 0000000..91e5b43
--- /dev/null
+++ b/schema.sql
@@ -0,0 +1,50 @@
+DROP TABLE IF EXISTS frames;
+
+CREATE TABLE frames (
+    id INTEGER PRIMARY KEY AUTOINCREMENT,
+    addresse TEXT,
+    alive INT,
+    altitude REAL,
+    comment TEXT,
+    course REAL,
+    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    format TEXT,
+    frame TEXT,
+    "from" TEXT,
+    gpsfixstatus TEXT,
+    latitude REAL,
+    longitude REAL,
+    mbits INT,
+    messagecapable INT,
+    message_text TEXT,
+    mtype TEXT,
+    object_format TEXT,
+    object_name TEXT,
+    path TEXT,
+    phg REAL,
+    phg_dir TEXT,
+    phg_gain REAL,
+    phg_height REAL,
+    phg_power REAL,
+    phg_range REAL,
+    posambiguity INT,
+    raw TEXT,
+    raw_timestamp TEXT,
+    speed REAL,
+    station_call TEXT,
+    station_lat REAL,
+    station_lon REAL,
+    status TEXT,
+    subpacket TEXT,
+    symbol TEXT,
+    symbol_table TEXT,
+    telemetry TEXT,
+    timestamp INT,
+    "to" TEXT,
+    tEQNS TEXT,
+    tPARM TEXT,
+    tUNIT TEXT,
+    via TEXT,
+    weather TEXT,
+    wx_raw_timestamp TIMESTAMP
+);
diff --git a/start-aprs_api.sh b/start-aprs_api.sh
old mode 100644
new mode 100755
diff --git a/tcp_kiss_send_recv.py b/tcp_kiss_send_recv.py
new file mode 100644
index 0000000..4e6fe5a
--- /dev/null
+++ b/tcp_kiss_send_recv.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+import os
+import sqlite3
+import aprs
+import json
+import aprslib
+import configparser
+
+MYCALL = os.environ.get("MYCALL", "W1CDN")
+KISS_HOST = os.environ.get("KISS_HOST", "192.168.0.30")
+KISS_PORT = os.environ.get("KISS_PORT", "8001")
+
+db_fields = ("id",
+"addresse",
+"alive",
+"altitude",
+"comment",
+"course",
+"created",
+"format",
+"frame",
+"from",
+"gpsfixstatus",
+"latitude",
+"longitude",
+"mbits",
+"messagecapable",
+"message_text",
+"mtype",
+"object_format",
+"object_name",
+"path",
+"posambiguity",
+"raw",
+"raw_timestamp",
+"speed",
+"station_call",
+"station_lat",
+"station_lon",
+"status",
+"symbol",
+"symbol_table",
+"telemetry",
+"timestamp",
+"to",
+"tEQNS",
+"tPARM",
+"tUNIT",
+"via",
+"weather",
+"wx_raw_timestamp")
+
+def read_config():
+    config = configparser.ConfigParser()
+    config.read('config.ini')
+    return config
+
+def get_db_connection():
+    conn = sqlite3.connect('database.db')
+    conn.row_factory = sqlite3.Row
+    return conn
+
+def main():
+
+    # Add the call and location of this station to the packet info
+    config = read_config()
+
+    ki = aprs.TCPKISS(host=KISS_HOST, port=int(KISS_PORT))
+    ki.start()
+
+    # Make a simple frame and send it
+    frame = aprs.APRSFrame.ui(
+        destination="APZ001",
+        source=MYCALL,
+        path=["WIDE1-1"],
+        info=b">Hello World!",
+    )
+    #ki.write(frame)
+
+    # Watch for new packets to come in
+    while True:
+        conn = get_db_connection()
+        for frame in ki.read(min_frames=1):
+            a = aprslib.parse(str(frame))
+            a['station_call'] = config['Settings']['station_call']
+            a['station_lat'] = config['Settings']['station_lat']
+            a['station_lon'] = config['Settings']['station_lon']
+            print(a)
+            # Make this a string and deal with it later (probably a mistake)
+            a['path'] = str(a['path'])
+            # Build an INSERT statement based on the fields we have from the frame
+            attrib_names = ', '.join(f'"{w}"' for w in a.keys())
+            attrib_values = ", ".join("?" * len(a.keys()))
+            sql = f"INSERT INTO frames ({attrib_names}) VALUES ({attrib_values})"
+            # Insert data
+            conn.execute(sql, list(a.values()))
+            conn.commit()
+
+            # TODO remove packets that are older ('created') than a limit set in config.ini
+            # "5 minutes" also works
+            conn.execute("DELETE FROM frames WHERE created < DATETIME('now', '"+config['Settings']['keep_time']+"')")
+            conn.commit()
+
+        conn.close()
+
+
+
+if __name__ == "__main__":
+    main()