/* ----------------------------------------------------------------------------- * parser.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 * * ----------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------------ */ /* Functions defined in parser.c */ /* -------------------------------------------------------------------------------------*/ /* 1. void cfgparser(char []) */ /* 2. void write_cfg_to_file() */ /* 3. void dataparser(char[]) */ /* 4. int check_statword(char stat[]) */ /* 5. void add_id_to_status_change_list(unsigned char idcode[]); */ /* 6. void remove_id_from_status_change_list(unsigned char idcode[]) */ /* 7. unsigned int to_intconvertor(unsigned char []) */ /* 8. void long_int_to_ascii_convertor (long int n,unsigned char hex[]); */ /* 9. void int_to_ascii_convertor(unsigned int n,unsigned char hex[]); */ /* 10.void copy_cbyc(unsigned char dst[],unsigned char *s,int size) */ /* 11.int ncmp_cbyc(unsigned char dst[],unsigned char src[],int size) */ /* 12.void byte_by_byte_copy(unsigned char dst[],unsigned char src[],int index,int n) */ /* 13.unsigned long int to_long_int_convertor(unsigned char array[]) */ /* 14.uint16_t compute_CRC(unsigned char *message,int length) */ /* ------------------------------------------------------------------------------------ */ #include #include #include #include #include #include "parser.h" #include "global.h" #include "dallocate.h" #include "align_sort.h" #include "connections.h" #include "recreate.h" /* ---------------------------------------------------------------------------- */ /* FUNCTION cfgparser(): */ /* It creates configuration objects for the received configuration frames. */ /* Configuration frame is also written in the file `cfg.bin`. */ /* If the object is already present, it will replace in cfg_frame LL and */ /* also in the file `cfg.bin` by calling */ /* ---------------------------------------------------------------------------- */ void cfgparser(unsigned char st[]){ unsigned char *s; unsigned char sync[3]; unsigned int num_pmu,phn,ann,dgn; int i,j,dgchannels,match = 0; struct cfg_frame *cfg; struct channel_names *cn; /******************** PARSING BEGINGS *******************/ pthread_mutex_lock(&mutex_file); cfg = malloc(sizeof(struct cfg_frame)); if(!cfg) { printf("No enough memory for cfg\n"); } printf("Inside cfgparser()\n"); s = st; /* Memory Allocation Begins - Allocate memory to framesize */ cfg->framesize = malloc(3*sizeof(unsigned char)); if(!cfg->framesize) { printf("No enough memory for cfg->framesize\n"); } // Allocate memory to idcode cfg->idcode = malloc(3*sizeof(unsigned char)); if(!cfg->idcode) { printf("No enough memory for cfg->idcode\n"); } // Allocate memory to soc cfg->soc = malloc(5*sizeof(unsigned char)); if(!cfg->soc) { printf("Not enough memory for cfg->soc\n"); } // Allocate memory to fracsec cfg->fracsec = malloc(5*sizeof(unsigned char)); if(!cfg->fracsec) { printf("Not enough memory for cfg->fracsec\n"); } // Allocate memory to time_base cfg->time_base = malloc(5*sizeof(unsigned char)); if(!cfg->time_base) { printf("Not enough memory for cfg->time_base\n"); } // Allocate memory to time_base cfg->time_base = malloc(5*sizeof(unsigned char)); if(!cfg->time_base) { printf("No enough memory for cfg->time_base\n"); } // Allocate memory to num_pmu cfg->num_pmu = malloc(3*sizeof(unsigned char)); if(!cfg->num_pmu) { printf("No enough memory for cfg->num_pmu\n"); } // Allocate memory to data_rate cfg->data_rate = malloc(3*sizeof(unsigned char)); if(!cfg->data_rate) { printf("No enough memory for cfg->data_rate\n"); } //Copy sync word to file copy_cbyc(sync,(unsigned char *)s,2); sync[2] = '\0'; s = s + 2; // Separate the FRAME SIZE copy_cbyc(cfg->framesize,(unsigned char *)s,2); cfg->framesize[2] = '\0'; unsigned int framesize; framesize = to_intconvertor(cfg->framesize); s = s + 2; //SEPARATE IDCODE copy_cbyc(cfg->idcode,(unsigned char *)s,2); cfg->idcode[2] = '\0'; int id = to_intconvertor(cfg->idcode); printf("ID Code %d\n",id); s = s + 2; /**** Remove the id from the list of Stat change if it is present ****/ remove_id_from_status_change_list(cfg->idcode); //SEPARATE SOC copy_cbyc(cfg->soc,(unsigned char *)s,4); cfg->soc[4] = '\0'; s =s + 4; //SEPARATE FRACSEC copy_cbyc(cfg->fracsec,(unsigned char *)s,4); cfg->fracsec[4] = '\0'; s = s + 4; //SEPARATE TIMEBASE copy_cbyc (cfg->time_base,(unsigned char *)s,4); cfg->time_base[4]='\0'; s = s + 4; //SEPARATE PMU NUM copy_cbyc (cfg->num_pmu,(unsigned char *)s,2); cfg->num_pmu[2] = '\0'; s = s + 2; num_pmu = to_intconvertor(cfg->num_pmu); printf("Number of PMU's %d\n",num_pmu); // Allocate Memeory For Each PMU cfg->pmu = malloc(num_pmu* sizeof(struct for_each_pmu *)); if(!cfg->pmu) { printf("Not enough memory for pmu[][]\n"); exit(1); } for (i = 0; i < num_pmu; i++) { cfg->pmu[i] = malloc(sizeof(struct for_each_pmu)); } j = 0; ///WHILE EACH PMU IS HANDLED while(jpmu[j]->stn = malloc(17*sizeof(unsigned char)); if(!cfg->pmu[j]->stn) { printf("Not enough memory cfg->pmu[j]->stn\n"); exit(1); } // Memory Allocation for idcode cfg->pmu[j]->idcode = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->idcode) { printf("Not enough memory cfg->pmu[j]->idcode\n"); exit(1); } // Memory Allocation for format cfg->pmu[j]->data_format = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->data_format) { printf("Not enough memory cfg->pmu[j]->data_format\n"); exit(1); } // Memory Allocation for phnmr cfg->pmu[j]->phnmr = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->phnmr) { printf("Not enough memory cfg->pmu[j]->phnmr\n"); exit(1); } // Memory Allocation for annmr cfg->pmu[j]->annmr = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->annmr) { printf("Not enough memory cfg->pmu[j]->annmr\n"); exit(1); } // Memory Allocation for dgnmr cfg->pmu[j]->dgnmr = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->dgnmr) { printf("Not enough memory cfg->pmu[j]->dgnmr\n"); exit(1); } // Memory Allocation for fnom cfg->pmu[j]->fnom = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->fnom) { printf("Not enough memory cfg->pmu[j]->fnom\n"); exit(1); } // Memory Allocation for cfg_cnt cfg->pmu[j]->cfg_cnt = malloc(3*sizeof(unsigned char)); if(!cfg->pmu[j]->cfg_cnt) { printf("Not enough memory cfg->pmu[j]->cfg_cnt\n"); exit(1); } //SEPARATE STATION NAME copy_cbyc (cfg->pmu[j]->stn,(unsigned char *)s,16); cfg->pmu[j]->stn[16] = '\0'; s = s + 16; //SEPARATE IDCODE copy_cbyc (cfg->pmu[j]->idcode,(unsigned char *)s,2); cfg->pmu[j]->idcode[2] = '\0'; s = s + 2; //SEPARATE DATA FORMAT copy_cbyc (cfg->pmu[j]->data_format,(unsigned char *)s,2); cfg->pmu[j]->data_format[2]='\0'; s = s + 2; printf("Data Format Word %d\n", to_intconvertor(cfg->pmu[j]->data_format)); unsigned char hex = cfg->pmu[j]->data_format[1]; hex <<= 4; // Extra field has been added to identify polar,rectangular,floating/fixed point cfg->pmu[j]->fmt = malloc(sizeof(struct format)); if((hex & 0x80) == 0x80) cfg->pmu[j]->fmt->freq = '1'; else cfg->pmu[j]->fmt->freq = '0'; if((hex & 0x40) == 0x40 ) cfg->pmu[j]->fmt->analog = '1'; else cfg->pmu[j]->fmt->analog = '0'; if((hex & 0x20) == 0x20) cfg->pmu[j]->fmt->phasor = '1'; else cfg->pmu[j]->fmt->phasor = '0'; if((hex & 0x10) == 0x10) cfg->pmu[j]->fmt->polar = '1'; else cfg->pmu[j]->fmt->polar = '0'; //SEPARATE PHASORS copy_cbyc (cfg->pmu[j]->phnmr,(unsigned char *)s,2); cfg->pmu[j]->phnmr[2]='\0'; phn = to_intconvertor(cfg->pmu[j]->phnmr); s = s + 2; //SEPARATE ANALOGS copy_cbyc (cfg->pmu[j]->annmr,(unsigned char *)s,2); cfg->pmu[j]->annmr[2]='\0'; ann = to_intconvertor(cfg->pmu[j]->annmr); s = s + 2; //SEPARATE DIGITALS copy_cbyc (cfg->pmu[j]->dgnmr,(unsigned char *)s,2); cfg->pmu[j]->dgnmr[2]='\0'; dgn = to_intconvertor(cfg->pmu[j]->dgnmr); s = s + 2; printf("CFG consist Phasor = %d, Analogs = %d Digitals = %d.\n",phn,ann,dgn); cn = malloc(sizeof(struct channel_names)); cn->first = NULL; ////SEPARATE PHASOR NAMES if(phn != 0){ cn->phnames = malloc(phn*sizeof(unsigned char*)); if(!cn->phnames) { printf("Not enough memory cfg->pmu[j]->cn->phnames[][]\n"); exit(1); } for (i = 0; i < phn; i++) { cn->phnames[i] = malloc(17*sizeof(unsigned char)); } i = 0; //Index for PHNAMES while(iphnames[i],(unsigned char *)s,16); cn->phnames[i][16]='\0'; printf("Phnames %s\n",cn->phnames[i]); s = s + 16; i++; } } //SEPARATE ANALOG NAMES if(ann != 0){ cn->angnames = malloc(ann*sizeof(unsigned char*)); if(!cn->angnames) { printf("Not enough memory cfg->pmu[j]->cn->phnames[][]\n"); exit(1); } for (i = 0; i < ann; i++) { cn->angnames[i] = malloc(17*sizeof(unsigned char)); } i=0; //Index for ANGNAMES while(iangnames[i],(unsigned char *)s,16); cn->angnames[i][16]='\0'; printf("ANGNAMES %s\n",cn->angnames[i]); s = s + 16; i++; } } int di; struct dgnames *q; i = 0; //Index for number of dgwords while(i < dgn) { struct dgnames *temp1 = malloc(sizeof(struct dgnames)); temp1->dgn = malloc(16*sizeof(unsigned char *)); if(!temp1->dgn) { printf("Not enough memory temp1->dgn\n"); exit(1); } for (di = 0; di < 16; di++) { temp1->dgn[di] = malloc(17*sizeof(unsigned char)); } temp1->dg_next = NULL; for(dgchannels = 0;dgchannels < 16; dgchannels++){ copy_cbyc (temp1->dgn[dgchannels],(unsigned char *)s,16); temp1->dgn[dgchannels][16]='\0'; s += 16; printf("%s\n",temp1->dgn[dgchannels]); } if(cn->first == NULL){ cn->first = q = temp1; } else { while(q->dg_next!=NULL){ q = q->dg_next; } q->dg_next = temp1; } i++; } //DGWORD WHILE ENDS cfg->pmu[j]->cnext = cn;//Assign to pointers ///PHASOR FACTORS if(phn != 0){ cfg->pmu[j]->phunit = malloc(phn*sizeof(unsigned char*)); if(!cfg->pmu[j]->phunit) { printf("Not enough memory cfg->pmu[j]->phunit[][]\n"); exit(1); } for (i = 0; i < phn; i++) { cfg->pmu[j]->phunit[i] = malloc(5); } i = 0; while(ipmu[j]->phunit[i],(unsigned char *)s,4); cfg->pmu[j]->phunit[i][4] = '\0'; s = s + 4; i++; } }//if for PHASOR Factors ends //ANALOG FACTORS if(ann != 0){ cfg->pmu[j]->anunit = malloc(ann*sizeof(unsigned char*)); if(!cfg->pmu[j]->anunit) { printf("Not enough memory cfg->pmu[j]->anunit[][]\n"); exit(1); } for (i = 0; i < ann; i++) { cfg->pmu[j]->anunit[i] = malloc(5); } i = 0; while(ipmu[j]->anunit[i],(unsigned char *)s,4); cfg->pmu[j]->anunit[i][4] = '\0'; s = s + 4; i++; } } // if for ANALOG Factors ends if(dgn != 0){ cfg->pmu[j]->dgunit = malloc(dgn*sizeof(unsigned char*)); if(!cfg->pmu[j]->dgunit) { printf("Not enough memory cfg->pmu[j]->dgunit[][]\n"); exit(1); } for (i = 0; i < dgn; i++) { cfg->pmu[j]->dgunit[i] = malloc(5); } i=0; while(ipmu[j]->dgunit[i],(unsigned char *)s,4); cfg->pmu[j]->dgunit[i][4] = '\0'; s = s + 4; i++; } } //if for Digital Words FActtors ends copy_cbyc (cfg->pmu[j]->fnom,(unsigned char *)s,2); cfg->pmu[j]->fnom[2]='\0'; s = s + 2; copy_cbyc (cfg->pmu[j]->cfg_cnt,(unsigned char *)s,2); cfg->pmu[j]->cfg_cnt[2]='\0'; s = s + 2; j++; }//While for PMU number ends copy_cbyc (cfg->data_rate,(unsigned char *)s,2); cfg->data_rate[2] = '\0'; s += 2; cfg->cfgnext = NULL; printf("Data Rate %d\n", to_intconvertor(cfg->data_rate)); /* Adjust the configuration object pointers and Lock the mutex_cfg */ pthread_mutex_lock(&mutex_cfg); // Index is kept to replace the cfgfirst if it matches int index = 0; if (cfgfirst == NULL) { // Main if cfgfirst = cfg; } else { struct cfg_frame *temp_cfg = cfgfirst,*tprev_cfg; tprev_cfg = temp_cfg; //Check if the configuration frame already exists while(temp_cfg!=NULL){ if(!ncmp_cbyc(cfg->idcode,temp_cfg->idcode,2)) { match = 1; break; } else { index++; tprev_cfg = temp_cfg; temp_cfg = temp_cfg->cfgnext; } }// While ends if(match) { if(!index) { // Replace the cfgfirst cfg->cfgnext = cfgfirst->cfgnext; free_cfgframe_object(cfgfirst); cfgfirst = cfg; } else { // Replace in between cfg tprev_cfg->cfgnext = cfg; cfg->cfgnext = temp_cfg->cfgnext; free_cfgframe_object(temp_cfg); } } else { // No match and not first cfg tprev_cfg->cfgnext = cfg; } } //Main if ends pthread_mutex_unlock(&mutex_cfg); pthread_mutex_unlock(&mutex_file); write_cfg_to_file(); } /* ---------------------------------------------------------------------------- */ /* FUNCTION write_cfg_to_file(): */ /* This function will perform the writing of iPDC Setup File. It will simply */ /* delete the put the information in it by the all available objects. */ /* ---------------------------------------------------------------------------- */ void write_cfg_to_file() { int tmpi, indx, i, j; unsigned int num_pmu,phn,ann,dgn; unsigned char cline[MAX_STRING_SIZE]; char tLine[50]; char fileName[200]; FILE *fp, *fp1; struct Lower_Layer_Details *temp_pmu; struct Upper_Layer_Details *temp_pdc; struct cfg_frame *cfg; pthread_mutex_lock(&mutex_file); if(cfgfirst != NULL) { fp = fopen(ipdcFilePath,"rb"); strcpy(fileName, ipdcFolderPath); strcat(fileName, "/tempFile.bin"); fp1 = fopen(fileName, "wb"); for(tmpi=5; tmpi>0; tmpi--) { memset(tLine,'\0',sizeof(tLine)); fgets (tLine, 50, fp); fputs(tLine, fp1); } temp_pmu = malloc(sizeof(struct Lower_Layer_Details)); if(LLfirst != NULL) { temp_pmu = LLfirst; tmpi = 0; while (temp_pmu != NULL) { tmpi++; temp_pmu = temp_pmu->next; } sprintf(tLine, "LowerDevices %d\n", tmpi); fputs(tLine, fp1); temp_pmu = LLfirst; while (temp_pmu != NULL) { fprintf(fp1,"%d",temp_pmu->pmuid); fputc(',',fp1); fprintf(fp1,"%s",temp_pmu->ip); fputc(',',fp1); fprintf(fp1,"%d",temp_pmu->port); fputc(',',fp1); fprintf(fp1,"%s",temp_pmu->protocol); fputc('\n',fp1); temp_pmu = temp_pmu->next; } } else { fputs("LowerDevices 0\n", fp1); } temp_pdc = malloc(sizeof(struct Upper_Layer_Details)); if(ULfirst != NULL) { temp_pdc = ULfirst; tmpi = 0; while (temp_pdc != NULL) { tmpi++; temp_pdc = temp_pdc->next; } sprintf(tLine, "UpperDevices %d\n", tmpi); fputs(tLine, fp1); temp_pdc = ULfirst; while (temp_pdc != NULL) { fprintf(fp1,"%s",temp_pdc->ip); fputc(',',fp1); fprintf(fp1,"%d",temp_pdc->port); fputc(',',fp1); fprintf(fp1,"%s",temp_pdc->protocol); fputc('\n',fp1); temp_pdc = temp_pdc->next; } } else { fputs("UpperDevices 0\n", fp1); } cfg = malloc(sizeof(struct cfg_frame)); if(cfgfirst != NULL) { cfg = cfgfirst; tmpi = 0; while (cfg != NULL) { tmpi++; cfg = cfg->cfgnext; } sprintf(tLine, "SourcesCFG %d\n", tmpi); fputs(tLine, fp1); cfg = cfgfirst; while (cfg != NULL) { indx = 0; //Copy sync word to file byte_by_byte_copy(cline,CFGSYNC,indx, 2); indx = indx + 2; // Separate the FRAME SIZE byte_by_byte_copy(cline, cfg->framesize, indx, 2); indx = indx + 2; unsigned int framesize; framesize = to_intconvertor(cfg->framesize); printf("CFG-framesize %d\n",framesize); //SEPARATE IDCODE byte_by_byte_copy(cline, cfg->idcode, indx, 2); indx = indx + 2; int id = to_intconvertor(cfg->idcode); printf("CFG-ID Code %d\n",id); //SEPARATE SOC byte_by_byte_copy(cline, cfg->soc, indx, 4); indx = indx + 4; //SEPARATE FRACSEC byte_by_byte_copy(cline, cfg->fracsec, indx, 4); indx = indx + 4; //SEPARATE TIMEBASE byte_by_byte_copy(cline, cfg->time_base, indx, 4); indx = indx + 4; //SEPARATE PMU NUM byte_by_byte_copy(cline, cfg->num_pmu, indx, 2); cfg->num_pmu[2] = '\0'; indx = indx + 2; num_pmu = to_intconvertor(cfg->num_pmu); printf("CFG-Number of PMU's %d\n",num_pmu); j = 0; ///WHILE EACH PMU IS HANDLED while(jpmu[j]->stn, indx, 16); indx = indx + 16; // Memory Allocation for idcode byte_by_byte_copy(cline, cfg->pmu[j]->idcode, indx, 2); indx = indx + 2; // Memory Allocation for format byte_by_byte_copy(cline, cfg->pmu[j]->data_format, indx, 2); indx = indx + 2; // Memory Allocation for phnmr byte_by_byte_copy(cline, cfg->pmu[j]->phnmr, indx, 2); indx = indx + 2; phn = to_intconvertor(cfg->pmu[j]->phnmr); // Memory Allocation for annmr byte_by_byte_copy(cline, cfg->pmu[j]->annmr, indx, 2); indx = indx + 2; ann = to_intconvertor(cfg->pmu[j]->annmr); // Memory Allocation for dgnmr byte_by_byte_copy(cline, cfg->pmu[j]->dgnmr, indx, 2); indx = indx + 2; dgn = to_intconvertor(cfg->pmu[j]->dgnmr); printf("CGF consist Phasor %d Analogs %d Digitals %d\n",phn,ann,dgn); // Copy Phasor Names i = 0; while(i < phn) { byte_by_byte_copy(cline, cfg->pmu[j]->cnext->phnames[i], indx, 16); indx = indx + 16; i++; } // Copy Analog Names i = 0; while(i < ann) { byte_by_byte_copy(cline, cfg->pmu[j]->cnext->angnames[i], indx, 16); indx = indx + 16; i++; } // Copy Digital Names i = 0; while(i < dgn) { struct dgnames *temp_dgname = cfg->pmu[j]->cnext->first; while (temp_dgname != NULL) { for(i = 0;i<16;i++) { byte_by_byte_copy(cline, temp_dgname->dgn[i], indx, 16); indx = indx + 16; } // Copy 16 channel names of digital word temp_dgname = temp_dgname->dg_next; } // Go to next Digital word i++; } //Copy Phasor Units i = 0; while(i < phn) { byte_by_byte_copy(cline, cfg->pmu[j]->phunit[i], indx, 4); indx = indx + 4; i++; } //Copy Analog Units i = 0; while(i < ann) { byte_by_byte_copy(cline, cfg->pmu[j]->anunit[i], indx, 4); indx = indx + 4; i++; } //Copy Digital Units i = 0; while(i < dgn) { byte_by_byte_copy(cline, cfg->pmu[j]->dgunit[i], indx, 4); indx = indx + 4; i++; } // Memory Allocation for fnom byte_by_byte_copy(cline, cfg->pmu[j]->fnom, indx, 2); indx = indx + 2; // Memory Allocation for cfg_cnt byte_by_byte_copy(cline, cfg->pmu[j]->cfg_cnt, indx, 2); indx = indx + 2; j++; }//While for PMU number ends byte_by_byte_copy(cline, cfg->data_rate, indx, 2); indx = indx + 2; uint16_t chk = compute_CRC(cline,indx); cline[indx++] = (chk >> 8) & ~(~0<<8); /* CHKSUM high byte; */ cline[indx++] = (chk ) & ~(~0<<8); /* CHKSUM low byte; */ char buff[15]; sprintf(buff, "%d", framesize); fputs(buff,fp1); fputc('\n',fp1); fwrite(cline, sizeof(unsigned char),framesize,fp1); fputc('\n',fp1); cfg = cfg->cfgnext; } } else { fputs("SourcesCFG 0\n", fp1); } free(temp_pmu); free(temp_pdc); free(cfg); fclose(fp); fclose(fp1); if (remove(ipdcFilePath) == -1) perror("Error in deleting a file"); else rename(fileName, ipdcFilePath); } pthread_mutex_unlock(&mutex_file); } /* ---------------------------------------------------------------------------- */ /* FUNCTION dataparser(): */ /* Parses the data frames and creates data objects. It searches for config- */ /* uration objects that matches with the IDCODE and then creates data objects. */ /* ---------------------------------------------------------------------------- */ int dataparser(unsigned char data[]) { int match=0,i,j=0; int stat_status,config_change = 0; unsigned int num_pmu,phnmr,annmr,dgnmr; unsigned char framesize[3],idcode[3],stat[3],outer_stat[3],*d; struct cfg_frame *temp_cfg; struct data_frame *df; d = data; d += 2; // Skip SYN //SEPARATE FRAMESIZE copy_cbyc (framesize,d,2); framesize[2]='\0'; d += 2; //SEPARATE IDCODE copy_cbyc (idcode,d,2); idcode[2]='\0'; unsigned int id = to_intconvertor(idcode); pthread_mutex_lock(&mutex_cfg); temp_cfg = cfgfirst; // Check for the IDCODE in Configuration Frame while(temp_cfg != NULL){ if(!ncmp_cbyc(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 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); d += 12; if(num_pmu > 1 ) { copy_cbyc (outer_stat,d,2); if((outer_stat[0] & 0x04) == 0x04) { add_id_to_status_change_list(idcode); //idcode = PMU/PDC return 14; } } 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 */ d -= 14; copy_cbyc (df->framesize,d,2); df->framesize[2] = '\0'; d += 2; //Copy IDCODE copy_cbyc (df->idcode,idcode,2); df->idcode[2] = '\0'; d += 2; //Copy SOC copy_cbyc (df->soc,d,4); df->soc[4] = '\0'; d += 4; //Copy FRACSEC copy_cbyc (df->fracsec,d,4); df->fracsec[4] = '\0'; d += 4; //Copy NUM PMU df->num_pmu = num_pmu; if(num_pmu > 1 ) d += 2; // Separate the data for each PMU while(jdpmu[j]->stat = malloc(3*sizeof(unsigned char)); if(!df->dpmu[j]->stat) { printf("Not enough memory for df->dpmu[j]->stat\n"); } copy_cbyc(df->dpmu[j]->stat,stat,2); df->dpmu[j]->stat[2] = '\0'; memset(stat,'\0',3); j++; continue; } else if((stat_status == 14)||(stat_status == 10)) { //Status for configuration bits have been changed. Add the pmu id to the 'status_change_pmupdcid linked list'. add_id_to_status_change_list(idcode); //idcode = PMU/PDC // 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"); } copy_cbyc(df->dpmu[j]->stat,stat,2); df->dpmu[j]->stat[2] = '\0'; memset(stat,'\0',3); config_change = stat_status; j++; continue; } // Extract PHNMR, DGNMR, ANNMR phnmr = to_intconvertor(temp_cfg->pmu[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"); } 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)); } /* 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)); } /* For Frequency */ 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)); } /* 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 */ //Check stat word of each PMU data block copy_cbyc (df->dpmu[j]->stat,stat,2); df->dpmu[j]->stat[2] = '\0'; memset(stat,'\0',3); // Copy FMT 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 num 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],d,8); df->dpmu[j]->phasors[i][8] = '\0'; d += 8; } } else { for(i=0;idpmu[j]->phasors[i],d,4); df->dpmu[j]->phasors[i][4] = '\0'; d += 4; } } /* For Freq */ if(temp_cfg->pmu[j]->fmt->freq == '1') { copy_cbyc (df->dpmu[j]->freq,d,4); df->dpmu[j]->freq[4] = '\0'; d += 4; copy_cbyc (df->dpmu[j]->dfreq,d,4); df->dpmu[j]->dfreq[4] = '\0'; d += 4; } else { copy_cbyc (df->dpmu[j]->freq,d,2); df->dpmu[j]->freq[2] = '\0'; d += 2; copy_cbyc (df->dpmu[j]->dfreq,d,2); df->dpmu[j]->dfreq[2] = '\0'; d += 2; } /* For Analogs */ if(temp_cfg->pmu[j]->fmt->analog == '1') { for(i = 0; idpmu[j]->analog[i],d,4); df->dpmu[j]->analog[i][4] = '\0'; d += 4; } } else { for(i = 0; idpmu[j]->analog[i],d,2); df->dpmu[j]->analog[i][2] = '\0'; d += 2; } } /* For Digital */ for(i = 0; idpmu[j]->digital[i],d,2); df->dpmu[j]->digital[i][2] = '\0'; d += 2; } j++; } //While ends // Now start Time aligning and Sorting Operation for data_frame df time_align(df); } else { //No match for configuration frame printf("Configuration is not fresent for received data frame!\n"); } if((config_change == 14) ||(config_change == 10)) return config_change; else return stat_status; } /* ---------------------------------------------------------------------------- */ /* FUNCTION check_statword(): */ /* Check the STAT word of the data frames for any change in the data block. */ /* Some of the prime errors are handled. */ /* ---------------------------------------------------------------------------- */ int check_statword(unsigned char stat[]) { int ret = 0; /* Programmer has used these bits as an indication for PMU data that has not arrived */ if(stat[1] == 0x0f) { ret = 16; return ret; } else if ((stat[0] & 0x04) == 0x04) { printf("Configuration Change error\n"); ret = 10; return ret; } else if ((stat[0] & 0x40) == 0x40) { printf("PMU error may includ configuration error\n"); ret = 14; return ret; } else if((stat[0] & 0x80) == 0x80) { printf("Data invalid\n"); ret = 15; return ret; } else if ((stat[0] & 0x20) == 0x20) { printf("PMU Sync error\n"); ret = 13; return ret; } else if ((stat[0] & 0x10) == 0x10) { printf("Data sorting error\n"); ret = 12; return ret; } else if ((stat[0] & 0x08) == 0x08) { printf("PMU Trigger error\n"); ret = 11; return ret; } return ret; } /* ---------------------------------------------------------------------------- */ /* FUNCTION add_id_to_status_change_list(): */ /* Status of data block has been changed. It adds the IDCODE of the PMU/PDC */ /* from which the data block is received to the status_change_pmupdcid' LL */ /* ---------------------------------------------------------------------------- */ void add_id_to_status_change_list(unsigned char idcode[]) { struct status_change_pmupdcid *t; t = malloc(sizeof(struct status_change_pmupdcid)); if(!t) { printf("No enough memory for struct (status_change_pmupdcid) t\n"); } copy_cbyc(t->idcode,idcode,2); t->idcode[2] = '\0'; t->pmuid_next = NULL; pthread_mutex_lock(&mutex_status_change); if(root_pmuid == NULL) { t = root_pmuid; } else { struct status_change_pmupdcid *temp = root_pmuid; while(temp->pmuid_next!=NULL) { temp = temp->pmuid_next; } temp->pmuid_next = t; } pthread_mutex_unlock(&mutex_status_change); } /* ---------------------------------------------------------------------------- */ /* FUNCTION remove_id_from_status_change_list(): */ /* It removes the IDCODE of PMU/PDC from status_change_pmupdcid' LL */ /* on receipt of configuration frame of corresponding PMU/PDC */ /* ---------------------------------------------------------------------------- */ void remove_id_from_status_change_list(unsigned char idcode[]) { struct status_change_pmupdcid *tprev; pthread_mutex_lock(&mutex_status_change); if(root_pmuid == NULL) { printf("***No Stat change***\n"); } else { struct status_change_pmupdcid *temp = root_pmuid; while(temp != NULL) { if(!ncmp_cbyc(temp->idcode,idcode,2)) { break; } else { tprev = temp; temp = temp->pmuid_next; } } // If It is the first element(root) in the list if(!ncmp_cbyc(temp->idcode,root_pmuid->idcode,2)) { root_pmuid = root_pmuid->pmuid_next; free(temp); // If it is any element other than first(root) in the list } else { tprev->pmuid_next = temp->pmuid_next; free(temp); } } pthread_mutex_unlock(&mutex_status_change); } /* ---------------------------------------------------------------------------- */ /* FUNCTION to_intconvertor(): */ /* ---------------------------------------------------------------------------- */ unsigned int to_intconvertor(unsigned char array[]) { unsigned int n; n = array[0]; n <<= 8; n |= array[1]; return n; } /* ---------------------------------------------------------------------------- */ /* FUNCTION long_int_to_ascii_convertor(): */ /* ---------------------------------------------------------------------------- */ void long_int_to_ascii_convertor(unsigned long int n,unsigned char hex[]) { hex[0] = n >> 24; hex[1] = n >> 16; hex[2] = n >> 8; hex[3] = n ; } /* ---------------------------------------------------------------------------- */ /* FUNCTION int_to_ascii_convertor(): */ /* ---------------------------------------------------------------------------- */ void int_to_ascii_convertor(unsigned int n,unsigned char hex[]) { hex[0] = n >> 8; hex[1] = n ; } /* ---------------------------------------------------------------------------- */ /* FUNCTION copy_cbyc(): */ /* ---------------------------------------------------------------------------- */ void copy_cbyc(unsigned char dst[],unsigned char *s,int size) { int i; for(i = 0; i< size; i++) dst[i] = *(s + i); } /* ---------------------------------------------------------------------------- */ /* FUNCTION ncmp_cbyc(): */ /* ---------------------------------------------------------------------------- */ int ncmp_cbyc(unsigned char dst[],unsigned char src[],int size) { int i,flag = 0; for(i = 0; i< size; i++) { if(dst[i] != src[i]) { flag = 1; break; } } return flag; } /* ---------------------------------------------------------------------------- */ /* FUNCTION byte_by_byte_copy(): */ /* ---------------------------------------------------------------------------- */ void byte_by_byte_copy(unsigned char dst[],unsigned char src[],int index,int n) { int i; for(i = 0;i>8)^message[i]; crc<<=8; quick=temp ^ ( temp >>4); crc ^=quick; quick<<=5; crc ^=quick; quick <<=7; crc ^= quick; } return crc; } /**************************************** End of File *******************************************************/