diff --git a/config.py b/config.py index 6e0f860..921945f 100755 --- a/config.py +++ b/config.py @@ -174,6 +174,8 @@ def build_config(_config_file): 'AUTHORIZED_TOKENS_FILE': config.get(section, 'AUTHORIZED_TOKENS_FILE'), 'AUTHORIZED_USERS_FILE': config.get(section, 'AUTHORIZED_USERS_FILE'), 'ACCESS_SYSTEMS_FILE': config.get(section, 'ACCESS_SYSTEMS_FILE'), + 'MY_API_NAME': config.get(section, 'MY_API_NAME'), + 'DASHBOARD_URL': config.get(section, 'DASHBOARD_URL'), }) diff --git a/full_bridge-SAMPLE.cfg b/full_bridge-SAMPLE.cfg index 2c24ad0..686f66d 100644 --- a/full_bridge-SAMPLE.cfg +++ b/full_bridge-SAMPLE.cfg @@ -175,11 +175,16 @@ AUTHORIZED_APPS_FILE: /path/to/authorized_apps.py AUTHORIZED_TOKENS_FILE: /tmp/hblink_auth_tokens.txt AUTHORIZED_USERS_FILE: /path/to/authorized_users.txt ACCESS_SYSTEMS_FILE: /path/to/access_systems.txt +MY_API_NAME: ABC + # The following options are used for the dashboard. The dashboard is optional. # Title of the Dashboard DASHBOARD_TITLE: HBLink3 D-APRS Dashboard +# Used for API, RSS feed link, etc +DASHBOARD_URL: http://localhost:8092 + # Logo used on dashboard page LOGO: https://raw.githubusercontent.com/kf7eel/hblink3/gps/HBlink.png @@ -210,9 +215,6 @@ ZOOM_LEVEL: 7 # The following are options for map themes and just work, you should use one of these: “OpenStreetMap”, “Stamen” (Terrain, Toner, and Watercolor), MAP_THEME: Stamen Toner -# RSS feed link, shows in the link section of each RSS item. -RSS_LINK: http://localhost:8092 - ##################################################################### # OPENBRIDGE INSTANCES - DUPLICATE SECTION FOR MULTIPLE CONNECTIONS # OpenBridge is a protocol originall created by DMR+ for connection between an diff --git a/full_bridge.py b/full_bridge.py index 92fdeb1..6f0fbaf 100644 --- a/full_bridge.py +++ b/full_bridge.py @@ -100,6 +100,10 @@ import libscrc import random from bitarray.util import hex2ba as hex2bits +#Used for sending data via API +import requests +import json +import hashlib # Does anybody read this stuff? There's a PEP somewhere that says I should do this. __author__ = 'Cortney T. Buffington, N0MJS' @@ -237,6 +241,59 @@ def sos_write(dmr_id, time, message): sos_file.write(str(sos_info)) sos_file.close() logger.info('Saved SOS.') +def send_app_request(url, message, source_id): + url = url + '/app' + #Load current AUTH token list + auth_file = ast.literal_eval(os.popen('cat ' + auth_token_file).read()) + the_token = str(hashlib.md5(str(time()).encode('utf-8')).hexdigest()) + new_auth_file = auth_file + new_auth_file.append(the_token) + # Write new list to file + with open(auth_token_file, 'w') as auth_token: + auth_token.write(str(auth_file)) + auth_token.close() + app_request = { + 'mode':'app', + 'system_name':CONFIG['GPS_DATA']['MY_API_NAME'], + 'response_url':CONFIG['GPS_DATA']['DASHBOARD_URL'], + 'auth_token':the_token, + 'data':{ + 'source_id':source_id, + 'slot':0, + 'msg_type':'unit', + 'msg_format':'motorola', + 'message':message + } + } + json_object = json.dumps(app_request, indent = 4) + print(json_object) + requests.post(url, data=json_object, headers={'Content-Type': 'application/json'}) + + +def send_msg_xfer(url, user, password, message, source_id, dest_id): + url = url + '/msg_xfer' + msg_xfer = { + 'mode':'msg_xfer', + 'system_name':CONFIG['GPS_DATA']['MY_API_NAME'], + 'response_url':CONFIG['GPS_DATA']['DASHBOARD_URL'], + 'auth_type':'private', + 'credentials': { + 'user':user, + 'password':password, + }, + 'data':{ + 1:{'source_id':source_id, + 'destination_id':dest_id, + 'slot':0, + 'msg_type':'unit', + 'msg_format':'motorola', + 'message':message + } + } + } + json_object = json.dumps(msg_xfer, indent = 4) + requests.post(url, data=json_object, headers={'Content-Type': 'application/json'}) + # Send email via SMTP function def send_email(to_email, email_subject, email_message): @@ -412,7 +469,32 @@ def process_sms(_rf_src, sms): logger.info(str(traceback.extract_tb(error_exception.__traceback__))) packet_assembly = '' - + elif '?' in parse_sms[0][0:1]: + use_api = CONFIG['GPS_DATA']['USE_API'] + print(use_api) + if use_api == True: + auth_tokens = ast.literal_eval(os.popen('cat ' + auth_token_file).read()) + access_systems = ast.literal_eval(os.popen('cat ' + access_systems_file).read()) + authorized_users = ast.literal_eval(os.popen('cat ' + authorized_users_file).read()) + system = parse_sms[0][1:] + #print(access_systems[system]) + #print(authorized_users) + # Determin msg_xfer or app + if access_systems[system]['mode'] == 'msg_xfer': + s = ' ' + message_to_send = s.join(parse_sms[2:]) + dest_id = int(parse_sms[1]) + source_id = int_id(_rf_src) + send_msg_xfer(access_systems[system]['url'], access_systems[system]['user'], access_systems[system]['password'], message_to_send, source_id, dest_id) + if access_systems[system]['mode'] == 'app': + s = ' ' + message_to_send = s.join(parse_sms[1:]) + source_id = int_id(_rf_src) + send_app_request(access_systems[system]['url'], message_to_send, source_id) + + + if use_api == False: + send_sms(False, int_id(_rf_src), data_id, 0000, 'unit', 'API not enabled. Contact server admin.') elif '@' in parse_sms[0][0:1] and 'M-' not in parse_sms[1][0:2] or '@' not in parse_sms[0][1:]: #Example SMS text: @ARMDS A-This is a test. s = ' ' @@ -2123,7 +2205,6 @@ class bridgeReportFactory(reportFactory): #************************************************ if __name__ == '__main__': - import argparse import sys import os diff --git a/scripts/dashboard/dashboard.py b/scripts/dashboard/dashboard.py index 3c8c494..663e5ab 100644 --- a/scripts/dashboard/dashboard.py +++ b/scripts/dashboard/dashboard.py @@ -731,6 +731,9 @@ def api(api_mode=None): access_systems = ast.literal_eval(os.popen('cat ' + access_systems_file).read()) authorized_users = ast.literal_eval(os.popen('cat ' + authorized_users_file).read()) api_data = request.json + #print(type(api_data)) + #print((api_data)) + # Find out mode of JSON ## try: # Filter msg_xfer @@ -738,28 +741,32 @@ def api(api_mode=None): # Handle authorization if api_data['auth_type'] == 'private': #Authenticate - if api_data['system_name'] in authorized_users and api_data['credentials']['user'] == authorized_users[api_data['system_name']]['user'] and api_data['credentials']['password'] == authorized_users[api_data['system_name']]['password']: - print(api_data['credentials']['user']) - print(api_data['credentials']['password']) - for sms in api_data['data'].items(): - sms_data = sms[1] - print((sms_data['destination_id'])) - print((sms_data['source_id'])) - print((sms_data['message'])) - print((sms_data['slot'])) - if sms_data['slot'] == 0: - send_slot = int(unit_sms_ts) - 1 - if sms_data['slot'] == 1: - send_slot = 0 - if sms_data['slot'] == 2: - send_slot = 1 - send_sms(False, sms_data['destination_id'], sms_data['source_id'], 0000, 'unit', send_slot, sms_data['message']) - return jsonify( - mode=api_data['mode'], - status='Generated SMS', - ) + if api_data['system_name'] in authorized_users: + if api_data['credentials']['user'] == authorized_users[api_data['system_name']]['user'] and api_data['credentials']['password'] == authorized_users[api_data['system_name']]['password']: + print(api_data['credentials']['user']) + print(api_data['credentials']['password']) + for sms in api_data['data'].items(): + sms_data = sms[1] + print((sms_data['destination_id'])) + print((sms_data['source_id'])) + print((sms_data['message'])) + print((sms_data['slot'])) + if sms_data['slot'] == 0: + send_slot = int(unit_sms_ts) - 1 + if sms_data['slot'] == 1: + send_slot = 0 + if sms_data['slot'] == 2: + send_slot = 1 + send_sms(False, sms_data['destination_id'], sms_data['source_id'], 0000, 'unit', send_slot, sms_data['message']) + return jsonify( + mode=api_data['mode'], + status='Generated SMS', + ) + else: + message = jsonify(message='Authentication error') + return make_response(message, 401) else: - message = jsonify(message='Authentication error') + message = jsonify(message='System not authorized') return make_response(message, 401) if api_data['auth_type'] == 'public': message = jsonify(message='Not implemented') @@ -770,7 +777,12 @@ def api(api_mode=None): if api_data['mode'] == 'app': auth_file = ast.literal_eval(os.popen('cat ' + auth_token_file).read()) for token in auth_file: + print() + print(token) + print(api_data['auth_token']) + print() if token == api_data['auth_token']: + auth_file.remove(api_data['auth_token']) for i in api_data['data'].items(): sms_data = i[1] @@ -855,7 +867,7 @@ if __name__ == '__main__': time_format = parser.get('GPS_DATA', 'TIME_FORMAT') # RSS feed link, shows in the link section of each RSS item. - rss_link = parser.get('GPS_DATA', 'RSS_LINK') + rss_link = parser.get('GPS_DATA', 'DASHBOARD_URL') # Default APRS comment for users. default_comment = parser.get('GPS_DATA', 'USER_APRS_COMMENT')