def lambda_handler()

in send_downlink_payload/src/app.py [0:0]


def lambda_handler(event, context):
    """ Invokes a AWS IoT Core for LoRaWAN send_data_to_device API based on parameters provided in Event
        Parameters
        ----------
        "WirelessDeviceId", "FPort", "PayloadData","TransmitMode"
        DeviceId : str
            AWS IoT Core for LoRaWAN Device Id
        FPort : int
            Port number
        PayloadData : str,  Base64 encoded twice
            Please note this this function expects that a binary payload is encoded twice using Base64.

            To understand the reason for double encoding, let's consider how a binary payload 
            (e.g. 0x414243) is processed in this sample:

            1. You initiate sending of data to a LoRaWAN devices by invocation of the AWS IoT Rule
               SendDataToWirelessDeviceRule. The rule can be invoked either by due to subscription
               as define in WHERE clause (https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-from.html) or via Basic Ingest (https://docs.aws.amazon.com/iot/latest/developerguide/iot-basic-ingest.html).

               For example you can invoke SendDataToWirelessDeviceRule by publishing to the MQTT broker topic `cmd/downlink/c7867453-5404-4680-a081-0fda2902110a`. You could also perform Basic Ingest by publishing to $aws/rules/SendDataToWirelessDeviceRule/cmd/downlink/c7867453-5404-4680-a081-0fda2902110a .

            2. The AWS IoT Rule SendDataToWirelessDeviceRule expects Base64-encoded payload as an input.

            3. Before AWS IoT Rule SendDataToWirelessDeviceRule can pass a payload to this AWS Lambda function, the payload have to be Base64-encoded once again. Please consult 
            https://docs.aws.amazon.com/iot/latest/developerguide/binary-payloads.html for details.

        TransmitMode : int
            Please consult AWS IoT Core for LoRaWAN documentation for details.

        """
    logger.info("Received event: %s" % json.dumps(event))

    # Check if all the necessary params are included and return an error ststus otherwise
    for i in OBLIGATORY_PARAMETERS:
        if not i in event:
            logger.error(f"Parameter {i} missing ")
            return {
                "status": 500,
                "errormessage": f"Parameter {i} missing"
            }

    (device_id, fport, transmit_mode, payload_data) = (
        event["WirelessDeviceId"], event["FPort"], event["TransmitMode"], event["PayloadData"])

    # Decode base64 payload. Please note that decoded payload will still have Base64
    # format. Please review the documentation of this function for details.
    print(f"Payload to decode : {payload_data}")
    payload_data_decoded = base64.b64decode(payload_data).decode("utf-8")

    print(f"Decoded data : {payload_data_decoded}")

    try:
        response = client.send_data_to_wireless_device(TransmitMode=transmit_mode,
                                                       Id=device_id,
                                                       WirelessMetadata={"LoRaWAN": {"FPort": fport}}, PayloadData=payload_data_decoded)
    except client.exceptions.ResourceNotFoundException as e:
        logger.error("Error calling LoRaWAN for AWS IoT Core API : " + str(e))
        return {
            "status": 500,
            "errormessage": f"Device with WirelessDeviceId {device_id} not found"
        }
    except Exception as e:
        exception_type, exception_value, exception_traceback = sys.exc_info()
        traceback_string = traceback.format_exception(
            exception_type, exception_value, exception_traceback)

        logger.error("Error calling LoRaWAN for AWS IoT Core API : " + str(e))
        return {
            "status": 500,
            "errormessage": str(e),
            "traceback": traceback_string
        }

    result = {
        "status": 200,
        "RequestId": response["ResponseMetadata"]["RequestId"],
        "MessageId": response["MessageId"],
        # Parameter trace below is for debugging and prototyping purposes and should
        # be removed in a production deployment unless needed
        "ParameterTrace": {
            "PayloadData": payload_data_decoded,
            "WirelessDeviceId": device_id,
            "Fport": fport,
            "TransmitMode": transmit_mode
        }
    }

    print(f"Successfull API call result {json.dumps(result)}")

    return result