RPC over Websocket¶
RPC api is reachable over websocket. A websocket server is instantiated and listen on path /rpc
.
The following python code example call RPC Totem.Layer.Steady
using a simple websocket client.
import hashlib
import json
import websocket
from datetime import datetime
def digest_message(nonce,cnounce, cmd):
cnonce = int(datetime.now().timestamp() * 1000)
digest_uri = {"method": "dummy_method", "path": "dummy_uri"}
user = "admin"
realm = "sdnesp01"
password = "password"
HA1 = hashlib.md5(f"{user}:{realm}:{password}".encode()).hexdigest()
HA2 = hashlib.md5(f"{digest_uri['method']}:{digest_uri['path']}".encode()).hexdigest()
combined = f"{HA1}:{nonce}:{cnounce}:{cnonce}:auth:{HA2}"
response = hashlib.md5(combined.encode()).hexdigest()
cmd['auth'] = {"realm": realm, "username": user, "nonce": nonce, "cnonce": cnonce, "response": response}
return json.dumps(cmd)
nonce_value = 0
id = int(datetime.now().microsecond * 1000)
cmd_data = {"src":"rpc","id":id, "method":"Totem.Layer.Steady","params":{"layer": 0, "color": "008888"}}
cnounce = 1
result = digest_message(nonce_value,cnounce, cmd_data)
ws = websocket.create_connection("ws://<device-ip>/rpc")
ws.send(result)
response = json.loads(ws.recv())
if response["error"]["code"] == 401:
message = json.loads(response["error"]["message"])
nonce_value = message["nonce"]
cnounce = message["nc"]
result = digest_message(nonce_value,cnounce, cmd_data)
ws.send(result)
response = json.loads(ws.recv())
print(response)
ws.close()
Client can’t know nonce’s value until he received an Unauthorized (401) response that contain the nonce.
Note
This example require python’s library websocket-client
.