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-09-17
Revision:
17:2b04e53f3b1d
Parent:
14:a4c259ca0325

File content as of revision 17:2b04e53f3b1d:

// 8 Jul
// did flowchart of states

// 7 Jul 
// done :decode should run once not every time tc received handle this
// handle sd card with cdms team

// done :replace tc_list header with VAR_SPACE HEAD
// done :delete data in rcv_tc
// done :handle last tc in mbg and rcv_tc
// done :delete all tc after pass


//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
#define TM_SHORT_SIZE 13
#define TM_TYPE1_SIZE 134

namespace MNG_TC
{
    unsigned char psc = PSC_START_VALUE;
    unsigned int total_valid_TC = 0;
    bool all_crc_pass = true;
    bool no_missing_TC = true;
    unsigned int exec_count = 0;

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

    namespace L1_ACK{
    
        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;
        }
    }
    
    namespace EXECUTION{

        TM_list* Manage_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 );
//            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;
//        }
        
        bool detect_ack(TM_list *tm_ptr){
//            printf("inside detect ack : ");
            if( tm_ptr != NULL ){
                unsigned char tm_ack = tm_ptr->TM_string[3];
                tm_ack &= 0xFF;//Ack or Nack can be decided just by checking [5:6] bits
                if( (tm_ack == 0xE0) || (tm_ack == 0xA0) || (tm_ack == 0xC0) ){
//                    printf("ack found\r\n");
                    return true;
                }
                else{
//                    printf("nack found\r\n");
                    return false;
                }
            }
            else{
//                printf("nack null\r\n");
                return false;
            }
        }
        
        bool obosc_tc(TC_list *tc_ptr){
            bool OBOSC = false;
            // check apid
            if(tc_ptr->apid == 2){
                // check service type
                if( (tc_ptr->TC_string[2]) >> 4 == 0xB ){    
                    // check service subtype
                    switch( (tc_ptr->TC_string[2]) & 0xf ){
                        case 1:
                        case 2:
                        case 5:
                        case 6:
                        case 15:
                            OBOSC = true;
//                            printf("found obosc\r\n");
                    }
                }
            }
            
            return OBOSC;
        }
        
        TM_list* execute_obosc(TC_list *tc_ptr){
//            printf("inside execute obosc\r\n");
            unsigned char service_subtype = (tc_ptr->TC_string[2]) & 0x0F;
            unsigned char num = 0;
            unsigned char psc = 0x00;
            switch( service_subtype ){
                case 0x01:
                    // disable tc
                    num = tc_ptr->TC_string[4];
                    psc = tc_ptr->TC_string[3];
                    
                    for(int i = 0 ; i < num ; ++i){
                        TC_list *tcp = VAR_SPACE::Head_node;
                        while( tcp != NULL ){
                            if(tcp->packet_seq_count == psc){
                                tcp->enabled = false;
                                ++psc;
                                break;
                            }
                        }
                    }
                    break;
                case 0x02:
                    // enable tc
                    num = tc_ptr->TC_string[4];
                    psc = tc_ptr->TC_string[3];
                    
                    for(int i = 0 ; i < num ; ++i){
                        TC_list *tcp = VAR_SPACE::Head_node;
                        while( tcp != NULL ){
                            if(tcp->packet_seq_count == psc){
                                tcp->enabled = true;
                                ++psc;
                                break;
                            }
                        }
                    }
                    break;
                case 0x05:
                    // retry executin of tc
                    psc = tc_ptr->TC_string[3];
                    
                    break;
            }
            // generate ackL234
            return NULL;
        }
        
        bool sdCardOp(TC_list* tc_ptr){
            bool readSD = false;

            if(tc_ptr->apid == 2){
                if( ( (tc_ptr->TC_string[2]) >> 4) == 0xF ){    
                    switch( (tc_ptr->TC_string[2]) & 0xf ){
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                        case 4:
                            readSD = true;
//                            printf("found sdcard op\r\n");             
                    }
                }
            }
            return readSD;
        }
        
        TM_list* CDMS_RLY_TMTC(TC_list* tc_ptr){
            return NULL;
        }
        
        bool execute_core(TC_list *tc_ptr){
            printf("executing core psc = %u\r\n", psc);
            
            if( !EXECUTION::sdCardOp(tc_ptr) ){
//                printf("not sd card op\r\n");
                TM_List *tm_ptr;
                
                // call relay here
                tm_ptr = EXECUTION::CDMS_RLY_TMTC(tc_ptr);
                                        
               // SEND DATA TO GS
//                snd_tm.head_pointer(tm_ptr);

                // for rolling buffer : 
                // send EoS only if TM to next tc has not arrived yet
                // else put the next TM itself.
                
                if( EXECUTION::detect_ack(tm_ptr) ){
                    tc_ptr->exec_status = 1;
                }
                else{
                    tc_ptr->exec_status = 2;
                    tc_ptr->enabled = false;
                    if( tc_ptr->abort_on_nack ){
                        return false;
                    }
                }
                
                // DELETE THE TM AFTER USE
                while(tm_ptr != NULL){
                    TM_list *temp = tm_ptr->next_TM;
                    delete tm_ptr;
                    tm_ptr = temp;
                }
            }
            else{
                // write sd card code
                read_TC(tc_ptr);
            }
            return true;
        }
    }

//    MEMBER FUNCTIONS

/*
@brief:     INITIALISE THE HEAD NODE AND RESET THE VARIABLES
@param:     TC_list *head : head node pointer
@return:    none
*/
    void init(){
//        printf("inside init\r\n");
        total_valid_TC = 0;
        all_crc_pass = true;
        no_missing_TC = true;
        psc = PSC_START_VALUE;
        exec_count = 0;
    }


/*
@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:    none
*/
    void start_with(){
        printf("inside start with\r\n");
        TC_list *current_TC = VAR_SPACE::Head_node;
        
        total_valid_TC = 0;
        all_crc_pass = true;

        TM_List *l1_ack = new TM_List;
        TM_List *l1_ack_head = l1_ack;
        L1_ACK::generate_L1_ack_TM(l1_ack);
        
        int TC_count = 0;
//        printf("outside while in start with\r\n");
//        TC_list *zing = VAR_SPACE::Head_node;
//        while(zing != NULL){
////            printf("packet seq count = %u\r\n", zing->packet_seq_count);
//            zing = zing->next_TC;
//        }
        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;
                printf("correct start with: psc = %u, short = %u\r\n", current_TC->packet_seq_count, (current_TC->short_or_long) ? 1 : 0 );

//                 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{
                printf("crc fail start with: psc = %u\r\n", current_TC->packet_seq_count);
                // 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;
                L1_ACK::generate_L1_ack_TM(l1_ack);
                
//                FILL TC_EXEC_CODE
//                APPEND CRC TO THE TM
                L1_ACK::execode_crc( all_crc_pass, l1_ack );
            }
        }
        
//        FILL UP THE REMAINING FIELDS WITH ZEROS
        while(TC_count < 8){
            l1_ack->TM_string[2] &= ~( 1 << (7-TC_count) );
//            l1_ack->TM_string[3+TC_count] = 0;
            l1_ack->TM_string[3+TC_count] = 0x01;
            ++TC_count;
        }
        
//        FILL TC_EXEC_CODE
//        APPEND CRC TO THE TM
        L1_ACK::execode_crc(all_crc_pass, l1_ack);       

        printf("Sending\r\n");
        snd_tm.head_pointer(l1_ack_head);
        printf("Sent\r\n");
        
        // delete the TM
        l1_ack = l1_ack_head;
        while(l1_ack != NULL){
            TM_List *temp = l1_ack->next_TM;
            
//            print
            for(int i = 0 ; i < 13 ; ++i){
                std::bitset<8> b = l1_ack->TM_string[i];
                cout << b << " ";
            }
            cout << ENDL;
            
            delete l1_ack;
            l1_ack = temp;
        }
        printf("finished start_with()\r\n");
    }

/*
@brief:     check for missing tc, also check crc, i.e. 
            if true execution can be started else have to wait
@param:     none
@return:    bool indicating whether there are missing tc
*/
    bool check_for_missing_TC(void){
        printf("checking for missing tc\r\n");
        no_missing_TC = true;
        
//        printf("total valid = %u\r\n", total_valid_TC);
        
        for(unsigned char p = PSC_START_VALUE ; p < (total_valid_TC + PSC_START_VALUE) ; ++p){
            bool flag = false;
            TC_list *node_ptr = VAR_SPACE::Head_node;
//            printf("checking for psc = %u\r\n", p);
            
            while(node_ptr != NULL){
//                printf("packet seq count = %u\t", node_ptr->packet_seq_count);
                if( (node_ptr->packet_seq_count == p) && (node_ptr->crc_pass) ){
                    flag = true;
                    break;
                }
                else{
                    node_ptr = node_ptr->next_TC;
                }
            }
//            printf("\r\n");
            if(flag == false){
                no_missing_TC = false;
                break;
            }
        }
        
        printf("returning from check for missing tc : %u\r\n", no_missing_TC ? 1 : 0);
        if(no_missing_TC){
            return true;
        }
        else{
            return false;
        }
    }



/*
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
*/
    TC_list *Second_head = NULL;
    void execute_TC(){
    //    EXECUTE ACCORDING TO THE PSC VALUE
        printf("inside execute tc : total valid tc = %u, psc = %u\r\n", total_valid_TC, psc);
        while( psc < (total_valid_TC+PSC_START_VALUE) ){
//            printf("Iterating : psc = %u\r\n", psc);
            // check for new tc received
            bool exec_flag_local = false;
            if( VAR_SPACE::new_tc_received ){
                printf("inaside new tc rx in obosc\r\n");
                VAR_SPACE::new_tc_received = false;
                
                VAR_SPACE::data_node = VAR_SPACE::head_data;
                Second_head = VAR_SPACE::last_node;
                COM_RCV_TC::rx_rcv_tc();
                Second_head = Second_head->next_TC;
                exec_flag_local = true;
            }
            else if( VAR_SPACE::execute_obosc ){
                printf("execute obosc flag found\r\n");
                exec_flag_local = true;
            }
            if( exec_flag_local ){
                exec_flag_local = false;
                
                start_with();
                
                if( !check_for_missing_TC() ){
                    VAR_SPACE::rx_state = 3;
                    printf("exiting from obosc\r\n");
                    return;
                }
                else{
                    printf("executing obosc\r\n");
                    // no missing tc : execute urgent
                    TC_list *tcp = Second_head;
                    while( tcp != NULL ){
                        if( EXECUTION::obosc_tc(tcp) ){
                            TM_list *tm_ptr = EXECUTION::execute_obosc(tcp);
//                            snd_tm.head_pointer(tm_ptr);
                            if( EXECUTION::detect_ack(tm_ptr) ){
                                tcp->exec_status = 1;
                            }
                            else{
                                tcp->exec_status = 2;
                                if( tcp->abort_on_nack ){
                                    tcp->enabled = false;
                                    VAR_SPACE::rx_state = 0;
                                    printf("exiting from obosc due to abort on nack\r\n");
                                    VAR_SPACE::rx_state = 0;
                                    return;
                                }
                            }
                        }
                        tcp = tcp->next_TC;
                    }
                }
                VAR_SPACE::execute_obosc = false;
                VAR_SPACE::rx_state = 2;
            }
            
            TC_list *tc_ptr = VAR_SPACE::Head_node;
    //        FIND THE TC CORRESPONDING TO THE PSC VALUE
            while(tc_ptr != NULL){
//                printf("in while : psc = %u\r\n", psc);
                if( (tc_ptr->packet_seq_count == psc) && (tc_ptr->crc_pass)){
    //                THE TC WITH THE REQUIRED PSC HAS BEEN FOUND, NOW EXECUTE
                    
                    if( (tc_ptr->exec_status == 0) || ((tc_ptr->exec_status == 2) && (tc_ptr->enabled)) ){
                        // execute tc
                        
                        ++exec_count;
                        if( EXECUTION::execute_core(tc_ptr) ){
                            // THE TC WITH APPROPRIATE PSC IS EXECUTED, START OVER
                            break;
                        }
                        else{
                            printf("returning due to abort on nack\r\n");
//                            do something for the unexecuted telecommands
                            VAR_SPACE::rx_state = 0;
                            return;
                        }
                    }
                    
                    else{
                        // either (execution failed and disabled) or (successful executed) hence break
                        break;
                    }
                }
                tc_ptr = tc_ptr->next_TC;
            }
            ++psc;
        }
        VAR_SPACE::rx_state = 0;
        printf("exiting after successfully executing tc, total executed = %u\r\n", exec_count);
    }
}