TELECOMMAND MANAGER V1
Dependencies: mbed SLCD mbed-rtos
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); }