iPDC-suite/iPDC/recreate.c

880 lines
22 KiB
C
Executable File

/* -----------------------------------------------------------------------------
* recreate.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 <panditnitesh@gmail.com>
* Kedar V. Khandeparkar <kedar.khandeparkar@gmail.com>
*
* ----------------------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include "parser.h"
#include "global.h"
#include "connections.h"
#include "recreate.h"
#include "new_pmu_or_pdc.h"
/* ------------------------------------------------------------------------------------ */
/* Functions defined in recreate.c */
/* ------------------------------------------------------------------------------------ */
/* 1. recreate_cfg_objects() */
/* 2. void init_cfgparser() */
/* 3. void recreate_Connection_Table() */
/* 4. void recreate_udp_connections(struct Lower_Layer_Details *t11) */
/* 5. void recreate_tcp_connections(struct Lower_Layer_Details *t12) */
/* ------------------------------------------------------------------------------------ */
/* ---------------------------------------------------------------------------- */
/* FUNCTION recreate_cfg_objects(): */
/* It re-creates Configuration Objects from file cfg.bin if the ./server */
/* program is stopped abruptly. It internally calls init_cfgparser() */
/* ---------------------------------------------------------------------------- */
void recreate_cfg_objects(){
/* ---------------------------------------------------------------- */
/* Initialize Global Mutex Variable from global.h */
/* ---------------------------------------------------------------- */
pthread_mutex_init(&mutex_file, NULL);
pthread_mutex_init(&mutex_cfg, NULL);
pthread_mutex_init(&mutex_status_change, NULL);
pthread_mutex_init(&mutex_Lower_Layer_Details, NULL);
pthread_mutex_init(&mutex_Upper_Layer_Details, NULL);
CMDSYNC[0] = 0xaa;
CMDSYNC[1] = 0x41;
CMDSYNC[2] = '\0';
CMDCFGSEND[0] = 0x00;
CMDCFGSEND[1] = 0x05;
CMDCFGSEND[2] = '\0';
CMDDATASEND[0] = 0x00;
CMDDATASEND[1] = 0x02;
CMDDATASEND[2] = '\0';
CMDDATAOFF[0] = 0x00;
CMDDATAOFF[1] = 0x01;
CMDDATAOFF[2] = '\0';
DATASYNC[0] = 0xaa;
DATASYNC[1] = 0x01;
DATASYNC[2] = '\0';
CFGSYNC[0] = 0xaa;
CFGSYNC[1] = 0x31;
CFGSYNC[2] = '\0';
int yes =1;
/* Create UDP socket for DB Server and bind to DBPORT */
if ((DB_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
} else {
printf("DB Socket:Sucessfully created\n");
}
if (setsockopt(DB_sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
bzero(&DB_Server_addr,sizeof(DB_Server_addr));
DB_Server_addr.sin_family = AF_INET; // host byte order
DB_Server_addr.sin_port = htons(DBPORT); // short, network byte order
DB_Server_addr.sin_addr.s_addr = inet_addr(dbserver_ip); // automatically fill with my IP
memset(&(DB_Server_addr.sin_zero),'\0', 8); // zero the rest of the struct
unsigned char *line;
unsigned int framesize;
int tempi;
char *rline = NULL, *d1;
ssize_t read;
size_t len = 0;
/* Create CFG Objects from cfg.bin*/
FILE *file = fopen (ipdcFilePath,"rb");
if(file != NULL)
{
tempi = 1;
while(tempi < 7) //iPDCServer
{
read = getline(&rline, &len, file);
tempi++;
}
if(read > 0) //LowerDevices
{
d1 = strtok (rline," ");
d1 = strtok (NULL,"\n");
tempi = atoi(d1);
while (tempi > 0)
{
read = getline(&rline, &len, file);
tempi--;
}
}
read = getline(&rline, &len, file); //UpperDevices
if(read > 0)
{
d1 = strtok (rline," ");
d1 = strtok (NULL,"\n");
tempi = atoi(d1);
while (tempi > 0)
{
read = getline(&rline, &len, file);
tempi--;
}
}
read = getline(&rline, &len, file); //SourcesCFG
if(read > 0)
{
d1 = strtok (rline," ");
d1 = strtok (NULL,"\n");
tempi = atoi(d1);
if (tempi > 0)
{
getline(&rline, &len, file);
framesize = atoi(rline);
line = malloc(framesize*sizeof(unsigned char));
fread(line, sizeof(unsigned char), framesize, file);
init_cfgparser(line);
free(line);
tempi--;
}
}
fclose (file);
}
else
{
printf("iPDC Setup File is missing, iPDC exit.\n");
exit(1);
}
}
/* ---------------------------------------------------------------------------- */
/* FUNCTION init_cfgparser(): */
/* It is called by recreate_cfg_object() to read the file `cfg.bin` */
/* and create cfg objects in the memory */
/* ---------------------------------------------------------------------------- */
void init_cfgparser(unsigned char st[]){
unsigned char *s;
unsigned int phn,ann,dgn,num_pmu;
int i,j,dgchannels;
struct cfg_frame *cfg;
struct channel_names *cn;
/******************** PARSING BEGINGS *******************/
cfg = malloc(sizeof(struct cfg_frame));
if(!cfg) {
printf("Not enough memory for cfg\n");
}
s = st;
/* Memory Allocation Begins - Allocate memory to framesize */
cfg->framesize = malloc(3*sizeof(unsigned char));
if(!cfg->framesize) {
printf("Not enough memory for cfg->framesize\n");
}
// Allocate memory to idcode
cfg->idcode = malloc(3*sizeof(unsigned char));
if(!cfg->idcode) {
printf("Not enough memory for cfg->framesize\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 num_pmu
cfg->num_pmu = malloc(3*sizeof(unsigned char));
if(!cfg->num_pmu) {
printf("Not 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("Not enough memory for cfg->data_rate\n");
}
// Skip the sync word
s = s + 2;
// Separate the FRAME SIZE
copy_cbyc (cfg->framesize,(unsigned char *)s,2);
cfg->framesize[2]='\0';
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;
//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 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(j<num_pmu) {
// Memory Allocation for stn
cfg->pmu[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;
// USE fmt
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';
s = s + 2;
phn = to_intconvertor(cfg->pmu[j]->phnmr);
//SEPARATE ANALOGS
copy_cbyc (cfg->pmu[j]->annmr,(unsigned char *)s,2);
cfg->pmu[j]->annmr[2]='\0';
s = s + 2;
ann = to_intconvertor(cfg->pmu[j]->annmr);
//SEPARATE DIGITALS
copy_cbyc (cfg->pmu[j]->dgnmr,(unsigned char *)s,2);
cfg->pmu[j]->dgnmr[2] = '\0';
s = s + 2;
dgn = to_intconvertor(cfg->pmu[j]->dgnmr);
printf("CFG consist Phasor = %d, Analogs = %d, and Digitals = %d.\n",phn,ann,dgn);
cn = malloc(sizeof(struct channel_names));
if(!cn) {
printf("Not enough memory cn\n");
exit(1);
}
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(i<phn){
copy_cbyc (cn->phnames[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(i<ann){
copy_cbyc (cn->angnames[i],(unsigned char *)s,16);
cn->angnames[i][16]='\0';
printf("ANGNAMES %s\n",cn->angnames[i]);
s =s + 16;
i++;
}
}
i = 0; //Index for number of dgwords
struct dgnames *q;
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 (i = 0; i < 16; i++) {
temp1->dgn[i] = 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*sizeof(unsigned char));
}
i = 0;
while(i<phn){ //Separate the Phasor conversion factors
copy_cbyc (cfg->pmu[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*sizeof(unsigned char));
}
i = 0;
while(i<ann){ //Separate the Phasor conversion factors
copy_cbyc (cfg->pmu[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*sizeof(unsigned char));
}
i = 0;
while(i<dgn){ //Separate the Phasor conversion factors
copy_cbyc (cfg->pmu[j]->dgunit[i],(unsigned char *)s,4);
cfg->pmu[j]->dgunit[i][4] = '\0';
s = s + 4;
i++;
}
} //if for Digital Words Factors 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';
cfg->cfgnext = NULL;
if (cfgfirst == NULL) {
cfgfirst = cfg;
} else {
struct cfg_frame *t=cfgfirst;
while(t->cfgnext != NULL){
t = t->cfgnext;
}
t->cfgnext = cfg;
}
}
/* ---------------------------------------------------------------------------- */
/* FUNCTION recreate_Connection_Table(): */
/* It re-creates objects by reading the file ipdcINFO.bin.*/
/* ---------------------------------------------------------------------------- */
void recreate_Connection_Table() {
char line[40],*ip,*port,*protocol,*id;
char *rline = NULL, *d1;
int err, tempi;
FILE *f;
ssize_t read;
size_t len = 0;
// A new thread is created for each TCP connection in 'detached' mode. Thus allowing any number of threads to be created.
pthread_attr_t attr;
pthread_attr_init(&attr);
/* In the detached state, the thread resources are immediately freed when it terminates, but
pthread_join(3) cannot be used to synchronize on the thread termination. */
if((err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
perror(strerror(err));
exit(1);
}
/* Shed policy = SCHED_FIFO (realtime, first-in first-out) */
if((err = pthread_attr_setschedpolicy(&attr,SCHED_FIFO))) {
perror(strerror(err));
exit(1);
}
f = fopen(ipdcFilePath,"rb");
tempi = 1;
while(tempi < 7)
{
read = getline(&rline, &len, f);
tempi++;
}
if(read > 0)
{
d1 = strtok (rline," ");
d1 = strtok (NULL,"\n");
tempi = atoi(d1);
if (tempi > 0) //1 if
{
printf("#### CONNECTION TABLE OF SOURCE DEVICES ####\n");
printf("-----------------------------------------------------------------\n");
printf("| PMU ID | Lower IP | Port | Protocol |\n");
printf("-----------------------------------------------------------------\n");
while (tempi > 0) //2 while
{
read = getline(&rline, &len, f);
/* Extract the ip and protocol */
id = strtok (rline,",");
ip = strtok (NULL,",");
port = strtok (NULL,",");
protocol = strtok (NULL,"\n");
protocol[3] = '\0';
printf("|\t%d\t|%s\t|\t%d\t|\t%s\t|\n",atoi(id),ip,atoi(port),protocol);
struct Lower_Layer_Details *temp_pmu;
temp_pmu = malloc(sizeof(struct Lower_Layer_Details));
if(!temp_pmu) {
printf("Not enough memory temp_pmu\n");
exit(1);
}
temp_pmu->pmuid = atoi(id);
strcpy(temp_pmu->ip,ip);
temp_pmu->port = atoi(port);
strcpy(temp_pmu->protocol,protocol);
temp_pmu->data_transmission_off = 0;
temp_pmu->pmu_remove = 0;
temp_pmu->request_cfg_frame = 0;
temp_pmu->next = NULL;
temp_pmu->prev = NULL;
if(!strncasecmp(temp_pmu->protocol,"UDP",3)) {
recreate_udp_connections(temp_pmu);
}
if(!strncasecmp(temp_pmu->protocol,"TCP",3)) {
recreate_tcp_connections(temp_pmu);
}
memset(line,'\0',40);
tempi--;
}
printf("-----------------------------------------------------------------\n");
} else {
printf("Source Devices Not Found.\n");
}
}
read = getline(&rline, &len, f);
if(read > 0)
{
d1 = strtok (rline," ");
d1 = strtok (NULL,"\n");
tempi = atoi(d1);
if (tempi > 0) //1 if
{
printf("#### CONNECTION TABLE OF DESTINATION DEVICES ####\n");
printf("-------------------------------------------------\n");
printf("| Upper IP | Port | Protocol |\n");
printf("-------------------------------------------------\n");
while (tempi > 0) //2 while
{
read = getline(&rline, &len, f);
/* Extract the ip and protocol */
ip = strtok (rline,",");
port = strtok (NULL,",");
protocol = strtok (NULL,"\n");
protocol[3] = '\0';
printf("|%s\t|\t%d\t|\t%s\t|\n",ip,atoi(port),protocol);
struct Upper_Layer_Details *temp_pdc;
temp_pdc = malloc(sizeof(struct Upper_Layer_Details));
if(!temp_pdc) {
printf("Not enough memory temp_pmu\n");
exit(1);
}
strcpy(temp_pdc->ip,ip);
temp_pdc->port = atoi(port);
strcpy(temp_pdc->protocol,protocol);
bzero(&temp_pdc->pdc_addr,sizeof(temp_pdc->pdc_addr));
temp_pdc->pdc_addr.sin_family = AF_INET;
temp_pdc->pdc_addr.sin_addr.s_addr = inet_addr(temp_pdc->ip);
temp_pdc->pdc_addr.sin_port = htons(temp_pdc->port);
memset(&(temp_pdc->pdc_addr.sin_zero), '\0', 8); // zero the rest of the struct
temp_pdc->config_change = 0;
temp_pdc->UL_upper_pdc_cfgsent = 0;
temp_pdc->UL_data_transmission_off = 1;
temp_pdc->address_set = 0;
temp_pdc->tcpup = 1;
if(ULfirst == NULL) {
ULfirst = temp_pdc;
temp_pdc->prev = NULL;
} else {
ULlast->next = temp_pdc;
temp_pdc->prev = ULlast;
}
ULlast = temp_pdc;
temp_pdc->next = NULL;
memset(line,'\0',40);
tempi--;
}
printf("-------------------------------------------------\n");
} else {
printf("Destination Devices Not Found.\n");
}
}
fclose(f);
}
/* ---------------------------------------------------------------------------- */
/* FUNCTION recreate_udp_connections(struct Lower_Layer_Details *t11): */
/* ---------------------------------------------------------------------------- */
void recreate_udp_connections(struct Lower_Layer_Details *t11) {
int err;
pthread_attr_t attr;
pthread_attr_init(&attr);
/* In the detached state, the thread resources are immediately freed when it terminates, but
pthread_join(3) cannot be used to synchronize on the thread termination. */
if((err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
perror(strerror(err));
exit(1);
}
/* Shed policy = SCHED_FIFO (realtime, first-in first-out) */
if((err = pthread_attr_setschedpolicy(&attr,SCHED_FIFO))) {
perror(strerror(err));
exit(1);
}
pthread_t t;
if(pthread_create(&t,&attr,connect_pmu_udp,(void *)t11)) {
perror(strerror(err));
exit(1);
}
}
/* ---------------------------------------------------------------------------- */
/* FUNCTION recreate_tcp_connections(struct Lower_Layer_Details *t12): */
/* ---------------------------------------------------------------------------- */
void recreate_tcp_connections(struct Lower_Layer_Details *t12) {
int err;
pthread_attr_t attr;
pthread_attr_init(&attr);
/* In the detached state, the thread resources are immediately freed when it terminates, but
pthread_join(3) cannot be used to synchronize on the thread termination. */
if((err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
perror(strerror(err));
exit(1);
}
/* Shed policy = SCHED_FIFO (realtime, first-in first-out) */
if((err = pthread_attr_setschedpolicy(&attr,SCHED_FIFO))) {
perror(strerror(err));
exit(1);
}
pthread_t t;
if(pthread_create(&t,&attr,connect_pmu_tcp,(void *)t12)) {
perror(strerror(err));
exit(1);
}
}
/**************************************** End of File *******************************************************/