2016-06-14 3 views
-2

Je suis un débutant Python et convertir un script php en python. Il se connecte mon LG SmartTV à mon Raspi, mais theres un problème avec la fonction de connexionconvertir Php en Python, base64 codé

Code d'origine php

 function connect() 
    { 
     $ws_handshake_cmd = "GET " . $this->path . " HTTP/1.1\r\n"; 
     $ws_handshake_cmd.= "Upgrade: websocket\r\n"; 
     $ws_handshake_cmd.= "Connection: Upgrade\r\n"; 
     $ws_handshake_cmd.= "Sec-WebSocket-Version: 13\r\n";    
     $ws_handshake_cmd.= "Sec-WebSocket-Key: " . $this->ws_key . "\r\n"; 
     $ws_handshake_cmd.= "Host: ".$this->host.":".$this->port."\r\n\r\n"; 
     $this->sock = fsockopen($this->host, $this->port, $errno, $errstr, 2); 
     socket_set_timeout($this->sock, 0, 10000); 
     echo  "Sending WS handshake\n$ws_handshake_cmd\n"; 
     $response = $this->send($ws_handshake_cmd); 
     if ($response) 
     { 
      echo "WS Handshake Response:\n$response\n"; 
     } else 
      echo "ERROR during WS handshake!\n"; 
     preg_match('#Sec-WebSocket-Accept:\s(.*)$#mU', $response, $matches); 
     if ($matches) { 
      $keyAccept = trim($matches[1]); 
      $expectedResonse = base64_encode(pack('H*', sha1($this->ws_key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); 
      $this->connected = ($keyAccept === $expectedResonse) ? true : false; 
     } else $this->connected=false; 
     if ($this->connected) echo "Sucessfull WS connection to $this->host:$this->port\n\n"; 
     return $this->connected; 
    } 

    function lg_handshake() 
    { 
     if (!$this->connected) $this->connect(); 
     if ($this->connected) 
     { 
      $handshake = "{"type":"register","id":"register_0","payload":{"forcePairing":false,"pairingType":"PROMPT","client-key":"HANDSHAKEKEYGOESHERE","manifest":{"manifestVersion":1,"appVersion":"1.1","signed":{"created":"20140509","appId":"com.lge.test","vendorId":"com.lge","localizedAppNames":{"":"LG Remote App","ko-KR":"리모컨 앱","zxx-XX":"ЛГ R�мot� AПП"},"localizedVendorNames":{"":"LG Electronics"},"permissions":["TEST_SECURE","CONTROL_INPUT_TEXT","CONTROL_MOUSE_AND_KEYBOARD","READ_INSTALLED_APPS","READ_LGE_SDX","READ_NOTIFICATIONS","SEARCH","WRITE_SETTINGS","WRITE_NOTIFICATION_ALERT","CONTROL_POWER","READ_CURRENT_CHANNEL","READ_RUNNING_APPS","READ_UPDATE_INFO","UPDATE_FROM_REMOTE_APP","READ_LGE_TV_INPUT_EVENTS","READ_TV_CURRENT_TIME"],"serial":"2f930e2d2cfe083771f68e4fe7bb07"},"permissions":["LAUNCH","LAUNCH_WEBAPP","APP_TO_APP","CLOSE","TEST_OPEN","TEST_PROTECTED","CONTROL_AUDIO","CONTROL_DISPLAY","CONTROL_INPUT_JOYSTICK","CONTROL_INPUT_MEDIA_RECORDING","CONTROL_INPUT_MEDIA_PLAYBACK","CONTROL_INPUT_TV","CONTROL_POWER","READ_APP_STATUS","READ_CURRENT_CHANNEL","READ_INPUT_DEVICE_LIST","READ_NETWORK_STATE","READ_RUNNING_APPS","READ_TV_CHANNEL_LIST","WRITE_NOTIFICATION_TOAST","READ_POWER_STATE","READ_COUNTRY_INFO"],"signatures":[{"signatureVersion":1,"signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw=="}]}}}"; 
      if (isset($this->lg_key)) 
       $handshake = str_replace('HANDSHAKEKEYGOESHERE',$this->lg_key,$handshake); 
      else $handshake = "{"type":"register","id":"register_0","payload":{"forcePairing":false,"pairingType":"PROMPT","manifest":{"manifestVersion":1,"appVersion":"1.1","signed":{"created":"20140509","appId":"com.lge.test","vendorId":"com.lge","localizedAppNames":{"":"LG Remote App","ko-KR":"리모컨 앱","zxx-XX":"ЛГ R�мot� AПП"},"localizedVendorNames":{"":"LG Electronics"},"permissions":["TEST_SECURE","CONTROL_INPUT_TEXT","CONTROL_MOUSE_AND_KEYBOARD","READ_INSTALLED_APPS","READ_LGE_SDX","READ_NOTIFICATIONS","SEARCH","WRITE_SETTINGS","WRITE_NOTIFICATION_ALERT","CONTROL_POWER","READ_CURRENT_CHANNEL","READ_RUNNING_APPS","READ_UPDATE_INFO","UPDATE_FROM_REMOTE_APP","READ_LGE_TV_INPUT_EVENTS","READ_TV_CURRENT_TIME"],"serial":"2f930e2d2cfe083771f68e4fe7bb07"},"permissions":["LAUNCH","LAUNCH_WEBAPP","APP_TO_APP","CLOSE","TEST_OPEN","TEST_PROTECTED","CONTROL_AUDIO","CONTROL_DISPLAY","CONTROL_INPUT_JOYSTICK","CONTROL_INPUT_MEDIA_RECORDING","CONTROL_INPUT_MEDIA_PLAYBACK","CONTROL_INPUT_TV","CONTROL_POWER","READ_APP_STATUS","READ_CURRENT_CHANNEL","READ_INPUT_DEVICE_LIST","READ_NETWORK_STATE","READ_RUNNING_APPS","READ_TV_CHANNEL_LIST","WRITE_NOTIFICATION_TOAST","READ_POWER_STATE","READ_COUNTRY_INFO"],"signatures":[{"signatureVersion":1,"signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw=="}]}}}"; 
      echo "Sending LG handshake\n$handshake\n"; 
      $response = $this->send(hybi10Encode($handshake)); 
      if ($response) 
      { 
       echo "\nLG Handshake Response\n".json_string($response)."\n"; 
       $result = json_array($response); 
       if ($result && array_key_exists('id',$result) && $result['id']=='result_0' && array_key_exists('client-key',$result['payload'])) 
       { 
        // LG client-key received: COMPARE!!! 
        if ($this->lg_key == $result['payload']['client-key']) 
         echo "LG Client-Key successfully approved\n"; 
       } else if ($result && array_key_exists('id',$result) && $result['id']=='register_0' && array_key_exists('pairingType',$result['payload']) && array_key_exists('returnValue',$result['payload'])) 
       { // LG TV is prompting for access rights 
        if ($result['payload']['pairingType'] == "PROMPT" && $result['payload']['returnValue'] == "true") 
        { 
         $starttime = microtime(1); 
         $lg_key_received = false; 
         $error_received = false; 
         do { 
          $response = @fread($this->sock, 8192); 
          $result = json_array($response); 
          if ($result && array_key_exists('id',$result) && $result['id']=='register_0' && is_array($result['payload']) && array_key_exists('client-key',$result['payload'])) 
          { 
           $lg_key_received = true; 
           $this->lg_key = $result['payload']['client-key']; 
           echo "LG Client-Key successfully received: $this->lg_key\n"; 
          } else if ($result && array_key_exists('id',$result) && $result['id']=='register_0' && array_key_exists('error',$result)) 
          { 
           $error_received = true; 
           echo "ERROR: ".$result['error']."\n"; 
          } 
          usleep(200000); 
          $time = microtime(1); 
         } while ($time-$starttime<60 && !$lg_key_received && !$error_received); 
        } 
       } 
      } else echo "ERROR during LG handshake:\n"; 
     } else return FALSE; 
    } 

    function disconnect() 
    { 
     $this->connected=false; 
     @fclose($this->sock); 
     echo "Connection closed to $this->host\n"; 
    } 

    function send($msg) 
    { 
     @fwrite($this->sock, $msg); 
     usleep(250000); 
     $response = @fread($this->sock, 8192); 
     return $response; 
    } 

    function send_command($cmd) 
    { 
     if (!$this->connected) $this->connect(); 
     if ($this->connected) 
     { 
      echo "Sending command  : $cmd\n"; 
      $response = $this->send(hybi10Encode($cmd)); 
      if ($response) 
       echo "Command response  : ".json_string($response)."\n"; 
      else 
       echo "Error sending command: $cmd\n"; 
      return $response;    
     } 
    } 

    function message($msg) 
    { 
     $command = "{"id":"message","type":"request","uri":"ssap://system.notifications/createToast","payload":{"message": "$msg"}}"; 
     $this->send_command($command); 
    } 

    function power_off() 
    { 
     $command = "{"id":"power_off","type":"request","uri":"ssap://system/turnOff"}"; 
     $this->send_command($command); 
    } 

    function set_volume($vol) 
    { 
     $command = "{"id":"set_volume","type":"request","uri":"ssap://audio/setVolume","payload":{"volume":$vol}}"; 
     $this->send_command($command); 
    } 
}  

function hybi10Encode($payload, $type = 'text', $masked = true) { 
     $frameHead = array(); 
     $frame = ''; 
     $payloadLength = strlen($payload); 

     switch ($type) { 
      case 'text': 
       // first byte indicates FIN, Text-Frame (10000001): 
       $frameHead[0] = 129; 
       break; 

      case 'close': 
       // first byte indicates FIN, Close Frame(10001000): 
       $frameHead[0] = 136; 
       break; 

      case 'ping': 
       // first byte indicates FIN, Ping frame (10001001): 
       $frameHead[0] = 137; 
       break; 

      case 'pong': 
       // first byte indicates FIN, Pong frame (10001010): 
       $frameHead[0] = 138; 
       break; 
     } 

     // set mask and payload length (using 1, 3 or 9 bytes) 
     if ($payloadLength > 65535) { 
      $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8); 
      $frameHead[1] = ($masked === true) ? 255 : 127; 
      for ($i = 0; $i < 8; $i++) { 
       $frameHead[$i + 2] = bindec($payloadLengthBin[$i]); 
      } 

      // most significant bit MUST be 0 (close connection if frame too big) 
      if ($frameHead[2] > 127) { 
       $this->close(1004); 
       return false; 
      } 
     } elseif ($payloadLength > 125) { 
      $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8); 
      $frameHead[1] = ($masked === true) ? 254 : 126; 
      $frameHead[2] = bindec($payloadLengthBin[0]); 
      $frameHead[3] = bindec($payloadLengthBin[1]); 
     } else { 
      $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength; 
     } 

     // convert frame-head to string: 
     foreach (array_keys($frameHead) as $i) { 
      $frameHead[$i] = chr($frameHead[$i]); 
     } 

     if ($masked === true) { 
      // generate a random mask: 
      $mask = array(); 
      for ($i = 0; $i < 4; $i++) { 
       $mask[$i] = chr(rand(0, 255)); 
      } 

      $frameHead = array_merge($frameHead, $mask); 
     } 
     $frame = implode('', $frameHead); 
     // append payload to frame: 
     for ($i = 0; $i < $payloadLength; $i++) { 
      $frame .= ($masked === true) ? $payload[$i]^$mask[$i % 4] : $payload[$i]; 
     } 

     return $frame; 
    } 

mon code python

def connect(self): 
    ws_handshake_cmd = "GET "+str(self._path)+" HTTP/1.1\r\n" 
    ws_handshake_cmd += "Upgrade: websocket\r\n" 
    ws_handshake_cmd += "Connection: Upgrade\r\n" 
    ws_handshake_cmd += "Sec-WebSocket-Version: 13\r\n" 
    ws_handshake_cmd += "Sec-WebSocket-Key: "+ str(self._wskey) + "\r\n" 
    ws_handshake_cmd += "Host: "+ str(self._host)+":"+str(self._port)+"\r\n\r\n" 

    try: 
     self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self._sock.connect((self._host, self._port)) 
     #self._sock.settimeout(20) 
    except: 
     print("Verbindung zu ", str(self._host), "nicht möglich!") 

    print("Sending WS handshake", ws_handshake_cmd) 

    response = self.send(ws_handshake_cmd.encode('utf-8')) 
    if response == '': 
     print("ERROR during WS handshake!") 
    else: 
     print("WS Handshake Response:", response) 
     matches = re.search('Sec-WebSocket-Accept:\s*(.*=)', response) 
     returnkey = matches.group().strip() 
     #print("Match in response ",keyAccept) 

    tvkey = '' # von TV 28 stellen 
    wskey = str(self._wskey).encode('utf8') #zu TV 26 stellen 
    key = str('258EAFA5-E914-47DA-95CA-C5AB0DC85B11').encode('utf8') 
    keys = str("%s%s" % (wskey , key)).encode('utf8') 
    hash = hashlib.sha1(keys).hexdigest() 
    print(hash) 
    asci = bytes(hash.encode('utf-8')) 
    print(asci) 
    print(base64.standard_b64encode(asci)) 
    expectedResonse = base64.b64encode(asci) 
    print("gerechneter wert",expectedResonse) 

    if returnkey == expectedResonse: 
     self._connected = True 
     print("Key Akzeptiert") 
    else: 
     self._connected = False 
     print("Key nicht Akzeptiert") 

    if self._connected: 
     print("Sucessfull WS connection to", self._host, ": ", self._port) 
    return self._connected 

def lg_handshake(self): 
    if self._connected == False: 
     self.connect() 
    if self._connected: 
     handshake ='{"type":"register","id":"register_0","payload":{"forcePairing":False,"pairingType":"PROMPT","client-key":"'+str(self._wskey)+'manifest":{"manifestVersion":1,"appVersion":"1.1","signed":{"created":"20140509","appId":"com.lge.test","vendorId":"com.lge","localizedAppNames":{"":"LG Remote App","ko-KR":"리모컨 앱","zxx-XX":"ЛГ RÑ?мotÑ? AПП"},"localizedVendorNames":{"":"LG Electronics"},"permissions":["TEST_SECURE","CONTROL_INPUT_TEXT","CONTROL_MOUSE_and_KEYBOARD","READ_INSTALLED_APPS","READ_LGE_SDX","READ_NOTIFICATIONS","SEARCH","WRITE_SETTINGS","WRITE_NOTIFICATION_ALERT","CONTROL_POWER","READ_CURRENT_CHANNEL","READ_RUNNING_APPS","READ_UPDATE_INFO","UPDATE_FROM_REMOTE_APP","READ_LGE_TV_INPUT_EVENTS","READ_TV_CURRENT_TIME"],"serial":"2f930e2d2cfe083771f68e4fe7bb07"},"permissions":["LAUNCH","LAUNCH_WEBAPP","APP_TO_APP","CLOSE","TEST_OPEN","TEST_PROTECTED","CONTROL_AUDIO","CONTROL_DISPLAY","CONTROL_INPUT_JOYSTICK","CONTROL_INPUT_MEDIA_RECORDING","CONTROL_INPUT_MEDIA_PLAYBACK","CONTROL_INPUT_TV","CONTROL_POWER","READ_APP_STATUS","READ_CURRENT_CHANNEL","READ_INPUT_DEVICE_LIST","READ_NETWORK_STATE","READ_RUNNING_APPS","READ_TV_CHANNEL_LIST","WRITE_NOTIFICATION_TOAST","READ_POWER_STATE","READ_COUNTRY_INFO"],"signatures":[{"signatureVersion":1,"signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw=="}]}}}' 
     if self._tvkey != '': 
      handshake = str.replace(self._handshakecode,self._tvkey) 
     else: 
      handshake = '{"type":"register","id":"register_0","payload":{"forcePairing":False,"pairingType":"PROMPT","manifest":{"manifestVersion":1,"appVersion":"1.1","signed":{"created":"20140509","appId":"com.lge.test","vendorId":"com.lge","localizedAppNames":{"":"LG Remote App","ko-KR":"리모컨 앱","zxx-XX":"ЛГ RÑ?мotÑ? AПП"},"localizedVendorNames":{"":"LG Electronics"},"permissions":["TEST_SECURE","CONTROL_INPUT_TEXT","CONTROL_MOUSE_and_KEYBOARD","READ_INSTALLED_APPS","READ_LGE_SDX","READ_NOTIFICATIONS","SEARCH","WRITE_SETTINGS","WRITE_NOTIFICATION_ALERT","CONTROL_POWER","READ_CURRENT_CHANNEL","READ_RUNNING_APPS","READ_UPDATE_INFO","UPDATE_FROM_REMOTE_APP","READ_LGE_TV_INPUT_EVENTS","READ_TV_CURRENT_TIME"],"serial":"2f930e2d2cfe083771f68e4fe7bb07"},"permissions":["LAUNCH","LAUNCH_WEBAPP","APP_TO_APP","CLOSE","TEST_OPEN","TEST_PROTECTED","CONTROL_AUDIO","CONTROL_DISPLAY","CONTROL_INPUT_JOYSTICK","CONTROL_INPUT_MEDIA_RECORDING","CONTROL_INPUT_MEDIA_PLAYBACK","CONTROL_INPUT_TV","CONTROL_POWER","READ_APP_STATUS","READ_CURRENT_CHANNEL","READ_INPUT_DEVICE_LIST","READ_NETWORK_STATE","READ_RUNNING_APPS","READ_TV_CHANNEL_LIST","WRITE_NOTIFICATION_TOAST","READ_POWER_STATE","READ_COUNTRY_INFO"],"signatures":[{"signatureVersion":1,"signature":"eyJhbGdvcml0aG0iOiJSU0EtU0hBMjU2Iiwia2V5SWQiOiJ0ZXN0LXNpZ25pbmctY2VydCIsInNpZ25hdHVyZVZlcnNpb24iOjF9.hrVRgjCwXVvE2OOSpDZ58hR+59aFNwYDyjQgKk3auukd7pcegmE2CzPCa0bJ0ZsRAcKkCTJrWo5iDzNhMBWRyaMOv5zWSrthlf7G128qvIlpMT0YNY+n/FaOHE73uLrS/g7swl3/qH/BGFG2Hu4RlL48eb3lLKqTt2xKHdCs6Cd4RMfJPYnzgvI4BNrFUKsjkcu+WD4OO2A27Pq1n50cMchmcaXadJhGrOqH5YmHdOCj5NSHzJYrsW0HPlpuAx/ECMeIZYDh6RMqaFM2DXzdKX9NmmyqzJ3o/0lkk/N97gfVRLW5hA29yeAwaCViZNCP8iC9aO0q9fQojoa7NQnAtw=="}]}}}' 
      print("Sending LG handshake",handshake) 
     response = self.send(self.hybi10Encode(handshake)) 
     if response == True: 
      print("LG Handshake Response",self.json_string(response)) 
      result = self.json_array(response) 
      if result and ('id' in result) and result['id']=='result_0' and ('client-key' in result['payload']): 

       #// LG client-key received: COMPARE!!! 
       if self._lg_key == result['payload']['client-key']: 
        print("LG Client-Key successfully approved") 
       else: 
        if result and ('id'in result) and result['id']=='register_0' and ('pairingType' in result['payload']) and ('returnValue' in result['payload']): 
         #// LG TV is prompting for access rights 
         if (result['payload']['pairingType'] == 'PROMPT') and (result['payload']['returnValue'] == 'True'): 
          starttime = time.time() 
          lg_key_received = False 
          error_received = False 
          while (time-starttime<60 and not lg_key_received and not error_received): 
           response = self._sock.read(8192) 
           result = self.json_array(response) 
           if result == True and ('id' in result) and result['id']=='register_0' and is_array(result['payload']) and ('client-key' in result['payload']): 
            lg_key_received = True 
            self._lg_key = result['payload']['client-key'] 
            print("LG Client-Key successfully received:",self._lg_key) 
           elif result and ('id' in result) and result['id']=='register_0' and ('error' in result): 
            error_received = True 
            print("ERROR: ",result['error']) 
           time.sleep(200000/1000000.0)#usleep(200000) 
           time = time.time() 
     else: 
      print("ERROR during LG handshake:") 
    else: 
     return False 

maintenant le problème est, tvkey est pas même que wskey + clé, mais je pense que ce n'est pas correct.

pour se connecter à la TV tvkey = touches ?!

Répondre

0

pour spécifier le problème, je pense que son juste la ligne avec la $ expectedResonse = base64_encode (pack ('H *', SHA1 ($ this-> ws_key. '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); je ne sais pas cela en python ...