/************************************************************************************************************************ * Printing.c * High managment logical unit of slow motors in the system ( 6 dispensers and the screw motor) * profile run up begins from screw homing to begin position and only then from fast motors activation. * when every slow motor tuches the limit switch (no matter whether its screw or dispenser) * an interrupt occures in the system and as long as its pushing the limit switch all the system is prevented from operation. * because of that the work flow with interrupts must be : * design a function handle (what to do in the moment the interrupt arrives) * configure the wanted interrupt in the cfg file (according to the defined port and pin and its interrupt number and the handler) * enable interupt for predefined gpio in the application * when the interrupt arrives the handle will be automatically called * in case of the limit switches since the operation is continuess the interrupt must be disabled in order to continue the application running. * then the operation is not continues (like butten pushing) there is no need in disabling the interrupts * Printing module is responsible for : * operating diffrent winding algorithms with predefined parameters from the UI * operating the dispensers according to predefined dispensing rate from the UI **************************************************************************************************************************/ ////////////////////////////////State machine operation//////////////////////////////////// //the state machine operation is used to operate in runtime correct profile flow execution //by recieved esign flow of the user from the UI /////////////////////////////////////////////////////////////////////////////////////////// #include #include #include "include.h" #include #include #include #include "Common/report/report.h" #include "PMR/Printing/JobSegment.pb-c.h" #include "PMR/Printing/JobRequest.pb-c.h" #include "PMR/Printing/JobResponse.pb-c.h" #include "PMR/Printing/CurrentJobRequest.pb-c.h" #include "PMR/Printing/CurrentJobResponse.pb-c.h" #include "PMR/Printing/ResumeCurrentJobRequest.pb-c.h" #include "PMR/Printing/ResumeCurrentJobResponse.pb-c.h" #include "PMR/Printing/JobStatus.pb-c.h" #include "PMR/Printing/AbortJobRequest.pb-c.h" #include "PMR/Printing/AbortJobResponse.pb-c.h" #include "PMR/Hardware/Hardwaremotor.pb-c.h" #include "PMR/Hardware/HardwareWinder.pb-c.h" #include "PMR/common/MessageContainer.pb-c.h" #include "Modules/General/process.h" #include "modules/Diagnostics/Diagnostics.h" #include "PMR/Stubs/StubJobRequest.pb-c.h" #include "PMR/Stubs/StubJobResponse.pb-c.h" #include "PMR/Stubs/StubAbortJobRequest.pb-c.h" #include "PMR/Stubs/StubAbortJobResponse.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingResponse.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingResponse.pb-c.h" #include "./printingSTM.h" #include "modules/thread/thread_ex.h" #include "modules/AlarmHandling/AlarmHandling.h" #include "modules/ids/ids_ex.h" #include "Modules/heaters/heaters_ex.h" #include "Modules/control/control.h" #define INVALID_MSG_ID 0xFFFF Mailbox_Handle JobmsgQ = NULL; //static Clock_Handle JobClock; //static Clock_Params jobclkParams; JobEndReasonEnum JobEndReason = JOB_OK; ErrorCode JobError_to_ErrorCode[JOB_ERRORS_MAX+1] = {ERROR_CODE__NONE,ERROR_CODE__JOB_UNSPECIFIED_ERROR,ERROR_CODE__JOB_THREAD_BREAK,ERROR_CODE__JOB_WINDER_DANCER_FAIL, ERROR_CODE__JOB_POOLER_DANCER_FAIL,ERROR_CODE__JOB_FEEDER_DANCER_FAIL,ERROR_CODE__JOB_OUT_OF_DYE,ERROR_CODE__JOB_OTHER_ALARM, ERROR_CODE__JOB_TEMPERATURE_ALARM,ERROR_CODE__JOB_LS_ALARM,ERROR_CODE__JOB_PRESSURE_ALARM,ERROR_CODE__JOB_CURRENT_ALARM, ERROR_CODE__JOB_MOTOR_ALARM,ERROR_CODE__JOB_OTHER_ALARM}; #define MAX_TICKET_SIZE 10000 //char CurrentJobBuffer[MAX_TICKET_SIZE]; JobTicket *CurrentJob = NULL;//(JobTicket *)CurrentJobBuffer; JobRequest *CurrentRequest = NULL; //char PreviousJobBuffer[MAX_TICKET_SIZE]; //JobTicket *PreviousJob = (JobTicket *)PreviousJobBuffer; ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle}; /******************************************************************************************** * functions describes motor operation flow and movement state during profile execution * used to operate in runtime correct profileflow execution *********************************************************************************************/ //static ReturnCode IdleState(void *JobDetails); //static ReturnCode ValidateState(void *JobDetails); static ReturnCode PrepareState(void *JobDetails); static ReturnCode PrintState(void *JobDetails); //static ReturnCode CleanState(void *JobDetails); static ReturnCode ExitState(void *JobDetails); /********************************************************************** * the array and enum of JobState_t below must be in sync order ***********************************************************************/ //static ReturnCode (* state[])(void *JobDetails) = { IdleState, ValidateState, PrepareState, PrintState, CleanState}; void AbortJob(char *Msg); typedef enum { Idle= 0, Validate, PrepareJob, Print, Clean, ExitJob } JobState_t; typedef struct { JobState_t m_sourceState; ReturnCode m_returnCode; JobState_t m_destinationState; } Transition_t; ////////////////////////Slow Motor State//////////////////////////////////// char JobToken[36+1]={0}; bool JobAbortedByUser = false; bool JobActive = false; bool JobResumed = false; //////////////////////////////////////////////////////////////////////////// void StartJob(void *JobDetails); //******************************************************************************************************************** bool JobIsActive(void) { return JobActive; } /******************************************************************************************************************** *function describes entry point of motor in profile execution - accelerate from stop position *functio
<UserControl x:Class="Tango.MachineStudio.Common.Controls.MdiContainerControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
             xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Resources>
        <converters:PointToMarginConverter x:Key="PointToMarginConverter"></converters:PointToMarginConverter>
    </UserControl.Resources>
    
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor},Path=ItemsSource}" x:Name="itemsControl">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas x:Name="canvas"  HorizontalAlignment="Left" VerticalAlignment="Top"></Canvas>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="FrameworkElement">
                        <Setter Property="Canvas.Left" Value="{Binding Location.X}"></Setter>
                        <Setter Property="Canvas.Top" Value="{Binding Location.Y}"></Setter>
                        <EventSetter Event="PreviewMouseDown" Handler="OnControlMouseDown"></EventSetter>
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="25"/>
                                    <RowDefinition Height="277*"/>
                                </Grid.RowDefinitions>

                                <Grid Background="{StaticResource AccentColorBrush}">
                                    <Thumb Opacity="0" DragDelta="OnControlDragging" Tag="{Binding}"></Thumb>
                                    <DockPanel LastChildFill="False">
                                        <StackPanel IsHitTestVisible="False" DockPanel.Dock="Left" VerticalAlignment="Center" Orientation="Horizontal" Margin="5 0 0 0">
                                            <materialDesign:PackIcon Kind="{Binding Icon}" Foreground="White"></materialDesign:PackIcon>
                                            <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White" Text="{Binding Header}"></TextBlock>
                                        </StackPanel>

                                        <StackPanel DockPanel.Dock="Right" VerticalAlignment="Center" Orientation="Horizontal">
                                            <Button Foreground="White" Style="{StaticResource MaterialDesignFlatButton}" ToolTip="Close" Width="24" Height="24" Padding="0" Click="OnControlClosed" Tag="{Binding}">
                                                <materialDesign:PackIcon Kind="WindowClose" />
                                            </Button>
                                        </StackPanel>
                                    </DockPanel>
                                </Grid>

                                <Grid Grid.Row="1" MinWidth="100" MinHeight="100">
                                    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                                        <ContentPresenter Content="{Binding View}"></ContentPresenter>
                                    </ScrollViewer>

                                    <Thumb HorizontalAlignment="Right" VerticalAlignment="Stretch" Opacity="0" Width="5" Cursor="SizeWE" DragDelta="OnControlSizeRight" Tag="{Binding}"></Thumb>
                                    <Thumb HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Opacity="0" Height="5" Cursor="SizeNS" DragDelta="OnControlSizeBottom" Tag="{Binding}"></Thumb>
                                    <Thumb HorizontalAlignment="Right" VerticalAlignment="Bottom" Opacity="0" Height="10" Width="10" Cursor="SizeNWSE" DragDelta="OnControlResize" Tag="{Binding}"></Thumb>
                                </Grid>
                            </Grid>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>    
    </Grid>
</UserControl>
ainer(MESSAGE_TYPE__StubJobResponse, JobToken, done, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void Stub_JobRequest(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; StubJobRequest* request = stub_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); JobTicket *Ticket = request->jobticket; StubJobResponse response = STUB_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; StubSpeed = Ticket->processparameters->dyeingspeed; StubLength = Ticket->length*100; StubLengthCounter = 0; ustrncpy (JobToken, requestContainer->token,36); StubControlId = AddControlCallback( SendStubJobProgress, eOneSecond,TemplateDataReadCBFunction,0,0,0); jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; responseContainer = createContainer(MESSAGE_TYPE__StubJobResponse, JobToken, false, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } // responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } void Stub_AbortJobRequest(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; StubAbortJobRequest* request = stub_abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); StubAbortJobResponse response = STUB_ABORT_JOB_RESPONSE__INIT; //RemoveControlCallback(StubControlId, SendStubJobProgress); StubLength = 0; StubLengthCounter = 10; //trigger job end message; responseContainer = createContainer(MESSAGE_TYPE__StubAbortJobResponse, requestContainer->token, false, &response, &stub_abort_job_response__pack, &stub_abort_job_response__get_packed_size); responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } //******************************************************************************************************************** void JobRequestFunc(MessageContainer* requestContainer) { uint32_t status = NOT_SUPPORTED; MessageContainer responseContainer; uint8_t* container_buffer; ErrorCode error = ERROR_CODE__NONE; JobEndReasonEnum JobAlarmReason = JOB_OK; int len; len = usnprintf(ErrorMsg, 100, "GJM"); JobRequest* request = job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); if (request != NULL) { ustrncpy (JobToken, requestContainer->token,36); previousJobLength = 0.0; JobTicket *Ticket = request->jobticket; int TicketSize = job_ticket__get_packed_size(Ticket); if (TicketSize >= MAX_TICKET_SIZE) { LOG_ERROR (TicketSize, "job ticket message too long"); status = FAILED; error = ERROR_CODE__BAD_CRC; len = usnprintf(ErrorMsg, 100, "job ticket message too long"); } else { //memcpy(CurrentJob, Ticket,TicketSize); CurrentJob = Ticket; if (CurrentRequest!= NULL) job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = request; status = PASSED; JobEndReason = JOB_OK; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); if (JobAlarmReason ==OK) { if (Ticket->processparameters) { if (HandleProcessParameters(Ticket->processparameters)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; len = usnprintf(ErrorMsg, 100, "Hardware Parameters Not Set"); } } if (Ticket->spool) { if (InternalWindingConfigMessage(Ticket->spool)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; len = usnprintf(ErrorMsg, 100, "spool parameters error"); } } } else { status = FAILED; error = JobError_to_ErrorCode[JobAlarmReason]; len = usnprintf(ErrorMsg, 100, "Existing alarms prevent running"); } } if (status == PASSED) { Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,Ticket->n_segments, Ticket->intersegmentlength); StartJob(CurrentJob); } } else status = FAILED; JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (status == PASSED) { JobResumed = false; len = usnprintf(ErrorMsg, 100, "Job Accepted"); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, false, &response, &job_response__pack, &job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } else { jobStatus.message = ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = true; response.canceled = true; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, true, &response, &job_response__pack, &job_response__get_packed_size); responseContainer.has_error = true; responseContainer.error = error; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); //We keep the job request until it is done // job_request__free_unpacked(request,NULL); } } //******************************************************************************************************************** char logmsg[254]; char infomsg[254]; uint8_t JobStatusBuffer[400]; void SendJobProgress(double ProcessedLength, int SegmentId, bool done, char *Message) { MessageContainer responseContainer; uint8_t* container_buffer; //int len; //static msdid = 0; //int length = (int)(ProcessedLength*100); //len = usnprintf(logmsg, 254, "MSG: Job Progress Length %d, Seg %d Done %d ",length, SegmentId, done); //REPORT_MSG(msdid++,logmsg); //Report(logmsg,__FILE__,__LINE__,SegmentId,RpWarning,SegmentId, done); /*if (Message) { strcpy (infomsg,Message); Report(infomsg,__FILE__,__LINE__,55,RpWarning,33, 44); }*/ if (JobToken[0] == 0) return; ResumeCurrentJobResponse resumeresponse = RESUME_CURRENT_JOB_RESPONSE__INIT; JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (Message) { jobStatus.message = Message; } //previousJobLength = ProcessedLength; jobStatus.has_progress = true; jobStatus.progress = TotalProcessedLength; jobStatus.has_currentsegmentindex = true; jobStatus.currentsegmentindex = SegmentId; if (JobResumed == true) { resumeresponse.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size,&JobStatusBuffer); } else { response.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &response, &job_response__pack, &job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &response, &job_response__pack, &job_response__get_packed_size,&JobStatusBuffer); } container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (done == true) { if(JobEndReason != JOB_OK) { responseContainer.has_error = true; responseContainer.error = JobError_to_ErrorCode[JobEndReason]; } if (JobAbortedByUser == true) { JobAbortedByUser = false; responseContainer.has_error = true; responseContainer.error = ERROR_CODE__CONTINUOUS_RESPONSE_ABORTED; } } if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); // if (SendChars(container_buffer, container_size) == false) //comm tx mailbox full if (SendCharsWithType(container_buffer, container_size,MESSAGE_TYPE__JobResponse) == false) //comm tx mailbox full { //AlarmHandlingToken[0] = 0; my_free(container_buffer); } } // if (responseContainer.data.data) // my_free(responseContainer.data.data); } void JobStopReporting(void) { JobToken[0] = 0; } void AbortJob(char *Msg) { //ReturnCode retcode; //retcode = JobSuccess; JobMessageStruc Message; PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData; Message.messageId = Abort; PrtMessage->messageId = PrintSystemFailure; strcpy(PrtMessage->messageData,Msg); Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } uint32_t CurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; CurrentJobRequest* request = current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); CurrentJobResponse response = CURRENT_JOB_RESPONSE__INIT; if (JobActive == true) { response.has_isjobinprogress = true; response.isjobinprogress = true; response.jobticket = CurrentJob; } else { response.has_isjobinprogress = true; response.isjobinprogress = false; response.jobticket = NULL; } responseContainer = createContainer(MESSAGE_TYPE__CurrentJobResponse, requestContainer->token, false, &response, ¤t_job_response__pack, ¤t_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } uint32_t ResumeCurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ResumeCurrentJobRequest* request = resume_current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ResumeCurrentJobResponse response = RESUME_CURRENT_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; ustrncpy (JobToken, requestContainer->token,36); JobResumed = true; usnprintf(ErrorMsg, 100, "Job Resumeded"); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, false, &response, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void StartJob(void *JobDetails) { JobMessageStruc Message; Message.messageId = JobRequestMsg; Message.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } /****************************************************************************** * ======== messageTsk ======== * Task for this function is created statically. See the project's .cfg file. * this message task is created statically in system initialization, ******************************************************************************/ Void jobTask(UArg arg0, UArg arg1) { JobMessageStruc Message; //char str[60]; //uint16_t length; //Clock_setTimeout(HostKAClock, 1000); //Clock_start(HostKAClock); JobmsgQ = Mailbox_create(MAX_MSG_LEN, 20, NULL,NULL); while(1) { Mailbox_pend(JobmsgQ , &Message, BIOS_WAIT_FOREVER); switch (Message.messageId) { case JobRequestMsg: JobEndReason = JOB_OK; JobActive = true; /*ValidateState (CurrentJob); break; case ValidationResultsOk:*/ PrepareState (CurrentJob); break; case ValidationResultsFail: //send message data as a validation error message to host ExitState(Message.messageData); break; case PreparationResultsOk: PrintState(CurrentJob); break; case PreparationResultsFail: //send message data as a validation error message to host EndState(CurrentJob, "Prepare Failed"); //ExitState(Message.messageData); break; case PrintMessage: //send message data as a validation error message to host PrintSTMMsgHandler(&Message); break; case PrintingResultsOk: JobActive = false; CurrentJob = NULL; if (CurrentRequest!= NULL) job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = NULL; SuspendLargeMessages = false; LOG_ERROR(4,"ResumeLargeMessages PrintingResultsOk"); //DiagnosticsStart(); //CleanState(CurrentJob); break; case PrintingResultsFail: JobActive = false; CurrentJob = NULL; if (CurrentRequest!= NULL) job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = NULL; SuspendLargeMessages = false; LOG_ERROR(3,"ResumeLargeMessages PrintingResultsFail"); //DiagnosticsStart(); //send message data as a validation error message to host ExitState(Message.messageData); break; case CleaningResultsOk: //send message data as a validation error message to host ExitState(Message.messageData); break; case CleaningResultsFail: //send message data as a validation error message to host ExitState(Message.messageData); break; case SystemFailure: //send message data as a validation error message to host ExitState(Message.messageData); break; case Abort: PrintSTMMsgHandler(&Message); break; default: break; } } }