// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#define _SWAP_H         // Preclude inclusion of unnecessary simulator header
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <setjmp.h>
#include "bool.h"
#include "Platform.h"
#include "ExecCommand_fp.h"
#include "Manufacture_fp.h"
#include "DRTM_fp.h"
#include "_TPM_Init_fp.h"
#include "TpmFail_fp.h"
#include <windows.h>
#include "TpmTcpProtocol.h"
static BOOL     s_isPowerOn = FALSE;
//
//
//          Functions
//
//          Signal_PowerOn()
//
//     This function processes a power-on indicataion. Amoung other things, it calls the _TPM_Init() hangler.
//
void
_rpc__Signal_PowerOn(
     BOOL          isReset
     )
{
     // if power is on and this is not a call to do TPM reset then return
     if(s_isPowerOn && !isReset)
         return;
     // If this is a reset but power is not on, then return
     if(isReset && !s_isPowerOn)
         return;
     // Pass power on signal to platform
     if(isReset)
         _plat__Signal_Reset();
     else
         _plat__Signal_PowerOn();
     // Pass power on signal to TPM
     _TPM_Init();
     // Set state as power on
     s_isPowerOn = TRUE;
}
//
//
//         Signal_PowerOff()
//
//     This function processes the power off indication. Its primary funtion is to set a flag indicating that the next
//     power on indication should cause _TPM_Init() to be called.
//
void
_rpc__Signal_PowerOff(
    void
    )
{
    if(!s_isPowerOn) return;
    // Pass power off signal to platform
    _plat__Signal_PowerOff();
    s_isPowerOn = FALSE;
    return;
}
//
//
//         _rpc__ForceFailureMode()
//
//     This function is used to debug the Failure Mode logic of the TPM. It will set a flag in the TPM code such
//     that the next call to TPM2_SelfTest() will result in a failure, putting the TPM into Failure Mode.
//
void
_rpc__ForceFailureMode(
    void
    )
{
    SetForceFailureMode();
}
//
//
//         _rpc__Signal_PhysicalPresenceOn()
//
//     This function is called to simulate activation of the physical presence pin.
//
void
_rpc__Signal_PhysicalPresenceOn(
    void
    )
{
    // If TPM is power off, reject this signal
    if(!s_isPowerOn) return;
    // Pass physical presence on to platform
    _plat__Signal_PhysicalPresenceOn();
    return;
}
//
//
//         _rpc__Signal_PhysicalPresenceOff()
//
//     This function is called to simulate deactivation of the physical presence pin.
//
void
_rpc__Signal_PhysicalPresenceOff(
    void
    )
{
    // If TPM is power off, reject this signal
    if(!s_isPowerOn) return;
    // Pass physical presence off to platform
    _plat__Signal_PhysicalPresenceOff();
    return;
}
//
//
//          _rpc__Signal_Hash_Start()
//
//      This function is called to simulate a _TPM_Hash_Start() event. It will call
//
void
_rpc__Signal_Hash_Start(
    void
    )
{
    // If TPM is power off, reject this signal
    if(!s_isPowerOn) return;
    // Pass _TPM_Hash_Start signal to TPM
    Signal_Hash_Start();
    return;
}
//
//
//          _rpc__Signal_Hash_Data()
//
//      This function is called to simulate a _TPM_Hash_Data() event.
//
void
_rpc__Signal_Hash_Data(
    _IN_BUFFER           input
    )
{
    // If TPM is power off, reject this signal
    if(!s_isPowerOn) return;
    // Pass _TPM_Hash_Data signal to TPM
    Signal_Hash_Data(input.BufferSize, input.Buffer);
    return;
}
//
//
//          _rpc__Signal_HashEnd()
//
//      This function is called to simulate a _TPM_Hash_End() event.
//
void
_rpc__Signal_HashEnd(
    void
    )
{
    // If TPM is power off, reject this signal
    if(!s_isPowerOn) return;
    // Pass _TPM_HashEnd signal to TPM
    Signal_Hash_End();
    return;
}
//
//      Command interface Entry of a RPC call
void
_rpc__Send_Command(
   unsigned char        locality,
   _IN_BUFFER           request,
   _OUT_BUFFER         *response
   )
{
   // If TPM is power off, reject any commands.
   if(!s_isPowerOn) {
       response->BufferSize = 0;
       return;
   }
   // Set the locality of the command so that it doesn't change during the command
   _plat__LocalitySet(locality);
   // Do implementation-specific command dispatch
   ExecuteCommand(request.BufferSize, request.Buffer,
                          &response->BufferSize, &response->Buffer);
   return;
}
//
//
//         _rpc__Signal_CancelOn()
//
//      This function is used to turn on the indication to cancel a command in process. An executing command is
//      not interrupted. The command code may perodically check this indication to see if it should abort the
//      current command processing and returned TPM_RC_CANCELLED.
//
void
_rpc__Signal_CancelOn(
   void
   )
{
   // If TPM is power off, reject this signal
   if(!s_isPowerOn) return;
   // Set the platform canceling flag.
   _plat__SetCancel();
   return;
}
//
//
//       _rpc__Signal_CancelOff()
//
//      This function is used to turn off the indication to cancel a command in process.
//
void
_rpc__Signal_CancelOff(
   void
   )
{
   // If TPM is power off, reject this signal
   if(!s_isPowerOn) return;
   // Set the platform canceling flag.
   _plat__ClearCancel();
   return;
}
//
//
//
//       _rpc__Signal_NvOn()
//
//      In a system where the NV memory used by the TPM is not within the TPM, the NV may not always be
//      available. This function turns on the indicator that indicates that NV is available.
//
void
_rpc__Signal_NvOn(
   void
   )
{
   // If TPM is power off, reject this signal
   if(!s_isPowerOn) return;
   _plat__SetNvAvail();
   return;
}
//
//
//       _rpc__Signal_NvOff()
//
//      This function is used to set the indication that NV memory is no longer available.
//
void
_rpc__Signal_NvOff(
   void
   )
{
   // If TPM is power off, reject this signal
   if(!s_isPowerOn) return;
   _plat__ClearNvAvail();
   return;
}
//
//
//       _rpc__Shutdown()
//
//      This function is used to stop the TPM simulator.
//
void
_rpc__Shutdown(
   void
   )
{
   RPC_STATUS status;
   // Stop TPM
   TPM_TearDown();
   status = RpcMgmtStopServerListening(NULL);
   if (status != RPC_S_OK)
   {
       printf_s("RpcMgmtStopServerListening returned: 0x%x\n", status);
       exit(status);
   }
   status = RpcServerUnregisterIf(NULL, NULL, FALSE);
   if (status != RPC_S_OK)
   {
       printf_s("RpcServerUnregisterIf returned 0x%x\n", status);
       exit(status);
   }
}
