CXM_generic_protocol.anubis 4.31 KB
/*
 * 
 * User: David RENE
 * Date: 25/04/2007
 * Time: 16:20
 * (c) Calexium
 *
 */

read system/muscle.anubis
read system/data_io.anubis
read system/string.anubis
read tools/basis.anubis
read system/message_queue.anubis
read calexium_lib/CXM_message_constants.anubis

public define Word32 _CXM_OK                  = 0.
public define Word32 _CXM_ERROR               = 1.
public define Word32 _CXM_UNKNOW_CMD          = 2.
public define Word32 _CXM_UNKNOW_SERVICE      = 3.
public define Word32 _CXM_MISSING_REQUIRED_FIELD          = 4.
public define Word32 _CXM_FORBIDDEN           = 5.
public define Word32 _CXM_BAD_AUTHENTICATION  = 6.
public define Word32 _CXM_TEMPORARY_ERROR     = 7.    // When received, the client should try later 

public type ProtocolResult:
  failure,
  timeout,
  unknow_cmd,
  error,
  error(Word32, String),
  ok,
  ok_msg(Message).
  
public define One
  send_ACK_error
  (
    MessageQueue  queue,
    Word32        cmd_id,
    Word32        error_code,
    String        error_string,
  )=
  with err_msg = message(_CXM_ACK),
  forget(add_int32(err_msg, "CMD", cmd_id));
  forget(add_int32(err_msg, "STATUS", error_code));
  (if error_string /= "" then forget(add_string(err_msg, "STATUS_MSG", error_string))
                         else unique);
  forget(queue.add_Message_to_send(err_msg)).
  
public define One
  send_ACK_error
  (
    MessageQueue  queue,
    Word32     cmd_id
  )=
  send_ACK_error(queue, cmd_id, _CXM_ERROR, "").

public define One
  send_ACK_ok
  (
    MessageQueue  queue,
    Word32         cmd_id
  )=
  with ok_msg = message(_CXM_ACK),
  forget(add_int32(ok_msg, "CMD", cmd_id));
  forget(add_int32(ok_msg, "STATUS", _CXM_OK));
  forget(queue.add_Message_to_send(ok_msg))
  .

public define One
  send_ACK_ok
  (
    MessageQueue  queue,
    Word32     cmd_id,
    Message   result
  )=
  with ok_msg = message(_CXM_ACK),
  forget(add_int32(ok_msg, "CMD", cmd_id));
  forget(add_int32(ok_msg, "STATUS", _CXM_OK));
  forget(add_message(ok_msg, "RESULT", result));
  forget(queue.add_Message_to_send(ok_msg))
  .
  
public define One
  send_result
  (
    MessageQueue    queue,
    Word32           cmd_id,
    Maybe(Message)  mb_msg
  )=
  if mb_msg is
  {
    failure       then send_ACK_error(queue, cmd_id),
    success(msg)  then send_ACK_ok(queue, cmd_id, msg)
  }.

public define One
  send_result
  (
    MessageQueue    queue,
    Word32           cmd_id,
    Result((Word32, String), Message)  mb_msg
  )=
  if mb_msg is
  {
    error(err)  then 
      if err is (err_code, err_string) then
      send_ACK_error(queue, cmd_id, err_code, err_string),
    ok(msg)     then send_ACK_ok(queue, cmd_id, msg)
  }.
  
public define One
  send_result
  (
    MessageQueue    queue,
    Word32           cmd_id,
    Bool            result
  )=
  if result then
    send_ACK_ok(queue, cmd_id)
  else
    send_ACK_error(queue, cmd_id).

public define ProtocolResult
  wait_for_reply
  (
    MessageQueue  mQ,
    Word32        wait_cmd,
    Int           t_out
  ) =
  if mQ.get_next_received_Message(t_out) is
  {
    timeout   then  timeout,
    closed    then  failure, //println("wait_for_reply closed");
    
    msg(_msg) then  
      if *_msg.what = _CXM_ACK then
        if find_int32(_msg, "CMD") is
        {
          failure       then failure, //println("wait_for_reply CMD");
          success(cmd)  then
//          println("wait_for_reply CMD="+to_hexa(cmd));
            if find_int32(_msg, "STATUS") is
            {
              failure         then failure, //println("wait_for_reply STATUS");
              success(status) then
                if cmd = wait_cmd then 
                (
                  if status = _CXM_OK then
                    if find_message(_msg, "RESULT") is
                    {
                      failure             then ok,
                      success(ok_message) then ok_msg(ok_message)
                    }
                  else if status = _CXM_ERROR then
                    error
                  else if status = _CXM_UNKNOW_CMD then
                    unknow_cmd
                  else
                    error(status, if find_string(_msg, "STATUS_MSG") is success(txt) then txt else "")
                )
                else
                  failure //println("wait_for_reply ");
            }
        }
      else
        failure //println("wait_for_reply not ACK");
    }.