Skip to content

Well known methods

Fanda Vacek edited this page May 22, 2023 · 61 revisions

Well known methods

hello

parameters:

  • clientType (optional) type of client
  • clientPubKey (optional) client RSA public key

client starts handshake with server when TCP connection is established

client ChainPack connection: <id:1, method:"hello">i{} or JSON connection: {"id":1, "method":"hello", "params": {"clientType": "shvspy"}}

Client hello might contain parameter clientPubKey to check client identity using RSA-OAEP.

server ChainPack connection: <id:1>i{2:{"nonce":"2101306386"}} or JSON connection: {"id":1, "result":{"nonce":"2101306386"}}

Server response result might contain parameter serverPubKey to check server identity. RSA-OAEP login password encryption can be used then.

login

client authorization to server when hello response is received

login types:

  • PLAIN
  • SHA1 - password == HEX(SHA1(nonce + HEX(SHA1(password))))
  • RSA-OAEP

client: <1:1, 8:2, 10:"login">i{1:{"login":{"password":"3d613ce0c3b59a36811e4acbad533ee771afa9f3", "user":"iot", "type":"SHA1"}, "options":{"device":{"deviceId":"bfsview_test", "mountPoint":""}, "idleWatchDogTimeOut":180}}}

server: <8:2>i{2:{"clientId":68384}}

RSA-OAEP authorization

  1. Client sends RSA-OAEP(nonce + HEX(SHA1(password))) encrypted by client private key in password
  2. If server identity have to be checked, server sends in login respose RSA-OAEP(nonce + HEX(SHA1(password))) using its private key.
  3. Client can check using server public key, that data received are the same nonce + HEX(SHA1(password))

RAS-OAEP login type is not implemented yet.

ping

client calls method ping on node .broker/app as its heart-beat. Is server does not receive client's ping for time longer than idleWatchDogTimeOut then server aborts TCP connection.

ping return value is not specified yet.

ls

list node children

ls() or ls(["", attributes]) or ls(["dirname", attributes])

attributes: bitfield of method attribute values to return. Currently supported attributes:

  1. HasChildren = 1 << 0 with return values
    • true - children exist
    • false - no children
    • null - info unavailable, for examble broker client-mount node must make RPC call do discover this

return: [[node_id_1 , ret_1, ..., ret_n], ..., [node_id_n , ret_1, ..., ret_n]]

example:

  • ls() -> ["foo", "bar", "baz"]
  • ls("", 1) -> [["foo", true], ["bar", false], ["baz", null]]

dir

list node methods

dir() or dir("method_name") or dir([method_name, attributes])

  • calling dir() is the same as calling dir([""]) is the same as calling dir(["", null])

  • calling dir("method") is the same as calling dir(["method"]) is the same as calling dir(["method", null])

  • method_name: currently supported are empty string to list all methods or method_name to get attributes of particular method dir(["method_name", 127]) or dir(["method_name", []]) or discover if method with method_name exists dir("method_name")

  • attributes

    • parameter missing or number - bitfield of method attribute values to return.
      • Supported attributes:
        1. Signature = 1 << 0, enum class Signature {VoidVoid = 0, VoidParam, RetVoid, RetParam};
        2. Flags = 1 << 1
        3. AccessGrant = 1 << 2
        4. Description = 1 << 3
        5. Tags = 1 << 4
      • Returns: [[method_1 , attr_val_1, ..., attr_val_n], ..., [node_id_n , attr_val_1, ..., attr_val_n]]
    • not-number or 127 - all the attributes are returned as dictionary. Parameter 127 is ambiguous and it is preferred to return list of maps, however some legacy clients may support list of lists only.
      • Returns: [{"name": "method_1", "signature": "attr_val_0" , "flags": flags_bits , "description": "attr_val_3", ...}, ...]

Flags:

  1. IsSignal = 1 << 0
  2. IsGetter = 1 << 1
  3. IsSetter = 1 << 2
  4. LargeResultHint = 1 << 3,

get

get node value

set

set node value

subscribe

subscribe notifications for subdir and method, must be called on shv path .broker/app

example: <T:RpcMessage, id:4u, shvPath:".broker/app", method:"subscribe">i{params:{"method":"chng", "path":"test"}}

subscribes all notifications with method chng on all subdirs of test broker directory

example: <T:RpcMessage, id:4u, shvPath:".broker/app", method:"subscribe">i{params:{"method":"foo", "path":""}}

subscribes all foo notifications

method cannot be empty, to enable rejectNotSubscribed implementation. With wild-card in method the most specific subscription cannot be always determined.

Privileged user can still create subscription with empty method to grab all the notification for debug purposes. rejectNotSubscribed might not work as expected in such a case.

unsubscribe

unsubscribe notifications for subdir and method, must be called on shv path .broker/app

example: <T:RpcMessage, id:4u, shvPath:".broker/app", method:"unsubscribe">i{params:{"method":"chng", "path":"test"}}

unsubscribes all notifications with method chng on all subdirs of test broker directory

shv_path and method must exactly match parameters of one of previous subscribe call.

Returns:

  • True if subscribe record is found and deleted
  • False otherwise

rejectNotSubscribed

rejectNotSubscribed({"method":"received-notify-method", "path":"received-notify-path"})

un-subscribe unexpected notification. When client receive unexpected notification, it can call this method to get rid of it. Broker returns true or false if some subscription matching path and method of unwanted notification was found and deleted or not.

If more subscriptions are found, the one with method wild-card will be removed first. This way the "debug subscriptions" will be removed first, what is correct, because they are not needed for proper system function.

chng

node value changed notification, cannot be called explicitly