Dummy program to demonstrate problems: working code

Dependencies:   SLCD mbed-rtos mbed

Fork of MNG_TC by Shreesha S

MNG_TC.h

Committer:
shreeshas95
Date:
2015-07-06
Revision:
7:e71ecfe3a340
Parent:
6:6e9ae3b44e60
Child:
8:cb93c1d3209a

File content as of revision 7:e71ecfe3a340:

// 3 July
// Dheeraj detect_nack()
// Sukhdeep SND_TM

//Jun 8

//Jun 7 
//PROBLEM IN DELETING TC_string pointer not solved

// Jun 6
// WHAT IS TC exec code in L1 ack ? 
// Removed class and introduced namespace

// Apil 15
//added back printf statements
//added back delete TC_string for debugging

// add number of tm packets while calling snd 
// function overloading z

// starting value of packet sequence count at each pass 
#define PSC_START_VALUE 1

// APID list
#define APID_CALLSIGN 0
#define APID_BAE 1
#define APID_CDMS 2
#define APID_SPEED 3

// HIGH PRIORITY TC - priority list
// not correct values here
#define HPTC1 5
#define HPTC2 6
// Add more entries above

// SIZE of tc in bytes
#define TC_SHORT_SIZE 11
#define TC_LONG_SIZE 135

// TMID list
#define TMID_ACK_L1 10

class MNG_TC
{
private:
    int total_valid_TC;
    bool all_crc_pass;
    bool no_missing_TC;
    bool stop_after_current_TC;
    bool execute_high_priority_TC;
    TC_list *Head_TC;


//SECONDARY FUNCTIONS : [SHOULD NOT BE CALLED INDEPENDENTLY]
//USED BY MEMBER FUNCTIONS FOUND BELOW

//PROBLEM IN DELETING TC_string POINTER
    void delete_TC(TC_list *tc_ptr, TC_list* previous_tc){
        // stitch the previous and next node
        TC_list *temp_n = tc_ptr->next_TC;
        
        if( (previous_tc != NULL) && (temp_n != NULL) ){
            previous_tc->next_TC = temp_n;
        }
        else if( (previous_tc == NULL) && (temp_n != NULL) ){
            // delete head node HENCE UPDATE HEADER
            Head_TC = temp_n;
        }
        else if( (previous_tc != NULL) && (temp_n == NULL) ){
            // delete last node
            previous_tc->next_TC = NULL;
        }
        else{
            // delete the only single node present
            // in which case head is the only node
            Head_TC = NULL;
        }

//             delete the node
        delete tc_ptr;
    }        
    
    void generate_L1_ack_TM(TM_list *tm_ptr){
        tm_ptr->next_TM = NULL;
        tm_ptr->TM_string = new unsigned char[TM_SHORT_SIZE];
        // TMID
        tm_ptr->tmid = 0xA;
        tm_ptr->TM_string[0] = 0xaf;
    }
    
    void execode_crc(bool all_pass, TM_list *tm_ptr){
        
        tm_ptr->TM_string[1] = ( all_crc_pass == true ) ? 0x01 : 0x00 ;
        
        uint16_t crc_checksum = CRC::crc16_gen(tm_ptr->TM_string, TM_SHORT_SIZE-2);

        tm_ptr->TM_string[TM_SHORT_SIZE-2] = (crc_checksum >> 8) & 0xff;
        tm_ptr->TM_string[TM_SHORT_SIZE-1] = crc_checksum & 0xff;
    }
    
    TM_list* respond_CDMS(TC_list *ptr_tc){
        
//            DUMMY PROGRAM TO CREATE A SAMPLE TM

//            allocate memory for new tm list
        TM_list *test_TM = new TM_list;
        
        test_TM->next_TM = NULL;
        
//            allocate memory for the tm string
        unsigned char *str = new unsigned char[TM_TYPE1_SIZE];
        
        
//            frame type-1 is 0. [ (0 << 7) = 0 ]
        str[0] = 0;
        
//            the tmid determines type-1, or 2
//            tmid : 0x1 belongs to type1 (dummy program)
        test_TM->tmid = 0x1;

        // 4 bit TMID
        str[0] += (0x1) << 3;
        
        // 20 bit seq. count
        str[0] += 0x7;
        str[1] = 0xff;
        str[2] = 0xff;

        // random data
        for(int i = 3 ; i < (TM_TYPE1_SIZE-2) ; ++i ){
            str[i] = 'a';
        }
        
//            APPEND CRC : ALL THE PROCESSES HAVE TO GENERATE AND APPEND CRC
        uint16_t crc_checksum = CRC::crc16_gen(str, TM_TYPE1_SIZE-2);
        str[TM_TYPE1_SIZE-2] = (crc_checksum >> 8) & 0xff;
        str[TM_TYPE1_SIZE-1] = crc_checksum & 0xff;

        test_TM->TM_string = str;

        return test_TM;
    }
    
    TM_list* RELAY(TC_list *tc_ptr){
    
//            FIRST send long or short tc
        unsigned char tc_len = ( tc_ptr->short_or_long ? TC_SHORT_SIZE : TC_LONG_SIZE );
        
        if( tc_ptr->apid == 0x01 ){
            // send TC to BAE microcontroler
            
        }
        else{
            // send TC to SPEED microcontroller
            
        }
        
        PC.putc( tc_len );
//            THE TARGET SHOULD READ 'n' MORE BYTES AS FOUND IN THE FIRST BYTE
        
//            SEND THE TC TO THE TARGET DEVICE [ALONG WITH CRC]
        for(unsigned int i = 0 ; i < tc_len ; ++i){
            PC.putc( tc_ptr->TC_string[i] );
        }
        
//            WAIT FOR THE TM
        TM_list* tm_head = new TM_list;
        TM_list* tm_ptr = tm_head;
        
//            FIRST RECEIVE NUMBER OF TM'S TO BE RECEVIVED
         unsigned char tm_num = PC.getc();
         for(unsigned int i = 0 ; i < tm_num ; ++i){
            
//                THEN FOR EACH TM FIRST SEND TYPE-1 OR TYPE-2 i.e. NUMBER OF BYTES TO READ 
            unsigned char tm_len = PC.getc();
            tm_ptr->TM_string = new unsigned char[tm_len];
            for(unsigned int j = 0 ; j < tm_len ; ++j){
                tm_ptr->TM_string[j] = PC.getc();
            }
            
//                DECODE TMID FROM THE PACKET
            if(tm_len == 134){
                unsigned char temp = tm_ptr->TM_string[0];
                tm_ptr->tmid = (temp >> 3) & 0xf;
            }
            else{
                unsigned char temp = tm_ptr->TM_string[4];
                tm_ptr->tmid = (temp >> 4) & 0xf;
            }
            
//                ALLOCATE MEMORY FOR NEXT TM PACKET
            if( i == tm_num-1 ){
                tm_ptr->next_TM = NULL;
            }
            else{
                tm_ptr->next_TM = new TM_list;
                tm_ptr = tm_ptr->next_TM;
            }
         }
         
//            FILL IN THE tm_ptr AND RETURN
        return tm_head;
    }
    
    
    /*
    @brief:     detect ack_l234 : first tm for any tc will be the ack_l234
    @param:     tm_ptr : pointer to the telemetry head
    @return:    true : ack
                false : nack
    */
    bool detect_ackl234(TM_list *tm_ptr){
        char temp = tm_ptr->TM_string[0];
        
        // 
        if( (temp  & 0xF0) == 0xB0 ){
            temp = tm_ptr->TM_string[3];
            
            // the nack and ack code
            if(temp != 0x00){
                return true;
            }
            else{
                return false;
            }
        }
        else{
            return false;
        }
    }
    
    bool sdCardOp(TC_list *tc_ptr){
        return false;
    }
        
public:
    
// Constructor
/*
@brief:     INITIALISE THE HEAD NODE AND RESET THE VARIABLES
@param:     TC_list *head : head node pointer
@return:    none
*/
    MNG_TC( TC_list *HEAD ){
//        printf("inside init\r\n");
        total_valid_TC = 0;
        all_crc_pass = true;
        no_missing_TC = true;
        stop_after_current_TC = false;
        execute_high_priority_TC = false;
        Head_TC = HEAD;
    }

/*
@brief:     DELETE THE CRC FAILED TC FROM THE LIST TO FREE-UP MEMORY AND UPDATE 
            THE TOTAL VALID TC AND GENERATE L1_ACK_TM
@param:     none
@return:    1 if all tc are crc pass
            0 if atleast one crc fail
*/
    int start_with(){
//        printf("inside start with\r\n");
        TC_list *current_TC = Head_TC;
        
        total_valid_TC = 0;
        all_crc_pass = true;

        TM_list *l1_ack = new TM_list;
        TM_list *l1_ack_head = l1_ack;
        generate_L1_ack_TM(l1_ack);
        
        int TC_count = 0;
        
        while(current_TC != NULL){
            
            unsigned char temp = 0;
            
//          FILL PSC of the TC [ don't care whether crc pass or fail ]
//          PSC starts from 4th byte
            l1_ack->TM_string[3+TC_count] = current_TC->TC_string[0];

//          IF CRC PASS
            if( current_TC->crc_pass ){
                ++total_valid_TC;

//                 set the crc pass field in TC_STATUS ???
                temp = l1_ack->TM_string[2];
                temp |= ( 1 << (7-TC_count) );
                l1_ack->TM_string[2] = temp;

//                 advance to the next node
                current_TC = current_TC->next_TC;
            }
//             if crc fail
            else{
                // unset the crc pass field in TC_STATUS
                temp = l1_ack->TM_string[2];
                temp &= ~( 1 << (7-TC_count) );
                l1_ack->TM_string[2] = temp;

                current_TC = current_TC->next_TC;
                all_crc_pass = false;
            }
            
            ++TC_count;

//             extend the TM linked list if TC_count > 7
            if(TC_count > 7){
                TC_count = 0;

                l1_ack->next_TM = new TM_list;
                l1_ack = l1_ack->next_TM;
                generate_L1_ack_TM(l1_ack);
                
//                FILL TC_EXEC_CODE
//                APPEND CRC TO THE TM
                execode_crc( all_crc_pass, l1_ack );
            }
        }
        
//        FILL UP THE REMAINING FIELDS WITH 0xFF since 0x00 causes problems with GS software
        while(TC_count < 8){
            l1_ack->TM_string[2] &= ~( 1 << (7-TC_count) );
            l1_ack->TM_string[3+TC_count] = 0xFF;
            ++TC_count;
        }
        
//        FILL TC_EXEC_CODE
//        APPEND CRC TO THE TM
        execode_crc(all_crc_pass, l1_ack);

        SND_TM(l1_ack_head);
        
        // delete the TM
        l1_ack = l1_ack_head;
        while(l1_ack != NULL){
            TM_list *temp = l1_ack->next_TM;
            delete l1_ack;
            l1_ack = temp;
        }

        if(all_crc_pass == false){
             return 0;
        }

        return 1;
    }
    
/*
@brief:     Run either start_with() or update_valid_tc()
@param:     none
@return:    int 1 for all crc pass
            int 0 if atleast one crc fail
*/
    void update_valid_TC(){
        TC_list *current_TC = Head_TC;
        
        total_valid_TC = 0;
        all_crc_pass = true;
        
        while(current_TC != NULL){
            if( current_TC->crc_pass ){
                ++total_valid_TC;
            }
            else{
                all_crc_pass = false;
            }
            current_TC = current_TC->next_TC;
        }
    }

/*
@brief:     decode the TCs and fill in the values in the tc-node. 
@param:     none
@return:    none
*/
    void decode_TC(){
        TC_list *node_ptr = Head_TC;

        while( node_ptr != NULL ){

            unsigned char temp;

            // PSC
            node_ptr->packet_seq_count = node_ptr->TC_string[0];
            // APID
            temp = node_ptr->TC_string[1];
            node_ptr->apid = (temp >> 6) & 3;
            // Abort On Nack
            node_ptr->abort_on_nack = (temp >> 3) & 1;
            // default values of enable and execution
            node_ptr->enabled = true;
            node_ptr->valid_execution = false;

            node_ptr = node_ptr->next_TC;
        }
    }

/*
@brief:     check for missing tc, run start_with() or update_valid_tc() before
@param:     none
@return:    int 1 no missing tc
            int 0 missing tc
*/

    int check_for_missing_TC(){
        no_missing_TC = true;
        
        for(unsigned char psc = PSC_START_VALUE ; psc < (total_valid_TC + PSC_START_VALUE) ; ++psc){
            bool flag = false;
            TC_list *node_ptr = Head_TC;
            
            while(node_ptr != NULL){
                if(node_ptr->packet_seq_count == psc){
                    flag = true;
                    break;
                }
                else{
                    node_ptr = node_ptr->next_TC;
                }
            }
            
            if(flag == false){
                no_missing_TC = false;
                break;
            }
        }
        
        if(no_missing_TC){
            return 1;
        }
        else{
            return 0;
        }
    }

/*
RUN start_with() before running execute_TC()
V1.0
@brief:     EXECUTE THE LIST OF TCs, WITH A SEQUENCE BASED ON PSC
            SEND THE TC TO THE TARGET AND WAIT FOR THE TM
            THEN FORWARD IT TO GS
@param:     none
@return:    none
*/
    void execute_TC(){
        unsigned char psc = PSC_START_VALUE;
        
    //    EXECUTE ACCORDING TO THE PSC VALUE
        while( psc < (total_valid_TC+PSC_START_VALUE) ){
            
            TC_list *tc_ptr = Head_TC;
            
    //        FIND THE TC CORRESPONDING TO THE PSC VALUE
            while(tc_ptr != NULL){
                if( (tc_ptr->packet_seq_count == psc) && (tc_ptr->crc_pass) ){
    //                THE TC WITH THE REQUIRED PSC HAS BEEN FOUND, NOW EXECUTE
                    
                    if( !sdCardOp(tc_ptr) ){
                        TM_list *tm_ptr;
                        if( tc_ptr->apid == APID_CDMS ){
        //                    IF THE TC BELONGS TO THE CDMS uc CALL THE LOCAL FUNCTION Manage_CDMS()
                            tm_ptr = respond_CDMS(tc_ptr);
                        }
                        else{
        //                IF THE TC BELONGS TO OTHER MODULE, RELAY() IS CALLED WHICH ACTS AS A MESSENGER
                            tm_ptr = RELAY(tc_ptr);
                        }
                        
                        // detect nack
                        if( detect_ackl234(tm_ptr) ){
                            tc_ptr->valid_execution = true;
                        }
                        else if( tc_ptr->abort_on_nack ){
                            tc_ptr->valid_execution = false;
                            // abort on nack is true and nack received : end thread
                            Thread::wait(osWaitForever);
                        }
                        else{
                            tc_ptr->valid_execution = false;
                        }
                        
        //                SEND DATA TO GS
                        SND_TM(tm_ptr);
                        
        //                DELETE THE TM AFTER USE
                        while(tm_ptr != NULL){
                            TM_list *temp = tm_ptr->next_TM;
                            delete tm_ptr;
                            tm_ptr = temp;
                        }
                        
                    }
                    else{
                        /*DO SD CARD OPERATION*/
                    }
                    
    //                THE TC WITH APPROPRIATE PSC IS EXECUTED, START OVER
                    break;
                }
                
                tc_ptr = tc_ptr->next_TC;
            }
        }
        
        // executed every tc : delete all
        TC_list *tc_ptr = Head_TC;
        while(tc_ptr != NULL){
            TC_list *temp = tc_ptr->next_TC;
            delete tc_ptr;
            tc_ptr = temp;
        }
    }
    
    void execute_urgent(){
        
        TC_list *tc_ptr = Head_TC;
        while( tc_ptr != NULL ){
            
        }
        
        // executed every tc : delete all
        tc_ptr = Head_TC;
        while(tc_ptr != NULL){
            TC_list *temp = tc_ptr->next_TC;
            delete tc_ptr;
            tc_ptr = temp;
        }
    }
};

void MNG_MAIN(void const *args){
    
    RCV_TC RcvClass( VAR_SPACE::Head_node1 );
    MNG_TC manager( VAR_SPACE::Head_node1 );
    
    if( manager.start_with() ){
        manager.decode_TC();
        if( manager.check_for_missing_TC() ){
            manager.execute_TC();
        }
    }
    
    Thread::wait(osWaitForever);
}