/******************************************************************************/
// @copyright   Copyright Notification
//   No part may be reproduced except as authorized by written permission.
//   The copyright and the foregoing restriction extend to reproduction in all media.
//   Trademark 2010, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_10wk37
// $Date: 2010-06-19 22:56:43 +0200 (Sat, 19 Jun 2010) $
// $Rev: 3388 $
/******************************************************************************/

module IP_PTC_Templates {

  //import from CommonDefs all;
  import from IP_ASP_TypeDefs all;

  //****************************************************************************
  // IP Connections
  //----------------------------------------------------------------------------

  template (value) IP_Socket_Type cs_IP_Socket(template (omit) IP_AddrInfo_Type p_IpAddr,
                                               template (omit) PortNumber_Type  p_PortNumber) :=
  {
    IpAddr := p_IpAddr,
    Port   := p_PortNumber
  };

  template IP_Socket_Type cr_IP_Socket(template IP_AddrInfo_Type p_IpAddr,
                                       template PortNumber_Type  p_PortNumber) :=
  {
    IpAddr := p_IpAddr,
    Port   := p_PortNumber
  };

  template IP_Socket_Type cr_IP_Socket_Any  := cr_IP_Socket(?, ?);
  template IP_Socket_Type cr_IP_Socket_Omit := cr_IP_Socket(omit, omit);

  template (value) IP_Connection_Type cs_IP_ConnectionId(InternetProtocol_Type p_Protocol,
                                                         template (omit) IP_Socket_Type p_LocalSocket,
                                                         template (omit) IP_Socket_Type p_RemoteSocket) :=
  {
    Protocol := p_Protocol,
    Local := p_LocalSocket,
    Remote := p_RemoteSocket
  };

  template IP_Connection_Type cr_IP_ConnectionId(InternetProtocol_Type p_Protocol,
                                                 template IP_Socket_Type p_LocalSocket,
                                                 template IP_Socket_Type p_RemoteSocket) :=
  {
    Protocol := p_Protocol,
    Local := p_LocalSocket,
    Remote := p_RemoteSocket
  };

  template (value) IP_Connection_Type cs_UDP_ConnectionId(template (omit) IP_Socket_Type p_LocalSocket,
                                                          template (omit) IP_Socket_Type p_RemoteSocket) :=
    cs_IP_ConnectionId(udp, p_LocalSocket, p_RemoteSocket);


  template IP_Connection_Type cr_UDP_ConnectionId(template IP_Socket_Type p_LocalSocket,
                                                  template IP_Socket_Type p_RemoteSocket) :=
    cr_IP_ConnectionId(udp, p_LocalSocket, p_RemoteSocket);

  template (value) IP_Connection_Type cs_ICMPv6_ConnectionId(template (omit) IP_Socket_Type p_LocalSocket,
                                                             template (omit) IP_Socket_Type p_RemoteSocket) :=
    cs_IP_ConnectionId(icmpv6, p_LocalSocket, p_RemoteSocket);


  template IP_Connection_Type cr_ICMPv6_ConnectionId(template IP_Socket_Type p_LocalSocket,
                                                     template IP_Socket_Type p_RemoteSocket) :=
    cr_IP_ConnectionId(icmpv6, p_LocalSocket, p_RemoteSocket);

  template (value) IP_Connection_Type cs_TCP_ConnectionId(template (omit) IP_Socket_Type p_LocalSocket,
                                                          template (omit) IP_Socket_Type p_RemoteSocket) :=
    cs_IP_ConnectionId(tcp, p_LocalSocket, p_RemoteSocket);


  template IP_Connection_Type cr_TCP_ConnectionId(template IP_Socket_Type p_LocalSocket,
                                                  template IP_Socket_Type p_RemoteSocket) :=
    cr_IP_ConnectionId(tcp, p_LocalSocket, p_RemoteSocket);

  //****************************************************************************
  // Requests
  //----------------------------------------------------------------------------

  function fl_IP_SockOptList(boolean p_AllowBroadcast) return IP_SockOptList_Type
  {
    var IP_SockOptList_Type v_SockOptList;
    v_SockOptList := {};
    if (p_AllowBroadcast) {
      v_SockOptList[0] := {SO_BROADCAST := true};
    }
    return v_SockOptList;
  }

  // UDP:

  template (value) IP_SOCKET_REQ cs_UDP_SOCKET_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                   boolean p_AllowBroadcast) :=
  {
    CTRL := {
      ConnectionId := cs_UDP_ConnectionId(p_LocalSocket, omit),
      Req := {
        UDP := {
          SocketReq := {
            SockOptList := fl_IP_SockOptList(p_AllowBroadcast)
          }
        }
      }
    }
  };

  template (value) IP_SOCKET_REQ cs_UDP_DATA_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                 template (value) IP_Socket_Type p_RemoteSocket,
                                                 template (value) UDP_Data_Type p_UDP_Data) :=
  {
    DATA := {
      ConnectionId := cs_UDP_ConnectionId(p_LocalSocket, p_RemoteSocket),
      Req := {
        UDP := {
          SendTo := p_UDP_Data
        }
      }
    }
  };

  template (value) IP_SOCKET_REQ cs_UDP_CLOSE_REQ(template (value) IP_Socket_Type p_LocalSocket) :=
  {
    CTRL := {
      ConnectionId := cs_UDP_ConnectionId(p_LocalSocket, omit),
      Req := {
        UDP := {
          Close := true
        }
      }
    }
  };

  // ICMPv6:

  template (value) IP_SOCKET_REQ cs_ICMPv6_SOCKET_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                      boolean p_AllowBroadcast) :=
  {
    CTRL := {
      ConnectionId := cs_ICMPv6_ConnectionId(p_LocalSocket, omit),
      Req := {
        ICMP := {
          SocketReq := {
            SockOptList := fl_IP_SockOptList(p_AllowBroadcast)
          }
        }
      }
    }
  };

  template (value) IP_SOCKET_REQ cs_ICMPv6_DATA_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                    template (value) IP_Socket_Type p_RemoteSocket,
                                                    template (value) ICMP_Data_Type p_ICMP_Data) :=
  {
    DATA := {
      ConnectionId := cs_ICMPv6_ConnectionId(p_LocalSocket, p_RemoteSocket),
      Req := {
        ICMP := {
          SendTo := p_ICMP_Data
        }
      }
    }
  };
  
  template (value) IP_SOCKET_REQ cs_ICMPv6_CLOSE_REQ(template (value) IP_Socket_Type p_LocalSocket) :=
  {
    CTRL := {
      ConnectionId := cs_ICMPv6_ConnectionId(p_LocalSocket, omit),
      Req := {
        ICMP := {
          Close := true
        }
      }
    }
  };
  
  // TCP:
  
  template (value) IP_SOCKET_REQ cs_TCP_LISTEN_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                   boolean p_AllowBroadcast) :=
  {
    CTRL := {
      ConnectionId := cs_TCP_ConnectionId(p_LocalSocket, omit),
      Req := {
        TCP := {
          Listen := {
            SockOptList := fl_IP_SockOptList(p_AllowBroadcast)
          }
        }
      }
    }
  };
  
  template (value) IP_SOCKET_REQ cs_TCP_DATA_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                 template (value) IP_Socket_Type p_RemoteSocket,
                                                 template (value) TCP_Data_Type p_TCP_Data) :=
  {
    DATA := {
      ConnectionId := cs_TCP_ConnectionId(p_LocalSocket, p_RemoteSocket),
      Req := {
        TCP := {
          Send := p_TCP_Data
        }
      }
    }
  };

  template (value) IP_SOCKET_REQ cs_TCP_CLOSE_REQ(template (value) IP_Socket_Type p_LocalSocket,
                                                  template (value) IP_Socket_Type p_RemoteSocket) :=
  {
    CTRL := {
      ConnectionId := cs_TCP_ConnectionId(p_LocalSocket, p_RemoteSocket),
      Req := {
        TCP := {
          Close := true
        }
      }
    }
  };


  //****************************************************************************
  // Indications
  //----------------------------------------------------------------------------

  // UDP:

  template IP_SOCKET_IND cr_UDP_SOCKET_CNF(template IP_Socket_Type p_LocalSocket) :=
  {
    CTRL := {
      ConnectionId := cr_UDP_ConnectionId(p_LocalSocket, cr_IP_Socket_Omit),
      Ind := {
        UDP := {
          SocketCnf := true
        }
      }
    }
  };

  template IP_SOCKET_IND cr_UDP_DATA_IND(template IP_Socket_Type p_LocalSocket) :=
  {
    DATA := {
      ConnectionId := cr_UDP_ConnectionId(p_LocalSocket, cr_IP_Socket_Any),
      Ind := {
        UDP := {
          RecvFrom := ?
        }
      }
    }
  };

  // ICMPv6:

  template IP_SOCKET_IND cr_ICMPv6_SOCKET_CNF(template IP_Socket_Type p_LocalSocket) :=
  {
    CTRL := {
      ConnectionId := cr_ICMPv6_ConnectionId(p_LocalSocket, cr_IP_Socket_Any),
      Ind := {
        ICMP := {
          SocketCnf := true
        }
      }
    }
  };

  template IP_SOCKET_IND cr_ICMPv6_DATA_IND(template IP_Socket_Type p_LocalSocket) :=
  {
    DATA := {
      ConnectionId := cr_ICMPv6_ConnectionId(p_LocalSocket, cr_IP_Socket_Any),
      Ind := {
        ICMP := {
          RecvFrom := ?
        }
      }
    }
  };

  // TCP:

  template IP_SOCKET_IND cr_TCP_ACCEPT_IND(template IP_Socket_Type p_LocalSocket) :=
  {
    CTRL := {
      ConnectionId := cr_TCP_ConnectionId(p_LocalSocket, cr_IP_Socket_Any),
      Ind := {
        TCP := {
          Accept := true
        }
      }
    }
  };

  template IP_SOCKET_IND cr_TCP_DATA_IND(template IP_Socket_Type p_LocalSocket,
                                         template IP_Socket_Type p_RemoteSocket) :=
  {
    DATA := {
      ConnectionId := cr_TCP_ConnectionId(p_LocalSocket, p_RemoteSocket),
      Ind := {
        TCP := {
          Recv := ?
        }
      }
    }
  };

}
