#ifndef CLIENT_H
#define CLIENT_H

#include <stdio.h>
#include <stdlib.h>
#include "opcode.h"
#include "ACSE-1.h"
#include "OSRTSocket.h"
#include "asn1berSocket.h"
#include "CSTA-ROSE-PDU-types.h"
#include "CSTA-accept-call.h"
#include "CSTA-agent-busy-event.h"
#include "CSTA-agent-logged-off-event.h"
#include "CSTA-agent-logged-on-event.h"
#include "CSTA-agent-not-ready-event.h"
#include "CSTA-agent-ready-event.h"
#include "CSTA-agent-working-after-call-event.h"
#include "CSTA-alternate-call.h"
#include "CSTA-answer-call.h"
#include "CSTA-application-context-information-csta3.h"
#include "CSTA-associate-data.h"
#include "CSTA-attach-media-service.h"
#include "CSTA-auto-answer-event.h"
#include "CSTA-auto-work-mode-event.h"
#include "CSTA-back-in-service-event.h"
#include "CSTA-bridged-event.h"
#include "CSTA-button-information-event.h"
#include "CSTA-button-press-event.h"
#include "CSTA-button-press.h"
#include "CSTA-call-back-call-related.h"
#include "CSTA-call-back-event.h"
#include "CSTA-call-back-message-call-related.h"
#include "CSTA-call-back-message-event.h"
#include "CSTA-call-back-message-non-call-related.h"
#include "CSTA-call-back-non-call-related.h"
#include "CSTA-call-cleared-event.h"
#include "CSTA-call-connection-identifiers.h"
#include "CSTA-call-control.h"
#include "CSTA-call-detail-record.h"
#include "CSTA-call-detail-records-notification.h"
#include "CSTA-call-detail-records-report.h"
#include "CSTA-call-information-event.h"
#include "CSTA-caller-id-status-event.h"
#include "CSTA-camp-on-call.h"
#include "CSTA-cancel-call-back-message.h"
#include "CSTA-cancel-call-back.h"
#include "CSTA-cancel-telephony-tones.h"
#include "CSTA-capability-exchange.h"
#include "CSTA-change-monitor-filter.h"
#include "CSTA-change-system-status-filter.h"
#include "CSTA-charge-info.h"
#include "CSTA-charging-event.h"
#include "CSTA-clear-call.h"
#include "CSTA-clear-connection.h"
#include "CSTA-concatenate-message.h"
#include "CSTA-conference-call.h"
#include "CSTA-conferenced-event.h"
#include "CSTA-connection-cleared-event.h"
#include "CSTA-connection-states.h"
#include "CSTA-consultation-call.h"
#include "CSTA-data-call-types.h"
#include "CSTA-data-collected.h"
#include "CSTA-data-collection-resumed.h"
#include "CSTA-data-collection-suspended.h"
#include "CSTA-data-collection.h"
#include "CSTA-data-path-resumed.h"
#include "CSTA-data-path-suspended.h"
#include "CSTA-deflect-call.h"
#include "CSTA-delete-message.h"
#include "CSTA-delivered-event.h"
#include "CSTA-detach-media-service.h"
#include "CSTA-device-capabilities-changed-event.h"
#include "CSTA-device-feature-types.h"
#include "CSTA-device-identifiers.h"
#include "CSTA-dial-digits.h"
#include "CSTA-digits-dialed-event.h"
#include "CSTA-digits-generated-event.h"
#include "CSTA-directed-pickup-call.h"
#include "CSTA-display-updated-event.h"
#include "CSTA-diverted-event.h"
#include "CSTA-do-not-disturb-event.h"
#include "CSTA-error-definition.h"
#include "CSTA-escape-register-abort.h"
#include "CSTA-escape-register-cancel.h"
#include "CSTA-escape-register.h"
#include "CSTA-escape-service.h"
#include "CSTA-escape-types.h"
#include "CSTA-established-event.h"
#include "CSTA-event-causes.h"
#include "CSTA-event-report-definitions.h"
#include "CSTA-extension-types.h"
#include "CSTA-failed-event.h"
#include "CSTA-fast-data.h"
#include "CSTA-forwarding-event.h"
#include "CSTA-generate-digits.h"
#include "CSTA-generate-telephony-tones.h"
#include "CSTA-get-agent-state.h"
#include "CSTA-get-auditory-apparatus-information.h"
#include "CSTA-get-auto-answer.h"
#include "CSTA-get-auto-work-mode.h"
#include "CSTA-get-button-information.h"
#include "CSTA-get-caller-id-status.h"
#include "CSTA-get-display.h"
#include "CSTA-get-do-not-disturb.h"
#include "CSTA-get-forwarding.h"
#include "CSTA-get-hookswitch-status.h"
#include "CSTA-get-lamp-information.h"
#include "CSTA-get-lamp-mode.h"
#include "CSTA-get-last-number-dialed.h"
#include "CSTA-get-logical-device-information.h"
#include "CSTA-get-message-waiting-indicator.h"
#include "CSTA-get-microphone-gain.h"
#include "CSTA-get-microphone-mute.h"
#include "CSTA-get-physical-device-information.h"
#include "CSTA-get-ringer-status.h"
#include "CSTA-get-routeing-mode.h"
#include "CSTA-get-speaker-mute.h"
#include "CSTA-get-speaker-volume.h"
#include "CSTA-get-switching-function-capabilities.h"
#include "CSTA-get-switching-function-devices.h"
#include "CSTA-group-pickup-call.h"
#include "CSTA-held-event.h"
#include "CSTA-hold-call.h"
#include "CSTA-hookswitch-event.h"
#include "CSTA-intrude-call.h"
#include "CSTA-io-register-abort.h"
#include "CSTA-io-register-cancel.h"
#include "CSTA-io-register.h"
#include "CSTA-join-call.h"
#include "CSTA-lamp-mode-event.h"
#include "CSTA-make-call.h"
#include "CSTA-make-predictive-call.h"
#include "CSTA-media-attached-event.h"
#include "CSTA-media-detached-event.h"
#include "CSTA-media-services.h"
#include "CSTA-message-waiting-event.h"
#include "CSTA-microphone-gain-event.h"
#include "CSTA-microphone-mute-event.h"
#include "CSTA-monitor-start.h"
#include "CSTA-monitor-stop.h"
#include "CSTA-network-capabilities-changed-event.h"
#include "CSTA-network-reached-event.h"
#include "CSTA-offered-event.h"
#include "CSTA-originated-event.h"
#include "CSTA-out-of-service-event.h"
#include "CSTA-park-call.h"
#include "CSTA-physical-device-feature.h"
#include "CSTA-play-event.h"
#include "CSTA-play-message.h"
#include "CSTA-private-data-version-selection.h"
#include "CSTA-private-event.h"
#include "CSTA-query-voice-attribute.h"
#include "CSTA-queued-event.h"
#include "CSTA-re-route-request.h"
#include "CSTA-reconnect-call.h"
#include "CSTA-record-event.h"
#include "CSTA-record-message.h"
#include "CSTA-reposition.h"
#include "CSTA-request-system-status.h"
#include "CSTA-resume-data-collection.h"
#include "CSTA-resume-data-path.h"
#include "CSTA-resume.h"
#include "CSTA-retrieve-call.h"
#include "CSTA-retrieved-event.h"
#include "CSTA-review-event.h"
#include "CSTA-review.h"
#include "CSTA-ringer-status-event.h"
#include "CSTA-route-end-request.h"
#include "CSTA-route-register-abort.h"
#include "CSTA-route-register-cancel.h"
#include "CSTA-route-register.h"
#include "CSTA-route-reject.h"
#include "CSTA-route-request.h"
#include "CSTA-route-select-request.h"
#include "CSTA-route-used-request.h"
#include "CSTA-routeing-mode-event.h"
#include "CSTA-security.h"
#include "CSTA-send-broadcast-data.h"
#include "CSTA-send-data.h"
#include "CSTA-send-multicast-data.h"
#include "CSTA-send-stored-call-detail-records.h"
#include "CSTA-send-user-information.h"
#include "CSTA-service-completion-failure-event.h"
#include "CSTA-service-initiated-event.h"
#include "CSTA-set-agent-state.h"
#include "CSTA-set-auto-answer.h"
#include "CSTA-set-auto-work-mode.h"
#include "CSTA-set-button-information.h"
#include "CSTA-set-caller-id-status.h"
#include "CSTA-set-display.h"
#include "CSTA-set-do-not-disturb.h"
#include "CSTA-set-forwarding.h"
#include "CSTA-set-hookswitch-status.h"
#include "CSTA-set-lamp-mode.h"
#include "CSTA-set-message-waiting-indicator.h"
#include "CSTA-set-microphone-gain.h"
#include "CSTA-set-microphone-mute.h"
#include "CSTA-set-ringer-status.h"
#include "CSTA-set-routeing-mode.h"
#include "CSTA-set-speaker-mute.h"
#include "CSTA-set-speaker-volume.h"
#include "CSTA-set-voice-attribute.h"
#include "CSTA-single-step-conference.h"
#include "CSTA-single-step-transfer.h"
#include "CSTA-snapshot-call-data.h"
#include "CSTA-snapshot-call.h"
#include "CSTA-snapshot-device-data.h"
#include "CSTA-snapshot-device.h"
#include "CSTA-speaker-mute-event.h"
#include "CSTA-speaker-volume-event.h"
#include "CSTA-start-call-detail-records-transmission.h"
#include "CSTA-start-data-collection.h"
#include "CSTA-start-data-path.h"
#include "CSTA-status-reporting.h"
#include "CSTA-stop-call-detail-records.h"
#include "CSTA-stop-data-collection.h"
#include "CSTA-stop-data-path.h"
#include "CSTA-stop-event.h"
#include "CSTA-stop.h"
#include "CSTA-suspend-data-collection.h"
#include "CSTA-suspend-data-path.h"
#include "CSTA-suspend-play-event.h"
#include "CSTA-suspend-record-event.h"
#include "CSTA-suspend.h"
#include "CSTA-switching-function-capabilities-changed.h"
#include "CSTA-switching-function-devices-changed.h"
#include "CSTA-switching-function-devices.h"
#include "CSTA-switching-function-objects.h"
#include "CSTA-synthesize-message.h"
#include "CSTA-system-register-abort.h"
#include "CSTA-system-register-cancel.h"
#include "CSTA-system-register.h"
#include "CSTA-system-status.h"
#include "CSTA-telephony-tones-generated-event.h"
#include "CSTA-transfer-call.h"
#include "CSTA-transferred-event.h"
#include "CSTA-voice-attributes-change-event.h"
#include "PanasonicMakeCall.h"
#include "Remote-Operations-Generic-ROS-PDUs.h"
#include "Remote-Operations-Information-Objects.h"
#include "Remote-Operations-Useful-Definitions.h"

#define MAXMSGLEN 1024
#define MAX_NUM_SIZE	20 

class Client
{
public:
   OSBOOL trace;
   OSBOOL callInitiated;
   OSBOOL monitorInitiated;
   OSBOOL eventReceived;
   enum MessageType { 
      messageonly, ietf, siemens_hipath_3000, siemens_cap, panasonic
   };
   MessageType mMessageType;
   ASN1T_ConnectionID mMostRecentCall;
   ASN1T_ConnectionID mInitiatedTransfer;
   ASN1T_MonitorCrossRefID mMostRecentMonitor;

   Client(OSBOOL _trace=TRUE):trace(_trace), mMessageType(messageonly),
      callInitiated(FALSE), monitorInitiated(FALSE), eventReceived(FALSE) { }


   /* send & receive message via socket, also adding header bytes if necessary */
   int sendMessage (OSRTSocket& cstaSocket, 
      ASN1BEREncodeBuffer& encodeBuffer, size_t len);
   int receiveMessage (OSRTSocket& cstaSocket, 
      ASN1BERDecodeBuffer &decodeBuffer);

   /* stdin request functions */
   void getstring(char *prompt, char *buf, int size);
   int  getint(char *prompt);
   int  gethex(char *prompt);


   /* processing decoded CSTA message functions */
   int receiveCSTAMessage(OSRTSocket& cstaSocket);
   void processPDU(ASN1T_CSTA_ROSE_PDU& pdu, OSBOOL trace);
   void processInvoke(ASN1T_CSTA_ROSE_PDU& pdu, OSBOOL trace);
   void processReturnResult(ASN1T_CSTA_ROSE_PDU& pdu, OSBOOL trace);
   void processReturnError(ASN1T_CSTA_ROSE_PDU& pdu, OSBOOL trace);
   void processReject(ASN1T_CSTA_ROSE_PDU& pdu, OSBOOL trace);
   void processEvent(ASN1T_cerd_CSTAEventReportArgument& eventReportArg, 
      OSBOOL trace);

   /* connection set up functions */
   int connect(OSRTSocket& cstaSocket);
   int release(OSRTSocket& cstaSocket);
   int receiveACSEMessage(OSRTSocket& cstaSocket);
   int receiveACSEConnectResponse(OSRTSocket& cstaSocket);
   int encodeACSEAbort (ASN1BEREncodeBuffer& encodeBuffer);
   int encodeACSEReleaseRequest (ASN1BEREncodeBuffer& encodeBuffer);
   int encodeACSEConnectionRequest (ASN1BEREncodeBuffer& encodeBuffer);
   int encodeGeneralACSEConnectionRequest (ASN1BEREncodeBuffer& encodeBuffer);
   int encodePanKxTdaACSEConnectionRequest (ASN1BEREncodeBuffer& encodeBuffer);
   int encodeSiemensCapACSEConnectionRequest (
      ASN1BEREncodeBuffer& encodeBuffer);
   int encodeSiemensHiPathACSEConnectionRequest (
      ASN1BEREncodeBuffer& encodeBuffer);

   /* ROSE header encode/decode functions */
   int encodeROSERequestHeader (ASN1BEREncodeBuffer& encodeBuffer, 
                                 int msglen, int opcode);
   int encodeROSEResponseHeader (ASN1BEREncodeBuffer& encodeBuffer, 
                                 int msglen, int opcode);

   /* CSTA III operation functions */

   /* makecall */
   int makeCall(OSRTSocket& cstaSocket);
   int encodeMakeCallRequest(ASN1BEREncodeBuffer& encodeBuffer);
   int encodePanMakeCallRequest(ASN1BEREncodeBuffer& encodeBuffer);
   void processMakeCallResult(ASN1T_MakeCallResult& makeCallRes);

   /* consultationcall (needed for transfercall) */
   int encodeConsCallRequest (ASN1BEREncodeBuffer& encodeBuffer);
   void processConsCallRes(ASN1T_ConsultationCallResult& consCallRes);
   
   /* transfercall */
   int transferCall (OSRTSocket& cstaSocket);
   int encodeTransferCallRequest (ASN1BEREncodeBuffer& encodeBuffer);
   int encodeTransferCallRequest (ASN1BEREncodeBuffer& encodeBuffer,
                                  ASN1T_ConnectionID initiatedTransfer);
   void processTransferCallRes(ASN1T_TransferCallResult& transferCallRes);

   /* monitorStop */
   int monitorStop (OSRTSocket& cstaSocket);
   int encodeMonitorStopRequest (ASN1BEREncodeBuffer& encodeBuffer, 
      ASN1T_MonitorCrossRefID& crossRefID);
   void processMonitorStopRes(ASN1T_MonitorStopResult& monitorStopRes);

   /* monitorStart */
   int monitorStart (OSRTSocket& cstaSocket);
   int encodeMonitorStartRequest (ASN1BEREncodeBuffer& encodeBuffer);
   void processMonitorStartRes(ASN1T_MonitorStartResult& monitorStartRes);

   /* answerCall */
   int answerCall (OSRTSocket& cstaSocket);
   int encodeAnswerCallRequest (ASN1BEREncodeBuffer& encodeBuffer);
   void processAnswerCallRes(ASN1T_AnswerCallResult& answerCallRes);

   /* singleStepTransfer */
   int singleStepTransfer (OSRTSocket& cstaSocket);
   int encodeSingleStepTransferRequest (ASN1BEREncodeBuffer& encodeBuffer);
   void processSingleStepTransferRes(ASN1T_SingleStepTransResult& sinTransRes);

   /* systemStatus */
   int systemStatus (OSRTSocket& cstaSocket);
   int encodeCSTASystemStatusResponse (ASN1BEREncodeBuffer& encodeBuffer);
   void processSystemStatusReq( ASN1T_SystemStatusArg& systemStatusArg);

   /* escape service */
   int escapeService(OSRTSocket& cstaSocket);
   int encodeEscapeServiceRequest(ASN1BEREncodeBuffer& encodeBuffer);
   void processEscapeServiceResult(ASN1T_EscapeResult& escapeRes);

};
#endif

