<commit_before>#include <config.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex>

#ifdef HAVE_MINUIT
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnMigrad.h"
#include "Minuit2/MnMinos.h"
#include "Minuit2/MnMinimize.h"
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/MnPrint.h"
#include "Minuit2/FCNBase.h"
#include "globalRVMKJ_Fcn.h"
#endif

#include "RVMnest.h"

#define DEG_TO_RAD	(M_PI/180.0)
#define RAD_TO_DEG	(180.0/M_PI)

using namespace std;

/******************************************** loglikelihood routine ****************************************************/

// Now an example, sample an egg box likelihood

// Input arguments
// ndim                                                 = dimensionality (total number of free parameters) of the problem
// npars                                                = total number of free plus derived parameters
// context                                              void pointer, any additional information
//
// Input/Output arguments
// Cube[npars]                                          = on entry has the ndim parameters in unit-hypercube
//                                                      on exit, the physical parameters plus copy any derived parameters you want to store with the free parameters
//
// Output arguments
// lnew                                                 = loglikelihood

void prior (double cube[], double theta[], int nDims,  void *context)
{
  int ipar = 0;

  theta[ipar] = cube[ipar] * (sp->r_alpha[1] - sp->r_alpha[0]) + sp->r_alpha[0];
  ipar++;
  theta[ipar] = cube[ipar] * (sp->r_delta[1] - sp->r_delta[0]) + sp->r_delta[0];
  ipar++;
  theta[ipar] = cube[ipar] * (sp->r_Phi0[1] - sp->r_Phi0[0]) + sp->r_Phi0[0];
  ipar++;
  theta[ipar] = cube[ipar] * 180. - 90.;
  ipar++;

  // RVM center Phase of the profiles - Can be marginalized
  if (!sp->margin_phi0) {
    for (unsigned int j = 0; j < par->n_epoch; j++) {
      theta[ipar] = cube[ipar] * (sp->r_phi0[1] - sp->r_phi0[0]) + sp->r_phi0[0];
      ipar++;
    }
  }

  // include an offset between the PA curves of the MP and IP
  if (sp->have_aberr_offset) {
    for (unsigned int j = 0; j < sp->n_epoch; j++) {
      theta[ipar] = (cube[ipar] * 16 - 8);
      ipar++;
    }
  }

  // Precession rate
  if (!sp->prate_fixed) {
    theta[ipar] = cube[ipar] * (sp->r_prate[1] - sp->r_prate[0]) + sp->r_prate[0];
    ipar++;
  }

  // Inclination angle
  if (!sp->inc_fixed) {
    theta[ipar] = cube[ipar] * (sp->r_inc[1] - sp->r_inc[0]) + sp->r_inc[0];
    ipar++;
  }

  // Psi0 jumps between different datasets
  if (sp->njump) {
    if(!sp->psi_jump_fixed) {
      for (unsigned  l=0; l<sp->njump; l++) {
	theta[ipar] = cube[ipar] * 90. + 45.;
	ipar++;
      }
    }
  }

}

double globalRVMLogLike_PC(double theta[], int nDims, double phi[], int nDerived, void *context) {

  //void globalRVMLogLike(double *Cube, int &ndim, int &npars, double &lnew, void *context) {

  //	MNStruct *par = ((MNStruct *)context);

	char label[16];
	double Qu,Uu;
        double chi = 0.0, Ln, PA2;
	double Ltot = 0., logdetN = 0.;
	double cosPA2, sinPA2;
	complex <double> L, arg;

	sp->alpha = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->delta = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->phase0 = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->psi00 = theta[ipar] * DEG_TO_RAD; ipar++;

	// RVM center Phase of the profiles - Can be marginalized
	if (!sp->margin_phi0) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
		sp->phi0[j] = theta[ipar] * DEG_TO_RAD;
		ipar++;
	    }
	} else {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) sp->phi0[j] = 5.0 * DEG_TO_RAD;
	}

	// include an offset between the PA curves of the MP and IP
	if (sp->have_aberr_offset) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
		sp->phi_aberr_offset[j] = theta[ipar] * DEG_TO_RAD;
		ipar++;
	    }
	}

	// Precession rate
	if (!sp->prate_fixed) {
	    sp->prate = theta[ipar];
	    ipar++;
	}

	// Inclination angle
	if (!sp->inc_fixed) {
 	    sp->inc = theta[ipar] * DEG_TO_RAD;
	    ipar++;
	}

	// EFACs
	if (sp->have_efac) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
	        sp->efac[j] = theta[ipar];
		ipar++;
	    }
	} else {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) sp->efac[j] = 1.;
	}

	// Psi0 jumps between different datasets
	if (sp->njump) {
	  if(!sp->psi_jump_fixed) {
	    for (unsigned  l=0; l<sp->njump; l++) {
	      sp->psi_jumps[l] = theta[ipar] * DEG_TO_RAD;
	      ipar++;
	    }
	  }
	}

	double rmsQ;
	double rmsU;

	vector<double> vrmsQ, vrmsU;
	vector< vector<double> > vQ, vU, vphase;
	vQ.resize(sp->n_epoch); vU.resize(sp->n_epoch); vphase.resize(sp->n_epoch);

	for(unsigned int j = 0; j < sp->n_epoch; j++) {
	  vrmsQ.push_back(sp->rmsQ[j]);
	  vrmsU.push_back(sp->rmsU[j]);
	  for(unsigned int i = 0; i < sp->npts[j]; i++) {
	    vQ[j].push_back(sp->Q[j][i]);
	    vU[j].push_back(sp->U[j][i]);
	    vphase[j].push_back(sp->phase[j][i]);
	  }
	}

#ifdef HAVE_MINUIT
	// Marginalize over Phi0
	if (sp->margin_phi0) {
	    //RVM_Fcn fFCN();
	    RVM_Fcn fFCN(vphase, vQ, vU, vrmsQ, vrmsU);
	    fFCN.set_params(sp);

	    MnUserParameters upar;
	    for(unsigned int j = 0; j < sp->n_epoch; j++) {
		sprintf(label, "phi0_%d", j);
		upar.Add(label, sp->phi0[j], 5.);
	    }

	    MnMinimize migrad(fFCN, upar);
	    //cout << upar << endl;
	    FunctionMinimum min = migrad();
	    //cout<<"minimum: "<<min<<endl;

	    for(unsigned int j = 0; j < sp->n_epoch; j++) {
		sprintf(label, "phi0_%d", j);
		sp->phi0[j] = min.UserState().Value(label);
		//printf("phi0[%02d] = %lf\n",j, par->phi0[j]);
	    }
	}
#endif

	get_globalRVM_chi2(sp);

	// shift the reference P.A. by 90 degrees and ensure that PA0 lies on -pi/2 -> pi/2
	if (sp->Ltot < 0.0) {
	    sp->psi00 += M_PI /2.;
	}
	sp->psi00 = atan( tan(sp->psi00) );

        lnew = -1.*sp->chi/2 - 0.5*sp->logdetN;
	return lnew;
}
<commit_msg>Compilation fixes: added variable declaration<commit_after>#include <config.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex>

#ifdef HAVE_MINUIT
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnMigrad.h"
#include "Minuit2/MnMinos.h"
#include "Minuit2/MnMinimize.h"
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/MnPrint.h"
#include "Minuit2/FCNBase.h"
#include "globalRVMKJ_Fcn.h"
#endif

#include "RVMnest.h"

#include "globalRVM_likelihood_PC.h"

#define DEG_TO_RAD	(M_PI/180.0)
#define RAD_TO_DEG	(180.0/M_PI)

using namespace std;

/******************************************** loglikelihood routine ****************************************************/

// Now an example, sample an egg box likelihood

// Input arguments
// ndim                                                 = dimensionality (total number of free parameters) of the problem
// npars                                                = total number of free plus derived parameters
// context                                              void pointer, any additional information
//
// Input/Output arguments
// Cube[npars]                                          = on entry has the ndim parameters in unit-hypercube
//                                                      on exit, the physical parameters plus copy any derived parameters you want to store with the free parameters
//
// Output arguments
// lnew                                                 = loglikelihood

void prior (double cube[], double theta[], int nDims,  void *context)
{
  int ipar = 0;

  theta[ipar] = cube[ipar] * (sp->r_alpha[1] - sp->r_alpha[0]) + sp->r_alpha[0];
  ipar++;
  theta[ipar] = cube[ipar] * (sp->r_delta[1] - sp->r_delta[0]) + sp->r_delta[0];
  ipar++;
  theta[ipar] = cube[ipar] * (sp->r_Phi0[1] - sp->r_Phi0[0]) + sp->r_Phi0[0];
  ipar++;
  theta[ipar] = cube[ipar] * 180. - 90.;
  ipar++;

  // RVM center Phase of the profiles - Can be marginalized
  if (!sp->margin_phi0) {
    for (unsigned int j = 0; j < sp->n_epoch; j++) {
      theta[ipar] = cube[ipar] * (sp->r_phi0[1] - sp->r_phi0[0]) + sp->r_phi0[0];
      ipar++;
    }
  }

  // include an offset between the PA curves of the MP and IP
  if (sp->have_aberr_offset) {
    for (unsigned int j = 0; j < sp->n_epoch; j++) {
      theta[ipar] = (cube[ipar] * 16 - 8);
      ipar++;
    }
  }

  // Precession rate
  if (!sp->prate_fixed) {
    theta[ipar] = cube[ipar] * (sp->r_prate[1] - sp->r_prate[0]) + sp->r_prate[0];
    ipar++;
  }

  // Inclination angle
  if (!sp->inc_fixed) {
    theta[ipar] = cube[ipar] * (sp->r_inc[1] - sp->r_inc[0]) + sp->r_inc[0];
    ipar++;
  }

  // Psi0 jumps between different datasets
  if (sp->njump) {
    if(!sp->psi_jump_fixed) {
      for (unsigned  l=0; l<sp->njump; l++) {
	theta[ipar] = cube[ipar] * 90. + 45.;
	ipar++;
      }
    }
  }

}

double globalRVMLogLike_PC(double theta[], int nDims, double phi[], int nDerived, void *context) {

  //void globalRVMLogLike(double *Cube, int &ndim, int &npars, double &lnew, void *context) {

  //	MNStruct *par = ((MNStruct *)context);

	char label[16];
	int ipar=0;
	double Qu,Uu;
	double lnew;

	sp->alpha = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->delta = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->phase0 = theta[ipar] * DEG_TO_RAD; ipar++;
	sp->psi00 = theta[ipar] * DEG_TO_RAD; ipar++;

	// RVM center Phase of the profiles - Can be marginalized
	if (!sp->margin_phi0) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
		sp->phi0[j] = theta[ipar] * DEG_TO_RAD;
		ipar++;
	    }
	} else {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) sp->phi0[j] = 5.0 * DEG_TO_RAD;
	}

	// include an offset between the PA curves of the MP and IP
	if (sp->have_aberr_offset) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
		sp->phi_aberr_offset[j] = theta[ipar] * DEG_TO_RAD;
		ipar++;
	    }
	}

	// Precession rate
	if (!sp->prate_fixed) {
	    sp->prate = theta[ipar];
	    ipar++;
	}

	// Inclination angle
	if (!sp->inc_fixed) {
 	    sp->inc = theta[ipar] * DEG_TO_RAD;
	    ipar++;
	}

	// EFACs
	if (sp->have_efac) {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) {
	        sp->efac[j] = theta[ipar];
		ipar++;
	    }
	} else {
	    for (unsigned int j = 0; j < sp->n_epoch; j++) sp->efac[j] = 1.;
	}

	// Psi0 jumps between different datasets
	if (sp->njump) {
	  if(!sp->psi_jump_fixed) {
	    for (unsigned  l=0; l<sp->njump; l++) {
	      sp->psi_jumps[l] = theta[ipar] * DEG_TO_RAD;
	      ipar++;
	    }
	  }
	}

	double rmsQ;
	double rmsU;

	vector<double> vrmsQ, vrmsU;
	vector< vector<double> > vQ, vU, vphase;
	vQ.resize(sp->n_epoch); vU.resize(sp->n_epoch); vphase.resize(sp->n_epoch);

	for(unsigned int j = 0; j < sp->n_epoch; j++) {
	  vrmsQ.push_back(sp->rmsQ[j]);
	  vrmsU.push_back(sp->rmsU[j]);
	  for(unsigned int i = 0; i < sp->npts[j]; i++) {
	    vQ[j].push_back(sp->Q[j][i]);
	    vU[j].push_back(sp->U[j][i]);
	    vphase[j].push_back(sp->phase[j][i]);
	  }
	}

#ifdef HAVE_MINUIT
	// Marginalize over Phi0
	if (sp->margin_phi0) {
	    //RVM_Fcn fFCN();
	    RVM_Fcn fFCN(vphase, vQ, vU, vrmsQ, vrmsU);
	    fFCN.set_params(sp);

	    MnUserParameters upar;
	    for(unsigned int j = 0; j < sp->n_epoch; j++) {
		sprintf(label, "phi0_%d", j);
		upar.Add(label, sp->phi0[j], 5.);
	    }

	    MnMinimize migrad(fFCN, upar);
	    //cout << upar << endl;
	    FunctionMinimum min = migrad();
	    //cout<<"minimum: "<<min<<endl;

	    for(unsigned int j = 0; j < sp->n_epoch; j++) {
		sprintf(label, "phi0_%d", j);
		sp->phi0[j] = min.UserState().Value(label);
		//printf("phi0[%02d] = %lf\n",j, par->phi0[j]);
	    }
	}
#endif

	get_globalRVM_chi2(sp);

	// shift the reference P.A. by 90 degrees and ensure that PA0 lies on -pi/2 -> pi/2
	if (sp->Ltot < 0.0) {
	    sp->psi00 += M_PI /2.;
	}
	sp->psi00 = atan( tan(sp->psi00) );

        lnew = -1.*sp->chi/2 - 0.5*sp->logdetN;
	return lnew;
}
<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_sec = 0;
  timeout.tv_usec = TIMEOUT * 1000;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "=== ACK TIMEOUT" << endl;
		sendPacket();
	}

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) usleep(delayT * 1000); //using milliseconds

    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
	  seqNum = (seqNum) ? false : true;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>Testing for timer<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define BUFSIZE 121
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
bool sendPacket();

bool seqNum = true;
struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
int length;
bool dropPck;
bool delayPck;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  calen = sizeof(ca);

  unsigned char packet[PAKSIZE + 1];
  rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  seqNum = true;
  dropPck = false;

  return true;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  bool isSeqNumSet = false;
  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
    if(!isSeqNumSet) {
      isSeqNumSet = true;
      char * str = new char[1];
      memcpy(str, &packet[0], 1);
      seqNum = boost::lexical_cast<int>(str);
    }
    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p ((seqNum) ? false : true, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= (length / BUFSIZE) + 1; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
		cout << "=== ACK TIMEOUT" << endl;
		sendPacket();
	}

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) usleep(delayT * 1000); //using milliseconds

    if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		cout << "Error number: " << errno << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
	  seqNum = (seqNum) ? false : true;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>


<commit_before>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;
	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(0, &stReadFDS);

	base = 0;
	int finale = -1;
	while(base * BUFSIZE < length) {
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		for(int x = 0; x < WIN_SIZE; x++) {
			cout << "begin loop no. " << x << endl;
			int t = select(1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t != 0) {
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT" << endl;
					x--;
					continue;
				}
			} else {
				cout << "=== ACK TIMEOUT" << endl;
				x--;
				continue;
			}
			if(isAck()) {
				handleAck();
			} else {
				handleAck();
				//handleNak(x);
			}
			if(finale > 0 && base == finale) break;
			memset(b, 0, BUFSIZE);
		}

	}

	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<commit_msg>wow that didn't make any sense to have there<commit_after>#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define USAGE "Usage:\r\nc \r\n[tux machine number] \r\n[probability of packet corruption in int form] \r\n[probability of packet loss in int form] \r\n[probability of packet delay] \r\n[length of delay in ms] \r\n"
#define PORT 10038
#define PAKSIZE 512
#define ACK 0
#define NAK 1
#define BUFSIZE 505
#define FILENAME "Testfile"
#define TIMEOUT 100 //in ms
#define WIN_SIZE 16

using namespace std;

bool isvpack(unsigned char * p);
bool init(int argc, char** argv);
bool loadFile();
bool getFile();
bool sendFile();
bool isAck();
void handleAck();
void handleNak(int& x);
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb);
Packet createPacket(int index);
void loadWindow();
bool sendPacket();
bool getGet();

struct sockaddr_in a;
struct sockaddr_in ca;
socklen_t calen;
int rlen;
int s;
bool ack;
string fstr;
char * file;
int probCorrupt;
int probLoss;
int probDelay;
int delayT;
Packet p;
Packet window[16];
int length;
bool dropPck;
bool delayPck;
int toms;
unsigned char b[BUFSIZE];
int base;

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  sendFile();

  return 0;
}

bool init(int argc, char** argv){

  if(argc != 6) {
    cout << USAGE << endl;
    return false;
  }

  char * probCorruptStr = argv[2];
  probCorrupt = boost::lexical_cast<int>(probCorruptStr);
  char * probLossStr = argv[3];
  probLoss = boost::lexical_cast<int>(probLossStr);
  char * probDelayStr = argv[4];
  probDelay = boost::lexical_cast<int>(probDelayStr);
  char* delayTStr = argv[5];
  delayT = boost::lexical_cast<int>(delayTStr);

  struct timeval timeout;
  timeout.tv_usec = TIMEOUT * 1000;
  toms = TIMEOUT;

  /* Create our socket. */
  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return 0;
  }

  setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

  /*
   * Bind our socket to an IP (whatever the computer decides)
   * and a specified port.
   *
   */

  if (!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY);
  a.sin_port = htons(PORT);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return 0;
  }

  fstr = string(file);
  cout << "File: " << endl << fstr << endl;

  base = 0;
  dropPck = false;
  calen = sizeof(ca);

  getGet();

  return true;
}

bool getGet(){
	unsigned char packet[PAKSIZE + 1];
	rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);
	return (rlen > 0) ? true : false;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[7];
  memcpy(css, &p[1], 6);
  css[6] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[2], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == 0) return false; //doesn't matter, only for the old version (netwark)
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){

  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&ca, &calen);

    for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
      char * css = new char[6];
      memcpy(css, &packet[1], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      cout << "Sent response: ";
      if(isvpack(packet)) {
        ack = ACK;
        //seqNum = (seqNum) ? false : true;
        file << dataPull;
      } else {
        ack = NAK;
      }
      cout << ((ack == ACK) ? "ACK" : "NAK") << endl;
      Packet p (false, reinterpret_cast<const char *>(dataPull));
      p.setCheckSum(boost::lexical_cast<int>(css));
      p.setAckNack(ack);

      if(sendto(s, p.str(), PAKSIZE, 0, (struct sockaddr *)&ca, calen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

void loadWindow(){
	for(int i = base; i < base + WIN_SIZE; i++) {
		window[i-base] = createPacket(i);
		if(strlen(window[i-base].getDataBuffer()) < BUFSIZE && window[i-base].chksm()) {
			cout << "In loadWindow's secret base, index is: " << i-base << endl;
			for(++i; i < base + WIN_SIZE; i++){
				window[i-base].loadDataBuffer("\0");
			}

		}
		/*cout << "window[i-base] seq. num: " << window[i-base].getSequenceNum() << endl;*/
	}

		/*cout << "packet " << base + 1 << ": " << window[1].str() << endl;
		cout << "packet " << base + 2 << ": " << window[2].str() << endl;*/
}

bool sendFile() {
	/*Currently causes the program to only send the first 16 packets of file out
		requires additional code later to sendFile again with updated window*/
	fd_set stReadFDS;
	struct timeval stTimeOut;

	FD_ZERO(&stReadFDS);
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 1000 * TIMEOUT;
	FD_SET(0, &stReadFDS);

	base = 0;
	int finale = -1;
	while(base * BUFSIZE < length) {
		loadWindow();

		if(p.str()[0] == '\0') finale = p.getSequenceNum();
		for(int x = 0; x < WIN_SIZE; x++) {
			p = window[x];
			if(!sendPacket()) continue;
		}
		for(int x = 0; x < WIN_SIZE; x++) {
			cout << "begin loop no. " << x << endl;
			int t = select(1, &stReadFDS, NULL, NULL, &stTimeOut);
			if (t != 0) {
				if(recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&ca, &calen) < 0) {
					cout << "=== ACK TIMEOUT" << endl;
					continue;
				}
			} else {
				cout << "=== ACK TIMEOUT" << endl;
				continue;
			}
			if(isAck()) {
				handleAck();
			} else {
				handleAck();
				//handleNak(x);
			}
			if(finale > 0 && base == finale) break;
			memset(b, 0, BUFSIZE);
		}

	}

	if(sendto(s, "\0", BUFSIZE, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Final package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
	}
	return true;
}

Packet createPacket(int index){
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);

	if(mstr.length() < BUFSIZE) {
		cout << "Null terminated mstr." << endl;
		mstr[length - (index * BUFSIZE)] = '\0';
    }

	cout << "index: " << index << endl;
    return Packet (index, mstr.c_str());
}

bool sendPacket(){
	cout << endl;
    cout << "=== TRANSMISSION START" << endl;
	cout << "Sequence number before gremlin function: " << p.getSequenceNum() << endl;
    int pc = probCorrupt; int pl = probLoss; int pd = probDelay;
	bool* pckStatus = gremlin(&p, pc, pl, pd);

	dropPck = pckStatus[0];
	delayPck = pckStatus[1];

	if (dropPck == true) return false;
	if (delayPck == true) p.setAckNack(1);

    if(sendto(s, p.str(), BUFSIZE + 8, 0, (struct sockaddr *)&ca, sizeof(ca)) < 0) {
		cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
		return false;
    }
    return true;
}
bool isAck() {
    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {
	int ack = boost::lexical_cast<int>(b);
	if(base < ack) base = ack;
	cout << "Window base: " << base << endl;
}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}
bool* gremlin(Packet * pack, int corruptProb, int lossProb, int delayProb){

  bool* packStatus = new bool[2];
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  packStatus[0] = false;
  packStatus[1] = false;

  if(r <= (lossProb)){
	packStatus[0] = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (delayProb)){
	  packStatus[1] = true;
	  cout << "Delayed!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
	cout << "Seq. num (pre-gremlin): " << pack->getSequenceNum() << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  //cout << "Message: "  << pack->getDataBuffer() << endl;

  return packStatus;
}<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/physics.h"

// GRINS
#include "grins/bc_handling_base.h"
#include "grins/ic_handling_base.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/elem.h"

namespace GRINS
{
  // Initialize static members
  bool Physics::_is_steady = false;

  Physics::Physics( const std::string& physics_name,
		    const GetPot& input )
    : _physics_name( physics_name ),
      _bc_handler(NULL),
      _ic_handler(new ICHandlingBase(physics_name)),
      _is_axisymmetric(false)
  {
    this->read_input_options(input);

    if( input( "Physics/is_axisymmetric", false ) )
      {
        _is_axisymmetric = true;
      }

    return;
  }

  Physics::~Physics()
  {
    // If a derived class created a bc_handler object, we kill it here.
    if( _bc_handler ) delete _bc_handler;

    if( _ic_handler ) delete _ic_handler;

    return;
  }

  void Physics::read_input_options( const GetPot& input )
  {
    int num_ids = input.vector_variable_size( "Physics/"+this->_physics_name+"/enabled_subdomains" );

    for( int i = 0; i < num_ids; i++ )
      {
	libMesh::subdomain_id_type dumvar = input( "Physics/"+this->_physics_name+"/enabled_subdomains", -1, i );
	_enabled_subdomains.insert( dumvar );
      }

    return;
  }

  bool Physics::enabled_on_elem( const libMesh::Elem* elem )
  {
    // Check if enabled_subdomains flag has been set
    if( _enabled_subdomains.empty() )
      return true;

    // Check if current physics is enabled on elem
    if( _enabled_subdomains.find( elem->subdomain_id() ) == _enabled_subdomains.end() )
      return false;

    return true;
  }

  void Physics::set_is_steady( bool is_steady )
  {
    _is_steady = is_steady;
    return;
  }

  bool Physics::is_steady() const
  {
    return _is_steady;
  }

  void Physics::set_time_evolving_vars( libMesh::FEMSystem* /*system*/ )
  {
    return;
  }

  void Physics::init_bcs( libMesh::FEMSystem* system )
  {
    // Only need to init BC's if the physics actually created a handler
    if( _bc_handler )
      {
	_bc_handler->init_bc_data( *system );
	_bc_handler->init_dirichlet_bcs( system );
	_bc_handler->init_dirichlet_bc_func_objs( system );
	_bc_handler->init_periodic_bcs( system );
      }

    return;
  }

  void Physics::init_ics( libMesh::FEMSystem* system,
                          GRINS::CompositeFunction<libMesh::Number>& all_ics )
  {
    if( _ic_handler )
      {
	_ic_handler->init_ic_data( *system, all_ics );
      }

    return;
  }

  void Physics::attach_neumann_bound_func( NBCContainer& neumann_bcs )
  {
    _bc_handler->attach_neumann_bound_func( neumann_bcs );
    return;
  }

  void Physics::attach_dirichlet_bound_func( const DBCContainer& dirichlet_bc )
  {
    _bc_handler->attach_dirichlet_bound_func( dirichlet_bc );
    return;
  }

  void Physics::init_context( AssemblyContext& /*context*/ )
  {
    return;
  }

  void Physics::compute_element_time_derivative_cache( const AssemblyContext&,
						       CachedValues& )
  {
    return;
  }

  void Physics::compute_side_time_derivative_cache( const AssemblyContext& /*context*/,
						    CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_time_derivative_cache( const AssemblyContext& /*context*/,
						        CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_element_constraint_cache( const AssemblyContext& /*context*/,
						  CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_side_constraint_cache( const AssemblyContext& /*context*/,
					       CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_constraint_cache( const AssemblyContext& /*context*/,
					           CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_mass_residual_cache( const AssemblyContext& /*context*/,
					     CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_mass_residual_cache( const AssemblyContext& /*context*/,
					              CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_element_cache( const AssemblyContext&,
				       const std::vector<libMesh::Point>&,
				       CachedValues& )
  {
    return;
  }

  void Physics::element_time_derivative( bool /*compute_jacobian*/,
					 AssemblyContext& /*context*/,
					 CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::side_time_derivative( bool /*compute_jacobian*/,
				      AssemblyContext& /*context*/,
				      CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_time_derivative( bool /*compute_jacobian*/,
				          AssemblyContext& /*context*/,
				          CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::element_constraint( bool /*compute_jacobian*/,
				    AssemblyContext& /*context*/,
				    CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::side_constraint( bool /*compute_jacobian*/,
				 AssemblyContext& /*context*/,
				 CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_constraint( bool /*compute_jacobian*/,
				     AssemblyContext& /*context*/,
				     CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::mass_residual( bool /*compute_jacobian*/,
			       AssemblyContext& /*context*/,
			       CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_mass_residual( bool /*compute_jacobian*/,
			                AssemblyContext& /*context*/,
			                CachedValues& /*cache*/ )
  {
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void Physics::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    _timer = grvy_timer;
    return;
  }
#endif

} // namespace GRINS
<commit_msg>Compatibility with FEMSystem::nonlocal_stuff()<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// This class
#include "grins/physics.h"

// GRINS
#include "grins/bc_handling_base.h"
#include "grins/ic_handling_base.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/elem.h"

namespace GRINS
{
  // Initialize static members
  bool Physics::_is_steady = false;

  Physics::Physics( const std::string& physics_name,
		    const GetPot& input )
    : _physics_name( physics_name ),
      _bc_handler(NULL),
      _ic_handler(new ICHandlingBase(physics_name)),
      _is_axisymmetric(false)
  {
    this->read_input_options(input);

    if( input( "Physics/is_axisymmetric", false ) )
      {
        _is_axisymmetric = true;
      }

    return;
  }

  Physics::~Physics()
  {
    // If a derived class created a bc_handler object, we kill it here.
    if( _bc_handler ) delete _bc_handler;

    if( _ic_handler ) delete _ic_handler;

    return;
  }

  void Physics::read_input_options( const GetPot& input )
  {
    int num_ids = input.vector_variable_size( "Physics/"+this->_physics_name+"/enabled_subdomains" );

    for( int i = 0; i < num_ids; i++ )
      {
	libMesh::subdomain_id_type dumvar = input( "Physics/"+this->_physics_name+"/enabled_subdomains", -1, i );
	_enabled_subdomains.insert( dumvar );
      }

    return;
  }

  bool Physics::enabled_on_elem( const libMesh::Elem* elem )
  {
    // Check if enabled_subdomains flag has been set and if we're
    // looking at a real element (rather than a nonlocal evaluation)
    if( !elem || _enabled_subdomains.empty() )
      return true;

    // Check if current physics is enabled on elem
    if( _enabled_subdomains.find( elem->subdomain_id() ) == _enabled_subdomains.end() )
      return false;

    return true;
  }

  void Physics::set_is_steady( bool is_steady )
  {
    _is_steady = is_steady;
    return;
  }

  bool Physics::is_steady() const
  {
    return _is_steady;
  }

  void Physics::set_time_evolving_vars( libMesh::FEMSystem* /*system*/ )
  {
    return;
  }

  void Physics::init_bcs( libMesh::FEMSystem* system )
  {
    // Only need to init BC's if the physics actually created a handler
    if( _bc_handler )
      {
	_bc_handler->init_bc_data( *system );
	_bc_handler->init_dirichlet_bcs( system );
	_bc_handler->init_dirichlet_bc_func_objs( system );
	_bc_handler->init_periodic_bcs( system );
      }

    return;
  }

  void Physics::init_ics( libMesh::FEMSystem* system,
                          GRINS::CompositeFunction<libMesh::Number>& all_ics )
  {
    if( _ic_handler )
      {
	_ic_handler->init_ic_data( *system, all_ics );
      }

    return;
  }

  void Physics::attach_neumann_bound_func( NBCContainer& neumann_bcs )
  {
    _bc_handler->attach_neumann_bound_func( neumann_bcs );
    return;
  }

  void Physics::attach_dirichlet_bound_func( const DBCContainer& dirichlet_bc )
  {
    _bc_handler->attach_dirichlet_bound_func( dirichlet_bc );
    return;
  }

  void Physics::init_context( AssemblyContext& /*context*/ )
  {
    return;
  }

  void Physics::compute_element_time_derivative_cache( const AssemblyContext&,
						       CachedValues& )
  {
    return;
  }

  void Physics::compute_side_time_derivative_cache( const AssemblyContext& /*context*/,
						    CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_time_derivative_cache( const AssemblyContext& /*context*/,
						        CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_element_constraint_cache( const AssemblyContext& /*context*/,
						  CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_side_constraint_cache( const AssemblyContext& /*context*/,
					       CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_constraint_cache( const AssemblyContext& /*context*/,
					           CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_mass_residual_cache( const AssemblyContext& /*context*/,
					     CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_nonlocal_mass_residual_cache( const AssemblyContext& /*context*/,
					              CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::compute_element_cache( const AssemblyContext&,
				       const std::vector<libMesh::Point>&,
				       CachedValues& )
  {
    return;
  }

  void Physics::element_time_derivative( bool /*compute_jacobian*/,
					 AssemblyContext& /*context*/,
					 CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::side_time_derivative( bool /*compute_jacobian*/,
				      AssemblyContext& /*context*/,
				      CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_time_derivative( bool /*compute_jacobian*/,
				          AssemblyContext& /*context*/,
				          CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::element_constraint( bool /*compute_jacobian*/,
				    AssemblyContext& /*context*/,
				    CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::side_constraint( bool /*compute_jacobian*/,
				 AssemblyContext& /*context*/,
				 CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_constraint( bool /*compute_jacobian*/,
				     AssemblyContext& /*context*/,
				     CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::mass_residual( bool /*compute_jacobian*/,
			       AssemblyContext& /*context*/,
			       CachedValues& /*cache*/ )
  {
    return;
  }

  void Physics::nonlocal_mass_residual( bool /*compute_jacobian*/,
			                AssemblyContext& /*context*/,
			                CachedValues& /*cache*/ )
  {
    return;
  }

#ifdef GRINS_USE_GRVY_TIMERS
  void Physics::attach_grvy_timer( GRVY::GRVY_Timer_Class* grvy_timer )
  {
    _timer = grvy_timer;
    return;
  }
#endif

} // namespace GRINS
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file shhrpc.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <test/TestHelper.h>
#include <test/libweb3jsonrpc/webthreestubclient.h>
#include <libethcore/KeyManager.h>
#include <libp2p/Common.h>
#include <libwhisper/WhisperHost.h>

using namespace std;
using namespace dev;
using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;

WebThreeDirect* web3;
unique_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<WebThreeStubClient> jsonrpcClient;
static uint16_t const web3port = 30333;

struct Setup
{
	Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = true;

		static bool setup = false;
		if (!setup)
		{
			setup = true;
			NetworkPreferences nprefs(std::string(), web3port, false);
			web3 = new WebThreeDirect("shhrpc-web3", "", WithExisting::Trust, {"eth", "shh"}, nprefs);
			web3->setIdealPeerCount(1);
			web3->ethereum()->setForceMining(false);
			auto server = new jsonrpc::HttpServer(8080);
			vector<KeyPair> v;
			KeyManager keyMan;
			TrivialGasPricer gp;
			jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(*server, *web3, nullptr, v, keyMan, gp));
			jsonrpcServer->setIdentities({});
			jsonrpcServer->StartListening();
			auto client = new jsonrpc::HttpClient("http://localhost:8080");
			jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(*client));
		}
	}

	~Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = false;
	}
};

BOOST_FIXTURE_TEST_SUITE(shhrpc, Setup)

BOOST_AUTO_TEST_CASE(basic)
{
	cnote << "Testing web3 basic functionality...";

	web3->startNetwork();
	unsigned const step = 10;
	for (unsigned i = 0; i < 3000 && !web3->haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(web3->haveNetwork());

	uint16_t const port2 = 30334;
	NetworkPreferences prefs2("127.0.0.1", port2, false);
	string const version2 = "shhrpc-host2";
	Host host2(version2, prefs2);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();

	for (unsigned i = 0; i < 3000 && !host2.haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());

	web3->addNode(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	vector<PeerSessionInfo> vpeers = web3->peers();
	BOOST_REQUIRE(!vpeers.empty());
	PeerSessionInfo const& peer = vpeers.back();
	BOOST_REQUIRE_EQUAL(peer.id, host2.id());
	BOOST_REQUIRE_EQUAL(peer.port, port2);
	BOOST_REQUIRE_EQUAL(peer.clientVersion, version2);

	web3->stopNetwork();

	for (unsigned i = 0; i < 3000 && (web3->haveNetwork() || host2.haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(!web3->peerCount());
	BOOST_REQUIRE(!host2.peerCount());
}

BOOST_AUTO_TEST_CASE(send)
{
	cnote << "Testing web3 send...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 10;
	unsigned const step = 10;
	uint16_t port2 = 30337;

	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = whost2->installWatch(BuildTopicMask("odd"));
		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: whost2->checkWatch(w))
			{
				Message msg = whost2->envelope(i).open(whost2->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	web3->requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (unsigned i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	auto messages = web3->whisper()->all();
	BOOST_REQUIRE_EQUAL(messages.size(), messageCount);

	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
}

BOOST_AUTO_TEST_CASE(receive)
{
	cnote << "Testing web3 receive...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 6;
	unsigned const step = 10;
	uint16_t port2 = 30338;
	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = web3->whisper()->installWatch(BuildTopicMask("odd"));

		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: web3->whisper()->checkWatch(w))
			{
				Message msg = web3->whisper()->envelope(i).open(web3->whisper()->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	host2.addNode(web3->id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), web3port, web3port));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (unsigned i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 27 + 125);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>small bugfix<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file shhrpc.cpp
* @author Vladislav Gluhovsky <vlad@ethdev.com>
* @date July 2015
*/

#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonJS.h>
#include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <test/TestHelper.h>
#include <test/libweb3jsonrpc/webthreestubclient.h>
#include <libethcore/KeyManager.h>
#include <libp2p/Common.h>
#include <libwhisper/WhisperHost.h>

using namespace std;
using namespace dev;
using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;

WebThreeDirect* web3;
unique_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<WebThreeStubClient> jsonrpcClient;
static uint16_t const web3port = 30333;

struct Setup
{
	Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = true;

		static bool setup = false;
		if (!setup)
		{
			setup = true;
			NetworkPreferences nprefs(std::string(), web3port, false);
			web3 = new WebThreeDirect("shhrpc-web3", "", WithExisting::Trust, {"eth", "shh"}, nprefs);
			web3->setIdealPeerCount(1);
			web3->ethereum()->setForceMining(false);
			auto server = new jsonrpc::HttpServer(8080);
			vector<KeyPair> v;
			KeyManager keyMan;
			TrivialGasPricer gp;
			jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(*server, *web3, nullptr, v, keyMan, gp));
			jsonrpcServer->setIdentities({});
			jsonrpcServer->StartListening();
			auto client = new jsonrpc::HttpClient("http://localhost:8080");
			jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(*client));
		}
	}

	~Setup()
	{
		dev::p2p::NodeIPEndpoint::test_allowLocal = false;
	}
};

BOOST_FIXTURE_TEST_SUITE(shhrpc, Setup)

BOOST_AUTO_TEST_CASE(basic)
{
	cnote << "Testing web3 basic functionality...";

	web3->startNetwork();
	unsigned const step = 10;
	for (unsigned i = 0; i < 3000 && !web3->haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(web3->haveNetwork());

	uint16_t const port2 = 30334;
	NetworkPreferences prefs2("127.0.0.1", port2, false);
	string const version2 = "shhrpc-host2";
	Host host2(version2, prefs2);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();

	for (unsigned i = 0; i < 3000 && !host2.haveNetwork(); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());

	web3->addNode(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	vector<PeerSessionInfo> vpeers = web3->peers();
	BOOST_REQUIRE(!vpeers.empty());
	PeerSessionInfo const& peer = vpeers.back();
	BOOST_REQUIRE_EQUAL(peer.id, host2.id());
	BOOST_REQUIRE_EQUAL(peer.port, port2);
	BOOST_REQUIRE_EQUAL(peer.clientVersion, version2);

	web3->stopNetwork();

	for (unsigned i = 0; i < 3000 && (web3->haveNetwork() || host2.haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(!web3->peerCount());
	BOOST_REQUIRE(!host2.peerCount());
}

BOOST_AUTO_TEST_CASE(send)
{
	cnote << "Testing web3 send...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 10;
	unsigned const step = 10;
	uint16_t port2 = 30337;

	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = whost2->installWatch(BuildTopicMask("odd"));
		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: whost2->checkWatch(w))
			{
				Message msg = whost2->envelope(i).open(whost2->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || !web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	web3->requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), port2, port2));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (unsigned i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	auto messages = web3->whisper()->all();
	BOOST_REQUIRE_EQUAL(messages.size(), messageCount);

	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81);
}

BOOST_AUTO_TEST_CASE(receive)
{
	cnote << "Testing web3 receive...";

	bool sent = false;
	bool ready = false;
	unsigned result = 0;
	unsigned const messageCount = 6;
	unsigned const step = 10;
	uint16_t port2 = 30338;
	Host host2("shhrpc-host2", NetworkPreferences("127.0.0.1", port2, false));
	host2.setIdealPeerCount(1);
	auto whost2 = host2.registerCapability(new WhisperHost());
	host2.start();
	web3->startNetwork();

	std::thread listener([&]()
	{
		setThreadName("listener");
		ready = true;
		auto w = web3->whisper()->installWatch(BuildTopicMask("odd"));

		set<unsigned> received;
		for (unsigned x = 0; x < 9000 && !sent; x += step)
			this_thread::sleep_for(chrono::milliseconds(step));

		for (unsigned x = 0, last = 0; x < 100 && received.size() < messageCount; ++x)
		{
			this_thread::sleep_for(chrono::milliseconds(50));
			for (auto i: web3->whisper()->checkWatch(w))
			{
				Message msg = web3->whisper()->envelope(i).open(web3->whisper()->fullTopics(w));
				last = RLP(msg.payload()).toInt<unsigned>();
				if (received.insert(last).second)
					result += last;
			}
		}
	});

	for (unsigned i = 0; i < 2000 && (!host2.haveNetwork() || !web3->haveNetwork()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE(host2.haveNetwork());
	BOOST_REQUIRE(web3->haveNetwork());

	host2.addNode(web3->id(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), web3port, web3port));

	for (unsigned i = 0; i < 3000 && (!web3->peerCount() || !host2.peerCount()); i += step)
		this_thread::sleep_for(chrono::milliseconds(step));

	BOOST_REQUIRE_EQUAL(host2.peerCount(), 1);
	BOOST_REQUIRE_EQUAL(web3->peerCount(), 1);

	KeyPair us = KeyPair::create();
	for (unsigned i = 0; i < messageCount; ++i)
	{
		web3->whisper()->post(us.sec(), RLPStream().append(i * i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even"), 777000, 1);
		this_thread::sleep_for(chrono::milliseconds(50));
	}

	sent = true;
	listener.join();
	BOOST_REQUIRE_EQUAL(result, 1 + 27 + 125);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>