diff --git a/gatewayNode/parking.py b/gatewayNode/parking.py index 4d94b8d..01d0c98 100644 --- a/gatewayNode/parking.py +++ b/gatewayNode/parking.py @@ -14,11 +14,14 @@ with open('/home/pi/project/data.json', 'r') as json_file: if json_data != "" and json_data != None: server_par = json.loads(json_data.replace('\n','').replace(' ','')) + # Initialize server IP and Port to make the connection. server_ip = server_par['ip'] server_port = server_par['port'] if server_ip != None and server_port != None: API_ENDPOINT = 'http://' + server_ip + ':' + server_port + '/parkingStatus' + + # Initialize Serial Connection with Arduino Uno ser = serial.Serial( port='/dev/ttyACM0', baudrate = 9600, @@ -32,28 +35,48 @@ if json_data != "" and json_data != None: ser.readline() prev_status = "-1" - device_session = requests.session() + # Authentication body content. data = """{"username" :""" + server_par['username'] + """, "password":""" + server_par['password'] + """, "device": """ + server_par['device'] + """}""" - s.post(url = API_ENDPOINT, data = data) - while 1: - park_status = ser.readline() - park_status_data = str(park_status).split("#") - - parkingCode = park_status_data[0].replace('b\'','') - parkingStatus = park_status_data[1].replace('\\r\\n\'', '') - - try: - if parkingStatus != prev_status: - data = """{"no":""" + parkingCode + ""","status":""" + parkingStatus + """}""" - r = s.post(url = API_ENDPOINT, data = data) - if parkingStatus == "0": - print("parking reserved. RESPONSE :", r.status_code, "\n") - elif parkingStatus == "1": - print("parking not reserved. RESPONSE : ", r.status_code, "\n") - except NameError as e: - print("**Not already prev variable. : ", str(e), "\n") - prev_status = parkingStatus - else: - print("Create a *.json configuration like: {'ip' : 'xxx.xxx.xxx.xxx', 'port': 'xxxx'}") + # Request to Authenticate Node. + resp = requests.post(url = API_ENDPOINT, data = data) + + # Unpack our data to a JSON object + data = json.loads(resp.content) + try: + # Check if node is Authenticated. "cookie + if data['cookie'] != None: + cookie = data['cookie'] + while 1: + # For a while we request to get Parking Status + # witch is a JSON object like [{"no": 1, "status": false}, {"no": 2, "status": true}, ..., {"no": n, "status": true}] + park_status = ser.readline() + + # Substring the input data from arduino. + # Data's notation is: # + park_status_data = str(park_status).split("#") + + # Decode and clear serial input data encoding. + parkingCode = park_status_data[0].replace('b\'','') + parkingStatus = park_status_data[1].replace('\\r\\n\'', '') + + try: + if parkingStatus != prev_status: + # If parking status changed from previous status + # server would informed about this change. + data = """{"no":""" + parkingCode + ""","status":""" + parkingStatus + """, "cookie": \"""" + cookie + """\"}""" + r = s.post(url = API_ENDPOINT, data = data) + + # IO : node prints to output the current + if parkingStatus == "0": + print("parking reserved. RESPONSE :", r.status_code, "\n") + elif parkingStatus == "1": + print("parking not reserved. RESPONSE : ", r.status_code, "\n") + except NameError as e: + print("**Not already prev variable. : ", str(e), "\n") + prev_status = parkingStatus + except TypeError as e: + print("Node must be authenticate first.") + else: + print("Create a *.json configuration like: {'ip' : 'xxx.xxx.xxx.xxx', 'port': 'xxxx'}") diff --git a/serverNode/__pycache__/serv.cpython-37.pyc b/serverNode/__pycache__/serv.cpython-37.pyc index d11e2ef..04c4797 100644 Binary files a/serverNode/__pycache__/serv.cpython-37.pyc and b/serverNode/__pycache__/serv.cpython-37.pyc differ diff --git a/serverNode/serv.py b/serverNode/serv.py index 2784887..93230b7 100644 --- a/serverNode/serv.py +++ b/serverNode/serv.py @@ -1,13 +1,14 @@ #Authors: Oulis Evangelos, Oulis Nikolaos, Drosos Katsibras #=================================================================== # using flask restful -from flask import Flask, request, jsonify, session +from flask import Flask, request, jsonify from flask_restful import Resource, Api from json import dumps import json from flask_cors import CORS import mysql.connector -import os +from base64 import b64encode +from os import urandom # ================================================================== # ================================================================== @@ -16,8 +17,8 @@ import os app = Flask(__name__) CORS(app) -# create the secret key for session -app.secret_key = os.urandom(24) +# Session list +sessions = [] # creating an API object api = Api(app) @@ -65,10 +66,13 @@ def isMember(username, password): # Function that return if the requested user is authenticated # or not (True / False). -def isAuthenticated(): - if 'device_id' in session: - return True - else: +def isAuthenticated(data): + try: + if data['cookie'] in sessions: + return True + else: + return False + except KeyError as e: return False @@ -77,16 +81,19 @@ def isAuthenticated(): # the get, post methods correspond to get and post requests # they are automatically mapped by flask_restful. # other methods include put, delete, etc. + +# Resource that returns th whole parking status in a JSON class Parking(Resource): def get(self): parks = None try: parks = getParkings() - except mysql.connector.errors.DatabaseError as e: + except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: mydb.reconnect(attempts=1, delay=0) return parks, 200 +# Update parking status resource from authenticated only Node class ParkingStatus(Resource): def get(self): return """ @@ -94,10 +101,9 @@ class ParkingStatus(Resource):

Not get at '/parkingStatus'.

""" def post(self): - if isAuthenticated(): - # Gets the data into as a JSON Object from HTTP request. - data = json.loads(request.data) - + # Gets the data into as a JSON Object from HTTP request. + data = json.loads(request.data) + if isAuthenticated(data): try: # SQL get all Parking places status. parks = getParkings() @@ -138,13 +144,14 @@ class ParkingStatus(Resource): myCursor.execute("UPDATE PARKING SET PARKING_STATUS=%s WHERE PARKING_CODE=%s", values) mydb.commit() parks = getParkings() - except mysql.connector.errors.DatabaseError as e: + except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: mydb.reconnect(attempts=1, delay=0) return currentParking, 201 else: return "Error! You aren't authenticated. [POST] /authenticate first.", 403 +# Authentication resource. class Authenticate(Resource): def post(self): try: @@ -155,22 +162,28 @@ class Authenticate(Resource): isValid = isMember(data['username'], data['password']) if isValid: - session['device_id'] = data['device'] + session_key = str(b64encode(urandom(32)).decode('utf-8')) + + # Send the cookie value back to clinet. + session = {"cookie": session_key} + sessions.append(session_key) + return session, 200 else: - return "Not Authenticatiove device", 403 + return "Not Authenticative device", 403 else: return "Error authentication", 403 - except mysql.connector.errors.DatabaseError as e: + except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: mydb.reconnect(attempts=1, delay=0) # ================================================================== -# adding the defined resources along with their corresponding urls to REST APIs +# matches the defined resources to their corresponding urls to REST APIs api.add_resource(Parking, '/') api.add_resource(ParkingStatus, '/parkingStatus') api.add_resource(Authenticate, '/authenticate') # ================================================================== -# driver function +# ===========================MAIN CLASS============================= +# driver function "Main Class" if __name__ == '__main__': app.run( debug=True, diff --git a/servo_pins_description.jpg b/servo_pins_description.jpg deleted file mode 100644 index 1f41f48..0000000 Binary files a/servo_pins_description.jpg and /dev/null differ