Monday, January 3, 2011

Part 6 of 6: CommunicationFlow.java

================================================================
PLEASE DOWNLOAD THE JAVA PROGRAM FROM HERE - DOWNLOAD THIS PROGRAM
================================================================
package com.jovialjava.example;

import com.jovialjava.DataOperation;
import com.jovialjava.DataResult;
import com.jovialjava.RS232Executor;
import com.jovialjava.DTO.Instruction;
import com.jovialjava.DTO.SerialConfiguration;
import com.jovialjava.exceptions.RS232Exception;

public class CommunicationFlow {    
    /*
     * We need two Objects to interact with Serial Device (D)
     */
    private Instruction instruction = null;
    private SerialConfiguration config = null;
    private RS232Executor executor = null;    
    /*
     * This is required to collect response from Serial Device
     */
    private String response = new String("");
    /*
     * Universal Values
     */
    public static final Byte ACK = new Byte((byte)6);
    public static final Byte NACK = new Byte((byte)21);    
    /*
     * Default Constructor
     */
    public CommunicationFlow(){
        /*
         * Setting up Serial Device Configuration.
         */
        this.config = new SerialConfiguration();
        this.config.setComPort("COM1");
        this.config.setBaud("9600");
        this.config.setDataBits("8");
        this.config.setFlowControl("none");
        this.config.setParity("none");
        this.config.setStopBits("1");
        /*
         * Preparing Instrcutor by passing this configuration to it.
         */
        this.instruction = new Instruction();
        this.instruction.setConfig(this.config);
        /*
         * Preparing the executor by passing the instructor to it.
         */
        this.executor = new RS232Executor();
        this.executor.init(instruction);        
    }
    
    /**
     * Main method to execute the Sample Example
     */
    public static void main(String... args){
        try {
            String request ="COM PORT COMMUNICATION USING JAVA BY JOVIAL JAVA";
            CommunicationFlow commFlow = new CommunicationFlow();
            request = Common.asciiToHex(request);
            commFlow.send(Common.appendSTX_ETX_LRC(request));
            System.out.println("___________________________________");
            System.out.println("RESPONSE -["+ commFlow.response+"]");
        } catch (RS232Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * This is the main method which implements the flow.
     */
    public void send(String hexRequestData) throws RS232Exception /* this is the only exception thrown by RS232Java */{
        /*
         * STEP 1 : Connect to Serial DEVICE and check if operation was successful
         */
        this.instruction.setOperation(DataOperation.INITIALIZE);
        this.executor.execute();
        this.checkInitResult(this.instruction.getResult());
        /*
         * STEP 2: If we reach here, means Computer (C) is SUCCESSFULLY CONNECTED TO Serial Device (D)
         * Our next target it to send data to serial device and wait for Serial Device to respond with ACK/NAK
         * Maximum Retry Count = 3
         * Waiting time for Serial Device to send ACK = 2000 ms
         * Data to send : request Data
         */
        this.SendRequest(hexRequestData, 2000, 3);
        /*
         * STEP 3: If we reach here, means serial device has SUCCESSFULLY SENT ACK.
         * Our next Target it to wait for SERIAL DEVICE TO SEND RESPONSE.
         * Waiting time for response = 30,000 ms
         * Maximum Retry Count = 3 ( In case of LRC is not correct)
         */
        this.performResponse(30000, 3);
        /*
         * STEP 4: If we reach here means RESPONSE HAS Been Received
         * Our next target it too close the connection with Serial Device.
         */
        this.instruction.setOperation(DataOperation.CLOSE_PORT);
        this.executor.execute();
        /*
         * If one wants, one can check the result of closing of operation by
         * this.instruction.getResult()
         */
        //=============MISSION ACCOMPLISHED=============================    
    }
    /*
     * This method checks the Initialization request
     */
    private void checkInitResult(DataResult result) {
        switch (result) {
        case SUCCESS:
            System.out.println("SERIAL DEVICE SUCCESSFUL INITIALIZED");
            break;
        case FAILED:
            System.err.println("____________________________________________");
            System.err.println(" SERIAL DEVICE FAILED TO INITALIZE ");
            System.err.println("____________________________________________");
            System.exit(1);        
        }
    }    
    /*
     * this method will send the DATA to Serial DEVICE and will wait for ACK/NAK
     */
    private void SendRequest(String requestData, Integer ackWaitTime, int retryCount) throws RS232Exception{
            this.instruction.setOperation(DataOperation.SEND_N_WAIT_FOR_ACK);
            this.instruction.setTimeOutInMilliSeconds(ackWaitTime);
            this.instruction.setRequest(requestData, null);
            executor.execute();            
            int NAKcounter = 0;
            int noDataCounter = 0;
            boolean breakFlag = false;            
while(!breakFlag){
            DataResult result = instruction.getResult();
                switch (result) {
                case ACK:{
                    System.out.println("SERIAL DEVICE COMMUNICATED SUCCESSFULLY");
                    breakFlag = true;
                    break;
                }
                case NACK:{
                    if(NAKcounter < retryCount){
                        NAKcounter++;
                        System.err.println("NACK Received, Retrying count["+NAKcounter+"]");
                        executor.execute();                
                    }else{
                        System.err.println("NACK Recieved more than "+ NAKcounter + " times");
                        System.exit(1);
                    }
                    break;
                }            
                case NO_DATA:{
                    if(noDataCounter < retryCount){
                        noDataCounter++;
                        System.err.println("NO Data Received, Retrying count["+noDataCounter+"]");
                        executor.execute();                                            
                    }else{
                        System.err.println("No Data Recieved more than "+ noDataCounter + " times");
                        System.exit(1);
                    }
                    break;
                }
                case FAILED:{
                    System.err.println("____________________________________________");
                    System.err.println(" SERIAL DEVICE FAILED TO COMMUNICATE ");
                    System.err.println("____________________________________________");
                    System.exit(1);
                }
                }
            }        
    }
    
    
private void performResponse(Integer responseTimeOut, Integer retryCount) throws RS232Exception{
        instruction.setOperation(DataOperation.WAIT_FOR_ETX_LRC);
        instruction.setTimeOutInMilliSeconds(responseTimeOut);
        executor.execute();        
        int NAKCounter = 0 ;        
        boolean breakFlag = false;
        
    while(!breakFlag){    
        DataResult result = instruction.getResult();
            switch (result) {
                case RESPONSE:{
                     this.response = instruction.getHexResponse();                                                          
                    // CHECK THE LRC value here    
                    if(!this.verifyLRC(this.response)){
                            if(NAKCounter < retryCount){                                
                                instruction.setRequest(null,new byte[]{NACK});
                                instruction.setOperation(DataOperation.CLR_SEND_N_WAIT_FOR_ETX_LRC);                                
                                executor.execute();        
                                NAKCounter++;
                                continue;
                            }else{
                                System.err.println("!!!ERROR!!! - BAD LRC IN RESPONSE");
                                System.exit(1);
                            }
                        }else{
                            /*
                             * Means LRC is OK, SEND ACK and RETURN
                             */
                            instruction.setRequest(null,new byte[]{ACK});
                            instruction.setOperation(DataOperation.SEND);
                            executor.execute();    
                            breakFlag = true;
                        }
                    break;                
                }case NO_DATA:{
                    System.err.println("____________________________________________");
                    System.err.println(" SERIAL DEVICE FAILED TO SEND RESPONSE ");
                    System.err.println("____________________________________________");
                    System.exit(1);                    
                }case FAILED:{
                    System.err.println("____________________________________________");
                    System.err.println(" SERIAL DEVICE FAILED TO COMMUNICATE ");
                    System.err.println("____________________________________________");
                    System.exit(1);                
                }
            }
    }
        
    }

    private boolean verifyLRC(String hexResponse){
        return Common.verify(response);        
    }
}

. . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Another Required File