Recent

Author Topic: Python to FPC conversion help - off topic  (Read 4966 times)

jwest

  • New Member
  • *
  • Posts: 38
Python to FPC conversion help - off topic
« on: April 08, 2016, 09:35:07 pm »
Hi,

Does someone could help me to convert this python code to fpc(lazarus):
[Edit: Juha added python code tag]
Code: Python  [Select][+][-]
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-  
  3.  
  4. # The following specifications have been used
  5. # as a basis for writing this example.
  6. #
  7. # NFC Data Exchange Format (NDEF), NDEF 1.0:
  8. # https://github.com/Tinkerforge/nfc-rfid-bricklet/raw/master/datasheets/specification_ndef.pdf
  9. #
  10. # Type 1 Tag Operation Specification, T1TOP 1.1:
  11. # https://github.com/Tinkerforge/nfc-rfid-bricklet/raw/master/datasheets/specification_type1.pdf
  12. #
  13. # Type 2 Tag Operation Specification, T2TOP 1.1:
  14. # https://github.com/Tinkerforge/nfc-rfid-bricklet/raw/master/datasheets/specification_type2.pdf
  15.  
  16. from tinkerforge.ip_connection import IPConnection
  17. from tinkerforge.bricklet_nfc_rfid import NFCRFID
  18.  
  19. try:
  20.     from Queue import Queue
  21. except ImportError:
  22.     from queue import Queue
  23.  
  24. from pprint import pprint
  25. import os
  26.  
  27. class NdefMessage:
  28.     tag_type = None
  29.     records = []
  30.     capability_container = [0, 0, 0, 0]
  31.  
  32.     def __init__(self, tag_type):
  33.         self.tag_type = tag_type
  34.  
  35.     def add_record(self, record):
  36.         self.records.append(record)
  37.  
  38.         # Set end and begin flags as needed
  39.         if len(self.records) == 1:
  40.             record.begin = True
  41.             record.end = True
  42.         else:
  43.             self.records[-2].end = False
  44.             self.records[-1].end = True
  45.  
  46.     def set_capability_container(self, version, tag_size, read_write_access):
  47.         # Magic number to indicate NFC Forum defined data is stored
  48.         self.capability_container[0] = 0xE1
  49.         self.capability_container[1] = version
  50.         if self.tag_type == NFCRFID.TAG_TYPE_TYPE1:
  51.             self.capability_container[2] = tag_size/8 - 1
  52.         else:
  53.             self.capability_container[2] = tag_size/8
  54.  
  55.         self.capability_container[3] = read_write_access
  56.  
  57.     def get_raw_data_in_chunks(self):
  58.         raw_data = []
  59.         for record in self.records:
  60.             raw_data.extend(record.get_raw_data())
  61.  
  62.         # Use Three consecutive byte format if necessary, see 2.3 TLV blocks
  63.         data_len = len(raw_data)
  64.         if data_len < 0xFF:
  65.             tlv_ndef = [0x03, data_len]
  66.         else:
  67.             tlv_ndef = [0x03, 0xFF, data_len >> 8, data_len % 256]
  68.  
  69.         if self.tag_type == NFCRFID.TAG_TYPE_TYPE1:
  70.             # CC set by set_capability_container
  71.             # default lock and memory TLVs
  72.             # NDEF TLV
  73.             # NDEF message
  74.             # Terminator TLV
  75.             raw_data = self.capability_container + \
  76.                        [0x01, 0x03, 0xF2, 0x30, 0x33, 0x02, 0x03, 0xF0, 0x02, 0x03] + \
  77.                        tlv_ndef + \
  78.                        raw_data + \
  79.                        [0xFE]
  80.         elif self.tag_type == NFCRFID.TAG_TYPE_TYPE2:
  81.             # CC set by set_capability_container
  82.             # NDEF TLV
  83.             # NDEF message
  84.             # Terminator TLV
  85.             raw_data = self.capability_container + \
  86.                        tlv_ndef + \
  87.                        raw_data + \
  88.                        [0xFE]
  89.         else:
  90.             # TODO: We could support TAG_TYPE_MIFARE_CLASSIC here, but mifare classic
  91.             # it is not supported in modern smart phones anyway.
  92.             return [[]]
  93.  
  94.  
  95.         chunks = []
  96.         for i in range(0, len(raw_data), 16):
  97.             chunks.append(raw_data[i:i+16])
  98.  
  99.         last_chunk_length = len(chunks[-1])
  100.         if last_chunk_length < 16:
  101.             chunks[-1].extend([0]*(16-last_chunk_length))
  102.  
  103.         return chunks
  104.  
  105. class NdefRecord:
  106.     FLAG_ID_LENGTH     = 1 << 3
  107.     FLAG_SHORT_RECORD  = 1 << 4
  108.     FLAG_CHUNK         = 1 << 5
  109.     FLAG_MESSAGE_END   = 1 << 6
  110.     FLAG_MESSAGE_BEGIN = 1 << 7
  111.  
  112.     TNF_EMPTY          = 0x0
  113.     TNF_WELL_KNOWN     = 0x01
  114.     TNF_MIME_MEDIA     = 0x02
  115.     TNF_ABSOLUTE_URI   = 0x03
  116.     TNF_EXTERNAL_TYPE  = 0x04
  117.     TNF_UNKNOWN        = 0x05
  118.     TNF_UNCHANGED      = 0x06
  119.     TNF_RESERVED       = 0x07
  120.  
  121.     NDEF_URIPREFIX_NONE         = 0x00
  122.     NDEF_URIPREFIX_HTTP_WWWDOT  = 0x01
  123.     NDEF_URIPREFIX_HTTPS_WWWDOT = 0x02
  124.     NDEF_URIPREFIX_HTTP         = 0x03
  125.     NDEF_URIPREFIX_HTTPS        = 0x04
  126.     NDEF_URIPREFIX_TEL          = 0x05
  127.     NDEF_URIPREFIX_MAILTO       = 0x06
  128.     NDEF_URIPREFIX_FTP_ANONAT   = 0x07
  129.     NDEF_URIPREFIX_FTP_FTPDOT   = 0x08
  130.     NDEF_URIPREFIX_FTPS         = 0x09
  131.     NDEF_URIPREFIX_SFTP         = 0x0A
  132.     NDEF_URIPREFIX_SMB          = 0x0B
  133.     NDEF_URIPREFIX_NFS          = 0x0C
  134.     NDEF_URIPREFIX_FTP          = 0x0D
  135.     NDEF_URIPREFIX_DAV          = 0x0E
  136.     NDEF_URIPREFIX_NEWS         = 0x0F
  137.     NDEF_URIPREFIX_TELNET       = 0x10
  138.     NDEF_URIPREFIX_IMAP         = 0x11
  139.     NDEF_URIPREFIX_RTSP         = 0x12
  140.     NDEF_URIPREFIX_URN          = 0x13
  141.     NDEF_URIPREFIX_POP          = 0x14
  142.     NDEF_URIPREFIX_SIP          = 0x15
  143.     NDEF_URIPREFIX_SIPS         = 0x16
  144.     NDEF_URIPREFIX_TFTP         = 0x17
  145.     NDEF_URIPREFIX_BTSPP        = 0x18
  146.     NDEF_URIPREFIX_BTL2CAP      = 0x19
  147.     NDEF_URIPREFIX_BTGOEP       = 0x1A
  148.     NDEF_URIPREFIX_TCPOBEX      = 0x1B
  149.     NDEF_URIPREFIX_IRDAOBEX     = 0x1C
  150.     NDEF_URIPREFIX_FILE         = 0x1D
  151.     NDEF_URIPREFIX_URN_EPC_ID   = 0x1E
  152.     NDEF_URIPREFIX_URN_EPC_TAG  = 0x1F
  153.     NDEF_URIPREFIX_URN_EPC_PAT  = 0x20
  154.     NDEF_URIPREFIX_URN_EPC_RAW  = 0x21
  155.     NDEF_URIPREFIX_URN_EPC      = 0x22
  156.     NDEF_URIPREFIX_URN_NFC      = 0x23
  157.  
  158.     NDEF_TYPE_MIME              = 0x02
  159.     NDEF_TYPE_URI               = 0x55
  160.     NDEF_TYPE_TEXT              = 0x54
  161.  
  162.     begin = False
  163.     end = False
  164.  
  165.     tnf = 0
  166.     record_type = None
  167.     payload = None
  168.     identifier = None
  169.  
  170.     def set_identifier(self, identifier):
  171.         self.identifier = identifier
  172.  
  173.     def get_raw_data(self):
  174.         if self.record_type == None or self.payload == None:
  175.             return []
  176.  
  177.         # Construct tnf and flags (byte 0 of header)
  178.         header = [self.tnf]
  179.         if self.begin:
  180.             header[0] |= NdefRecord.FLAG_MESSAGE_BEGIN
  181.         if self.end:
  182.             header[0] |= NdefRecord.FLAG_MESSAGE_END
  183.         if len(self.payload) < 256:
  184.             header[0] |= NdefRecord.FLAG_SHORT_RECORD
  185.         if self.identifier != None:
  186.             header[0] |= NdefRecord.FLAG_ID_LENGTH
  187.  
  188.         # Type length (byte 1 of header)
  189.         header.append(len(self.record_type))
  190.  
  191.         # Payload length (byte 2 of header)
  192.         # TODO: payload > 255?
  193.         header.append(len(self.payload))
  194.  
  195.         # ID length (byte 3 of header)
  196.         if self.identifier != None:
  197.             header.append(len(self.identifier))
  198.  
  199.         # Record type (byte 4ff of header)
  200.         header.extend(self.record_type)
  201.  
  202.         # ID
  203.         if self.identifier != None:
  204.             header.extend(self.identifier)
  205.  
  206.         return header + self.payload
  207.  
  208. class NdefTextRecord(NdefRecord):
  209.     # Call with text and ISO/IANA language code
  210.     def __init__(self, text, language='en'):
  211.         self.tnf = NdefRecord.TNF_WELL_KNOWN
  212.         self.record_type = [NdefRecord.NDEF_TYPE_TEXT]
  213.  
  214.         lang_list = map(ord, language)
  215.         text_list = map(ord, text)
  216.  
  217.         # Text Record Content: Status byte, ISO/IANA language code, text
  218.         # See NDEF 1.0: 3.2.1
  219.         self.payload = [len(lang_list)] + lang_list + text_list
  220.  
  221. class NdefUriRecord(NdefRecord):
  222.     def __init__(self, uri, uri_prefix=NdefRecord.NDEF_URIPREFIX_NONE):
  223.         self.tnf = NdefRecord.TNF_WELL_KNOWN
  224.         self.record_type = [NdefRecord.NDEF_TYPE_URI]
  225.  
  226.         uri_list = map(ord, uri)
  227.  
  228.         # Text Record Content: URI prefix, URI
  229.         # See NDEF 1.0: 3.2.2
  230.         self.payload = [uri_prefix] + uri_list
  231.  
  232. class NdefMediaRecord(NdefRecord):
  233.     def __init__(self, mime_type, data):
  234.         self.tnf = NdefRecord.TNF_MIME_MEDIA
  235.  
  236.         self.record_type = map(ord, mime_type)
  237.         if type(data) == str:
  238.             self.payload = map(ord, data)
  239.         else:
  240.             self.payload = data
  241.  
  242. class ExampleNdef:
  243.     HOST = "localhost"
  244.     PORT = 4223
  245.     UID = "hjw" # Change to your UID
  246.  
  247.     state_queue = Queue()
  248.     tag_type = None
  249.     tag_size = None
  250.  
  251.     def __init__(self, tag_type, tag_size=512):
  252.         self.tag_type = tag_type
  253.         self.tag_size = tag_size
  254.         self.ipcon = IPConnection() # Create IP connection
  255.         self.nfc = NFCRFID(self.UID, self.ipcon) # Create device object
  256.  
  257.         self.ipcon.connect(self.HOST, self.PORT) # Connect to brickd
  258.  
  259.         self.nr.register_callback(self.nr.CALLBACK_STATE_CHANGED, self.state_changed)
  260.  
  261.     def write_message(self):
  262.         chunks = self.message.get_raw_data_in_chunks()
  263.         print("Trying to write the follwing data to the tag:")
  264.         pprint(chunks)
  265.  
  266.         self.nr.request_tag_id(self.tag_type)
  267.         state = self.state_queue.get()
  268.         if state != self.nr.STATE_REQUEST_TAG_ID:
  269.             return -1
  270.  
  271.         state = self.state_queue.get()
  272.         if state != self.nr.STATE_REQUEST_TAG_ID_READY:
  273.             return -2
  274.        
  275.         # NFC Forum Type 1 start page is 1 (start of capability container)
  276.         # NFC Forum Type 2 start page is 3 (start of capability container)
  277.         if self.tag_type == NFCRFID.TAG_TYPE_TYPE1:
  278.             current_page = 1
  279.         else:
  280.             current_page = 3
  281.  
  282.         for chunk in chunks:
  283.             self.nr.write_page(current_page, chunk)
  284.             state = self.state_queue.get()
  285.             if state != self.nr.STATE_WRITE_PAGE:
  286.                 return -3
  287.  
  288.             state = self.state_queue.get()
  289.             if state != self.nr.STATE_WRITE_PAGE_READY:
  290.                 return -4
  291.  
  292.             # NFC Forum Type 1 has 2 pages per chunk (16 byte)
  293.             # NFC Forum Type 2 has 4 pages per chunk (16 byte)
  294.             if self.tag_type == NFCRFID.TAG_TYPE_TYPE1 :      
  295.                 current_page += 2
  296.             else:
  297.                 current_page += 4
  298.  
  299.         return 0
  300.  
  301.     def state_changed(self, state, idle):
  302.         self.state_queue.put(state)
  303.  
  304.     def make_message_small(self):
  305.         self.message = NdefMessage(self.tag_type)
  306.  
  307.         # Capabilities:
  308.         # Version 1.0               (0x10)
  309.         # Tag size bytes            (given by self.tag_size)
  310.         # Read/write access for all (0x00)
  311.         self.message.set_capability_container(0x10, self.tag_size, 0x00)
  312.  
  313.         record = NdefUriRecord('tinkerforge.com', NdefRecord.NDEF_URIPREFIX_HTTP_WWWDOT)
  314.         self.message.add_record(record)
  315.  
  316.     def make_message_large(self):
  317.         self.message = NdefMessage(self.tag_type)
  318.  
  319.         # Capabilities:
  320.         # Version 1.0               (0x10)
  321.         # Tag size bytes            (given by self.tag_size)
  322.         # Read/write access for all (0x00)
  323.         self.message.set_capability_container(0x10, self.tag_size, 0x00)
  324.  
  325.         rec1 = NdefTextRecord('Hello World', 'en')
  326.         self.message.add_record(rec1)
  327.         rec2 = NdefTextRecord('Hallo Welt', 'de')
  328.         self.message.add_record(rec2)
  329.         rec3 = NdefUriRecord('tinkerforge.com', NdefRecord.NDEF_URIPREFIX_HTTP_WWWDOT)
  330.         self.message.add_record(rec3)
  331.         text = '<html><head><title>Hello</title></head><body>World!</body></html>'
  332.         rec4 = NdefMediaRecord('text/html', text)
  333.         self.message.add_record(rec4)
  334.  
  335.         # To test an "image/png" you can can download the file from:
  336.         # http://download.tinkerforge.com/_stuff/tf_16x16.png
  337.         if os.path.isfile('tf_16x16.png'):
  338.             logo = file('tf_16x16.png').read()
  339.             rec5 = NdefMediaRecord('image/png', map(ord, logo))
  340.             self.message.add_record(rec5)
  341.  
  342. if __name__ == '__main__':
  343.     example = ExampleNdef(tag_type=NFCRFID.TAG_TYPE_TYPE2, tag_size=888)
  344. #    example.make_message_large() # Writes different texts, URI, html site and image
  345.     example.make_message_small() # Writes simple URI record
  346.     ret = example.write_message()
  347.     if ret < 0:
  348.         print('Could not write NDEF Message: ' + str(ret))
  349.     else:
  350.         print('NDEF Message written successfully')
  351.  
« Last Edit: April 09, 2016, 12:36:05 pm by JuhaManninen »

Trenatos

  • Hero Member
  • *****
  • Posts: 540
    • MarcusFernstrom.com
Re: Python to FPC conversion help - off topic
« Reply #1 on: April 08, 2016, 10:11:57 pm »
No?

You could have linked to the source https://github.com/Tinkerforge/nfc-rfid-bricklet

But that's also reliant on other python libraries, so you can't just translate this one thing and make it work.

HIGH-Zen

  • New Member
  • *
  • Posts: 17
Re: Python to FPC conversion help - off topic
« Reply #2 on: April 09, 2016, 12:04:55 pm »
I don't see any programming problem or question that needs to be answered here.
What you are asking here is to do your work for you.

If you program in Pascal and Python, then there is no problem to do that.
I did convert code in C -> (Pascal <-> Python) without any problems.
The thing is - noone will do that work for you (or at least not for free).

And if the biggest problem is - you can't convert classes, then you don't know Python, Pascal, both or maybe programming is not for you.  8)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8836
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Python to FPC conversion help - off topic
« Reply #3 on: April 09, 2016, 06:23:18 pm »
I think this conversion could be an interesrting add on for all fpc community. Not only to me.
Could be, but NFC is not a really widespread technology. I think it's even has much less crowd than embedded systems. Even the wider web technology doesn't seem to have much follower here.
Neither whatever help necessarily need pay for.
I have other delphi/pascal forum where I participate and I never charge someone for help.
Try asking there then. I won't provide free (complex) code conversion service, but you may still hope for it here though. I even had a single quite easy to write function that got paid $50 from someone in this forum, simply because it's about business, not education. That's why Bounties page exists.
This is not an complete app, is a piece of code in PYthon.
With references to specific Python libraries:
Code: Python  [Select][+][-]
  1. from tinkerforge.ip_connection import IPConnection
  2. from tinkerforge.bricklet_nfc_rfid import NFCRFID
  3.  
  4. try:
  5.     from Queue import Queue
  6. except ImportError:
  7.     from queue import Queue
  8.  
  9. from pprint import pprint
  10. import os
  11.  
That we don't know how their recursive references will be.

jwest

  • New Member
  • *
  • Posts: 38
Re: Python to FPC conversion help - off topic
« Reply #4 on: April 09, 2016, 08:24:34 pm »
OK, It´s good know about Bounties.
Maybe, you are sure.

Luiz

 

TinyPortal © 2005-2018