Exemple #1
0
int peisk_recvBlocking(int fd,void *buf,size_t len,int flags,double timeout) {
  int i, new_bytes;
  char *data=(char*)buf;
  double t0 = peisk_gettimef();

  while(len>0) {
    errno=0;
    new_bytes=recv(fd,data,len,flags|MSG_NOSIGNAL);
    if(errno == EPIPE || new_bytes == 0) {
      /* Broken pipe - close socket and return */
      for(i=0;i<PEISK_MAX_CONNECTIONS;i++) {
	if(peisk_printLevel & PEISK_PRINT_CONNECTIONS)
	  printf("Connection %d socket=%d\n",i,peiskernel.connections[i].connection.tcp.socket);
	if(peiskernel.connections[i].id != -1 && peiskernel.connections[i].connection.tcp.socket == fd)
	  peisk_closeConnection(peiskernel.connections[i].id);
      }
      /*printf("<\n"); fflush(stdout); */
      return 0;
    }
    if(new_bytes == -1) peisk_waitForRead(fd,0.01); /* was: usleep 0 */
    else {
      if(new_bytes == 0) if(peisk_printLevel & PEISK_PRINT_CONNECTIONS)  printf("peisk: error - not getting any bytes, broken connection?\n");
      len -= new_bytes;
      data+=new_bytes;
    }
    if(peisk_gettimef() > t0 + timeout) { /*printf("< (TIME)\n"); fflush(stdout);*/ return 0; } /* Timeout reached */
  }
  return 1;
}
Exemple #2
0
int peisk_bluetoothReceiveIncomming(struct PeisConnection *connection,struct PeisPackage *package) {
  int status;
  double t0, t1;

  static float lastReceive=0.0; /* For debugging only */

  errno=0;
  t0 = peisk_gettimef();
  status=recv(connection->connection.bluetooth.socket,(void*)package,sizeof(PeisPackage),MSG_NOSIGNAL);
  t1 = peisk_gettimef();
  if(t1 - t0 > 0.1) {
    printf("Receive took %.3fs\n",t1-t0);
  }
  if(errno == EAGAIN || status == 0) return 0;       /* Nothing received, come back later */

  if(status > 0) {
    peisk_logTimeStamp(stdout);
    printf("BT receive: %d bytes, sock: %d ",status,connection->connection.bluetooth.socket);
    /*peisk_hexDump(package,status);*/
    peisk_printNetPackageInfo(package);
    lastReceive = peisk_timeNow;
  }

  if(errno == EPIPE || status == -1) {          /* Error - close socket */
    if(1 || peisk_printLevel & PEISK_PRINT_CONNECTIONS) {
      peisk_logTimeStamp(stdout);
      printf("peisk: warning - error EPIPE in BT receive, closing socket status: %d\n",status);
      perror("");
      printf("Time since last read: %.1fs\n",peisk_timeNow - lastReceive);
    }
    peisk_closeConnection(connection->id);
    return 0;
  }
  if(status < sizeof(package->header)) {
    /* For L2CAP it is an error to not receive the full data in each
       recv operation. */
    fprintf(stderr,"Warning, only got partial data on BT connection\n");
    peisk_closeConnection(connection->id);
    return 0;
  }
  if(ntohs(package->header.datalen) > PEISK_MAX_PACKAGE_SIZE) { /* Check for bad package length */
    if(1 || peisk_printLevel & PEISK_PRINT_CONNECTIONS)
      fprintf(stdout,"peisk: error, too large (%d) package received on BT connection %d\n",package->header.datalen,connection->id);
    /*peisk_syncflush(connection);*/
    peisk_closeConnection(connection->id);
    return 0;
  }
  return 1;
}
Exemple #3
0
void peisk_bluetoothConnectOutgoing() {
  int i;
  PeisBluetoothAdaptor *adaptor;
  int status=0;

  for(i=0;i<peisk_nBluetoothAdaptors;i++) {
    adaptor = &peisk_bluetoothAdaptors[i];
    if(adaptor->outgoing.mode == 0) continue;
    if(adaptor->outgoing.mode == 1) {
      /* See if connect() have finished */
      struct pollfd fds;
      fds.fd = adaptor->outgoing.socket;
      fds.events = -1;
      fds.revents = 0;
      if(poll(&fds,1,0)) {
	socklen_t slen;
	slen=sizeof(status);
	if(getsockopt(adaptor->outgoing.socket,SOL_SOCKET,SO_ERROR,(void*) &status,&slen)) {
	  printf("Get sockopt failed...\n");
	}
	printf("Connection finished: status=0x%x (time elapsed: %.3fs)\n",status,
	       peisk_gettimef()-adaptor->outgoing.timeout+PEISK_CONNECT_TIMEOUT);
	if(status) {
	  printf("Outgoing connection failed: "); perror(""); printf("\n");
	  peisk_abortConnect(adaptor->outgoing.connection);
	  close(adaptor->outgoing.socket);
	  adaptor->outgoing.mode = 0;
	} else {
	  adaptor->outgoing.connection->type=eBluetoothConnection;
	  adaptor->outgoing.connection->connection.bluetooth.adaptor=adaptor;
	  adaptor->outgoing.connection->connection.bluetooth.socket=adaptor->outgoing.socket;

	  printf("Outgoing connection %x has id %d\n",
		 (unsigned int)  adaptor->outgoing.connection,adaptor->outgoing.connection->id);

	  PeisConnectMessage message;
	  peisk_initConnectMessage(&message,adaptor->outgoing.flags);
	  printf("Sending connection message:\n"); peisk_hexDump(&message,sizeof(message)); printf("\n");
	  send(adaptor->outgoing.socket,&message,sizeof(message),MSG_NOSIGNAL);
	  peisk_outgoingConnectFinished(adaptor->outgoing.connection,adaptor->outgoing.flags);

	  if(1 || peisk_printLevel & PEISK_PRINT_CONNECTIONS)
	    fprintf(stdout,"peisk: new outbound BLUETOOTH connection established\n");

	  adaptor->outgoing.mode = 0;
	}
      }
    }
    if(adaptor->outgoing.timeout < peisk_timeNow &&
       adaptor->outgoing.mode != 0) {
      printf("Giving up on outgoing CONNECT\n");
      peisk_abortConnect(adaptor->outgoing.connection);
      close(adaptor->outgoing.socket);
      adaptor->outgoing.mode = 0;
    }
  }
}
Exemple #4
0
void peisk_registerPeriodicWithName(double period,void *data,PeisPeriodic *hook,char *name) {
    int i;
    for(i=0;i<PEISK_MAX_PERIODICS;i++) if(peiskernel.periodics[i].periodicity == -1.0) break;
    if(i == PEISK_MAX_PERIODICS) {
        fprintf(stderr,"peisk: error, too many periodic functions registered\n");
        exit(0);
    }
    peiskernel.periodics[i].periodicity = period;
    peiskernel.periodics[i].data = data;
    peiskernel.periodics[i].hook = hook;
    peiskernel.periodics[i].last = peisk_gettimef();
    peiskernel.periodics[i].name = name;
    if(i > peiskernel.highestPeriodic) peiskernel.highestPeriodic = i;
}
Exemple #5
0
void peisk_wait(int useconds) {
    double t0=peisk_gettimef()+1e-6*useconds;
    fd_set readSet, writeSet, excpSet;
    int n=0;
    int ret;

#ifdef GUMSTIX
    struct timeval timeout;
#else
    struct timespec timeout;
#endif

    double offset=peiskernel.timeOffset[0] + 1e-6*peiskernel.timeOffset[1];
    double offset2;

    peisk_step();
    while(peisk_int_isRunning)  {

        /* Compensate if kernel clock has changed */
        offset2=peiskernel.timeOffset[0]+1e-6*peiskernel.timeOffset[1];
        if(fabs(offset2 - offset) > 0.1) {
            /*printf("adjusting time to sleep to with %f secs\n",offset2-offset);*/
            t0 += offset2-offset; offset=offset2;
        }

        timeout.tv_sec = 0;
#ifdef GUMSTIX
        timeout.tv_usec = MIN((int)1e4,
                  (int)(1e6 * fmod((t0 - peisk_gettimef()),1.0)));
        if(timeout.tv_usec <= 0) break;
#else
        timeout.tv_nsec = MIN((int)1e7,
                              (int)(1e9 * fmod((t0 - peisk_gettimef()),1.0)));
        if(timeout.tv_nsec <= 0) break;
#endif

        FD_ZERO(&readSet);
        FD_ZERO(&writeSet);
        FD_ZERO(&excpSet);
        n=0;

        if(peiskernel.avgStepTime < 0.005) {
            /* Perform a forced sleep if we are running to quickly to
           compensate for the pselect bug */

        } else {
            /* Perform a normal sleep for 10ms or until we have new data
           available */
            peisk_setSelectReadSignals(&n,&readSet,&writeSet,&excpSet);
        }

        errno=0;
#ifdef GUMSTIX
        ret=select(n,&readSet,&writeSet,&excpSet,&timeout);
#else
        ret=pselect(n,&readSet,&writeSet,&excpSet,&timeout,NULL);
#endif

        if(ret == -1) perror("peisk_wait::select");

        /*
          double t1=peisk_gettimef();
          if(t1 - t0 < 0.0001) {
          printf("sleep: %3.6f nsec=%d ret=%d ",t1-t0,timeout.tv_nsec,ret);
          int i;
          printf("FD: ");
          for(i=0;i<n;i++) {
          if(FD_ISSET(i,&readSet)) printf("r%d ",i);
          if(FD_ISSET(i,&writeSet)) printf("w%d ",i);
          if(FD_ISSET(i,&excpSet)) printf("e%d ",i);
          }
          printf("\n"); fflush(stdout);
          }*/

        peisk_step();
    }
}
Exemple #6
0
void peisk_initialize(int *argc,char **args) {

    int i, j;
    char name[256];
    char *hostname, *progname;
    unsigned char *ip;
    char tmp[256];
    int t0,t1;
    PeisConnectionMgrInfo *connMgrInfo;

    if(peisk_int_isRunning)
        peisk_shutdown();

    peisk_getrawtime2(&t0,&t1);

    srand((int) t1);

    peiskernel.id = rand() % 10000;
    peiskernel.tcp_serverPort=8000;
    peiskernel.udp_serverPort=8000;
    peiskernel.tcp_isListening=0;
    peiskernel.lastStep = peisk_gettimef();
    peiskernel.nextConnectionId = 1;
    peisk_printLevel = 0;
    peiskernel.highestPeriodic=0;
    peiskernel.highestConnection=0;
    hostname = NULL;
    peiskernel.isLeaf=0;
    peiskernel.timeOffset[0]=0;
    peiskernel.timeOffset[1]=0;
    peiskernel.isTimeMaster=0;
    peiskernel.avgStepTime=0.1;
    peiskernel.incomingTraffic=0;
    peiskernel.outgoingTraffic=0;
    peiskernel.nAcknowledgementPackages=0;
    peiskernel.deadhostHook = NULL;
    peiskernel.nAckHooks = 0;
    peiskernel.tick = 0;
    peiskernel.broadcastingCounter = 0;

    peisk_cl_user = getenv("USER");
    if(!peisk_cl_user) peisk_cl_user = "******";

    signal(SIGINT, peisk_trapCtrlC);
    signal(SIGTERM, peisk_trapCtrlC);
    signal(SIGPIPE, peisk_trapPipe);

    peiskernel_initNetInterfaces();

    for(i=0;i<PEISK_MAX_CONNECTIONS;i++) {
        peiskernel.connections[i].id=-1;
        peiskernel.connections[i].routingTable = NULL;
        for(j=0;j<PEISK_MAX_ROUTING_PAGES;j++)
            peiskernel.connections[i].routingPages[j] = NULL;
    }

    peiskernel.freeQueuedPackages=NULL;
    peiskernel.nDirConnReqs=0;

    peiskernel.doShutdown=0;

    for(i=0;i<PEISK_NPORTS;i++) peiskernel.hooks[i]=NULL;

    for(i=0;i<PEISK_MAX_PERIODICS;i++) peiskernel.periodics[i].periodicity=-1.0;

    for(i=0;i<PEISK_MAX_LONG_MESSAGES;i++) {
        peiskernel.assemblyBuffers[i].seqid = 0;
        peiskernel.assemblyBuffers[i].seqlen = 0;
        peiskernel.assemblyBuffers[i].allocated_seqlen = 0;
        peiskernel.assemblyBuffers[i].received = NULL;
        peiskernel.assemblyBuffers[i].data = NULL;
    }

    peiskernel.routingTable = peisk_hashTable_create(PeisHashTableKey_Integer);

    if(peiskernel.routingTable == NULL) {
        fprintf(stderr,"peisk: error, failed to create routing table\n");
        exit(-1);
    }

    for(i=0;i<PEISK_LOOPINFO_HASH_SIZE;i++) peiskernel.loopHashTable[i]=-1;
    for(i=0;i<PEISK_LOOPINFO_SIZE;i++) peiskernel.loopTable[i].id=-1;


    peisk_initBluetooth();
    peisk_initP2PLayer();
    peisk_registerDefaultServices();

    //peisk_getOptions(argc,args);

    peisk_parseOptions(NULL,"command-line");

    peisk_restartServer();

    if(peiskernel.tcp_isListening)
    if(peisk_printLevel & PEISK_PRINT_STATUS)
        printf("peisk: serving at port %d\n",peiskernel.tcp_serverPort);
    peisk_id = peiskernel.id;
    peiskernel.magicId = rand();

    peisk_registerDefaultServices2();

    hostname=peisk_cl_hostname;
    if(!hostname) hostname=getenv("HOSTNAME");
    if(!hostname) {
        FILE *fp = fopen("/etc/hostname","r");
        if(!fp) fp = fopen("/etc/HOSTNAME","r");
        if(!fp) { if(system("hostname > /tmp/peisk_cl_hostname")!=-1) fp = fopen("/tmp/peisk_cl_hostname","r"); }
        if(fp) {
            if(!fgets(name,255,fp)) sprintf(name,"johndoe");
            fclose(fp);
            for(i=0;i<255&&name[i];i++) if(name[i]=='\n' || name[i]==' ' || name[i] == '.') name[i]=0;
            hostname=strdup(name);
        }
        else {
            char name[256];
            sprintf(name,"johndoe-%d",peisk_id / 100);
            hostname=strdup(name);
        }
    }

    for(i=0;i<255;i++) {
        if(hostname[i] == 0 || hostname[i] == '.' || hostname[i] == ' ') break;
        else name[i] = hostname[i];
    }
    name[i]=0;

    if(peisk_cl_componentName)
        progname=peisk_cl_componentName;
    else {
        for(progname = args[0]+strlen(args[0]);progname>=args[0]&&*progname!='/';progname--) {} progname++;
    }

    peiskernel.hostInfo.id = peiskernel.id;
    peiskernel.hostInfo.magic = peiskernel.magicId;
    peiskernel.hostInfo.networkCluster = peiskernel.id;

    int mypid = getpid();

    snprintf(peiskernel.hostInfo.fullname,sizeof(peiskernel.hostInfo.fullname),"%s@%s!%d",progname,name,mypid);

    snprintf(peiskernel.hostInfo.hostname,sizeof(peiskernel.hostInfo.hostname),"%s",name);

    peisk_setStringTuple("kernel.hostname",peiskernel.hostInfo.hostname);

    snprintf(tmp,sizeof(tmp),"v%lf (proto %d)",1.0,peisk_protocollVersion);

    peisk_setStringTuple("kernel.version",tmp);
    peisk_setStringTuple("kernel.name",progname);
    peisk_setStringTuple("kernel.do-quit","");
    peisk_setStringTuple("kernel.user",peisk_cl_user);
    snprintf(tmp,sizeof(tmp),"%d",peiskernel.id);
    peisk_setStringTuple("kernel.id",tmp);


    if(peisk_printLevel & PEISK_PRINT_STATUS)
        printf("peisk #%d: started\n",peisk_id);

    peiskernel.hostInfo.nLowlevelAddresses=0;

    if(peiskernel.tcp_isListening) {

        for(i=0,j=peiskernel.hostInfo.nLowlevelAddresses;i<peisk_nInetInterfaces;i++) {

            if(peiskernel.isLeaf && !peisk_inetInterface[i].isLoopback) continue;

            if(peiskernel.udp_serverPort != 0  && 0) {
                peiskernel.hostInfo.lowAddr[j].type = ePeisUdpIPv4;
                ip = (unsigned char *)&peisk_inetInterface[i].ip;
                peiskernel.hostInfo.lowAddr[j].addr.udpIPv4.ip[0]=ip[0];
                peiskernel.hostInfo.lowAddr[j].addr.udpIPv4.ip[1]=ip[1];
                peiskernel.hostInfo.lowAddr[j].addr.udpIPv4.ip[2]=ip[2];
                peiskernel.hostInfo.lowAddr[j].addr.udpIPv4.ip[3]=ip[3];
                peiskernel.hostInfo.lowAddr[j].addr.udpIPv4.port=peiskernel.udp_serverPort;
            } else {
                peiskernel.hostInfo.lowAddr[j].type = ePeisTcpIPv4;
                ip = (unsigned char *)&peisk_inetInterface[i].ip;
                peiskernel.hostInfo.lowAddr[j].addr.tcpIPv4.ip[0]=ip[0];
                peiskernel.hostInfo.lowAddr[j].addr.tcpIPv4.ip[1]=ip[1];
                peiskernel.hostInfo.lowAddr[j].addr.tcpIPv4.ip[2]=ip[2];
                peiskernel.hostInfo.lowAddr[j].addr.tcpIPv4.ip[3]=ip[3];
                peiskernel.hostInfo.lowAddr[j].addr.tcpIPv4.port=peiskernel.tcp_serverPort;
            }
            strncpy(peiskernel.hostInfo.lowAddr[j].deviceName,peisk_inetInterface[i].name,sizeof(peiskernel.hostInfo.lowAddr[i].deviceName));
            peiskernel.hostInfo.lowAddr[j].isLoopback = peisk_inetInterface[i].isLoopback ? 1 : 0;
            j++;
        }
        peiskernel.hostInfo.nLowlevelAddresses=j;
    }

    peisk_addBluetoothLowlevelAddresses();

    peiskernel.hostInfoHT = peisk_hashTable_create(PeisHashTableKey_Integer);
    peiskernel.connectionMgrInfoHT = peisk_hashTable_create(PeisHashTableKey_Integer);

    peisk_insertHostInfo(peiskernel.id,&peiskernel.hostInfo);
    connMgrInfo = (PeisConnectionMgrInfo*) malloc(sizeof(PeisConnectionMgrInfo));
    peisk_insertConnectionMgrInfo(peiskernel.id,connMgrInfo);
    connMgrInfo->nTries = 0;
    connMgrInfo->nextRetry = peisk_timeNow;
    connMgrInfo->usefullTraffic=0;
    connMgrInfo->lastUsefullTraffic=0;

    printf("PeisKernel v%lf (protocoll %d)@%s %s ",1.0,peisk_protocollVersion,__DATE__,__TIME__);

    peisk_printHostInfo(&peiskernel.hostInfo);

    peisk_int_isRunning=1;

    PeisRoutingInfo *routingInfo;

    if(peisk_hashTable_getValue(peiskernel.routingTable,(void*)(intA)peiskernel.id,(void**)(void*)&routingInfo) == 0) {
        PEISK_ASSERT(routingInfo->connection == NULL,("Route to ourselves points to nonzero connection\n"));
    }
}
Exemple #7
0
void peisk_logTimeStamp(FILE *stream) {
    fprintf(stream,"%3.2f ",fmod(peisk_gettimef(),1000));
}