/* ----------------------------------------------------------------------------- * align_sort.c * * iPDC - Phasor Data Concentrator * * Copyright (C) 2011-2012 Nitesh Pandit * Copyright (C) 2011-2012 Kedar V. Khandeparkar * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Authors: * Nitesh Pandit * Kedar V. Khandeparkar * * ----------------------------------------------------------------------------- */ #include #include #include #include #include "parser.h" #include "global.h" #include "align_sort.h" #include "connections.h" #include "dallocate.h" /* ------------------------------------------------------------------------------------ */ /* Functions in align_sort.c */ /* ------------------------------------------------------------------------------------ */ /* 1. void time_align(struct data_frame *df) */ /* 2. void assign_df_to_TSB(struct data_frame *df,int index) */ /* 3. void dispatch(int index) */ /* 4. void sort_data_inside_TSB(int index) */ /* 5. void clear_TSB(int index) */ /* 6. void create_dataframe(int index) */ /* 7. void create_cfgframe() */ /* -----------------------------------------------------------------------------*/ /* ---------------------------------------------------------------------------- */ /* FUNCTION time_align(): */ /* It searches for the correct TSB[index] where data frame df is to be */ /* assigned. If the df has soc and fracsec which is older then soc and fracsec */ /* of TSB[first] then we discard the data frame */ /* ---------------------------------------------------------------------------- */ void time_align(struct data_frame *df) { int flag = 0; int i; unsigned int IDcode; unsigned int df_soc,df_fracsec,tsb_soc,tsb_fracsec; if (front == -1) { // TSB is used for the first time front = rear = 0; assign_df_to_TSB(df,front); struct cfg_frame *temp_cfg = cfgfirst; while(temp_cfg != NULL) { printf("%d--",to_intconvertor(temp_cfg->idcode)); temp_cfg = temp_cfg->cfgnext; } printf("\n"); return; } else { df_soc = to_long_int_convertor(df->soc); unsigned char *fsec; fsec = malloc(3*sizeof(unsigned char)); fsec[0] = df->fracsec[1]; fsec[1] = df->fracsec[2]; fsec[2] = df->fracsec[3]; df_fracsec = to_long_int_convertor1(fsec); unsigned char *tsb_fsec; tsb_fsec = malloc(3*sizeof(unsigned char)); tsb_fsec[0] = TSB[front].fracsec[1]; tsb_fsec[1] = TSB[front].fracsec[2]; tsb_fsec[2] = TSB[front].fracsec[3]; tsb_soc = to_long_int_convertor((unsigned char *)TSB[front].soc); tsb_fracsec = to_long_int_convertor1(tsb_fsec); IDcode = to_intconvertor(df->idcode); if((old_df_front != -1) && ((df_soc < ODFT[old_df_front].soc) || ((df_soc == ODFT[old_df_front].soc) && (df_fracsec < ODFT[old_df_front].fracsec)))) { // if((df_soc < tsb_soc) || ((df_soc == tsb_soc) && (df_fracsec < tsb_fracsec))) { free_dataframe_object(df); myfree(tsb_fsec); myfree(fsec); unsigned char *tsb_fsec1; tsb_fsec1 = malloc(3*sizeof(unsigned char)); tsb_fsec1[0] = TSB[rear].fracsec[1]; tsb_fsec1[1] = TSB[rear].fracsec[2]; tsb_fsec1[2] = TSB[rear].fracsec[3]; unsigned int tsb_fracsec1 = to_long_int_convertor1(tsb_fsec1); unsigned int tsb_soc1 = to_long_int_convertor((unsigned char *)TSB[rear].soc); printf("LOssId = %u df soc %u fsec =%u front tsb_soc %u tsb_fsec %u rear soc %u fsec %u \n",IDcode,df_soc,df_fracsec,tsb_soc,tsb_fracsec,tsb_soc1,tsb_fracsec1); writeTimeToLog(88,IDcode,df_soc,df_fracsec); pthread_mutex_unlock(&mutex_on_thread); // Added by KK on 19-Oct-2013 return; } for(i = 0; isoc,4); copy_cbyc((unsigned char *)TSB[index].fracsec,df->fracsec,4); TSB[index].num = 0; // Kedar 06-05-2013 v1.4 initialize the old soc and fracsec unsigned char *fsec; fsec = malloc(3*sizeof(unsigned char)); fsec[0] = TSB[index].fracsec[1]; fsec[1] = TSB[index].fracsec[2]; fsec[2] = TSB[index].fracsec[3]; if(old_df_front == -1) { old_df_front = 0; old_df_rear = 0; ODFT[old_df_rear].soc = to_long_int_convertor(TSB[index].soc); ODFT[old_df_rear].fracsec = to_long_int_convertor1(fsec); } else { old_df_rear = (old_df_rear + 1)%OLDFRAMECOUNT; ODFT[old_df_rear].soc = to_long_int_convertor(TSB[index].soc); ODFT[old_df_rear].fracsec = to_long_int_convertor1(fsec); } Tsb_Count++; TSB[index].first_data_frame = df; /* Assign df to the 'first_data_frame' in the data frame linked list of TSB[index] */ TSB[index].count = 1; /* Now we need to store the pmu/pdc id in the pmupdc_id_list that would be required while sorting */ struct pmupdc_id_list *temp_pmuid; while(temp_cfg != NULL) { /* Create a node of the type 'pmupdc_id_list' and copy the pmu/pde id from the cfg to it */ struct pmupdc_id_list *pmuid = malloc(sizeof(struct pmupdc_id_list)); pmuid->idcode = malloc(3); memset(pmuid->idcode,'\0',3); copy_cbyc((unsigned char *)pmuid->idcode,temp_cfg->idcode,2); pmuid->num_pmu = to_intconvertor(temp_cfg->num_pmu); pmuid->nextid = NULL; TSB[index].num++; if(TSB[index].idlist == NULL) { /* Assign the pmuid to the idlist as it is the first id in the list */ TSB[index].idlist = temp_pmuid = pmuid; } else { temp_pmuid->nextid = pmuid; temp_pmuid = pmuid; } temp_cfg = temp_cfg->cfgnext; } // while ends . A pmu/pdc id list is created for the TSB[index] TSB[index].counter = 1; unsigned int IDcode = to_intconvertor(df->idcode); unsigned int df_soc = to_long_int_convertor(df->soc); fsec[0] = df->fracsec[1]; fsec[1] = df->fracsec[2]; fsec[2] = df->fracsec[3]; unsigned int df_fracsec = to_long_int_convertor1(fsec); if(TSB[index].count == TSB[index].num) { int xx = index; writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting intermediate_dispatch(xx); } else { writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting } int k = 0; for (k=0;kidcode); df_soc = to_long_int_convertor(TSB[k].first_data_frame->soc); fsec[0] = TSB[k].first_data_frame->fracsec[1]; fsec[1] = TSB[k].first_data_frame->fracsec[2]; fsec[2] = TSB[k].first_data_frame->fracsec[3]; df_fracsec = to_long_int_convertor1(fsec); writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting intermediate_dispatch(k); } } } free(fsec); pthread_mutex_unlock(&mutex_on_thread); // Added by KK on 19-Oct-2013 } else { // 1 if else struct cfg_frame *temp_cfg = cfgfirst; if(TSB[index].first_data_frame == NULL) { // 2 if /* After TSB[index] is cleared this is the first data frame for it. The memory for the member variables of TSB[index] has already been allocated. Hence after dispatch() and clear_TSB() operation this TSB is to be assigned the data_frame for the first time. */ copy_cbyc((unsigned char *)TSB[index].soc,df->soc,4); copy_cbyc((unsigned char *)TSB[index].fracsec,df->fracsec,4); // Kedar 06-05-2013 v1.4 Reset the old frame times old_df_rear = (old_df_rear + 1) % OLDFRAMECOUNT; ODFT[old_df_rear].soc = to_long_int_convertor(TSB[index].soc); unsigned char *fsec; fsec = malloc(3*sizeof(unsigned char)); fsec[0] = TSB[index].fracsec[1]; fsec[1] = TSB[index].fracsec[2]; fsec[2] = TSB[index].fracsec[3]; ODFT[old_df_rear].fracsec = to_long_int_convertor1(fsec); TSB[index].first_data_frame = df; /* Assign df to the 'first_data_frame' in the data frame linked list of TSB[index] */ Tsb_Count++; TSB[index].count = 1; TSB[index].num = 0; /* Now we need to store the pmu/pdc id in the pmupdc_id_list that would be required while sorting */ struct pmupdc_id_list *temp_pmuid; while(temp_cfg != NULL) { /* Create a node of the type 'pmupdc_id_list' and copy the pmu/pde id from the cfg to it */ struct pmupdc_id_list *pmuid = malloc(sizeof(struct pmupdc_id_list)); pmuid->idcode = malloc(3); memset(pmuid->idcode,'\0',3); copy_cbyc((unsigned char *)pmuid->idcode,temp_cfg->idcode,2); pmuid->num_pmu = to_intconvertor(temp_cfg->num_pmu); pmuid->nextid = NULL; TSB[index].num++; if(TSB[index].idlist == NULL) { /* Assign the pmuid to the idlist as it is the first id in the list */ TSB[index].idlist = temp_pmuid = pmuid; } else { temp_pmuid->nextid = pmuid; temp_pmuid = pmuid; } temp_cfg = temp_cfg->cfgnext; } // while ends TSB[index].counter = 1; unsigned int IDcode = to_intconvertor(df->idcode); unsigned int df_soc = to_long_int_convertor(df->soc); fsec[0] = df->fracsec[1]; fsec[1] = df->fracsec[2]; fsec[2] = df->fracsec[3]; unsigned int df_fracsec = to_long_int_convertor1(fsec); if(TSB[index].count == TSB[index].num) { int xx = index; writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting intermediate_dispatch(xx); } else { writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting } int k = 0; for (k=0;kidcode); df_soc = to_long_int_convertor(TSB[k].first_data_frame->soc); fsec[0] = TSB[k].first_data_frame->fracsec[1]; fsec[1] = TSB[k].first_data_frame->fracsec[2]; fsec[2] = TSB[k].first_data_frame->fracsec[3]; df_fracsec = to_long_int_convertor1(fsec); writeTimeToLog(2,IDcode,df_soc,df_fracsec); // Checkpoint time before sorting intermediate_dispatch(k); } } } free(fsec); pthread_mutex_unlock(&mutex_on_thread); // Added by KK on 19-Oct-2013 } else { // 2 if else // printf("Inside assign_df id = %d index %d front = %d,rear = %d\n",IDcode,index,front,rear); /* Traverse the data frames of TSB[index] and assign the df to 'dnext' of the last element in the data frame LL.*/ struct data_frame *temp_df,*check_df; /* Need to check if df with same idcode and soc is already assigned to the TSB[index] */ check_df = TSB[index].first_data_frame; while(check_df != NULL) { if(!ncmp_cbyc(check_df->idcode,df->idcode,2)) { free_dataframe_object(df); return; } else { check_df = check_df->dnext; } } temp_df = TSB[index].first_data_frame; while(temp_df->dnext != NULL) { temp_df = temp_df->dnext; } temp_df->dnext = df; TSB[index].count++; // New Code by Kedar unsigned int df_soc,df_fracsec; df_soc = to_long_int_convertor(df->soc); unsigned char *fsec; fsec = malloc(3*sizeof(unsigned char)); fsec[0] = df->fracsec[1]; fsec[1] = df->fracsec[2]; fsec[2] = df->fracsec[3]; df_fracsec = to_long_int_convertor1(fsec); unsigned int IDcode = to_intconvertor(df->idcode); free(fsec); writeTimeToLog(2,IDcode,df_soc,df_fracsec); pthread_mutex_unlock(&mutex_on_thread); // Added by KK on 19-Oct-2013 if(TSB[index].count == TSB[index].num) { int xx = index; intermediate_dispatch(xx); } } // 2 if ends } // 1 if ends } void intermediate_dispatch(int xx) { unsigned int yy = xx; if(front < rear) { if(xx == rear) { dispatch(xx); rear= (rear - 1 )<0 ? rear-1+MAXTSB:rear -1; // one step backward } else if(xx == front) { dispatch(front); front = (front + 1) % MAXTSB; } else if(xx rear) { if(xx == rear) { dispatch(rear); if(front - rear == MAXTSB) { rear = front; } else { rear = rear - 1; if(rear <0) rear = rear + MAXTSB; } } else if(xx == front) { dispatch(front); front = (front + 1) % MAXTSB; } else if(xx > front) { // xx>front dispatch(xx); int rr = xx; while (rr != rear) { int h = (rr + 1) % MAXTSB; copy_cbyc (TSB[rr].soc,(unsigned char *)TSB[h].soc,4); copy_cbyc (TSB[rr].fracsec,(unsigned char *)TSB[h].fracsec,4); TSB[rr].count = TSB[h].count; TSB[rr].num = TSB[h].num; TSB[rr].counter = TSB[h].counter; TSB[rr].idlist = TSB[h].idlist; TSB[rr].first_data_frame = TSB[h].first_data_frame; rr = (rr + 1) % MAXTSB; } memset(TSB[rear].soc,'\0',5); memset(TSB[rear].fracsec,'\0',5); TSB[rear].count = 0; TSB[rear].num = 0; TSB[rear].counter = 0; TSB[rear].first_data_frame = NULL; TSB[rear].idlist = NULL; rear= (rear - 1 )<0 ? rear-1+MAXTSB:rear -1; // one step backward } else if(xx < front) { dispatch(xx); int rr = xx; while (rr != rear) { int h = (rr + 1) % MAXTSB; copy_cbyc (TSB[rr].soc,(unsigned char *)TSB[h].soc,4); copy_cbyc (TSB[rr].fracsec,(unsigned char *)TSB[h].fracsec,4); TSB[rr].count = TSB[h].count; TSB[rr].num = TSB[h].num; TSB[rr].counter = TSB[h].counter; TSB[rr].idlist = TSB[h].idlist; TSB[rr].first_data_frame = TSB[h].first_data_frame; rr = (rr + 1) % MAXTSB; } memset(TSB[rear].soc,'\0',5); memset(TSB[rear].fracsec,'\0',5); TSB[rear].count = 0; TSB[rear].num = 0; TSB[rear].counter = 0; TSB[rear].first_data_frame = NULL; TSB[rear].idlist = NULL; rear= (rear - 1 )<0 ? rear-1+MAXTSB:rear -1; // one step backward } } else { dispatch(front); } } /* ---------------------------------------------------------------------------- */ /* FUNCTION dispatch(): */ /* It dispatches the combined data frame to all the destination devices */ /* ---------------------------------------------------------------------------- */ void dispatch(int index) { int size,flag = 0; Tsb_Count--; unsigned int tsb_soc = to_long_int_convertor(TSB[index].soc); struct data_frame *df = TSB[index].first_data_frame; unsigned int IDcode = to_intconvertor(df->idcode); adjustOldFrameCount(index); unsigned char *tsb_fsec; tsb_fsec = malloc(3*sizeof(unsigned char)); tsb_fsec[0] = TSB[index].fracsec[1]; tsb_fsec[1] = TSB[index].fracsec[2]; tsb_fsec[2] = TSB[index].fracsec[3]; unsigned int tsb_fracsec = to_long_int_convertor1(tsb_fsec); // writeTimeToLog(3,IDcode,tsb_soc,tsb_fracsec); // Checkpoint time before sorting create_dataframe(index); writeTimeToLog(3,IDcode,tsb_soc,tsb_fracsec); // Checkpoint time after Creation of combined data frame pthread_mutex_lock(&mutex_Upper_Layer_Details); struct Upper_Layer_Details *temp_pdc = ULfirst; while(temp_pdc != NULL ) { if((temp_pdc->UL_upper_pdc_cfgsent == 1) && (temp_pdc->UL_data_transmission_off == 0)) { if(flag == 0) { size = create_dataframe(index); // writeTimeToLog(2,IDcode,tsb_soc,tsb_fracsec); //Checkpoint time after creation of combined data frame flag = 1; } if(temp_pdc->config_change == 1) { dataframe[14] = 0x04; dataframe[15] = 0x00; } else { dataframe[14] = 0x00; dataframe[15] = 0x00; } if(temp_pdc->port == UDPPORT) { if (sendto(temp_pdc->sockfd,dataframe, size, 0, (struct sockaddr *)&temp_pdc->pdc_addr,sizeof(temp_pdc->pdc_addr)) == -1) perror("sendto"); } else if((temp_pdc->port == TCPPORT) && (temp_pdc->tcpup == 1)) { if(send(temp_pdc->sockfd,dataframe,size, 0)== -1) { perror("send"); //printf("TCP connection closed\n"); temp_pdc->tcpup = 0; pthread_cancel(temp_pdc->thread_id); } } } temp_pdc = temp_pdc->next; } pthread_mutex_unlock(&mutex_Upper_Layer_Details); free(tsb_fsec); /*if(dataframe != NULL) free(dataframe);*/ clear_TSB(index); } void adjustOldFrameCount(int index) { int flag = 0; int i; unsigned char *tsb_fsec; unsigned int tsb_soc,tsb_fracsec; tsb_fsec = malloc(3*sizeof(unsigned char)); tsb_fsec[0] = TSB[index].fracsec[1]; tsb_fsec[1] = TSB[index].fracsec[2]; tsb_fsec[2] = TSB[index].fracsec[3]; tsb_soc = to_long_int_convertor((unsigned char *)TSB[index].soc); tsb_fracsec = to_long_int_convertor1(tsb_fsec); for(i = 0; i< OLDFRAMECOUNT; i++) { if((ODFT[i].soc == tsb_soc) && (ODFT[i].fracsec == tsb_fracsec)) { flag = 1; break; } } if(flag) { int xx = i; ODFT[xx].soc = 0; ODFT[xx].fracsec = 0; if(old_df_front < old_df_rear) { if(xx == old_df_rear) { old_df_rear= (old_df_rear - 1)%OLDFRAMECOUNT; if(old_df_rear <0) old_df_rear = old_df_rear + OLDFRAMECOUNT;// } else if(xx == old_df_front) { old_df_front = (old_df_front + 1) % OLDFRAMECOUNT; } else if(xx < old_df_rear) { while (xx < old_df_rear) { ODFT[xx].soc = ODFT[xx + 1].soc; ODFT[xx].fracsec = ODFT[xx + 1].fracsec; xx++; } ODFT[old_df_rear].soc = 0; ODFT[old_df_rear].fracsec = 0; old_df_rear = (old_df_rear - 1) % OLDFRAMECOUNT; if(old_df_rear < 0) old_df_rear = old_df_rear + OLDFRAMECOUNT; } } else if (old_df_front > old_df_rear) { if(xx == old_df_rear) { if(old_df_front - old_df_rear == OLDFRAMECOUNT) { //front = rear; old_df_rear = old_df_front; } else { old_df_rear = old_df_rear - 1; if(old_df_rear <0) old_df_rear = old_df_rear + OLDFRAMECOUNT; } } else if(xx == old_df_front) { old_df_front = (old_df_front + 1) % OLDFRAMECOUNT; } else { // xx>front int rr = xx; while (rr != old_df_rear) { int h = (rr + 1) % OLDFRAMECOUNT; ODFT[rr].soc = ODFT[h].soc; ODFT[rr].fracsec = ODFT[h].fracsec; rr = (rr + 1) % OLDFRAMECOUNT; } old_df_rear = (old_df_rear - 1) % OLDFRAMECOUNT; if(old_df_rear < 0) old_df_rear = old_df_rear + OLDFRAMECOUNT; } } else { old_df_front = (old_df_front + 1)%OLDFRAMECOUNT; old_df_rear = old_df_front; } }else { // printf("No match with ODFT\n"); } } /* ---------------------------------------------------------------------------- */ /* FUNCTION clear_TSB(): */ /* It clears TSB[index] and frees all data frame objects after the data frames */ /* in TSB[index] have been dispatched to destination device */ /* ---------------------------------------------------------------------------- */ void clear_TSB(int index) { // memset(TSB[index].soc,'\0',5); memset(TSB[index].fracsec,'\0',5); struct pmupdc_id_list *t_list,*r_list; t_list = TSB[index].idlist; TSB[index].count = 0; while(t_list != NULL) { r_list = t_list->nextid; free(t_list->idcode); free(t_list); t_list = r_list; } struct data_frame *t,*r; t = TSB[index].first_data_frame; while(t != NULL) { r = t->dnext; free_dataframe_object(t); t = r; } TSB[index].first_data_frame = NULL; TSB[index].idlist = NULL; TSB[index].num = 0; TSB[index].counter = 0; } /* ---------------------------------------------------------------------------- */ /* FUNCTION create_dataframe(): */ /* It creates the IEEEC37.118 Standard based combined data frame from the data */ /* frames received from all the source devices to be sent to the destination */ /* devices. */ /* ---------------------------------------------------------------------------- */ int create_dataframe(int index) { int total_frame_size = 0; unsigned char temp[3]; struct data_frame *temp_df; uint16_t chk; unsigned int offset = 14; //unsigned int dfSize; temp_df = TSB[index].first_data_frame; // Calculate the single combined data frame size total_frame_size = COMBINE_DF_SIZE + 16; /* 16 is for comman fields SYNC + FRAMESIZE + idcode + soc + fracsec + checksum */ if(dataframe == NULL) { dataframe = malloc((total_frame_size + 1)*sizeof(unsigned char)); if(!dataframe) printf("No enough memory for dataframe\n"); memset(dataframe,'\0',total_frame_size+1); } else { char *fsize; fsize = malloc(3); fsize[0] = dataframe[2]; fsize[1] = dataframe[3]; fsize[2] = '\0'; int size = to_intconvertor(fsize); free(fsize); if(size idcode)); if((found_item = hsearch(item, FIND)) == NULL) { printf("Node not found in hash table\n"); break; } z = offset + ((struct hashTable *)found_item->data)->startIndex; ((struct hashTable *)found_item->data)->visited = true; attacheEachDataFrame(temp_df,z); temp_df = temp_df->dnext; } // 1 while // Search for unvisted nodes/Missing frames sprintf(item.key,"%d",to_long_int_convertor1(cfgfirst->idcode)); if((found_item = hsearch(item, FIND)) != NULL) { checkForMissingFrames(found_item); } else { printf("no item of this kind in the has table\n"); } // Attach a checksum int totalSize = offset + COMBINE_DF_SIZE; chk = compute_CRC(dataframe,totalSize); dataframe[totalSize++] = (chk >> 8) & ~(~0<<8); /* CHKSUM high byte; */ dataframe[totalSize++] = (chk ) & ~(~0<<8); /* CHKSUM low byte; */ // For iPDC configuration changed old_fsize = totalSize; return totalSize; } /* ---------------------------------------------------------------------------- */ /* FUNCTION create_cfgframe(): */ /* It creates the IEEEC37.118 Standard based combined configuration frame from */ /* the configuration frames received from all the source devices to be sent to */ /* destination devices */ /* ---------------------------------------------------------------------------- */ int create_cfgframe() { struct cfg_frame *temp_cfg; int total_frame_size = 0,count = 0; unsigned char datarate[2],soc[4],fracsec[4]; // hard coded int total_num_pmu = 0; unsigned char time_base[4]; unsigned int fsize,num_pmu,phnmr,dgnmr,annmr; unsigned int data_rate,temp_data_rate; unsigned long int sec,frac = 0,temp_tb,tb; uint16_t chk; sec = (long int)time (NULL); long_int_to_ascii_convertor(sec,soc); long_int_to_ascii_convertor(frac,fracsec); temp_cfg = cfgfirst; while(temp_cfg != NULL) { if(count == 0) { // Copy the soc,fracsec,timebase from the first CFG to the combined CFG //SEPARATE TIMBASE tb = to_long_int_convertor(temp_cfg->time_base); copy_cbyc (time_base,temp_cfg->time_base,4); data_rate = to_intconvertor(temp_cfg->data_rate); copy_cbyc (datarate,temp_cfg->data_rate,2); fsize = to_intconvertor(temp_cfg->framesize); total_frame_size += fsize; count++; // count used to count num of cfg num_pmu = to_intconvertor(temp_cfg->num_pmu); total_num_pmu += num_pmu; temp_cfg = temp_cfg->cfgnext; } else { fsize = to_intconvertor(temp_cfg->framesize); total_frame_size += fsize; total_frame_size -= 24; // take the Lowest Timebase temp_tb = to_long_int_convertor(temp_cfg->time_base); if(temp_tb < tb) { copy_cbyc (time_base,temp_cfg->time_base,4); tb = temp_tb; } // take the highest data rate temp_data_rate = to_intconvertor(temp_cfg->data_rate); if(temp_data_rate > data_rate) { copy_cbyc (datarate,temp_cfg->data_rate,2); data_rate = temp_data_rate; } count++; // count used to count num of cfg num_pmu = to_intconvertor(temp_cfg->num_pmu); total_num_pmu += num_pmu; temp_cfg = temp_cfg->cfgnext; } } // While ENDS cfgframe = malloc((total_frame_size + 1)*sizeof(unsigned char)); // Allocate memory for data frame cfgframe[total_frame_size] = '\0'; // Start the Combined CFG frame creation int z = 0; byte_by_byte_copy(cfgframe,CFGSYNC,z,2); // SYNC z += 2; unsigned char temp[3]; memset(temp,'\0',3); int_to_ascii_convertor(total_frame_size,temp); byte_by_byte_copy(cfgframe,temp,z,2); // FRAME SIZE z += 2; unsigned char tmp[2]; tmp[0]= cfgframe[2]; tmp[1]= cfgframe[3]; int newl; newl = to_intconvertor(tmp); printf("CFG Frame Len %d.\n",newl); memset(temp,'\0',3); int_to_ascii_convertor(PDC_IDCODE,temp); byte_by_byte_copy(cfgframe,temp,z,2); // PDC ID z += 2; byte_by_byte_copy(cfgframe,soc,z,4); //SOC z += 4; byte_by_byte_copy(cfgframe,fracsec,z,4); //FRACSEC z += 4; byte_by_byte_copy(cfgframe,time_base,z,4); //TIMEBASE z += 4; memset(temp,'\0',3); int_to_ascii_convertor(total_num_pmu,temp); byte_by_byte_copy(cfgframe,temp,z,2); // No of PMU z += 2; int i,j; temp_cfg = cfgfirst; while(temp_cfg != NULL) { // 1 num_pmu = to_intconvertor(temp_cfg->num_pmu); j = 0; while (j < num_pmu) { //2 byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->stn,z,16); // STN z += 16; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->idcode,z,2); // IDCODE z += 2; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->data_format,z,2); // FORMAT z += 2; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->phnmr,z,2); // PHNMR z += 2; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->annmr,z,2); // ANNMR z += 2; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->dgnmr,z,2); // DGNMR z += 2; phnmr = to_intconvertor(temp_cfg->pmu[j]->phnmr); annmr = to_intconvertor(temp_cfg->pmu[j]->annmr); dgnmr = to_intconvertor(temp_cfg->pmu[j]->dgnmr); // Copy Phasor Names if(phnmr != 0){ for(i = 0; ipmu[j]->cnext->phnames[i],z,16); // Phasor Names z += 16; } } // Copy Analog Names if(annmr != 0){ for(i = 0; ipmu[j]->cnext->angnames[i],z,16); // Analog Names z += 16; } } // Copy Digital Names if(dgnmr != 0) { struct dgnames *temp_dgname = temp_cfg->pmu[j]->cnext->first; while (temp_dgname != NULL) { for(i = 0;i<16;i++) { byte_by_byte_copy(cfgframe,temp_dgname->dgn[i],z,16); // Digital Names z += 16; } // Copy 16 channel names of digital word temp_dgname = temp_dgname->dg_next; } // Go to next Digital word } // PHUNIT if(phnmr != 0){ for (i = 0; ipmu[j]->phunit[i],z,4); // PHUNIT z += 4; } } // ANUNIT if(annmr != 0){ for (i = 0; ipmu[j]->anunit[i],z,4); // ANUNIT z += 4; } } // DGUNIT if(dgnmr != 0){ for (i = 0; ipmu[j]->dgunit[i],z,4); // DGUNIT z += 4; } } byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->fnom,z,2); // FNOM z += 2; byte_by_byte_copy(cfgframe,temp_cfg->pmu[j]->cfg_cnt,z,2); // CFGCNT z += 2; j++; // index for pmu_num } // while 2 temp_cfg = temp_cfg->cfgnext; // Take next CFG } // while 1 byte_by_byte_copy(cfgframe,datarate,z,2); // DATA RATE z += 2; chk = compute_CRC(cfgframe,z); cfgframe[z++] = (chk >> 8) & ~(~0<<8); /* CHKSUM high byte; */ cfgframe[z++] = (chk ) & ~(~0<<8); /* CHKSUM low byte; */ return z; } /* ---------------------------------------------------------------------------- */ /* FUNCTION unsigned char* generate_dummy_dataframe(int id): */ /* ---------------------------------------------------------------------------- */ struct data_frame* generate_dummy_dataframe(unsigned char *idcode) { int match=0,i,j=0, fsize=0; unsigned char tempI[2]; unsigned int num_pmu,phnmr,annmr,dgnmr; struct cfg_frame *temp_cfg; struct data_frame *df; unsigned char temp2[2] = {0, 0}; unsigned char temp4[4] = {0, 0, 0, 0}; unsigned char temp8[8] = {0, 0, 0, 0, 0, 0, 0, 0}; //printf("Inside generate_dummy_dataframe\n"); pthread_mutex_lock(&mutex_cfg); temp_cfg = cfgfirst; // Check for the data frame IDCODE in Configuration Frame? while(temp_cfg != NULL){ if(!ncmp_cbyc((unsigned char *) idcode,temp_cfg->idcode,2)) { match = 1; break; } else { temp_cfg = temp_cfg->cfgnext; } } pthread_mutex_unlock(&mutex_cfg); // If idcode matches with cfg idcode if(match){ //Allocate memory for data frame df = malloc(sizeof(struct data_frame)); if(!df) { printf("Not enough memory for dummy df\n"); exit(1); } df->dnext = NULL; // Allocate memory for df->framesize df->framesize = malloc(3*sizeof(unsigned char)); if(!df->framesize) { printf("Not enough memory df->idcode\n"); exit(1); } // Allocate memory for df->idcode df->idcode = malloc(3*sizeof(unsigned char)); if(!df->idcode) { printf("Not enough memory df->idcode\n"); exit(1); } // Allocate memory for df->soc df->soc = malloc(5*sizeof(unsigned char)); if(!df->soc) { printf("Not enough memory df->soc\n"); exit(1); } // Allocate memory for df->fracsec df->fracsec = malloc(5*sizeof(unsigned char)); if(!df->fracsec) { printf("Not enough memory df->fracsec\n"); exit(1); } // Allocate Memeory For Each PMU num_pmu = to_intconvertor(temp_cfg->num_pmu); /* For each PMU data */ df->dpmu = malloc(num_pmu* sizeof(struct data_for_each_pmu *)); if(!df->dpmu) { printf("Not enough memory df->dpmu[][]\n"); exit(1); } for (i = 0; i < num_pmu; i++) { df->dpmu[i] = malloc(sizeof(struct data_for_each_pmu)); } /* Now start separating the data from data frame */ /* Copy Framesize */ copy_cbyc (df->framesize,temp2,2); df->framesize[2] = '\0'; //Copy IDCODE copy_cbyc (df->idcode,idcode,2); df->idcode[2] = '\0'; //Copy SOC copy_cbyc (df->soc,temp4,4); df->soc[4] = '\0'; //Copy FRACSEC copy_cbyc (df->fracsec,temp4,4); df->fracsec[4] = '\0'; fsize += 16; // For SYNC + FRAMESIZE + idcode + soc + fracsec + checksum //Copy NUM PMU df->num_pmu = num_pmu; // Separate the data for each PMU while(jpmu[j]->phnmr); annmr = to_intconvertor(temp_cfg->pmu[j]->annmr); dgnmr = to_intconvertor(temp_cfg->pmu[j]->dgnmr); //Allocate memory for stat, Phasors, Analogs,Digitals and Phasors and Frequencies /* Memory Allocation Begins */ // Allocate memory for stat df->dpmu[j]->stat = malloc(3*sizeof(unsigned char)); if(!df->dpmu[j]->stat) { printf("Not enough memory for df->dpmu[j]->stat\n"); } // Allocate memory for Phasor df->dpmu[j]->phasors = malloc(phnmr*sizeof(unsigned char *)); if(!df->dpmu[j]->phasors) { printf("Not enough memory df->dpmu[j]->phasors[][]\n"); exit(1); } if(temp_cfg->pmu[j]->fmt->phasor == '1') { for (i = 0; i < phnmr; i++) df->dpmu[j]->phasors[i] = malloc(9*sizeof(unsigned char)); } else { for (i = 0; i < phnmr; i++) df->dpmu[j]->phasors[i] = malloc(5*sizeof(unsigned char)); } /* Allocate memory for Analogs */ df->dpmu[j]->analog = malloc(annmr*sizeof(unsigned char *)); if(!df->dpmu[j]->analog) { printf("Not enough memory df->dpmu[j]->analog[][]\n"); exit(1); } if(temp_cfg->pmu[j]->fmt->analog == '1') { for (i = 0; i < annmr; i++) df->dpmu[j]->analog[i] = malloc(9*sizeof(unsigned char)); } else { for (i = 0; i < annmr; i++) df->dpmu[j]->analog[i] = malloc(5*sizeof(unsigned char)); } /* Allocate memory for Frequency & DFREQ */ if(temp_cfg->pmu[j]->fmt->freq == '1') { df->dpmu[j]->freq = malloc(5*sizeof(unsigned char)); df->dpmu[j]->dfreq = malloc(5*sizeof(unsigned char)); } else { df->dpmu[j]->freq = malloc(3*sizeof(unsigned char)); df->dpmu[j]->dfreq = malloc(3*sizeof(unsigned char)); } /* Allocate memory for Digital */ df->dpmu[j]->digital = malloc(dgnmr* sizeof(unsigned char*)); if(!df->dpmu[j]->digital) { printf("Not enough memory df->dpmu[j]->digital[][]\n"); exit(1); } for (i = 0; i < dgnmr; i++) { df->dpmu[j]->digital[i] = malloc(3*sizeof(unsigned char)); } /* Memory Allocation Ends here */ // Copy the PMU data fields tempI[0] = 0x82; //changed by Kedar on 4-7-2013 tempI[1] = 0x00; copy_cbyc (df->dpmu[j]->stat,tempI,2); df->dpmu[j]->stat[2] = '\0'; fsize += 2; // Copy Format Word df->dpmu[j]->fmt = malloc(sizeof(struct format)); df->dpmu[j]->fmt->freq = temp_cfg->pmu[j]->fmt->freq; df->dpmu[j]->fmt->analog = temp_cfg->pmu[j]->fmt->analog; df->dpmu[j]->fmt->phasor = temp_cfg->pmu[j]->fmt->phasor; df->dpmu[j]->fmt->polar = temp_cfg->pmu[j]->fmt->polar; // Copy number of phasors, analogs, and digitals df->dpmu[j]->phnmr = phnmr; df->dpmu[j]->annmr = annmr; df->dpmu[j]->dgnmr = dgnmr; //Phasors if(temp_cfg->pmu[j]->fmt->phasor == '1') { for(i=0;idpmu[j]->phasors[i],temp8,8); df->dpmu[j]->phasors[i][8] = '\0'; fsize += 8; } } else { for(i=0;idpmu[j]->phasors[i],temp4,4); df->dpmu[j]->phasors[i][4] = '\0'; fsize += 4; } } /* For Freq */ if(temp_cfg->pmu[j]->fmt->freq == '1') { copy_cbyc (df->dpmu[j]->freq,temp4,4); df->dpmu[j]->freq[4] = '\0'; fsize += 4; copy_cbyc (df->dpmu[j]->dfreq,temp4,4); df->dpmu[j]->dfreq[4] = '\0'; fsize += 4; } else { copy_cbyc (df->dpmu[j]->freq,temp2,2); df->dpmu[j]->freq[2] = '\0'; fsize += 2; copy_cbyc (df->dpmu[j]->dfreq,temp2,2); df->dpmu[j]->dfreq[2] = '\0'; fsize += 2; } /* For Analogs */ if(temp_cfg->pmu[j]->fmt->analog == '1') { for(i = 0; idpmu[j]->analog[i],temp4,4); df->dpmu[j]->analog[i][4] = '\0'; fsize += 4; } } else { for(i = 0; idpmu[j]->analog[i],temp2,2); df->dpmu[j]->analog[i][2] = '\0'; fsize += 2; } } /* For Digital */ for(i = 0; idpmu[j]->digital[i],temp2,2); df->dpmu[j]->digital[i][2] = '\0'; fsize += 2; } j++; } //While ends for sub PMUs tempI[0] = fsize>>8; tempI[1] = fsize; copy_cbyc (df->framesize,tempI,2); df->framesize[2] = '\0'; return df; } } /* ---------------------------------------------------------------------------- */ /* int matchDataFrameTimeToTSBTime(unsigned int df_soc,unsigned int df_fracsec) */ /* ---------------------------------------------------------------------------- */ int matchDataFrameTimeToTSBTime(unsigned int df_soc,unsigned int df_fracsec) { pthread_mutex_lock(&mutex_on_TSB); int flag = 0,i; unsigned int tsb_soc,tsb_fracsec; unsigned char *tsb_fsec; tsb_fsec = malloc(3*sizeof(unsigned char)); for(i = 0; idata)->visited == true) { ((struct hashTable *)found_item->data)->visited = false; int nextid = ((struct hashTable *)found_item->data)->nextIdcode; if( nextid != -1) { sprintf(item.key,"%d",nextid); if((found_item = hsearch(item, FIND)) == NULL) { printf("Node not found in hash table--\n"); return; } checkForMissingFrames(found_item); } } else if (((struct hashTable *)found_item->data)->visited == false) { unsigned char *temp = malloc(3*sizeof(unsigned char)); memset(temp,'\0',3); int_to_ascii_convertor(((struct hashTable *)found_item->data)->Idcode,temp); struct data_frame *curr_df; curr_df = generate_dummy_dataframe(temp); free(temp); int z = ((struct hashTable *)found_item->data)->startIndex; attacheEachDataFrame(curr_df,z); int nextid = ((struct hashTable *)found_item->data)->nextIdcode; if( nextid != -1) { sprintf(item.key,"%d",nextid); if((found_item = hsearch(item, FIND)) == NULL) { printf("Node not found in hash table++\n"); return; } checkForMissingFrames(found_item); } } } /* ---------------------------------------------------------------------------- */ /* void attacheEachDataFrame(struct data_frame *temp_df,int z) */ /* ---------------------------------------------------------------------------- */ void attacheEachDataFrame(struct data_frame *temp_df,int z) { int j = 0; while(j < temp_df->num_pmu) { // 2 //Copy STAT Word byte_by_byte_copy(dataframe,temp_df->dpmu[j]->stat,z,2); z += 2; int i = 0; //Copy Phasors if(temp_df->dpmu[j]->phnmr != 0) { if(temp_df->dpmu[j]->fmt->phasor == '1') { while(i < temp_df->dpmu[j]->phnmr) { byte_by_byte_copy(dataframe,temp_df->dpmu[j]->phasors[i],z,8); // Phasors z += 8; i++; } } else { while(i < temp_df->dpmu[j]->phnmr) { byte_by_byte_copy(dataframe,temp_df->dpmu[j]->phasors[i],z,4); // Phasors z += 4; i++; } } } //Copy FREQ if(temp_df->dpmu[j]->fmt->freq == '1') { byte_by_byte_copy(dataframe,temp_df->dpmu[j]->freq,z,4); // FREQ z += 4; byte_by_byte_copy(dataframe,temp_df->dpmu[j]->dfreq,z,4); // FREQ z += 4; } else { byte_by_byte_copy(dataframe,temp_df->dpmu[j]->freq,z,2); // FREQ z += 2; byte_by_byte_copy(dataframe,temp_df->dpmu[j]->dfreq,z,2); // FREQ z += 2; } // Copy Analogs if(temp_df->dpmu[j]->annmr != 0) { if(temp_df->dpmu[j]->fmt->analog == '1') { for(i = 0; idpmu[j]->annmr; i++){ byte_by_byte_copy(dataframe,temp_df->dpmu[j]->analog[i],z,4); // ANALOGS z += 4; } } else { for(i = 0; idpmu[j]->annmr; i++){ byte_by_byte_copy(dataframe,temp_df->dpmu[j]->analog[i],z,2); // ANALOGS z += 2; } } } i = 0; //Copy DIGITAL if(temp_df->dpmu[j]->dgnmr != 0) { while(i < temp_df->dpmu[j]->dgnmr) { byte_by_byte_copy(dataframe,temp_df->dpmu[j]->digital[i],z,2); // DIGITAL z += 2; i++; } } j++; } // 2 while } /**************************************** End of File *******************************************************/