Ejemplo n.º 1
0
    def on_post(self, request, response):
        configuration = self.configuration_store.get()

        if configuration.get_device_status() is not DeviceStatus.ACTIVE:
            error = 'Not allowed to trigger actions when device is not activated.'
            Logger.error(LOCATION, error)
            raise falcon.HTTPForbidden(description=error)

        Logger.info(LOCATION,
                    INCOMING_REQUEST + METHOD_POST + ' ' + ACTIONS_ENDPOINT)
        data = request.media
        if ACTION_ID not in data.keys():
            Logger.error(
                LOCATION, 'Missing parameter `' + ACTION_ID + '` for ' +
                METHOD_POST + ' ' + ACTIONS_ENDPOINT)
            raise falcon.HTTPBadRequest

        action_id = data[ACTION_ID]
        value = data[VALUE_KEY] if VALUE_KEY in data.keys() else None

        success = self.action_service.trigger(action_id, value)
        if success:
            response.media = {'message': 'Action triggered'}
        else:
            raise falcon.HTTPServiceUnavailable
Ejemplo n.º 2
0
 def _get_response(data):
     if RESPONSE_DATA_KEY not in data:
         Logger.error(
             LOCATION,
             'Unexpected response format from BoT.' + json.dumps(data))
         raise falcon.HTTPInternalServerError
     return json.loads(data[RESPONSE_DATA_KEY])
Ejemplo n.º 3
0
 def save_qrcode(image):
     try:
         with open(_qr_image_path, 'wb') as qr_image:
             image.save(qr_image)
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 4
0
 def set_configuration(configuration):
     try:
         with open(_configuration_file_path, 'w') as configuration_file:
             configuration_file.write(json.dumps(configuration))
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 5
0
 def on_advertising_start(self, error):
     if error:
         Logger.error(LOCATION, 'Failed to start advertising.')
     else:
         Logger.info(LOCATION, 'Successfully started advertising.')
     if not error:
         bleno.setServices([blenoService], self.on_set_services)
Ejemplo n.º 6
0
 def set_actions(actions):
     try:
         with open(_actions_file_path, 'w') as actions_file:
             actions_file.write(json.dumps(actions))
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 7
0
 def get_configuration():
     try:
         with open(_configuration_file_path, 'r') as configuration_file:
             configuration = configuration_file.read()
             return json.loads(configuration)
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
 def activate(self):
     try:
         self.bot_service.post(RESOURCE, {DEVICE_ID: self.device_id})
         Logger.success(LOCATION, 'Device successfully activated. Triggering actions enabled.')
         return True
     except:
         Logger.error(LOCATION, 'Failed to activate device.')
         return False
Ejemplo n.º 9
0
 def _get_action(self, action_id):
     actions = self.get_actions()
     for action in actions:
         if action[ACTION_ID] == action_id:
             Logger.success(LOCATION, 'Action found')
             return action
     Logger.error(LOCATION, 'Action not found')
     raise falcon.HTTPNotFound(description='Action not found')
Ejemplo n.º 10
0
 def get_bot_public_key():
     try:
         with open(_bot_public_key) as bot_file:
             public_key = bot_file.read()
             return public_key
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 11
0
 def onWriteRequest(self, data, offset, without_response, callback):
     if offset:
         callback(Characteristic.RESULT_ATTR_NOT_LONG)
     else:
         callback(Characteristic.RESULT_SUCCESS)
     if offset > len(data):
         callback(bleno.Characteristic.RESULT_INVALID_OFFSET)
         Logger.error(LOCATION, 'Error in Characteristic')
     else:
         callback(Characteristic.RESULT_SUCCESS)
         #decode the byte sequence sent from the client and prepare a JSON structure
         details = json.loads(data.decode())
         #skip wifi configuration
         skip_wifi_config = False
         try:
             skip_wifi_config = details['Skip']
         except:
             Logger.info(LOCATION, 'Wifi Configuration is available ..')
         #wifi configuration is enabled from the client
         if skip_wifi_config == True:
             Logger.info(
                 LOCATION, 'Connected device skipped Wifi setup. ' +
                 'Initializing pairing process...')
             PairingService().run()
         else:
             wifi_details = ''
             #if valid SSID provided then create the wpa supplicant configuration.
             if details['SSID'] != '':
                 wifi_details = 'ctrl_interface=DIR=/var/run/wpa_supplicant' + \
                               ' GROUP=netdev\r\n update_config=1\r\n country=GB \r\n'+ \
                               'network={ \r\n        ssid="' + details['SSID'] + \
                               '" \r\n' + \
                               '        psk="' + details['PWD'] + \
                               '" \r\n        ' + \
                               'key_mgmt=WPA-PSK \r\n}'
             Logger.info(
                 LOCATION,
                 'Wifi setup complete. Initializing pairing process...')
             PairingService().run()
             time.sleep(3)
             subprocess.run([
                 'sudo echo \'' + wifi_details +
                 '\' > ./wpa_supplicant.conf'
             ],
                            shell=True)
             subprocess.run([
                 "sudo", "cp", "./wpa_supplicant.conf",
                 "/etc/wpa_supplicant/"
             ])
             Logger.info(
                 LOCATION,
                 'Wifi configuration done! Device reboot in progress')
             # run the necessary command to update the wpa supplicant file with in /etc/
             subprocess.run(["sudo", "rm", "./wpa_supplicant.conf"])
             subprocess.run(["sudo", "sleep", "1"])
             # reboot the device after successful update of wpa suppicant configuration
             subprocess.run(["sudo", "reboot"])
Ejemplo n.º 12
0
 def _decode(token):
     try:
         data = jwt.decode(token,
                           Store.get_bot_public_key(),
                           algorithms=['RS256'])
     except:
         Logger.error(LOCATION, 'Could not decode message from BoT.')
         raise falcon.HTTPInternalServerError
     return data
Ejemplo n.º 13
0
 def on_get(self, request, response):
     Logger.info(LOCATION, "Serving Activation Request...")
     configuration = self.configuration_store.get()
     if configuration.get_device_status() is DeviceStatus.ACTIVE:
         error = 'Device is already activated'
         Logger.error(LOCATION, error)
         raise falcon.HTTPBadRequest(description=error)
     else:
         self.configuration_service.resume_configuration()
Ejemplo n.º 14
0
 def get_last_triggered(action_id):
     if not os.path.isfile(_last_triggered_file_path):
         return None
     try:
         with open(_last_triggered_file_path) as last_triggered_file:
             data = json.loads(last_triggered_file.read())
             return data[action_id] if action_id in data.keys() else None
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 15
0
 def on_get(self, request, response):
     Logger.info(LOCATION,
                 INCOMING_REQUEST + METHOD_GET + ' ' + PAIRING_ENDPOINT)
     configuration = self.configuration_store.get()
     if configuration.get_device_status() is not DeviceStatus.NEW:
         error = 'Device is already paired.'
         Logger.error(LOCATION, error)
         raise falcon.HTTPForbidden(description=error)
     response.media = configuration.get_device_information
     subprocess.Popen(['make', 'pair'])
Ejemplo n.º 16
0
 def get_actions():
     if not os.path.isfile(_actions_file_path):
         return []
     try:
         with open(_actions_file_path, 'r') as actions_file:
             actions = json.loads(actions_file.read())
             return actions
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 17
0
 def pair(self):
     try:
         response = self.bot_service.get(RESOURCE)
     except:
         Logger.error(LOCATION, 'Failed pairing attempt.')
         return False
     if response['status'] is True:
         Logger.success(LOCATION, 'Device successfully paired.')
         return True
     else:
         Logger.error(LOCATION, 'Failed pairing attempt.')
         return False
 def generate_qr_code(self):
     try:
         Logger.info(LOCATION,
                     'Generating QR Code for alternative pairing...')
         device_information = self.configuration.get_device_information()
         image = qrcode.make(json.dumps(device_information),
                             image_factory=PymagingImage)
         Store.save_qrcode(image)
         Logger.success(LOCATION, 'QR Code successfully generated')
     except Exception as exception:
         Logger.error(LOCATION, 'QR Code not generated')
         raise exception
Ejemplo n.º 19
0
 def set_last_triggered(action_id, time):
     data = {}
     if os.path.isfile(_last_triggered_file_path):
         with open(_last_triggered_file_path, 'r') as last_triggered_file:
             data = json.loads(last_triggered_file.read())
     data[action_id] = time
     try:
         with open(_last_triggered_file_path, 'w') as last_triggered_file:
             last_triggered_file.write(json.dumps(data))
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 20
0
 def remove_configuration():
     try:
         if Store.has_configuration():
             os.remove(_configuration_file_path)
             os.remove(_qr_image_path)
             Logger.success(LOCATION,
                            'Successfully removed configuration file')
         else:
             Logger.warning(LOCATION,
                            'Could not reset, no configuration available')
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 21
0
 def pair(self):
     try:
         response = self.bot_service.get(RESOURCE)
         Logger.info(LOCATION, 'Pairing Response: ' + str(response))
     # TODO : Make exception more specific
     except:
         Logger.error(LOCATION, 'Failed pairing attempt.')
         return False
     if response['status'] is True:
         Logger.success(LOCATION, 'Device successfully paired.')
         return True
     else:
         Logger.error(LOCATION, 'Failed pairing attempt.')
         return False
Ejemplo n.º 22
0
    def onAdvertisingStart(self, error):
        if error:
            Logger.error(LOCATION, 'Failed to start advertising.')
        else:
            Logger.info(LOCATION, 'Successfully started advertising.')
        if not error:

            def on_setServiceError(error):
                if error:
                    Logger.error(LOCATION, 'setServices: ', error)
                else:
                    Logger.info(LOCATION, 'Successfully set services.')

            bleno.setServices([blenoService], on_setServiceError)
Ejemplo n.º 23
0
    def trigger(self, action_id, value=None):
        Logger.info(LOCATION, 'Triggering action: ' + action_id)
        action = self._get_action(action_id)
        self._validate_frequency(action)
        Logger.success(LOCATION, 'Action valid')

        data = self.create_trigger_body(action_id, value)
        try:
            self.bot_service.post(ACTIONS_ENDPOINT, data)
            Logger.success(LOCATION, 'Successfully triggered action: ' + action_id)
            self.store.set_last_triggered(action_id, time.time())
            return True
        except:
            Logger.error(LOCATION, 'Unable to trigger action: ' + action_id)
            return False
Ejemplo n.º 24
0
 def get(self, url):
     session = requests.Session()
     session.mount(API_URL, FingerprintAdapter(SSL_FINGERPRINT))
     try:
         response = session.get(API_URL + url,
                                headers=self.configuration.get_headers())
         data = self._decode(response.text)
         if response.status_code < 200 or response.status_code >= 300:
             Logger.error(
                 LOCATION, 'status: ' + str(response.status_code) +
                 ', body: ' + json.dumps(data))
             raise falcon.HTTPServiceUnavailable
         return self._get_response(data)
     except requests.exceptions.SSLError:
         self._handle_ssl_exception()
Ejemplo n.º 25
0
 def post(self, url, data):
     session = requests.Session()
     session.mount(API_URL, FingerprintAdapter(SSL_FINGERPRINT))
     try:
         response = session.post(API_URL + url,
                                 data=self._create_request_body(data),
                                 headers=self.configuration.get_headers())
         if response.status_code < 200 or response.status_code >= 300:
             Logger.error(
                 LOCATION, 'status: ' + str(response.status_code) +
                 ', body: ' + response.text)
             raise falcon.HTTPServiceUnavailable
     except requests.exceptions.SSLError:
         self._handle_ssl_exception()
     except:
         Logger.error(LOCATION, 'Failed to POST resource.')
         raise falcon.HTTPServiceUnavailable
Ejemplo n.º 26
0
    def onWriteRequest(self, data, offset, withoutResponse, callback):
        if offset:
            callback(Characteristic.RESULT_ATTR_NOT_LONG)
        else:
            callback(Characteristic.RESULT_SUCCESS)

        if offset > len(data):
            callback(bleno.Characteristic.RESULT_INVALID_OFFSET)
            Logger.error(LOCATION, 'Error in Characteristic')
        else:
            callback(Characteristic.RESULT_SUCCESS, data[offset:])
            details = json.loads(data)

            if details['Skip'] == True:
                Logger.info(
                    LOCATION, 'Connected device skipped Wifi setup. ' +
                    'Initializing pairing process...')
                PairingService().run()
            else:
                wifiDetails = ''

                if details['SSID'] != '':
                    wifiDetails = 'ctrl_interface=DIR=/var/run/wpa_supplicant' + \
                                  ' GROUP=netdev\r\n update_config=1\r\n country=GB \r\n'+ \
                                  'network={ \r\n        ssid="' + details['SSID'] + \
                                  '" \r\n' + \
                                  '        psk="' + details['PWD'] + \
                                  '" \r\n        ' + \
                                  'key_mgmt=WPA-PSK \r\n}'

                Logger.info(
                    LOCATION,
                    'Wifi setup complete. Initializing pairing process...')
                PairingService().run()
                time.sleep(3)
                subprocess.run([
                    'sudo echo \'' + wifiDetails + '\' > ./wpa_supplicant.conf'
                ],
                               shell=True)
                subprocess.run([
                    "sudo", "cp", "./wpa_supplicant.conf",
                    "/etc/wpa_supplicant/"
                ])
                subprocess.run(["sudo", "rm", "./wpa_supplicant.conf"])
                subprocess.run(["sudo", "sleep", "1", "&&", "reboot"])
Ejemplo n.º 27
0
 def remove_configuration():
     try:
         if Store.has_configuration():
             os.remove(_configuration_file_path)
             if os.path.isfile(_qr_image_path):
                 os.remove(_qr_image_path)
             if os.path.isfile(_saved_actions_path):
                 os.remove(_saved_actions_path)
             if os.path.isfile(_last_triggered_path):
                 os.remove(_last_triggered_path)
             Logger.success(LOCATION,
                            'Successfully reset device configuration')
         else:
             Logger.warning(LOCATION,
                            'Could not reset, no configuration available')
     except IOError as io_error:
         Logger.error(LOCATION, io_error.message)
         raise io_error
Ejemplo n.º 28
0
 def _handle_ssl_exception():
     error = 'SSL Fingerprint verification failed. Could not verify server.'
     Logger.error(LOCATION, error)
     raise falcon.HTTPServiceUnavailable(description=error)
Ejemplo n.º 29
0
 def _handle_unsupported_frequency(frequency):
     error = 'Frequency not supported: ' + frequency
     Logger.error(LOCATION, error)
     raise falcon.HTTPBadRequest(description=error)
Ejemplo n.º 30
0
 def on_setServiceError(error):
     if error:
         Logger.error(LOCATION, 'setServices: ', error)
     else:
         Logger.info(LOCATION, 'Successfully set services.')