ClusterM

Tuya protocop

Oct 25th, 2021
102
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. public byte[] CreatePayload(Command command, string data)
  2. {
  3.     byte[] payload = Encoding.UTF8.GetBytes(data);
  4.  
  5.     if (Version == ProtocolVersion.V33)
  6.     {                
  7.         payload = Encrypt(payload); // Encrypt
  8.         // Add protocol 3.3 header
  9.         if ((command != Command.DP_QUERY) && (command != Command.UPDATED_PS))
  10.             payload = Enumerable.Concat(PROTOCOL_33_HEADER, payload).ToArray();
  11.     }
  12.     else if (command == Command.CONTROL)
  13.     {
  14.         // Encrypt
  15.         payload = Encrypt(payload);
  16.         // Encode to base64
  17.         string data64 = Convert.ToBase64String(payload);
  18.         // Make string
  19.         payload = Encoding.UTF8.GetBytes($"data={data64}||lpv=3.1||");
  20.         using (var md5 = MD5.Create())
  21.         using (var ms = new MemoryStream())
  22.         {
  23.             // Calculate MD5 of data
  24.             ms.Write(payload, 0, payload.Length);
  25.             // ...and encryption key
  26.             var binaryKey = Encoding.UTF8.GetBytes(LocalKey);
  27.             ms.Write(binaryKey, 0, binaryKey.Length);
  28.  
  29.             string md5s =
  30.                 BitConverter.ToString( // Make string from MD5                            
  31.                     md5.ComputeHash(ms.ToArray()) // Calculate MD5
  32.                 )                        
  33.                 .Replace("-", string.Empty) // Remove '-'                        
  34.                 .Substring(8, 16)   // Get part of it                                          
  35.                 .ToLower();         // Lowercase
  36.             // Data with version & MD5 hash/signature
  37.             payload = Encoding.UTF8.GetBytes($"3.1{md5s}{data64}");
  38.         }
  39.     }
  40.  
  41.     using (var ms = new MemoryStream())
  42.     {
  43.         byte[] seqNo = BitConverter.GetBytes(SeqNo++);
  44.         if (BitConverter.IsLittleEndian) Array.Reverse(seqNo); // Make big-endian
  45.         byte[] dataLength = BitConverter.GetBytes(payload.Length + 8);
  46.         if (BitConverter.IsLittleEndian) Array.Reverse(dataLength); // Make big-endian
  47.  
  48.         ms.Write(PREFIX_VALUE, 0, 4);   // Prefix
  49.         ms.Write(seqNo, 0, 4);          // Packet number
  50.         ms.Write(new byte[] { 0, 0, 0, (byte) command }, 0, 4); // Command number
  51.         ms.Write(dataLength, 0, 4);     // Length of data + length of suffix
  52.         ms.Write(payload, 0, payload.Length);   // Data
  53.         var crc32 = new Crc32();
  54.         var crc = crc32.Get(ms.ToArray());
  55.         byte[] crcBin = BitConverter.GetBytes(crc);
  56.         if (BitConverter.IsLittleEndian) Array.Reverse(crcBin); // Make big-endian
  57.         ms.Write(crcBin, 0, 4);         // CRC32 checksum
  58.         ms.Write(SUFFIX_VALUE, 0, 4);   // Suffix
  59.         payload = ms.ToArray();
  60.     }
  61.  
  62.     return payload;
  63. }
  64.  
RAW Paste Data Copied