SolarisFalls

Untitled

Jan 10th, 2026
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.30 KB | None | 0 0
  1. import socket, time
  2. from threading import Thread, Lock
  3. from tkinter import *
  4. from tkinter import ttk
  5. from tkinter import messagebox
  6.  
  7. HOST = "127.0.0.1"
  8. PORT = 7447
  9.  
  10. sendBuffer = []
  11. sendBufferMutex = Lock()
  12.  
  13. receiveBuffer = []
  14. receiveBufferMutex = Lock()
  15.  
  16. def RunTCPConnection():
  17.     socketInstance = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  18.  
  19.     socketInstance.connect((HOST, PORT))
  20.     socketInstance.setblocking(False)
  21.    
  22.     while 1:
  23.         try:
  24.             amsPacket = socketInstance.recv(1000)
  25.         except socket.error:
  26.             pass
  27.         else:
  28.             with receiveBufferMutex:
  29.                 receiveBuffer.append(amsPacket.decode("utf-8"))
  30.             HandleAMSPackets()
  31.        
  32.         with sendBufferMutex:
  33.             if len(sendBuffer) > 0:
  34.                 socketInstance.send(str.encode(sendBuffer[0]))
  35.                 del sendBuffer[0]
  36.                 time.sleep(0.1)
  37.  
  38. t = Thread(target = RunTCPConnection)
  39. t.start()
  40.  
  41. tkRoot = Tk()
  42. tkForm = ttk.Frame(tkRoot, padding = 10)
  43. tkForm.master.title("YACAN-CSP-AMS")
  44. tkForm.grid()
  45. tkRoot.resizable(False, False)
  46.  
  47. AMS_PORT_AAS = 16
  48. AMS_PORT_PAS = 17
  49.  
  50. commandType = IntVar()
  51. actionID = StringVar()
  52. transactionID = IntVar()
  53. transactionIDAuto = BooleanVar()
  54. amsVersion = StringVar()
  55. commandArgument = StringVar()
  56. pasAccessType = IntVar()
  57.  
  58. amsVersion.set("cbe2")
  59. transactionIDAuto.set(True)
  60. commandType.set(AMS_PORT_AAS)
  61. pasAccessType.set(3)
  62.  
  63. def SendForm():
  64.     if transactionID.get() > 0xFF:
  65.         transactionID.set(0)
  66.    
  67.     # AMS header
  68.     command = f"send 01{format(transactionID.get(), '02x')}"
  69.    
  70.     if len(amsVersion.get()) == 4:
  71.         try:
  72.             int(amsVersion.get(), 16)
  73.         except:
  74.             messagebox.showerror("Error", "The AMS version is invalid hex")
  75.             return
  76.     else:
  77.         messagebox.showerror("Error", "The AMS version is not 2 bytes")
  78.         return
  79.    
  80.     if commandType.get() == AMS_PORT_AAS:
  81.         command += f"0102{amsVersion.get()}0000{actionID.get()}{commandArgument.get()}"
  82.     elif commandType.get() == AMS_PORT_PAS:
  83.         command += f"{format(pasAccessType.get(), '02x')}02{amsVersion.get()}0000{actionID.get()}{commandArgument.get()}"
  84.     else:
  85.         messagebox.showerror("Error", "An invalid command type is set - Please make sure you've selected either AAS or PAS")
  86.         return
  87.    
  88.     if transactionIDAuto.get() == True:
  89.         transactionID.set(transactionID.get() + 1)
  90.        
  91.     with sendBufferMutex:
  92.         sendBuffer.append(command)
  93.        
  94.     print(f"Sending command to YACAN-CSP: \"{command}\"")
  95.    
  96. def UpdateConfiguration():
  97.     commands = []
  98.    
  99.     commands.append(f"source_node = 17")
  100.     commands.append(f"source_port = 48")
  101.     commands.append(f"destination_node = 15")
  102.     commands.append(f"priority = 0")
  103.     commands.append(f"destination_port = {commandType.get()}")
  104.    
  105.     with sendBufferMutex:
  106.         for command in commands:
  107.             sendBuffer.append(command)
  108.  
  109. ttk.Label(tkForm, text = "Command Type").grid(column = 0, row = 0, sticky = W)
  110. W_RadiobuttonAAS = Radiobutton(tkForm, text = "AAS", variable = commandType, value = AMS_PORT_AAS, command = UpdateConfiguration).grid(column = 0, row = 1, padx = 135, sticky = W)
  111. W_RadiobuttonPAS = Radiobutton(tkForm, text = "PAS", variable = commandType, value = AMS_PORT_PAS, command = UpdateConfiguration).grid(column = 0, row = 1, padx = 140, sticky = E)
  112.  
  113. ttk.Label(tkForm, text = "PAS Access Type").grid(column = 0, row = 2, sticky = W)
  114. W_RadiobuttonAAS = Radiobutton(tkForm, text = "Get Scalar", variable = pasAccessType, value = 3).grid(column = 0, row = 3, padx = 135, sticky = W)
  115. W_RadiobuttonPAS = Radiobutton(tkForm, text = "Set Scalar", variable = pasAccessType, value = 4).grid(column = 0, row = 3, padx = 100, sticky = E)
  116.  
  117. ttk.Label(tkForm, text = "Action ID / Param ID (hexadecimal)").grid(column = 0, row = 5, sticky = W)
  118. W_EntryActionID = Entry(tkForm, textvariable = actionID).grid(column = 0, row = 6)
  119.  
  120. ttk.Label(tkForm, text = "Transaction ID (decimal)").grid(column = 0, row = 7, sticky = W)
  121. W_EntryTransactionID = Entry(tkForm, textvariable = transactionID).grid(column = 0, row = 8)
  122. W_CheckbuttonAutoTransactionID = Checkbutton(tkForm, text = "Auto", variable = transactionIDAuto, onvalue = 1, offvalue = 0).grid(column = 0, row = 8, padx = 80, sticky = E)
  123.  
  124. ttk.Label(tkForm, text = "AMS Version (hexadecimal)").grid(column = 0, row = 9, sticky = W)
  125. W_EntryTransactionID = Entry(tkForm, textvariable = amsVersion).grid(column = 0, row = 10)
  126.  
  127. ttk.Label(tkForm, text = "Arguments (hexadecimal)").grid(column = 0, row = 11, sticky = W)
  128. W_EntryCommandArgument = Entry(tkForm, textvariable = commandArgument).grid(column = 0, row = 12)
  129.  
  130. W_ButtonSendPacket = Button(tkForm, text = "Send Packet", command = SendForm, width = 20).grid(column = 0, row = 13, pady = 10)
  131.  
  132. ttk.Label(tkForm, text = "Response Log (top is most recent)").grid(column = 0, row = 14, sticky = W)
  133. W_TreeviewResponseLog = ttk.Treeview(tkForm, column = ("Transaction ID", "Data"), show = "headings", height = 6)
  134. W_TreeviewResponseLog.grid(column = 0, row = 15)
  135.  
  136. W_TreeviewResponseLog.heading("#1", text="Transaction ID (decimal)")
  137. W_TreeviewResponseLog.heading("#2", text="Data (hexadecimal)")
  138.  
  139. ttk.Label(tkForm, text = "Error Log (top is most recent)").grid(column = 0, row = 16, sticky = W)
  140. W_TreeviewErrorLog = ttk.Treeview(tkForm, column = ("Transaction ID", "Status code"), show = "headings", height = 6)
  141. W_TreeviewErrorLog.grid(column = 0, row = 17)
  142.  
  143. W_TreeviewErrorLog.heading("#1", text="Transaction ID (decimal)")
  144. W_TreeviewErrorLog.heading("#2", text="Status Code")
  145.  
  146. def HandleAMSPackets():
  147.     with receiveBufferMutex:
  148.         for packet in receiveBuffer:
  149.             print(f"Received AMS Packet: 0x{packet}")
  150.            
  151.             if len(packet) < 4:
  152.                 print(f"Received an AMS packet which is too short (length is {len(packet) / 2} bytes)")
  153.                 continue
  154.            
  155.             responseType = packet[0:2]
  156.             transactionID = packet[2:4]
  157.            
  158.             if responseType == "01":
  159.                 responseData = packet[4:-8] # account for hash on the end which is 4 bytes
  160.                
  161.                 displayResponseData = responseData
  162.                
  163.                 if displayResponseData == "":
  164.                     displayResponseData = "(no response)"
  165.                
  166.                 W_TreeviewResponseLog.insert("", 0, values = [int(transactionID, 16), f"{displayResponseData}"])
  167.                
  168.             elif responseType == "02":
  169.                 statusCode = packet[4:12]
  170.                
  171.                 statusCodeText = [
  172.                     "Success",
  173.                     "Generic Failure",
  174.                     "Invalid Parameter",
  175.                     "Timeout",
  176.                     "Insufficient Resources",
  177.                     "Not Implemented"
  178.                 ]
  179.                
  180.                 statusCodeValue = int(statusCode, 16)
  181.                
  182.                 W_TreeviewErrorLog.insert("", 0, values = [int(transactionID, 16), f"{statusCodeText[statusCodeValue]} ({statusCodeValue})"])
  183.             else:
  184.                 print(f"[Error] Received an unknown response type: {responseType}")
  185.                 continue
  186.            
  187.         receiveBuffer.clear()
  188.  
  189. tkRoot.mainloop()
  190. t.join()
Advertisement
Add Comment
Please, Sign In to add comment