Advertisement
developer_su

4 friedkeenan's FOSS initiative

Mar 28th, 2019
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.99 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import usb.core
  4. import usb.util
  5. import struct
  6. import sys
  7. import os
  8.  
  9. from PFS0 import PFS0
  10.  
  11. def get_switch():
  12.     dev=usb.core.find(idVendor=0x057e, idProduct=0x3000)
  13.     if dev is None:
  14.         raise ValueError("Device not found")
  15.     return dev
  16. def get_ep(dev):
  17.     dev.set_configuration()
  18.     intf=dev.get_active_configuration()[(0,0)]
  19.     return (usb.util.find_descriptor(intf,
  20.             custom_match=lambda e:usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_OUT),
  21.             usb.util.find_descriptor(intf,
  22.             custom_match=lambda e:usb.util.endpoint_direction(e.bEndpointAddress)==usb.util.ENDPOINT_IN))
  23.  
  24. class CommandId:
  25.     GLUC=0x43554c47
  26.     ConnectionRequest=0
  27.     ConnectionResponse=1
  28.     NSPName=2
  29.     Start=3
  30.     NSPData=4
  31.     NSPContent=5
  32.     NSPTicket=6
  33.     Finish=7
  34.  
  35. class Command:
  36.     def __init__(self,cmd_id=0,raw=None):
  37.         if raw is None:
  38.             self.cmd_id=cmd_id
  39.         else:
  40.             self.cmd_id=struct.unpack("=I",raw)[0]
  41.     def has_id(self,cmd_id):
  42.         return self.cmd_id==cmd_id
  43.     def __bytes__(self):
  44.         return struct.pack("=I",self.cmd_id)
  45.  
  46. dev=get_switch()
  47. ep=get_ep(dev)
  48. def write(buffer,timeout=3000):
  49.     ep[0].write(buffer,timeout=timeout)
  50. def read(length,timeout=3000):
  51.     return ep[1].read(length,timeout=timeout).tobytes()
  52.  
  53. invalid_cmd="An invalid command was received. Are you sure Goldleaf is active?"
  54. install_cancelled="Goldleaf has canceled the installation."
  55.  
  56. def main():
  57.     gluc_cmd=Command(CommandId.GLUC)
  58.     c=Command()
  59.     c.has_id(CommandId.ConnectionRequest)
  60.     write(bytes(gluc_cmd))
  61.     write(bytes(c))
  62.     c=Command(raw=read(4))
  63.     if c.has_id(CommandId.GLUC):
  64.         c=Command(raw=read(4))
  65.         if c.has_id(CommandId.ConnectionResponse):
  66.             print("Connection was established with Goldleaf.")
  67.             c=Command(CommandId.NSPName)
  68.             write(bytes(gluc_cmd))
  69.             write(bytes(c))
  70.             base_name=os.path.basename(sys.argv[1])
  71.             write(struct.pack("=I",len(base_name)))
  72.             write(base_name.encode())
  73.             print("NSP name sent to Goldleaf")
  74.             resp=None
  75.             while resp is None:
  76.                 try:
  77.                     resp=read(4)
  78.                     c=Command(raw=resp)
  79.                 except usb.core.USBError:
  80.                     pass
  81.             if c.has_id(CommandId.GLUC):
  82.                 c=Command(raw=read(4))
  83.                 if c.has_id(CommandId.Start):
  84.                     print("Goldleaf is ready for the installation. Preparing everything...")
  85.                     pnsp=PFS0(sys.argv[1])
  86.                     c=Command(CommandId.NSPData)
  87.                     write(bytes(gluc_cmd))
  88.                     write(bytes(c))
  89.                     write(struct.pack("=I",len(pnsp.files)))
  90.                     tik_idx=-1
  91.                     tmp_idx=0
  92.                     for file in pnsp.files:
  93.                         write(struct.pack("=I",len(file.name)))
  94.                         write(file.name.encode())
  95.                         write(struct.pack("=Q",pnsp.header_size+file.file_offset))
  96.                         write(struct.pack("=Q",file.file_size))
  97.                         if os.path.splitext(file.name)[1][1:].lower()=="tik":
  98.                             tik_idx=tmp_idx
  99.                         tmp_idx+=1
  100.                     while True:
  101.                         c=Command(raw=read(4))
  102.                         if c.has_id(CommandId.GLUC):
  103.                             c=Command(raw=read(4))
  104.                             if c.has_id(CommandId.NSPContent):
  105.                                 idx=struct.unpack("=I",read(4))[0]
  106.                                 print("Sending content '"+pnsp.files[idx].name+"'... ("+str(idx+1)+" of "+str(len(pnsp.files))+")")
  107.                                 for buf in pnsp.read_chunks(idx):
  108.                                     write(buf)
  109.                                 print("Content was sent to Goldleaf.")
  110.                             elif c.has_id(CommandId.NSPTicket):
  111.                                 print("Sending ticket file...")
  112.                                 write(pnsp.read_file(tik_idx))
  113.                             elif c.has_id(CommandId.Finish):
  114.                                 break
  115.                         else:
  116.                             print(invalid_cmd)
  117.                             return 1
  118.                 elif c.has_id(CommandId.Finish):
  119.                     print(install_cancelled)
  120.                 else:
  121.                     print(invalid_cmd)
  122.                     return 1
  123.             else:
  124.                 print(invalid_cmd)
  125.                 return 1
  126.         elif c.has_id(CommandId.Finish):
  127.             print(install_cancelled)
  128.         else:
  129.             print(invalid_cmd)
  130.             return 1
  131.     else:
  132.         print(invalid_cmd)
  133.         return 1
  134.     print("The installation has finished.")
  135.     #c=Command(CommandId.Finish)
  136.     #write(bytes(c))
  137.     return 0
  138.  
  139. if __name__=="__main__":
  140.     sys.exit(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement