Beispiel #1
0
    def _getResponseLength(self, timeout: int):
        PN532_NACK = [0, 0, 0xFF, 0xFF, 0, 0]
        timer = 0

        while (not self._isReady()):
            time.sleep(.001)  # sleep 1 ms
            timer += 1
            if ((0 != timeout) and (timer > timeout)):
                return -1

        data = self._xfer_bytes([DATA_READ] + [0 for i in range(5)])
        data = data[1:]  # first byte is garbage
        DMSG('_getResponseLength length frame: {!r}'.format(data))

        if data[:-2] != bytearray(
            [PN532_PREAMBLE, PN532_STARTCODE1, PN532_STARTCODE2]):
            DMSG('Invalid Response frame: {}'.format(data))
            return PN532_INVALID_FRAME

        length = data[3]
        l_checksum = data[4]
        if (0 != (length + l_checksum) & 0xFF):
            DMSG('Invalid Length Checksum: len {:d} checksum {:d}'.format(
                length, l_checksum))
            return PN532_INVALID_FRAME

        DMSG('_getResponseLength length is {:d}'.format(length))

        #  Not needed for SPI
        # request for last respond msg again
        # DMSG('_getResponseLength writing nack: {!r}'.format(PN532_NACK))
        # self._send_bytes([DATA_WRITE] + PN532_NACK)

        return length
Beispiel #2
0
    def _getResponseLength(self, timeout: int):
        PN532_NACK = [0, 0, 0xFF, 0xFF, 0, 0]
        timer = 0

        while 1:
            responses = self._wire.transaction(reading(PN532_I2C_ADDRESS, 6))
            data = bytearray(responses[0])
            DMSG('_getResponseLength length frame: {!r}'.format(data))
            if data[0] & 0x1:
                # check first byte --- status
                break  # PN532 is ready

            time.sleep(.001)  # sleep 1 ms
            timer += 1
            if ((0 != timeout) and (timer > timeout)):
                return -1

        if (PN532_PREAMBLE != data[1] or  # PREAMBLE
                PN532_STARTCODE1 != data[2] or  # STARTCODE1
                PN532_STARTCODE2 != data[3]  # STARTCODE2
            ):
            DMSG('Invalid Length frame: {}'.format(data))
            return PN532_INVALID_FRAME

        length = data[4]
        DMSG('_getResponseLength length is {:d}'.format(length))

        # request for last respond msg again
        DMSG('_getResponseLength writing nack: {!r}'.format(PN532_NACK))
        self._wire.transaction(writing(PN532_I2C_ADDRESS, PN532_NACK))

        return length
Beispiel #3
0
    def waitForConnection(self, timeout: int = LLCP_DEFAULT_TIMEOUT) -> int:
        type = 0

        self.mode = 1
        self.ns = 0
        self.nr = 0

        # Get CONNECT PDU
        DMSG("wait for a CONNECT PDU\n")
        while 1:
            status, data = self.link.read()
            if (2 > status):
                return -1

            type = getPType(data)
            if (PDU_CONNECT == type):
                break
            elif (PDU_SYMM == type):
                if (not self.link.write(bytearray(self.SYMM_PDU))):
                    return -2
            else:
                return -3

        # Put CC PDU
        DMSG("put a CC(Connection Complete) PDU to response the CONNECT PDU\n")
        ssap = getDSAP(data)
        dsap = getSSAP(data)
        header = buildHeader(dsap, PDU_CC, ssap)
        if (not self.link.write(header)):
            return -2

        return 1
Beispiel #4
0
    def writeCommand(self, header: bytearray, body: bytearray = bytearray()):
        self._command = header[0]
        data_out = [PN532_PREAMBLE, PN532_STARTCODE1, PN532_STARTCODE2]

        length = len(header) + len(
            body) + 1  # length of data field: TFI + DATA
        data_out.append(length)
        data_out.append((~length & 0xFF) + 1)  # checksum of length

        data_out.append(PN532_HOSTTOPN532)
        dsum = PN532_HOSTTOPN532 + sum(header) + sum(body)  # sum of TFI + DATA

        data_out += list(header)
        data_out += list(body)
        checksum = ((~dsum & 0xFF) + 1) & 0xFF  # checksum of TFI + DATA

        data_out += [checksum, PN532_POSTAMBLE]

        DMSG("writeCommand: {}    {}    {}".format(header, body, data_out))

        try:
            # send data
            self._wire.transaction(writing(PN532_I2C_ADDRESS, tuple(data_out)))
        except Exception as e:
            DMSG(e)
            DMSG(
                "\nToo many data to send, I2C doesn't support such a big packet\n"
            )  # I2C max packet: 32 bytes
            return PN532_INVALID_FRAME

        return self._readAckFrame()
Beispiel #5
0
    def felica_Release(self) -> int:
        """
        Release FeliCa card
        :returns:   1: Success, < 0: error
        """
    
        # InRelease
        header = bytearray([
            PN532_COMMAND_INRELEASE,
            0x00,  # All target
        ])

        DMSG("Release all FeliCa target\n")

        if (self._interface.writeCommand(header)):
            DMSG("No ACK\n")
            return -1  # no ACK

        # Wait card response
        frameLength, response = self._interface.readResponse()
        if (frameLength < 0):
            DMSG("Could not receive response\n")
            return -2


        # Check status (response[0])
        if ((response[0] & 0x3F)!=0):
            DMSG("Status code indicates an error: ")
            DMSG_HEX(response[7])
            DMSG("\n")
            return -3

        return 1
Beispiel #6
0
    def felica_RequestSystemCode(self) -> (int, List[int]):
        """
        Sends FeliCa Request System Code command

        :returns:   (status, systemCodeList)
                    status          1: Success, < 0: error
                    systemCodeList  System Code list (Array length should longer than 16)

         """

        cmd = bytearray([FELICA_CMD_REQUEST_SYSTEM_CODE]) + self._felicaIDm[:8]

        status, response = self.felica_SendCommand(cmd)
        responseLength = len(response)
        if (status != 1):
            DMSG("Request System Code command failed\n")
            return -1, []

        numSystemCode = response[9]

        # length check
        if (responseLength < 10 + 2 * numSystemCode):
            DMSG("Request System Code command failed (wrong response length)\n")
            return -2, []

        systemCodeList = []
        for i in range(numSystemCode):
            systemCodeList.append((response[10 + i * 2] << 8) + response[10 + i * 2 + 1])

        return 1, systemCodeList
Beispiel #7
0
    def writeCommand(self, header: bytearray,
                     body: bytearray = bytearray()) -> int:

        # dump serial buffer
        if (self._serial.inWaiting()):
            DMSG("Dump serial buffer: ")
            ret = self._serial.read()
            DMSG_HEX(ret)

        self.command = header[0]

        self._serial.write(
            PN532_WAKEUP
        )  # Extra long Preamble in case PN532 is in low VBat mode
        self._serial.write(
            bytearray([PN532_PREAMBLE, PN532_STARTCODE1, PN532_STARTCODE2]))

        length = len(header) + len(
            body) + 1  # length of data field: TFI + DATA
        self._serial.write(
            bytearray([length, (~length + 1) & 0xff,
                       PN532_HOSTTOPN532]))  # checksum of length

        dsum = PN532_HOSTTOPN532 + sum(header) + sum(body)

        DMSG("\nWrite: ")

        self._serial.write(header)
        self._serial.write(body)

        checksum = (~dsum + 1) & 0xff  # checksum of TFI + DATA
        self._serial.write(bytearray([checksum, PN532_POSTAMBLE]))

        return self.readAckFrame()
Beispiel #8
0
    def _writeFrame(self, header: bytearray, body: bytearray):
        data_out = [
            DATA_WRITE, PN532_PREAMBLE, PN532_STARTCODE1, PN532_STARTCODE2
        ]

        length = len(header) + len(
            body) + 1  # length of data field: TFI + DATA
        data_out.append(length)
        data_out.append((~length + 1) & 0xFF)

        data_out.append(PN532_HOSTTOPN532)
        dsum = PN532_HOSTTOPN532 + sum(header) + sum(body)  # sum of TFI + DATA

        data_out += list(header)
        data_out += list(body)
        checksum = (~dsum + 1) & 0xFF  # checksum of TFI + DATA

        data_out += [checksum, PN532_POSTAMBLE]

        DMSG("writeCommand: {}    {}    {}".format(header, body, data_out))
        try:
            # send data
            self._send_bytes(data_out)
        except Exception as e:
            DMSG(e)
            DMSG("\nError writing frame\n")  # I2C max packet: 32 bytes
            raise
Beispiel #9
0
    def waitForDisconnection(self, timeout: int = LLCP_DEFAULT_TIMEOUT) -> int:
        type = 0

        # Get DISC PDU
        DMSG("wait for a DISC PDU\n")
        while 1:
            status, data = self.link.read()
            if (2 > status):
                return -1

            type = getPType(data)
            if (PDU_DISC == type):
                break
            elif (PDU_SYMM == type):
                if (not self.link.write(bytearray(self.SYMM_PDU))):
                    return -2
            else:
                return -3

        # Put DM PDU
        DMSG("put a DM(Disconnect Mode) PDU to response the DISC PDU\n")
        # ssap = getDSAP(headerBuf)
        # dsap = getSSAP(headerBuf)
        header = buildHeader(self.dsap, PDU_DM, self.ssap)
        if (not self.link.write(header)):
            return -2

        return 1
Beispiel #10
0
    def readResponse(self, timeout: int = 1000) -> (int, bytearray):
        t = 0
        length = self._getResponseLength(timeout)
        buf = bytearray()

        if length < 0:
            return length, buf

        # [RDY] 00 00 FF LEN LCS (TFI PD0 ... PDn) DCS 00
        while 1:
            responses = self._wire.transaction(
                reading(PN532_I2C_ADDRESS, 6 + length + 2))
            data = bytearray(responses[0])
            if (data[0] & 1):
                # check first byte --- status
                break  # PN532 is ready

            time.sleep(.001)  # sleep 1 ms
            t += 1
            if ((0 != timeout) and (t > timeout)):
                return -1, buf

        if (PN532_PREAMBLE != data[1] or  # PREAMBLE
                PN532_STARTCODE1 != data[2] or  # STARTCODE1
                PN532_STARTCODE2 != data[3]  # STARTCODE2
            ):
            DMSG('Invalid Response frame: {}'.format(data))
            return PN532_INVALID_FRAME, buf

        length = data[4]

        if (0 != (length + data[5] & 0xFF)):
            # checksum of length
            DMSG('Invalid Length Checksum: len {:d} checksum {:d}'.format(
                length, data[5]))
            return PN532_INVALID_FRAME, buf

        cmd = self._command + 1  # response command
        if (PN532_PN532TOHOST != data[6] or (cmd) != data[7]):
            return PN532_INVALID_FRAME, buf

        length -= 2

        DMSG("readResponse read command:  {:x}".format(cmd))

        dsum = PN532_PN532TOHOST + cmd
        buf = data[8:-2]
        DMSG('readResponse response: {!r}\n'.format(buf))
        dsum += sum(buf)

        checksum = data[-2]
        if (0 != (dsum + checksum) & 0xFF):
            DMSG("checksum is not ok: sum {:d} checksum {:d}\n".format(
                dsum, checksum))
            return PN532_INVALID_FRAME, buf
        # POSTAMBLE data [-1]

        return length, buf
Beispiel #11
0
    def readPassiveTargetID(self, cardbaudrate: int, timeout: int = 1000, inlist: bool = False) -> (bool, bytearray):
        """
        Waits for an ISO14443A target to enter the field

        :param  cardBaudRate:  Baud rate of the card
        :param  timeout:       The number of tries before timing out
        :param  inlist:        If set to True, the card will be inlisted

        :returns: (True if successful, uid of the card)
        """
        header = bytearray([
            PN532_COMMAND_INLISTPASSIVETARGET,
            1,  # max 1 cards at once (we can set this to 2 later)
            cardbaudrate & 0xFF,
        ])
        if (self._interface.writeCommand(header)) :
            return False, bytearray()  # command failed


        # read data packet
        status, response = self._interface.readResponse(timeout)
        if (status < 0):
            return False, bytearray()
        
        # check some basic stuff
        # ISO14443A card response should be in the following format:

          # byte            Description
          # -------------   ------------------------------------------
          # b0              Tags Found
          # b1              Tag Number (only one used in this example)
          # b2..3           SENS_RES
          # b4              SEL_RES
          # b5              NFCID Length
          # b6..NFCIDLen    NFCID

        if (response[0] != 1):
            return False, bytearray()

        sens_res = response[2]
        sens_res <<= 8
        sens_res |= response[3]

        DMSG("ATQA: 0x")
        DMSG_HEX(sens_res)
        DMSG("SAK: 0x")
        DMSG_HEX(response[4])
        DMSG("\n")

        # Card appears to be Mifare Classic 
        uidLength = response[5]
        uid = bytearray(response[6:6 + uidLength])

        if (inlist) :
            self.inListedTag = response[1]
        
        return True, uid
Beispiel #12
0
    def _readAckFrame(self) -> int:
        PN532_ACK = [0, 0, 0xFF, 0, 0xFF, 0]

        DMSG("wait for ack at : ")
        DMSG(time.time())
        DMSG('\n')

        t = 0
        while 1:
            responses = self._wire.transaction(
                reading(PN532_I2C_ADDRESS,
                        len(PN532_ACK) + 1))
            data = bytearray(responses[0])
            if (data[0] & 1):
                # check first byte --- status
                break  # PN532 is ready

            time.sleep(.001)  # sleep 1 ms
            t += 1
            if (t > PN532_ACK_WAIT_TIME):
                DMSG("Time out when waiting for ACK\n")
                return PN532_TIMEOUT

        DMSG("ready at : ")
        DMSG(time.time())
        DMSG('\n')

        ackBuf = list(data[1:])

        if ackBuf != PN532_ACK:
            DMSG("Invalid ACK {}\n".format(ackBuf))
            return PN532_INVALID_ACK

        return 0
Beispiel #13
0
    def readAckFrame(self):
        PN532_ACK = bytearray([0, 0, 0xFF, 0, 0xFF, 0])

        DMSG("\nAck: ")

        num, ackBuf = self.receive(len(PN532_ACK), PN532_ACK_WAIT_TIME)
        if (num <= 0):
            DMSG("Timeout\n")
            return PN532_TIMEOUT

        if (ackBuf != PN532_ACK):
            DMSG("Invalid\n")
            return PN532_INVALID_ACK
        return 0
Beispiel #14
0
    def write(self, buf: bytearray, timeout: int = 0) -> int:
        """
        Write a SNEP packet, the packet should be less than (255 - 2 - 3) bytes
        :param:    buf     the buffer to contain the packet
        :param:    len     length of the buffer
        :param:    timeout max time to wait, 0 means no timeout
        :returns:   >0      success
                    =0      timeout
                    <0      failed
        """
        if (0 >= self.llcp.activate(timeout)):
            DMSG("failed to activate PN532 as a target\n")
            return -1

        if (0 >= self.llcp.connect(timeout)):
            DMSG("failed to set up a connection\n")
            return -2

        # response a success SNEP message
        header = bytearray([
            SNEP_DEFAULT_VERSION,
            SNEP_REQUEST_PUT,
            0,
            0,
            0,
            len(buf),
        ])

        if (0 >= self.llcp.write(header, buf)):
            return -3

        status, rbuf = self.llcp.read()
        if (6 > status):
            return -4

        # check SNEP version
        if (SNEP_DEFAULT_VERSION != rbuf[0]):
            DMSG("The received SNEP message's major version is different\n")
            # Todo: send Unsupported Version response
            return -4

        # expect a put request
        if (SNEP_RESPONSE_SUCCESS != rbuf[1]):
            DMSG("Expect a success response\n")
            return -4

        self.llcp.disconnect(timeout)

        return 1
Beispiel #15
0
    def disconnect(self, timeout: int = LLCP_DEFAULT_TIMEOUT) -> int:
        type = 0

        # try to get a SYMM PDU
        status, data = self.link.read()
        if (2 > status):
            return -1
        type = getPType(data)
        if (PDU_SYMM != type):
            return -1

        # put a DISC PDU
        header = buildHeader(LLCP_DEFAULT_DSAP, PDU_DISC, LLCP_DEFAULT_SSAP)
        if (not self.link.write(header)):
            return -2

        # wait for a DM PDU
        DMSG("wait for a DM PDU\n")
        while 1:
            status, data = self.link.read()
            if (2 > status):
                return -1

            type = getPType(data)
            if (PDU_CC == type):
                break
            elif (PDU_DM == type):
                if (not self.link.write(bytearray(self.SYMM_PDU))):
                    return -2
            else:
                return -3

        return 1
Beispiel #16
0
    def inDataExchange(self, send: bytearray) -> (bool, bytearray):
        """
                Exchanges an APDU with the currently inlisted peer

        :param  send:            Pointer to data to send
        :param  response:        Pointer to response data
        :param  responseLength:  Pointer to the response data length
        """

        header = bytearray([
            0x40,  # PN532_COMMAND_INDATAEXCHANGE
            self.inListedTag
        ])

        if (self._interface.writeCommand(header, send)):
            return False, bytearray()
        

        status, response = self._interface.readResponse()
        if (status < 0):
            return False, bytearray()
        

        if ((response[0] & 0x3f) != 0):
            DMSG("Status code indicates an error\n")
            return False, bytearray()

        response = response[1:]
        return True, response
Beispiel #17
0
    def setNdefFile(self, ndef: bytearray):
        ndefLength = len(ndef)
        if (ndefLength > (NDEF_MAX_LENGTH - 2)):
            DMSG("ndef file too large (> NDEF_MAX_LENGHT -2) - aborting")
            return

        self.ndef_file = bytearray([ndefLength >> 8, ndefLength & 0xFF]) + ndef
Beispiel #18
0
    def writeCommand(self, header: bytearray,
                     body: bytearray = bytearray()) -> int:
        self._command = header[0]
        self._writeFrame(header, body)

        timeout = PN532_ACK_WAIT_TIME
        while (not self._isReady()):
            time.sleep(.001)  # sleep 1 ms
            timeout -= 1
            if (0 >= timeout):
                DMSG("Time out when waiting for ACK\n")
                return PN532_TIMEOUT
        if (not self._readAckFrame()):
            DMSG("Invalid ACK\n")
            return PN532_INVALID_ACK

        return 0
Beispiel #19
0
    def readResponse(self, timeout: int = 1000) -> (int, bytearray):

        DMSG("\nRead:  ")

        # Frame Preamble and Start Code
        num, tmp = self.receive(3, timeout)
        if (num <= 0):
            return PN532_TIMEOUT, tmp
        if (0 != tmp[0] or 0 != tmp[1] or 0xFF != tmp[2]):
            DMSG("Preamble error")
            return PN532_INVALID_FRAME, bytearray()

        # receive length and check
        num, tmp = self.receive(2, timeout)
        if (num <= 0):
            return PN532_TIMEOUT, tmp

        length, lchksm = tmp[0], tmp[1]
        if (0 != (length + lchksm) & 0xff):
            DMSG("Length error")
            return PN532_INVALID_FRAME, bytearray()
        length -= 2

        # receive self.command byte
        cmd = self.command + 1  # response self.command
        num, tmp = self.receive(2, timeout)
        if (num <= 0):
            return PN532_TIMEOUT, tmp
        if (PN532_PN532TOHOST != tmp[0] or cmd != tmp[1]):
            DMSG("Command error")
            return PN532_INVALID_FRAME, bytearray()

        num, buf = self.receive(length, timeout)
        if (num != length):
            return PN532_TIMEOUT, buf
        dsum = PN532_PN532TOHOST + cmd + sum(buf)

        # checksum and postamble
        num, tmp = self.receive(2, timeout)
        if (num <= 0):
            return PN532_TIMEOUT, tmp
        if (0 != (dsum + tmp[0]) & 0xff or 0 != tmp[1]):
            DMSG("Checksum error")
            return PN532_INVALID_FRAME, bytearray()

        return length, buf
Beispiel #20
0
    def wakeup(self):
        self._serial.write(PN532_WAKEUP)

        #  dump serial buffer
        if (self._serial.inWaiting()):
            DMSG("Dump serial buffer: ")
            ret = self._serial.read()
            DMSG_HEX(ret)
Beispiel #21
0
    def _readAckFrame(self):
        """Returns true if ack was successfully read"""
        PN532_ACK = bytearray([0, 0, 0xFF, 0, 0xFF, 0])

        ackBuf = self._xfer_bytes([DATA_READ] +
                                  [0 for i in range(len(PN532_ACK))])
        DMSG("_readAckFrame: ack    {}".format(ackBuf[1:]))
        return ackBuf[1:] == PN532_ACK
Beispiel #22
0
    def mifareclassic_ReadDataBlock (self, blockNumber: int) -> (bool, bytearray):
        """
        Tries to read an entire 16-bytes data block at the specified block
        address.

        :param  blockNumber:   The block number to authenticate.  (0..63 for
                              1KB cards, and 0..255 for 4KB cards).
        :param  data:          Pointer to the byte array that will hold the
                              retrieved data (if any)

        :returns: tuple (result, data)
            result: bool True if operation was successful, False if error
            data: bytearray data read
        """
    
        DMSG("Trying to read 16 bytes from block ")
        DMSG(blockNumber)

        #  Prepare the command
        header = bytearray([
            PN532_COMMAND_INDATAEXCHANGE,
            1,                  # Card number
            MIFARE_CMD_READ,    # Mifare Read command = 0x30
            blockNumber,        # Block Number (0..63 for 1K, 0..255 for 4K)
        ])
        #  Send the command 
        if (self._interface.writeCommand(header)):
            return False, bytearray()
        

        #  Read the response packet 
        status, response = self._interface.readResponse()

        #  If byte 8 isn't 0x00 we probably have an error 
        if (status < 0 or response[0] != 0x00):
            DMSG("Authentication failed\n")
            return False, bytearray()

        #  Copy the 16 data bytes to the output buffer        
        #  Block content starts at byte 9 of a valid response
        return True, response[1:17]
Beispiel #23
0
    def felica_ReadWithoutEncryption(self, serviceCodeList: List[int], blockList: List[int]) -> (int, List[bytearray]):

        """
            Sends FeliCa Read Without Encryption command

            :param  serviceCodeList:    Service Code List (Big Endian)
            :param  blockList:          Block List (Big Endian, This API only accepts 2-byte block list element)
            :returns:       (status, blockData)
                              status    1: Success, < 0: error
                              blockData Block Data
        """
        no_data = []
        numService =  len(serviceCodeList)
        if (numService > FELICA_READ_MAX_SERVICE_NUM):
            DMSG("numService is too large\n")
            return -1, no_data

        numBlock = len(blockList)
        if (numBlock > FELICA_READ_MAX_BLOCK_NUM):
            DMSG("numBlock is too large\n")
            return -2, no_data

        cmd = bytearray([FELICA_CMD_READ_WITHOUT_ENCRYPTION]) + self._felicaIDm[:8] + bytearray([numService])
        for i in range(numService):
            cmd.append(serviceCodeList[i] & 0xFF)
            cmd.append((serviceCodeList[i] >> 8) & 0xff)

        cmd.append(numBlock)
        for i in range(numBlock):
            cmd.append((blockList[i] >> 8) & 0xFF)
            cmd.append(blockList[i] & 0xff)

        status, response = self.felica_SendCommand(cmd)
        if (status != 1):
            DMSG("Read Without Encryption command failed\n")
            return -3, no_data


        # length check
        responseLength = len(response)
        if (responseLength != 12 + 16 * numBlock):
            DMSG("Read Without Encryption command failed (wrong response length)\n")
            return -4, no_data

        # status flag check
        if (response[9] != 0 or response[10] != 0):
            DMSG("Read Without Encryption command failed (Status Flag: ")
            DMSG_HEX(response[9])
            DMSG_HEX(response[10])
            DMSG(")\n")
            return -5, no_data

        k = 12
        blockData = []
        for i in range(numBlock):
            start = 12+ i * 16
            blockData.append(response[start: start + 16])

        return 1, blockData
Beispiel #24
0
    def writeGPIO(self,  pinstate: int) -> bool:
        """
        Writes an 8-bit value that sets the state of the PN532's GPIO  (P3)

        :warning: This function is provided exclusively for board testing and
                 is dangerous since it will throw an error if any pin other
                 than the ones marked "Can be used as GPIO" are modified!  All
                 pins that can not be used as GPIO should ALWAYS be left high
                 (value = 1) or the system will become unstable and a HW reset
                 will be required to recover the PN532.

                 pinState[0]  = P30     Can be used as GPIO
                 pinState[1]  = P31     Can be used as GPIO
                 pinState[2]  = P32     *** RESERVED (Must be 1!) ***
                 pinState[3]  = P33     Can be used as GPIO
                 pinState[4]  = P34     *** RESERVED (Must be 1!) ***
                 pinState[5]  = P35     Can be used as GPIO

        :returns 1 if everything executed properly, 0 for an error
        """
    
        # Make sure pinstate does not try to toggle P32 or P34
        pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34)

        # Fill command buffer
        header = bytearray([PN532_COMMAND_WRITEGPIO,
                            (PN532_GPIO_VALIDATIONBIT | pinstate),  # P3 Pins
                            0x00])  # P7 GPIO Pins (not used ... taken by I2C)

        DMSG("Writing P3 GPIO: ")
        DMSG_HEX(header)
        DMSG("\n")

        # Send the WRITEGPIO command (0x0E)
        if (self._interface.writeCommand(header)):
            return False

        status, response = self._interface.readResponse()
        return status >= 0
Beispiel #25
0
    def readGPIO(self) -> int:
        """
            Reads the state of the PN532's GPIO pins (P3)

            :returns: An 8-bit value containing the pin state where:

                 pinState[0]  = P30
                 pinState[1]  = P31
                 pinState[2]  = P32
                 pinState[3]  = P33
                 pinState[4]  = P34
                 pinState[5]  = P35 
        """
    
        header = bytearray([PN532_COMMAND_READGPIO])

        # Send the READGPIO command (0x0C)
        if (self._interface.writeCommand(header)):
            return 0x0

        status, response = self._interface.readResponse()
        # READGPIO response without prefix and suffix should be in the following format:
        # 
        #   byte            Description
        #   -------------   ------------------------------------------
        #   b0              P3 GPIO Pins
        #   b1              P7 GPIO Pins (not used ... taken by I2C)
        #   b2              Interface Mode Pins (not used ... bus select pins)

        DMSG("P3 GPIO: ") 
        DMSG_HEX(response[0])
        DMSG("P7 GPIO: ") 
        DMSG_HEX(response[1])
        DMSG("I0I1 GPIO: ") 
        DMSG_HEX(response[2])
        DMSG("\n")

        return response[0]
Beispiel #26
0
    def felica_RequestService(self, nodeCodeList: List[int]) -> (int, List[int]):
        """
            Sends FeliCa Request Service command

            :param  nodeCodeList:      Node codes(Big Endian)
            :returns:   (status, keyVersions)
                        status      1: Success, < 0: error
                        keyVersions Key Version of each Node (Big Endian)
        """
        no_data = []
        numNode = len(nodeCodeList)
        if (numNode > FELICA_REQ_SERVICE_MAX_NODE_NUM):
            DMSG("numNode is too large\n")
            return -1, no_data

        cmd = bytearray([FELICA_CMD_REQUEST_SERVICE]) + self._felicaIDm[:8] + bytearray([numNode])
        for i in range(numNode):
            cmd.append(nodeCodeList[i] & 0xFF)
            cmd.append((nodeCodeList[i] >> 8) & 0xff)

        status, response = self.felica_SendCommand(cmd)
        if (status != 1):
            DMSG("Request Service command failed\n")
            return -2, no_data

        # length check
        responseLength = len(response)
        if (responseLength != 10 + 2 * numNode):
            DMSG("Request Service command failed (wrong response length)\n")
            return -3, no_data

        keyVersions = []
        for i in range(numNode):
            keyVersions.append(response[10 + i * 2] + (response[10 + i * 2 + 1] << 8))

        return 1, keyVersions
Beispiel #27
0
    def felica_RequestResponse(self) -> (int, int):
        """
        Sends FeliCa Request Response command

        :returns:     (status, mode)
                    status  1: Success, < 0: error
                    mode    Current Mode of the card
        """

        cmd = bytearray([FELICA_CMD_REQUEST_RESPONSE]) + self._felicaIDm[:8]

        status, response = self.felica_SendCommand(cmd)
        responseLength = len(response)
        if (status != 1):
            DMSG("Request Response command failed\n")
            return -1, -1

        # length check
        if (responseLength != 10):
            DMSG("Request Response command failed (wrong response length)\n")
            return -2, -1

        mode = response[9]
        return 1, mode
Beispiel #28
0
    def readResponse(self, timeout: int = 1000) -> (int, bytearray):
        timer = 0
        buf = bytearray()
        result = 0

        length = self._getResponseLength(timeout)

        if length < 0:
            return length, buf

        data = self._xfer_bytes(
            [DATA_READ] +
            [0 for i in range(length + 1)
             ])  #  Total length - 1 for RW byte, SPI is full duplex

        cmd = self._command + 1  # response command
        if (PN532_PN532TOHOST != data[0] or (cmd) != data[1]):
            return PN532_INVALID_FRAME, buf

        length -= 2

        DMSG("readResponse read command:  {:x}".format(cmd))

        dsum = PN532_PN532TOHOST + cmd
        buf = data[2:-2]
        DMSG('readResponse response: {!r}\n'.format(buf))
        dsum += sum(buf)

        checksum = data[-2]
        if (0 != (dsum + checksum) & 0xFF):
            DMSG("checksum is not ok: sum {:d} checksum {:d}\n".format(
                dsum, checksum))
            return PN532_INVALID_FRAME, buf
        # POSTAMBLE data [-1]

        return length, buf
Beispiel #29
0
    def SAMConfig(self) -> bool:
        """
        Configures the SAM (Secure Access Module)
        :returns: True if success, False if error
        """
        header = bytearray([PN532_COMMAND_SAMCONFIGURATION,
                            0x01,   # normal mode
                            0x14,   # timeout 50ms * 20 = 1 second
                            0x01])  # use IRQ pin!

        DMSG("SAMConfig\n")

        if (self._interface.writeCommand(header)):
            return False

        status, response = self._interface.readResponse()
        return status >= 0
Beispiel #30
0
    def felica_WriteWithoutEncryption(self, serviceCodeList: List[int], blockList: List[int], blockData: List[bytearray]) -> int:

        """
            Sends FeliCa Write Without Encryption command

            :param  serviceCodeList:    Service Code List (Big Endian)
            :param  blockList:          Block List (Big Endian, This API only accepts 2-byte block list element)
            :returns:       status    1: Success, < 0: error
        """
        numService, numBlock = len(serviceCodeList), len(blockList)
        if (numService > FELICA_WRITE_MAX_SERVICE_NUM):
            DMSG("numService is too large\n")
            return -1

        if (numBlock > FELICA_WRITE_MAX_BLOCK_NUM):
            DMSG("numBlock is too large\n")
            return -2

        cmd = bytearray([FELICA_CMD_WRITE_WITHOUT_ENCRYPTION]) + self._felicaIDm[:8] + bytearray([numService])
        for i in range(numService):
            cmd.append(serviceCodeList[i] & 0xFF)
            cmd.append((serviceCodeList[i] >> 8) & 0xff)

        cmd.append(numBlock)
        for i in range(numBlock):
            cmd.append((blockList[i] >> 8) & 0xFF)
            cmd.append(blockList[i] & 0xff)

        for i in range(numBlock):
            for k in range(16):
                cmd.append(blockData[i][k])

        status, response = self.felica_SendCommand(cmd)
        responseLength = len(response)
        if (status != 1):
            DMSG("Write Without Encryption command failed\n")
            return -3

        # length check
        if (responseLength != 11):
            DMSG("Write Without Encryption command failed (wrong response length)\n")
            return -4

        # status flag check
        if (response[9] != 0 or response[10] != 0):
            DMSG("Write Without Encryption command failed (Status Flag: ")
            DMSG_HEX(response[9])
            DMSG_HEX(response[10])
            DMSG(")\n")
            return -5

        return 1