# Welcome to socket_protocol’s documentation!

## socket_protocol (Socket Protocol)

Author:

- Dirk Alders <sudo-dirk@mount-mockery.de>

Description:

> This Module supports point to point communication for client-server issues.

Submodules:

- `socket_protocol.data_storage`
- `socket_protocol.pure_json_protocol`
- `socket_protocol.struct_json_protocol`

Unittest:

> See also the `unittest` documentation.

Module Documentation:

`socket_protocol.``AUTH_STATE_KEY_TRANSFERRED` = 3

  Authentification Status for ‘Key has been sent’

`socket_protocol.``AUTH_STATE_SEED_REQUESTED` = 1

  Authentification Status for ‘Seed was requested’

`socket_protocol.``AUTH_STATE_SEED_TRANSFERRED` = 2

  Authentification Status for ‘Seed has been sent’

`socket_protocol.``AUTH_STATE_TRUSTED_CONNECTION` = 4

  Authentification Status for a ‘Trusted Connection’

`socket_protocol.``AUTH_STATE_UNTRUSTED_CONNECTION` = 0

  Authentification Status for an ‘Untrusted Connection’

`socket_protocol.``AUTH_STATE__NAMES` = {0: 'Untrusted Connection', 1: 'Seed was requested', 2: 'Seed has been sent', 3: 'Key has been sent', 4: 'Trusted Connection'}

  Authentification Status names for previous defined authentification states

`socket_protocol.``DID_AUTH_KEY` = 1

  DID for authentification (key)

`socket_protocol.``DID_AUTH_SEED` = 0

  DID for authentification (seed)

`socket_protocol.``DID_CHANNEL_NAME` = 0

  DID for channel name

exception `socket_protocol.``RequestSidExistsError`

exception `socket_protocol.``ResponseSidExistsError`

`socket_protocol.``SID_AUTH_REQUEST` = 0

  SID for authentification request

`socket_protocol.``SID_AUTH_RESPONSE` = 1

  SID for authentification response

`socket_protocol.``SID_CHANNEL_NAME_REQUEST` = 8

  SID for channel name exchange request

`socket_protocol.``SID_CHANNEL_NAME_RESPONSE` = 9

  SID for channel name exchange response

`socket_protocol.``SID_EXECUTE_REQUEST` = 30

  SID for a execute request

`socket_protocol.``SID_EXECUTE_RESPONSE` = 31

  SID for a execute response

`socket_protocol.``SID_READ_REQUEST` = 10

  SID for a read data request

`socket_protocol.``SID_READ_RESPONSE` = 11

  SID for read data response

`socket_protocol.``SID_WRITE_REQUEST` = 20

  SID for a write data request

`socket_protocol.``SID_WRITE_RESPONSE` = 21

  SID for a write data response

`socket_protocol.``STATUS_AUTH_REQUIRED` = 3

  Status for ‘authentification is required’

`socket_protocol.``STATUS_BUFFERING_UNHANDLED_REQUEST` = 1

  Status for ‘unhandled request’

`socket_protocol.``STATUS_CALLBACK_ERROR` = 2

  Status for ‘callback errors’

`socket_protocol.``STATUS_CHECKSUM_ERROR` = 5

  Status for ‘checksum error’

`socket_protocol.``STATUS_LOG_LVL` = {0: 20, 1: 30, 2: 40, 3: 30, 4: 40, 5: 40, 6: 30}

  Status depending log level for messages

`socket_protocol.``STATUS_OKAY` = 0

  Status for ‘okay’

`socket_protocol.``STATUS_OPERATION_NOT_PERMITTED` = 6

  Status for ‘operation not permitted’

`socket_protocol.``STATUS_SERVICE_OR_DATA_UNKNOWN` = 4

  Status for ‘service or data unknown’

class `socket_protocol.``data_storage`(*args, **kwargs)

  This is a storage object for socket_protocol messages.

  Parameters: | status (int) – The message status. service_id (int) – The Service-ID. data_id (int) – The Data-ID. data (any) – The transfered data.

  `get_data`(default=None)

    This Method returns the message data.

    Parameters: | default – The default value, if no data is available.

  `get_data_id`(default=None)

    This Method returns the message Data-ID.

    Parameters: | default – The default value, if no data is available.

  `get_service_id`(default=None)

    This Method returns the message Service-ID.

    Parameters: | default – The default value, if no data is available.

  `get_status`(default=None)

    This Method returns the message status.

    Parameters: | default – The default value, if no data is available.

class `socket_protocol.``pure_json_protocol`(comm_instance, secret=None, auto_auth=False, channel_name=None)

  This class supports to transfer a message and it’s data.

  Parameters: | comm_instance (instance) – A communication instance. secret (str) – An optinal secret (e.g. created by `binascii.hexlify(os.urandom(24))`). auto_auth (bool) – An optional parameter to enable (True) automatic authentification, otherwise you need to do it manually, if needed. channel_name (str) – An optional parameter to set a channel name for logging of the communication.

  Hint

  - The Service-ID is designed to identify the type of the communication (e.g. `READ_REQUEST`, `WRITE_REQUEST`, `READ_RESPONSE`, `WRITE_RESPONSE`, …)
  - The Data-ID is designed to identify the requests / responses using the same Service_ID.

  Note

  The `comm_instance` needs to have at least the following interface:

  - A Method `comm_instance.init_channel_name()` to set the channel name.
  - A Constant `comm_instance.IS_CLIENT` to identify that the `comm_instance` is a client (True) or a server (False).
  - A Method `comm_instance.is_connected()` to identify if the instance is connected (True) or not (False).
  - A Method `comm_instance.reconnect()` to initiate a reconnect.
  - A Method `comm_instance.register_callback()` to register a data available callback.
  - A Method `comm_instance.register_connect_callback()` to register a connect callback.
  - A Method `comm_instance.register_disconnect_callback()` to register a disconnect callback.
  - A Method `comm_instance.send()` to send data via the `comm_instance`.

  Note

  The parameter `auto_auth` is only relevant, if a secret is given and the `comm_instance` is a client. The authentification is initiated directly after the connection is established.

  Note

  The `channel_name`-exchange will be initiated by the client directly after the the connection is established.

  - If a channel_name is given at both communication sides and they are different, the client name is taken over and the server will log a warning message.

  Example:

      import sys
      sys.path.append('../..')

      import report
      import socket_protocol
      from socket_protocol_server import example_protocol, DID_ASC_TIME
      import tcp_socket
      import time

      if __name__ == '__main__':
          report.stdoutLoggingConfigure(log_name_lvl=[('root', 'INFO'), ])
          c = tcp_socket.tcp_client_stp('127.0.0.1', 17017)
          sp = example_protocol(c, channel_name='example_client')
          sp.send(socket_protocol.SID_READ_REQUEST, DID_ASC_TIME, None)
          print('The Client received: %s' % repr(sp.receive(socket_protocol.SID_READ_RESPONSE, 0).get_data()))

  and

      import sys
      sys.path.append('../..')

      import report
      import socket_protocol
      import tcp_socket
      import time

      DID_ASC_TIME = 0

      class example_protocol(socket_protocol.pure_json_protocol):
          def __init__(self, *args, **kwargs):
              socket_protocol.pure_json_protocol.__init__(self, *args, **kwargs)
              #
              self.add_data((socket_protocol.SID_READ_REQUEST, socket_protocol.SID_READ_RESPONSE), DID_ASC_TIME, 'asc_time')
              #
              if not self.__comm_inst__.IS_CLIENT:
                  self.register_callback(socket_protocol.SID_READ_REQUEST, 0, self.time_callback)

          def time_callback(self, msg):
              if msg.get_status() == socket_protocol.STATUS_OKAY:
                  return socket_protocol.STATUS_OKAY, time.asctime()
              else:
                  return socket_protocol.STATUS_OPERATION_NOT_PERMITTED, None

      if __name__ == '__main__':
          report.stdoutLoggingConfigure(log_name_lvl=[('root', 'INFO'), ])
          s = tcp_socket.tcp_server_stp('127.0.0.1', 17017)
          sp = example_protocol(s, channel_name='example_server')

          i = 0
          while not s.is_connected() and i <= 20:
              i += 1
              time.sleep(.1)  # wait for a connection

          i = 0
          while s.is_connected() and i <= 20:
              i += 1
              time.sleep(.1)  # wait for disconnect

  Will result to the following output:

      2021-01-12 09:13:30,657: root.socket_protocol.example_client - INFO - prot-client: Resetting authentification state to AUTH_STATE_UNTRUSTED_CONNECTION
      2021-01-12 09:13:30,657: root.socket_protocol - INFO - prot-client: Initialisation finished.
      2021-01-12 09:13:30,657: root.socket_protocol.example_client - INFO - prot-client: TX -> service: read data request, data_id: asc_time, status: okay, data: "None"
      2021-01-12 09:13:30,708: root.tcp_socket.example_client - INFO - comm-client: Connection established... (to 127.0.0.1:17017)
      2021-01-12 09:13:30,708: root.socket_protocol.example_client - INFO - prot-client: TX -> service: channel name request, data_id: name, status: okay, data: "'example_client'"
      2021-01-12 09:13:30,708: root.tcp_socket.example_client - INFO - comm-client: TX -> "(74): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 38 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 65 78 61 6d 70 6c 65 5f 63 6c 69 65 6e 74 22 7d f5 cd dd e7"
      2021-01-12 09:13:30,758: root.tcp_socket.example_client - INFO - comm-client: TX -> "(63): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 30 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 45 05 7b b4"
      2021-01-12 09:13:30,759: root.stringtools.stp - INFO - STP: message identified - (62): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 39 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 30 59 be 2f
      2021-01-12 09:13:30,760: root.tcp_socket.example_client - INFO - comm-client: RX  <- "(62): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 39 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 6e 75 6c 6c 7d 30 59 be 2f"
      2021-01-12 09:13:30,760: root.socket_protocol.example_client - INFO - prot-client: RX <- service: channel name response, data_id: name, status: okay, data: "None"
      2021-01-12 09:13:30,811: root.stringtools.stp - INFO - STP: message identified - (85): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 31 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 54 75 65 20 4a 61 6e 20 31 32 20 30 39 3a 31 33 3a 33 30 20 32 30 32 31 22 7d 2b b5 b2 77
      2021-01-12 09:13:30,812: root.tcp_socket.example_client - INFO - comm-client: RX  <- "(85): 7b 22 64 61 74 61 5f 69 64 22 3a 20 30 2c 20 22 73 65 72 76 69 63 65 5f 69 64 22 3a 20 31 31 2c 20 22 73 74 61 74 75 73 22 3a 20 30 2c 20 22 64 61 74 61 22 3a 20 22 54 75 65 20 4a 61 6e 20 31 32 20 30 39 3a 31 33 3a 33 30 20 32 30 32 31 22 7d 2b b5 b2 77"
      2021-01-12 09:13:30,812: root.socket_protocol.example_client - INFO - prot-client: RX <- service: read data response, data_id: asc_time, status: okay, data: "'Tue Jan 12 09:13:30 2021'"
      The Client received: 'Tue Jan 12 09:13:30 2021'

  `add_data`(service_id, data_id, name)

    Method to add a name for a specific message.

    Parameters: | service_id (int or list of ints) – The Service-ID of the message. See class definitions starting with `SID_`. data_id (int) – The Data-ID of the message. name (str) – The Name for the transfered message.

  `add_msg_to_auth_whitelist_`(service_id, data_id)

    Method to add a specific message to the list, where no authentification is required.

    Parameters: | service_id (int) – The Service-ID of the message. See class definitions starting with `SID_`. data_id (int) – The Data-ID of the message.

  `add_service`(req_sid, resp_sid, req_name=None, resp_name=None)

    Method to add a Service defined by Request- and Response Serivce-ID.

    Parameters: | req_sid (int) – The Request Service-ID. resp_sid (int) – The Response Service-ID.

  `add_status`(status, name)

    Method to add a name for a status.

    Parameters: | status (int) – The Status. See class definitions starting with `STATUS_`. name (str) – The Name for the Status.

  `authentificate`(timeout=2)

    This method authetificates the client at the server.

    Parameters: | timeout (float) – The timeout for the authentification (requesting seed, sending key and getting authentification_feedback).
    Returns: | True, if authentification was successfull; False, if not.
    Return type: | bool

    Note

    An authentification will only processed, if a secret had been given on initialisation.

    Note

    Client and Server needs to use the same secret.

  `check_authentification_state`()

    This Method return the Authitification State as boolean value.

    Returns: | True, if authentification state is okay, otherwise False
    Return type: | bool

  `connection_established`()

    This Method returns the Connection state including authentification as a boolean value.

    Returns: | True, if the connection is established (incl. authentification, if a secret has been given)
    Return type: | bool

  `is_connected`()

    This Methods returns Connection state of the Communication Instance `comm_instance.is_connected()`.

    Returns: | True if the `comm_instance` is connected, otherwise False..
    Return type: | bool

  `receive`(service_id, data_id, timeout=1)

    This Method returns a message object for a defined message or None, if this message is not available after the given timout.

    Parameters: | service_id (int) – The Service-ID for the message. See class definitions starting with `SID_`. data_id (int) – The Data-ID for the message. timeout (float) – The timeout for receiving.
    Returns: | The received data storage object or None, if no data was received.
    Return type: | data_storage

  `reconnect`()

    This methods initiates a reconnect by calling `comm_instance.reconnect()`.

  `register_callback`(service_id, data_id, callback, *args, **kwargs)

    This method registers a callback for the given parameters. Giving `None` means, that all Service-IDs or all Data-IDs are used. If a message hitting these parameters has been received, the callback will be executed.

    Parameters: | service_id (int) – The Service-ID for the message. See class definitions starting with `SID_`. data_id (int) – The Data-ID for the message.

    Note

    The `callback()` is priorised in the following order:

    - Callbacks with defined Service-ID and Data-ID.
    - Callbacks with a defined Service-ID and all Data-IDs.
    - Callbacks with a defined Data-ID and all Service-IDs.
    - Unspecific Callbacks.

    Note

    The `callback()` is executed with these arguments:

    Parameters given at the callback call:

    - The first Arguments is the received message as `data_storage` object.
    - Further arguments given at registration.
    - Further keyword arguments given at registration.

    Return value of the callback:

    If the Callback is a Request Callback for a registered Service, the return value has to be a tuple or list with

    - `response_status`: The response status (see class definitions starting with `STA_*`.
    - `response_data`: A JSON iterable object to be used as data for the response.

    Note

    Only registered services will respond via the callbacks return values with the same data_id.

  `send`(service_id, data_id, data, status=0, timeout=2)

    This methods sends out a message with the given content.

    Parameters: | service_id (int) – The Service-ID for the message. See class definitions starting with `SERVICE_`. data_id (int) – The Data-ID for the message. data (str) – The data to be transfered. The data needs to be json compatible. status (int) – The Status for the message. All requests should have `STATUS_OKAY`. timeout (float) – The timeout for sending data (e.g. time to establish new connection).
    Returns: | True if data had been sent, otherwise False.
    Return type: | bool

class `socket_protocol.``struct_json_protocol`(*args, **kwargs)

  This Class has the same functionality like `pure_json_protocol`. The message length is less than for `pure_json_protocol`, but the functionality and compatibility is reduced. See also parent `pure_json_protocol`.

  Note

  This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of `pure_json_protocol` is recommended.

# Indices and tables

- Index
- Module Index
- Search Page