<commit_before>#include <iostream>                                         /* allows to perform standard input and output operations */
#include <fstream>
#include <stdio.h>                                          /* Standard input/output definitions */
#include <stdint.h>                                         /* Standard input/output definitions */
#include <stdlib.h>                                         /* defines several general purpose functions */
#include <unistd.h>                                         /* UNIX standard function definitions */
#include <fcntl.h>                                          /* File control definitions */
#include <errno.h>                                          /* Error number definitions */
#include <termios.h>                                        /* POSIX terminal control definitions */
#include <ctype.h>                                        /* isxxx() */

const char* serialport="/dev/ttyAMA0";                      /* defines used serialport */
int serialport_bps=B38400;                                  /* defines baudrate od serialport */
int32_t EncoderL;                                           /* stores encoder value left read from md49 */
int32_t EncoderR;                                           /* stores encoder value right read from md49 */
unsigned char speed_l=128, speed_r=128;                               /* speed to set for MD49 */

int filedesc;                                               // File descriptor of serial port we will talk to
int fd;                                                     /* serial port file descriptor */
unsigned char serialBuffer[16];                             /* Serial buffer to store uart data */
struct termios orig;                                        // Port options

using namespace std;

int openSerialPort(const char * device, int bps);
void writeBytes(int descriptor, int count);
void readBytes(int descriptor, int count);
void read_MD49_Data (void);
void set_MD49_speed (unsigned char speed_l, unsigned char speed_r);
char* itoa(int value, char* result, int base);
unsigned char md49_data[18];

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

    // Open serial port
    // ****************
    filedesc = openSerialPort("/dev/ttyAMA0", serialport_bps);
    if (filedesc == -1) exit(1);
    usleep(10000);                                      // Sleep for UART to power up and set options

    while( 1 )
    {

        // Read encoder and other data from MD49
        // and put into sqlite db
        // *************************************
        read_MD49_Data();
        usleep(50000);

        // Read commands from sqlite db and
        // set speed and other commands to MD49
        // ************************************
        string line;
        ifstream myfile ("md49_commands.txt");
        if (myfile.is_open())
        {
            int i=0;
            while ( getline (myfile,line) )
            {
                //cout << line << '\n';
                char data[10];
                std::copy(line.begin(), line.end(), data);
                md49_data[i]=atoi(data);
                i =i++;
            }
            myfile.close();
            speed_l=md49_data[0];
            speed_r=md49_data[1];
        }
        else cout << "Unable to open file";
        set_MD49_speed(speed_l, speed_r);
        usleep(50000);

    }// end.mainloop

    return 1;
} // end.main

int openSerialPort(const char * device, int bps){
   struct termios neu;
   char buf[128];

   //fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
   fd = open(device, O_RDWR | O_NOCTTY);

   if (fd == -1)
   {
      sprintf(buf, "openSerialPort %s error", device);
      perror(buf);
   }
   else
   {
      tcgetattr(fd, &orig); 						/* save current serial settings */
      tcgetattr(fd, &neu);
      cfmakeraw(&neu);
      //fprintf(stderr, "speed=%d\n", bps);
      cfsetispeed(&neu, bps);
      cfsetospeed(&neu, bps);
      tcflush(fd, TCIFLUSH);
      tcsetattr(fd, TCSANOW, &neu); 				/* set new serial settings */
      fcntl (fd, F_SETFL, O_RDWR);
   }
   return fd;
}

void writeBytes(int descriptor, int count) {
    if ((write(descriptor, serialBuffer, count)) == -1) {	// Send data out
        perror("Error writing");
        close(descriptor);				// Close port if there is an error
        exit(1);
    }

}

void readBytes(int descriptor, int count) {
    if (read(descriptor, serialBuffer, count) == -1) {	// Read back data into buf[]
        perror("Error reading ");
        close(descriptor);				// Close port if there is an error
        exit(1);
    }
}

void read_MD49_Data (void){
    serialBuffer[0] = 82;							// 82=R Steuerbyte um alle Daten vom MD49 zu lesen
    writeBytes(fd, 1);
    //Daten lesen und in Array schreiben
    readBytes(fd, 18);

    ofstream myfile;
    myfile.open ("md49_data.txt");
    //myfile << "Writing this to a file.\n";
    char buffer[33];

    EncoderL = serialBuffer[0] << 24;                        // Put together first encoder value
    EncoderL |= (serialBuffer[1] << 16);
    EncoderL |= (serialBuffer[2] << 8);
    EncoderL |= (serialBuffer[3]);
    EncoderR = serialBuffer[4] << 24;                        // Put together second encoder value
    EncoderR |= (serialBuffer[5] << 16);
    EncoderR |= (serialBuffer[6] << 8);
    EncoderR |= (serialBuffer[7]);

    int i=0;

    for (i=0;i<18;i++){
        if (serialBuffer[i]==0){
            myfile << "000";
        }
        else if (serialBuffer[i]<10){
            myfile << "00";
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        else if (serialBuffer[i]<100){
            myfile << "0";
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        else{
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        myfile << "\n";
    }

    printf("\033[2J");        /*  clear the screen  */
    printf("\033[H");         /*  position cursor at top-left corner */
    printf ("MD49-Data read from AVR-Master: \n");
    printf("====================================================== \n");
    printf("Encoder1 Byte1: %i ",serialBuffer[0]);
    printf("Byte2: %i ",serialBuffer[1]);
    printf("Byte3: % i ",serialBuffer[2]);
    printf("Byte4: %i \n",serialBuffer[3]);
    printf("Encoder2 Byte1: %i ",serialBuffer[4]);
    printf("Byte2: %i ",serialBuffer[5]);
    printf("Byte3: %i ",serialBuffer[6]);
    printf("Byte4: %i \n",serialBuffer[7]);
    printf("EncoderL: %i ",EncoderL);
    printf("EncoderR: %i \n",EncoderR);
    printf("====================================================== \n");
    printf("Speed1: %i ",serialBuffer[8]);
    printf("Speed2: %i \n",serialBuffer[9]);
    printf("Volts: %i \n",serialBuffer[10]);
    printf("Current1: %i ",serialBuffer[11]);
    printf("Current2: %i \n",serialBuffer[12]);
    printf("Error: %i \n",serialBuffer[13]);
    printf("Acceleration: %i \n",serialBuffer[14]);
    printf("Mode: %i \n",serialBuffer[15]);
    printf("Regulator: %i \n",serialBuffer[16]);
    printf("Timeout: %i \n",serialBuffer[17]);
    printf("speed_l = %i \n",speed_l);
    printf("speed_r = %i \n",speed_r);

    myfile.close();
}

void set_MD49_speed (unsigned char speed_l, unsigned char speed_r){
    serialBuffer[0] = 88;					// 88 =X Steuerbyte um Commands an MD49 zu senden
    serialBuffer[1] = 115;					// 115=s Steuerbyte setSpeed
    serialBuffer[2] = speed_l;				// speed1
    serialBuffer[3] = speed_r;				// speed2
    writeBytes(fd, 4);
}

char* itoa(int value, char* result, int base) {
        // check that the base if valid
        if (base < 2 || base > 36) { *result = '\0'; return result; }

        char* ptr = result, *ptr1 = result, tmp_char;
        int tmp_value;

        do {
            tmp_value = value;
            value /= base;
            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
        } while ( value );

        // Apply negative sign
        if (tmp_value < 0) *ptr++ = '-';
        *ptr-- = '\0';
        while(ptr1 < ptr) {
            tmp_char = *ptr;
            *ptr--= *ptr1;
            *ptr1++ = tmp_char;
        }
        return result;
    }
<commit_msg>Update code<commit_after>/*! \brief serial_controller_node.
 *         Manages serial communications with AVR-Master.
 *
 *  This node manages serial communications with the AVR-Master.
 *  Therefore it first requests all data from AVR-Master and then sends all
 *  commands to AVR-Master in a Loop. Data read is stored in md49_data.txt,
 *  commands to be send are read from md49_commands.txt.
 *
 */

// Includes
// *********************************************************
#include <iostream>                                         /* allows to perform standard input and output operations */
#include <fstream>                                          /* Input/output stream class to operate on files. */
#include <stdio.h>                                          /* Standard input/output definitions */
#include <stdint.h>                                         /* Standard input/output definitions */
#include <stdlib.h>                                         /* defines several general purpose functions */
#include <unistd.h>                                         /* UNIX standard function definitions */
#include <fcntl.h>                                          /* File control definitions */
#include <errno.h>                                          /* Error number definitions */
#include <termios.h>                                        /* POSIX terminal control definitions */
#include <ctype.h>                                          /* isxxx() */

// Global variables
const char* serialport="/dev/ttyAMA0";                      /* defines used serialport */
int serialport_bps=B38400;                                  /* defines used baudrate on serialport */
//int filedesc;                                               // File descriptor of serial port we will talk to
int fd;                                                     /* serial port file descriptor */
int32_t EncoderL;                                           /* stores encoder value left read from md49 */
int32_t EncoderR;                                           /* stores encoder value right read from md49 */
unsigned char speed_l=128, speed_r=128;                     /* speed to set for MD49 */
unsigned char serialBuffer[16];                             /* Serial buffer to store uart data */
unsigned char md49_data[18];                                /* keeps data from MD49, read from AVR-Master */
struct termios orig;                                        // Port options

using namespace std;

// Declare functions
// *********************************************************
int openSerialPort(const char * device, int bps);
void writeBytes(int descriptor, int count);
void readBytes(int descriptor, int count);
void read_MD49_Data_serial (void);
void read_md49_commands_txt(void);
void set_MD49_speed (unsigned char speed_l, unsigned char speed_r);
char* itoa(int value, char* result, int base);

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

    // Open serial port
    // ****************
    fd = openSerialPort("/dev/ttyAMA0", serialport_bps);
    if (fd == -1) exit(1);
    usleep(10000);                                          // Sleep for UART to power up and set options

    while( 1 )
    {
        // Mainloop running @ aprox. 10Hz
        // Read encoder and other data from MD49
        // serial. Data ist stored in md49_data.txt
        // ****************************************
        read_MD49_Data_serial();
        usleep(50000);

        // Read commands from md49_commands.txt:
        // *************************************
        read_md49_commands_txt();

        // Set speed and other commands as
        // read from md49_commands.txt
        // ************************************
        set_MD49_speed(speed_l, speed_r);
        usleep(50000);

    }// end.mainloop
    return 1;
} // end.main

void read_MD49_Data_serial (void){
    serialBuffer[0] = 82;                                   // 82=R Steuerbyte um alle Daten vom MD49 zu lesen
    writeBytes(fd, 1);
    //Daten lesen und in Array schreiben
    readBytes(fd, 18);

    ofstream myfile;
    myfile.open ("md49_data.txt");
    //myfile << "Writing this to a file.\n";
    char buffer[33];

    // Put toghether encoder values from their
    // corresponding bytes, read from MD49
    // ***************************************
    EncoderL = serialBuffer[0] << 24;                       // Put together first encoder value
    EncoderL |= (serialBuffer[1] << 16);
    EncoderL |= (serialBuffer[2] << 8);
    EncoderL |= (serialBuffer[3]);
    EncoderR = serialBuffer[4] << 24;                       // Put together second encoder value
    EncoderR |= (serialBuffer[5] << 16);
    EncoderR |= (serialBuffer[6] << 8);
    EncoderR |= (serialBuffer[7]);

    // write read data from MD49 into md49_data.txt
    // ********************************************
    int i=0;
    for (i=0;i<18;i++){
        if (serialBuffer[i]==0){
            myfile << "000";
        }
        else if (serialBuffer[i]<10){
            myfile << "00";
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        else if (serialBuffer[i]<100){
            myfile << "0";
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        else{
            myfile << itoa(serialBuffer[i],buffer,10);
        }
        myfile << "\n";
    }

    printf("\033[2J");                                      /*  clear the screen  */
    printf("\033[H");                                       /*  position cursor at top-left corner */
    printf ("MD49-Data read from AVR-Master: \n");
    printf("========================================\n");
    printf("Encoder1 Byte1: %i ",serialBuffer[0]);
    printf("Byte2: %i ",serialBuffer[1]);
    printf("Byte3: % i ",serialBuffer[2]);
    printf("Byte4: %i \n",serialBuffer[3]);
    printf("Encoder2 Byte1: %i ",serialBuffer[4]);
    printf("Byte2: %i ",serialBuffer[5]);
    printf("Byte3: %i ",serialBuffer[6]);
    printf("Byte4: %i \n",serialBuffer[7]);
    printf("EncoderL: %i ",EncoderL);
    printf("EncoderR: %i \n",EncoderR);
    printf("========================================\n");
    printf("Speed1: %i ",serialBuffer[8]);
    printf("Speed2: %i \n",serialBuffer[9]);
    printf("Volts: %i \n",serialBuffer[10]);
    printf("Current1: %i ",serialBuffer[11]);
    printf("Current2: %i \n",serialBuffer[12]);
    printf("Error: %i \n",serialBuffer[13]);
    printf("Acceleration: %i \n",serialBuffer[14]);
    printf("Mode: %i \n",serialBuffer[15]);
    printf("Regulator: %i \n",serialBuffer[16]);
    printf("Timeout: %i \n",serialBuffer[17]);
    printf("speed_l = %i \n",speed_l);
    printf("speed_r = %i \n",speed_r);

    myfile.close();
}

void set_MD49_speed (unsigned char speed_l, unsigned char speed_r){
    serialBuffer[0] = 88;                                   // 88 =X Steuerbyte um Commands an MD49 zu senden
    serialBuffer[1] = 115;                                  // 115=s Steuerbyte setSpeed
    serialBuffer[2] = speed_l;                              // set speed1
    serialBuffer[3] = speed_r;                              // set speed2
    writeBytes(fd, 4);
}

void read_md49_commands_txt(void){
    string line;
    ifstream myfile ("md49_commands.txt");
    if (myfile.is_open())
    {
        int i=0;
        while ( getline (myfile,line) )
        {
            //cout << line << '\n';
            char data[10];
            std::copy(line.begin(), line.end(), data);
            md49_data[i]=atoi(data);
            i =i++;
        }
        myfile.close();
        speed_l=md49_data[0];
        speed_r=md49_data[1];
    }
    else cout << "Unable to open file";
}

int openSerialPort(const char * device, int bps){
   struct termios neu;
   char buf[128];

   //fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
   fd = open(device, O_RDWR | O_NOCTTY);

   if (fd == -1)
   {
      sprintf(buf, "openSerialPort %s error", device);
      perror(buf);
   }
   else
   {
      tcgetattr(fd, &orig);                                 /* save current serial settings */
      tcgetattr(fd, &neu);
      cfmakeraw(&neu);
      cfsetispeed(&neu, bps);
      cfsetospeed(&neu, bps);
      tcflush(fd, TCIFLUSH);
      tcsetattr(fd, TCSANOW, &neu);                         /* set new serial settings */
      fcntl (fd, F_SETFL, O_RDWR);
   }
   return fd;
}

void writeBytes(int descriptor, int count) {
    if ((write(descriptor, serialBuffer, count)) == -1) {   // Send data out
        perror("Error writing");
        close(descriptor);                                  // Close port if there is an error
        exit(1);
    }

}

void readBytes(int descriptor, int count) {
    if (read(descriptor, serialBuffer, count) == -1) {      // Read back data into buf[]
        perror("Error reading ");
        close(descriptor);                                  // Close port if there is an error
        exit(1);
    }
}

char* itoa(int value, char* result, int base) {
        // check that the base if valid
        if (base < 2 || base > 36) { *result = '\0'; return result; }

        char* ptr = result, *ptr1 = result, tmp_char;
        int tmp_value;

        do {
            tmp_value = value;
            value /= base;
            *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
        } while ( value );

        // Apply negative sign
        if (tmp_value < 0) *ptr++ = '-';
        *ptr-- = '\0';
        while(ptr1 < ptr) {
            tmp_char = *ptr;
            *ptr--= *ptr1;
            *ptr1++ = tmp_char;
        }
        return result;
    }
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010, Joshua Lackey
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     *  Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *
 *     *  Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * kal
 *
 *    Two functions:
 *
 * 	1.  Calculates the frequency offset between a local GSM tower and the
 * 	    USRP clock.
 *
 *	2.  Identifies the frequency of all GSM base stations in a given band.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PACKAGE_VERSION "custom build"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/time.h>
#endif
#ifdef D_HOST_OSX
#include <libgen.h>
#endif /* D_HOST_OSX */
#include <string.h>

#include <errno.h>

#include "usrp_source.h"
#include "fcch_detector.h"
#include "arfcn_freq.h"
#include "offset.h"
#include "c0_detect.h"
#include "version.h"
#ifdef _WIN32
#include <getopt.h>
#define basename(x) "meh"
#define strtof strtod
#endif

#define GSM_RATE (1625000.0 / 6.0)

int g_verbosity = 0;
int g_debug = 0;

void
usage (char *prog)
{

  printf ("kalibrate v%s-hackrf, Copyright (c) 2010, Joshua Lackey\n",
	  kal_version_string);
  printf
    ("modified for use with hackrf devices, Copyright (c) 2014, scateu@gmail.com");
  printf ("\nUsage:\n");
  printf ("\tGSM Base Station Scan:\n");
  printf ("\t\t%s <-s band indicator> [options]\n", basename (prog));
  printf ("\n");
  printf ("\tClock Offset Calculation:\n");
  printf ("\t\t%s <-f frequency | -c channel> [options]\n", basename (prog));
  printf ("\n");
  printf ("Where options are:\n");
  printf ("\t-s\tband to scan (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)\n");
  printf ("\t-f\tfrequency of nearby GSM base station\n");
  printf ("\t-c\tchannel of nearby GSM base station\n");
  printf ("\t-b\tband indicator (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)\n");
  printf ("\t-a\trf amplifier enable\n");
  printf ("\t-g\tvga (bb) gain in dB, 0-40dB, 8dB step\n");
  printf ("\t-l\tlna (if) gain in dB, 0-62dB, 2dB step\n");
  printf ("\t-d\trtl-sdr device index\n");	// TODO: fuck it off.
  printf ("\t-e\tinitial frequency error in ppm\n");
  printf ("\t-v\tverbose\n");
  printf ("\t-D\tenable debug messages\n");
  printf ("\t-h\thelp\n");
  exit (-1);
}

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

  char *endptr;
  int c, antenna = 1, bi = BI_NOT_DEFINED, chan = -1, bts_scan = 0;
  int ppm_error = 0;
  unsigned int subdev = 0, decimation = 192;
  long int fpga_master_clock_freq = 52000000;
  int amp_gain = 0, lna_gain = 0, vga_gain = 0;
  double freq = -1.0, fd;
  usrp_source *u;

  while ((c = getopt (argc, argv, "f:c:s:b:R:A:ag:l:e:d:vDh?")) != EOF)
    {
      switch (c)
	{
	case 'f':
	  freq = strtod (optarg, 0);
	  break;

	case 'c':
	  chan = strtoul (optarg, 0, 0);
	  break;

	case 's':
	  if ((bi = str_to_bi (optarg)) == -1)
	    {
	      fprintf (stderr, "error: bad band "
		       "indicator: ``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  bts_scan = 1;
	  break;

	case 'b':
	  if ((bi = str_to_bi (optarg)) == -1)
	    {
	      fprintf (stderr, "error: bad band "
		       "indicator: ``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  break;

	case 'R':
	  errno = 0;
	  subdev = strtoul (optarg, &endptr, 0);
	  if ((!errno) && (endptr != optarg))
	    break;
	  if (tolower (*optarg) == 'a')
	    {
	      subdev = 0;
	    }
	  else if (tolower (*optarg) == 'b')
	    {
	      subdev = 1;
	    }
	  else
	    {
	      fprintf (stderr, "error: bad side: " "``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  break;

	case 'A':
	  if (!strcmp (optarg, "RX2"))
	    {
	      antenna = 1;
	    }
	  else if (!strcmp (optarg, "TX/RX"))
	    {
	      antenna = 0;
	    }
	  else
	    {
	      errno = 0;
	      antenna = strtoul (optarg, &endptr, 0);
	      if (errno || (endptr == optarg))
		{
		  fprintf (stderr, "error: bad " "antenna: ``%s''\n", optarg);
		  usage (argv[0]);
		}
	    }
	  break;

	case 'a':
	  amp_gain = 1;
	  break;

	case 'g':
	  vga_gain = atoi (optarg);
	  break;

	case 'l':
	  lna_gain = atoi (optarg);
	  break;

	case 'F':
	  fpga_master_clock_freq = strtol (optarg, 0, 0);
	  if (!fpga_master_clock_freq)
	    fpga_master_clock_freq = (long int) strtod (optarg, 0);

	  // was answer in MHz?
	  if (fpga_master_clock_freq < 1000)
	    {
	      fpga_master_clock_freq *= 1000000;
	    }
	  break;

	case 'e':
	  ppm_error = strtol (optarg, 0, 0);
	  break;

	case 'd':
	  subdev = strtol (optarg, 0, 0);
	  break;

	case 'v':
	  g_verbosity++;
	  break;

	case 'D':
	  g_debug = 1;
	  break;

	case 'h':
	case '?':
	default:
	  usage (argv[0]);
	  break;
	}

    }

  // sanity check frequency / channel
  if (bts_scan)
    {
      if (bi == BI_NOT_DEFINED)
	{
	  fprintf (stderr, "error: scaning requires band\n");
	  usage (argv[0]);
	}
    }
  else
    {
      if (freq < 0.0)
	{
	  if (chan < 0)
	    {
	      fprintf (stderr, "error: must enter channel or " "frequency\n");
	      usage (argv[0]);
	    }
	  if ((freq = arfcn_to_freq (chan, &bi)) < 869e6)
	    usage (argv[0]);
	}
      if ((freq < 869e6) || (2e9 < freq))
	{
	  fprintf (stderr, "error: bad frequency: %lf\n", freq);
	  usage (argv[0]);
	}
      chan = freq_to_arfcn (freq, &bi);
    }

#if 0
  // sanity check clock
  if (fpga_master_clock_freq < 48000000)
    {
      fprintf (stderr, "error: FPGA master clock too slow: %li\n",
	       fpga_master_clock_freq);
      usage (argv[0]);
    }

  // calculate decimation -- get as close to GSM rate as we can
  fd = (double) fpga_master_clock_freq / GSM_RATE;
  decimation = (unsigned int) fd;
#endif
  if (g_debug)
    {
#ifdef D_HOST_OSX
      printf ("debug: Mac OS X version\n");
#endif
      printf ("debug: FPGA Master Clock Freq:\t%li\n",
	      fpga_master_clock_freq);
      printf ("debug: decimation            :\t%u\n", decimation);
      printf ("debug: RX Subdev Spec        :\t%s\n", subdev ? "B" : "A");
      printf ("debug: Antenna               :\t%s\n",
	      antenna ? "RX2" : "TX/RX");
      printf ("debug: RF Amp                :\t%s\n",
	      amp_gain ? "ON" : "OFF");
      printf ("debug: LNA (IF) Gain         :\t%d\n", lna_gain);
      printf ("debug: VGA (BB) Gain         :\t%d\n", vga_gain);
    }

  u = new usrp_source (decimation, fpga_master_clock_freq);
  if (!u)
    {
      fprintf (stderr, "error: usrp_source\n");
      return -1;
    }
  if (u->open (subdev) == -1)
    {
      fprintf (stderr, "error: usrp_source::open\n");
      return -1;
    }
//      u->set_antenna(antenna);
  if (!u->set_gain (amp_gain, lna_gain, vga_gain))
    {
      fprintf (stderr, "error: usrp_source::set_gain\n");
      return -1;
    }

  if (ppm_error != 0)
    {
      if (u->set_freq_correction (ppm_error) < 0)
	{
	  fprintf (stderr, "error: usrp_source::set_freq_correction\n");
	  return -1;
	}
    }

  if (!bts_scan)
    {
      if (!u->tune (freq))
	{
	  fprintf (stderr, "error: usrp_source::tune\n");
	  return -1;
	}

      fprintf (stderr, "%s: Calculating clock frequency offset.\n",
	       basename (argv[0]));
      fprintf (stderr, "Using %s channel %d (%.1fMHz)\n",
	       bi_to_str (bi), chan, freq / 1e6);

      return offset_detect (u);
    }

  fprintf (stderr, "%s: Scanning for %s base stations.\n",
	   basename (argv[0]), bi_to_str (bi));

  return c0_detect (u, bi);
}
<commit_msg>HackRF only has one antenna<commit_after>/*
 * Copyright (c) 2010, Joshua Lackey
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     *  Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *
 *     *  Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * kal
 *
 *    Two functions:
 *
 * 	1.  Calculates the frequency offset between a local GSM tower and the
 * 	    USRP clock.
 *
 *	2.  Identifies the frequency of all GSM base stations in a given band.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define PACKAGE_VERSION "custom build"
#endif /* HAVE_CONFIG_H */

#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/time.h>
#endif
#ifdef D_HOST_OSX
#include <libgen.h>
#endif /* D_HOST_OSX */
#include <string.h>

#include <errno.h>

#include "usrp_source.h"
#include "fcch_detector.h"
#include "arfcn_freq.h"
#include "offset.h"
#include "c0_detect.h"
#include "version.h"
#ifdef _WIN32
#include <getopt.h>
#define basename(x) "meh"
#define strtof strtod
#endif

#define GSM_RATE (1625000.0 / 6.0)

int g_verbosity = 0;
int g_debug = 0;

void
usage (char *prog)
{

  printf ("kalibrate v%s-hackrf, Copyright (c) 2010, Joshua Lackey\n",
	  kal_version_string);
  printf
    ("modified for use with hackrf devices, Copyright (c) 2014, scateu@gmail.com");
  printf ("\nUsage:\n");
  printf ("\tGSM Base Station Scan:\n");
  printf ("\t\t%s <-s band indicator> [options]\n", basename (prog));
  printf ("\n");
  printf ("\tClock Offset Calculation:\n");
  printf ("\t\t%s <-f frequency | -c channel> [options]\n", basename (prog));
  printf ("\n");
  printf ("Where options are:\n");
  printf ("\t-s\tband to scan (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)\n");
  printf ("\t-f\tfrequency of nearby GSM base station\n");
  printf ("\t-c\tchannel of nearby GSM base station\n");
  printf ("\t-b\tband indicator (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)\n");
  printf ("\t-a\trf amplifier enable\n");
  printf ("\t-g\tvga (bb) gain in dB, 0-40dB, 8dB step\n");
  printf ("\t-l\tlna (if) gain in dB, 0-62dB, 2dB step\n");
  printf ("\t-d\trtl-sdr device index\n");	// TODO: fuck it off.
  printf ("\t-e\tinitial frequency error in ppm\n");
  printf ("\t-v\tverbose\n");
  printf ("\t-D\tenable debug messages\n");
  printf ("\t-h\thelp\n");
  exit (-1);
}

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

  char *endptr;
  int c, bi = BI_NOT_DEFINED, chan = -1, bts_scan = 0;
  int ppm_error = 0;
  unsigned int subdev = 0, decimation = 192;
  long int fpga_master_clock_freq = 52000000;
  int amp_gain = 0, lna_gain = 0, vga_gain = 0;
  double freq = -1.0, fd;
  usrp_source *u;

  while ((c = getopt (argc, argv, "f:c:s:b:R:ag:l:e:d:vDh?")) != EOF)
    {
      switch (c)
	{
	case 'f':
	  freq = strtod (optarg, 0);
	  break;

	case 'c':
	  chan = strtoul (optarg, 0, 0);
	  break;

	case 's':
	  if ((bi = str_to_bi (optarg)) == -1)
	    {
	      fprintf (stderr, "error: bad band "
		       "indicator: ``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  bts_scan = 1;
	  break;

	case 'b':
	  if ((bi = str_to_bi (optarg)) == -1)
	    {
	      fprintf (stderr, "error: bad band "
		       "indicator: ``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  break;

	case 'R':
	  errno = 0;
	  subdev = strtoul (optarg, &endptr, 0);
	  if ((!errno) && (endptr != optarg))
	    break;
	  if (tolower (*optarg) == 'a')
	    {
	      subdev = 0;
	    }
	  else if (tolower (*optarg) == 'b')
	    {
	      subdev = 1;
	    }
	  else
	    {
	      fprintf (stderr, "error: bad side: " "``%s''\n", optarg);
	      usage (argv[0]);
	    }
	  break;

	case 'a':
	  amp_gain = 1;
	  break;

	case 'g':
	  vga_gain = atoi (optarg);
	  break;

	case 'l':
	  lna_gain = atoi (optarg);
	  break;

	case 'F':
	  fpga_master_clock_freq = strtol (optarg, 0, 0);
	  if (!fpga_master_clock_freq)
	    fpga_master_clock_freq = (long int) strtod (optarg, 0);

	  // was answer in MHz?
	  if (fpga_master_clock_freq < 1000)
	    {
	      fpga_master_clock_freq *= 1000000;
	    }
	  break;

	case 'e':
	  ppm_error = strtol (optarg, 0, 0);
	  break;

	case 'd':
	  subdev = strtol (optarg, 0, 0);
	  break;

	case 'v':
	  g_verbosity++;
	  break;

	case 'D':
	  g_debug = 1;
	  break;

	case 'h':
	case '?':
	default:
	  usage (argv[0]);
	  break;
	}

    }

  // sanity check frequency / channel
  if (bts_scan)
    {
      if (bi == BI_NOT_DEFINED)
	{
	  fprintf (stderr, "error: scaning requires band\n");
	  usage (argv[0]);
	}
    }
  else
    {
      if (freq < 0.0)
	{
	  if (chan < 0)
	    {
	      fprintf (stderr, "error: must enter channel or " "frequency\n");
	      usage (argv[0]);
	    }
	  if ((freq = arfcn_to_freq (chan, &bi)) < 869e6)
	    usage (argv[0]);
	}
      if ((freq < 869e6) || (2e9 < freq))
	{
	  fprintf (stderr, "error: bad frequency: %lf\n", freq);
	  usage (argv[0]);
	}
      chan = freq_to_arfcn (freq, &bi);
    }

#if 0
  // sanity check clock
  if (fpga_master_clock_freq < 48000000)
    {
      fprintf (stderr, "error: FPGA master clock too slow: %li\n",
	       fpga_master_clock_freq);
      usage (argv[0]);
    }

  // calculate decimation -- get as close to GSM rate as we can
  fd = (double) fpga_master_clock_freq / GSM_RATE;
  decimation = (unsigned int) fd;
#endif
  if (g_debug)
    {
#ifdef D_HOST_OSX
      printf ("debug: Mac OS X version\n");
#endif
      printf ("debug: FPGA Master Clock Freq:\t%li\n",
	      fpga_master_clock_freq);
      printf ("debug: decimation            :\t%u\n", decimation);
      printf ("debug: RX Subdev Spec        :\t%s\n", subdev ? "B" : "A");
      printf ("debug: RF Amp                :\t%s\n",
	      amp_gain ? "ON" : "OFF");
      printf ("debug: LNA (IF) Gain         :\t%d\n", lna_gain);
      printf ("debug: VGA (BB) Gain         :\t%d\n", vga_gain);
    }

  u = new usrp_source (decimation, fpga_master_clock_freq);
  if (!u)
    {
      fprintf (stderr, "error: usrp_source\n");
      return -1;
    }
  if (u->open (subdev) == -1)
    {
      fprintf (stderr, "error: usrp_source::open\n");
      return -1;
    }
  if (!u->set_gain (amp_gain, lna_gain, vga_gain))
    {
      fprintf (stderr, "error: usrp_source::set_gain\n");
      return -1;
    }

  if (ppm_error != 0)
    {
      if (u->set_freq_correction (ppm_error) < 0)
	{
	  fprintf (stderr, "error: usrp_source::set_freq_correction\n");
	  return -1;
	}
    }

  if (!bts_scan)
    {
      if (!u->tune (freq))
	{
	  fprintf (stderr, "error: usrp_source::tune\n");
	  return -1;
	}

      fprintf (stderr, "%s: Calculating clock frequency offset.\n",
	       basename (argv[0]));
      fprintf (stderr, "Using %s channel %d (%.1fMHz)\n",
	       bi_to_str (bi), chan, freq / 1e6);

      return offset_detect (u);
    }

  fprintf (stderr, "%s: Scanning for %s base stations.\n",
	   basename (argv[0]), bi_to_str (bi));

  return c0_detect (u, bi);
}
<|endoftext|>


<commit_before>#include "HelloWorld5Module.h"
#include "NFComm/NFCore/NFTimer.h"
#include <thread>
#include "NFComm/NFCore/NFIComponent.h"
#include "NFCTestComponent.h"

bool HelloWorld5Module::Init()
{
    //ʼ
    std::cout << "Hello, world5, Init" << std::endl;

    return true;
}

bool HelloWorld5Module::AfterInit()
{
    //ʼ
    std::cout << "Hello, world5, AfterInit, ThreadID: " << std::this_thread::get_id() << std::endl;

    m_pKernelModule = dynamic_cast<NFIKernelModule*>(pPluginManager->FindModule("NFCKernelModule"));
    m_pEventProcessModule = dynamic_cast<NFIEventProcessModule*>(pPluginManager->FindModule("NFCEventProcessModule"));
    m_pElementInfoModule = dynamic_cast<NFIElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

	//int nActorID = m_pEventProcessModule->AddActorEventCallBack<NFCTestComponent, HelloWorld5Module>(this, &HelloWorld5Module::OnSyncEvent);
	int nActorID = m_pEventProcessModule->AddActorEventCallBack<NFCTestComponent>(this, &HelloWorld5Module::OnSyncEvent);

    m_pEventProcessModule->SendActorMsg(nActorID, 555, NFIDENTID(), "Event Param");

    std::cout << "End Test Actor, ThreadID: " << std::this_thread::get_id() << std::endl;

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

    return true;
}

int HelloWorld5Module::OnSyncEvent(const NFIDENTID& self, const int event, const std::string& arg)
{
    //¼ص
    std::cout << "End OnEvent EventID: " << event << " self: " << self.nData64 << " argList: " << arg << " ThreadID: " << std::this_thread::get_id() << std::endl;

    return 0;
}

bool HelloWorld5Module::Execute( const float fLasFrametime, const float fStartedTime )
{
    //ÿִ֡
    //std::cout << "Hello, world5, Execute" << std::endl;

    return true;
}

bool HelloWorld5Module::BeforeShut()
{
    //ʼ֮ǰ
    std::cout << "Hello, world5, BeforeShut" << std::endl;

    m_pKernelModule->DestroyAll();

    return true;
}

bool HelloWorld5Module::Shut()
{
    //ʼ
    std::cout << "Hello, world5, Shut" << std::endl;

    return true;
}
<commit_msg>Tutorial<commit_after>#include "HelloWorld5Module.h"
#include "NFComm/NFCore/NFTimer.h"
#include <thread>
#include "NFComm/NFCore/NFIComponent.h"
#include "NFCTestComponent.h"

bool HelloWorld5Module::Init()
{
    //ʼ
    std::cout << "Hello, world5, Init" << std::endl;

    return true;
}

bool HelloWorld5Module::AfterInit()
{
    //ʼ
    std::cout << "Hello, world5, AfterInit, ThreadID: " << std::this_thread::get_id() << std::endl;

    m_pKernelModule = dynamic_cast<NFIKernelModule*>(pPluginManager->FindModule("NFCKernelModule"));
    m_pEventProcessModule = dynamic_cast<NFIEventProcessModule*>(pPluginManager->FindModule("NFCEventProcessModule"));
    m_pElementInfoModule = dynamic_cast<NFIElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

	//int nActorID = m_pEventProcessModule->AddActorEventCallBack<NFCTestComponent, HelloWorld5Module>(this, &HelloWorld5Module::OnSyncEvent);
	int nActorID = m_pEventProcessModule->AddActorEventCallBack<NFCTestComponent>(this, &HelloWorld5Module::OnSyncEvent);

	for (int i = 0; i < 20; ++i)
	{
		m_pEventProcessModule->SendActorMsg(nActorID, 555, NFIDENTID(), boost::lexical_cast<std::string>(i));
	}

    std::cout << "End Test Actor, ThreadID: " << std::this_thread::get_id() << std::endl;

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

    return true;
}

int HelloWorld5Module::OnSyncEvent(const NFIDENTID& self, const int event, const std::string& arg)
{
    //¼ص
    std::cout << "End OnEvent EventID: " << event << " self: " << self.nData64 << " argList: " << arg << " ThreadID: " << std::this_thread::get_id() << std::endl;

    return 0;
}

bool HelloWorld5Module::Execute( const float fLasFrametime, const float fStartedTime )
{
    //ÿִ֡
    //std::cout << "Hello, world5, Execute" << std::endl;

    return true;
}

bool HelloWorld5Module::BeforeShut()
{
    //ʼ֮ǰ
    std::cout << "Hello, world5, BeforeShut" << std::endl;

    m_pKernelModule->DestroyAll();

    return true;
}

bool HelloWorld5Module::Shut()
{
    //ʼ
    std::cout << "Hello, world5, Shut" << std::endl;

    return true;
}
<|endoftext|>


<commit_before>/*
 * sys_io.cpp
 *
 * Handles the low level details of system I/O
 *
 * Created: 03/14/2013
 *  Author: Collin Kidder
 */

#include "sys_io.h"
#include "eeprom_layout.h"
#include "pref_handler.h"

//pin definitions for system IO
uint8_t adc[NUM_ANALOG][2] = {{6,7}, {4,5}, {2,3}, {0,1}}; //low, high
uint8_t dig[] = {8, 11, 12, 13};
uint8_t out[] = {50, 26, 44, 36};
ADC_COMP adc_comp[NUM_ANALOG];

void setup_sys_io() {
  int i;
  //requires the value to be contiguous in memory
  for (i = 0; i < NUM_ANALOG; i++) {
    //sysPrefs.Read(EESYS_ADC0_GAIN + 4*i, &adc_comp[i].gain);
    //sysPrefs.Read(EESYS_ADC0_OFFSET + 4*i, &adc_comp[i].offset);
    adc_comp[i].gain = 1024;
    adc_comp[i].offset = 0;
  }
}

//get value of one of the 4 analog inputs
//Probably handles scaling, bias, and differential input
//but does nothing to smooth the output. Subsequent stages
//must handle that.
uint16_t getAnalog(uint8_t which) {
	uint32_t low, high;

	if (which >= NUM_ANALOG) which = 0;

	low = analogRead(adc[which][0]);
	high = analogRead(adc[which][1]);

        //first remove the bias to bring us back to where it rests at zero input volts
        low -= adc_comp[which].offset;
        high -= adc_comp[which].offset;

        //gain multiplier is 1024 for 1 to 1 gain, less for lower gain, more for higher.
        low *= adc_comp[which].gain;
        low = low >> 10; //divide by 1024 again to correct for gain multiplier
        high *= adc_comp[which].gain;
        high = high >> 10;

        //Lastly, the input scheme is basically differential so we have to subtract
        //low from high to get the actual value
	high = high - low;

	return high;
}

//get value of one of the 4 digital inputs
boolean getDigital(uint8_t which) {
	if (which >= NUM_DIGITAL) which = 0;
	return !digitalRead(dig[which]);
}

//set output high or not
void setOutput(uint8_t which, boolean active) {
	if (which >= NUM_OUTPUT) which = 0;
	if (active)
		digitalWrite(out[which], HIGH);
	else digitalWrite(out[which], LOW);
}

//get current value of output state (high?)
boolean getOutput(uint8_t which) {
	if (which >= NUM_OUTPUT) which = 0;
	return digitalRead(out[which]);
}
<commit_msg>Fixed - Analog IO defines were all wrong<commit_after>/*
 * sys_io.cpp
 *
 * Handles the low level details of system I/O
 *
 * Created: 03/14/2013
 *  Author: Collin Kidder
 */

#include "sys_io.h"
#include "eeprom_layout.h"
#include "pref_handler.h"

//pin definitions for system IO
uint8_t adc[NUM_ANALOG][2] = {{1,0}, {3,2}, {5,4}, {7,6}}; //low, high
uint8_t dig[] = {8, 11, 12, 13};
uint8_t out[] = {50, 26, 44, 36};
ADC_COMP adc_comp[NUM_ANALOG];

void setup_sys_io() {
  int i;
  //requires the value to be contiguous in memory
  for (i = 0; i < NUM_ANALOG; i++) {
    //sysPrefs.Read(EESYS_ADC0_GAIN + 4*i, &adc_comp[i].gain);
    //sysPrefs.Read(EESYS_ADC0_OFFSET + 4*i, &adc_comp[i].offset);
    adc_comp[i].gain = 1024;
    adc_comp[i].offset = 0;
  }
}

//get value of one of the 4 analog inputs
//Probably handles scaling, bias, and differential input
//but does nothing to smooth the output. Subsequent stages
//must handle that.
uint16_t getAnalog(uint8_t which) {
	uint32_t low, high;

	analogResolution(12);

	if (which >= NUM_ANALOG) which = 0;

	low = analogRead(adc[which][0]);
	high = analogRead(adc[which][1]);

        //first remove the bias to bring us back to where it rests at zero input volts
        low -= adc_comp[which].offset;
        high -= adc_comp[which].offset;

        //gain multiplier is 1024 for 1 to 1 gain, less for lower gain, more for higher.
        low *= adc_comp[which].gain;
        low = low >> 10; //divide by 1024 again to correct for gain multiplier
        high *= adc_comp[which].gain;
        high = high >> 10;

        //Lastly, the input scheme is basically differential so we have to subtract
        //low from high to get the actual value
	high = high - low;

	return high;
}

//get value of one of the 4 digital inputs
boolean getDigital(uint8_t which) {
	if (which >= NUM_DIGITAL) which = 0;
	return !digitalRead(dig[which]);
}

//set output high or not
void setOutput(uint8_t which, boolean active) {
	if (which >= NUM_OUTPUT) which = 0;
	if (active)
		digitalWrite(out[which], HIGH);
	else digitalWrite(out[which], LOW);
}

//get current value of output state (high?)
boolean getOutput(uint8_t which) {
	if (which >= NUM_OUTPUT) which = 0;
	return digitalRead(out[which]);
}
<|endoftext|>


<commit_before>#include <qore/common.h>
#include <qore/QoreValue.h>
#include <qore/DBI.h>
#include <qore/QoreEncoding.h>
#include <qore/QoreString.h>
#include <qore/SQLStatement.h>
#include <qore/QoreStringNode.h>
#include <qore/AbstractPrivateData.h>
#include <qore/QoreQueue.h>
#include <qore/Datasource.h>
#include <qore/QoreListNode.h>
#include <qore/QoreHashNode.h>
#include <qore/QoreValue.h>

#include "connection.h"
#include "emptystatement.h"
#include "command.h"
#include "dbmodulewrap.h"
#include "utils.h"

namespace ss {

inline bool expect_row(command::ResType rt) {
    switch (rt) {
        case command::RES_ROW:
        case command::RES_PARAM:
            return true;
        default:
            return false;
    }
}

class Statement : public EmptyStatement {
    QoreHashNode *_execRes;

    bool has_res() {
        return _execRes ? true : false;
    }

    void set_res(QoreHashNode *res, ExceptionSink* xsink) {
        if (_execRes) _execRes->deref(xsink);
        _execRes = res;
    }

    QoreHashNode * release_res() {
        QoreHashNode *rv = _execRes;
        _execRes = 0;
        return rv;
    }

    ~Statement() {}

    SafePtr<command> context;
    Placeholders placeholders;
public:
    typedef connection Connection;

    Statement() : _execRes(0) {}

    static void Delete(Statement *self, ExceptionSink* xsink) {
        if (!self) return;
        self->set_res(0, xsink);
        delete self;
    }

    int exec(connection *conn,
            const QoreString *query,
            const QoreListNode *args,
            bool raw,
            ExceptionSink* xsink)
    {
        if (context.get()) context->cancel();
#ifdef _QORE_HAS_DBI_EXECRAW
        if (raw) {
            context.reset(conn->create_command(query, xsink));
        } else
#endif
        {
            context.reset(conn->create_command(query, args, xsink));
        }
        // not sure what to do with the returned value here
        context->read_next_result(xsink);
        return 0;
    }

    bool next(SQLStatement* stmt, ExceptionSink* xsink) {
        command::ResType res = context->read_next_result(xsink);
        if (expect_row(res)) {
            if (!has_res()) {
                set_res(context->fetch_row(xsink), xsink);
            }
        }

        return has_res();
    }

    QoreHashNode * fetch_row(SQLStatement* stmt, ExceptionSink* xsink) {
        return  release_res();
    }

    int define(SQLStatement* stmt, ExceptionSink* xsink) {
        return 0;
    }

    QoreListNode* fetch_rows(SQLStatement* stmt, int rows,
            ExceptionSink* xsink)
    {
        int r = rows;
        ReferenceHolder<QoreListNode> reslist(xsink);
        reslist = new QoreListNode();

        // next was already called once
        do {
            // acording the doc rows <=0 means fetch all
            if (r > 0) {
                if (rows <= 0) break;
                rows--;
            }
            if (xsink->isException()) return 0;
            ReferenceHolder<QoreHashNode> h(xsink);
            h = fetch_row(stmt, xsink);
            if (!h) continue;
            reslist->insert(h.release());
        } while (next(stmt, xsink));
        return reslist.release();
    }

    QoreHashNode* get_output(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->read_cols(&placeholders, xsink);
    }

    int affected_rows(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->get_row_count();
    }

    QoreHashNode* fetch_columns(SQLStatement* stmt, int rows, ExceptionSink* xsink) {
        return context->read_cols(0,  xsink);
    }

    int bind_placeholders(SQLStatement* stmt,
            const QoreListNode& l,
            ExceptionSink* xsink)
    {
        placeholders.clear();
        ConstListIterator it(l);
        while (it.next()) {
            QoreValue v(it.getValue());
            QoreStringNode *s = v.get<QoreStringNode>();
            placeholders.push_back(s->getBuffer());
        }
        return 0;
    }
};

void init(qore_dbi_method_list &methods) {
    DBModuleWrap<Statement> module(methods);
    module.reg();
}

} // namespace ss
<commit_msg>sybase: fix select result order<commit_after>#include <qore/common.h>
#include <qore/QoreValue.h>
#include <qore/DBI.h>
#include <qore/QoreEncoding.h>
#include <qore/QoreString.h>
#include <qore/SQLStatement.h>
#include <qore/QoreStringNode.h>
#include <qore/AbstractPrivateData.h>
#include <qore/QoreQueue.h>
#include <qore/Datasource.h>
#include <qore/QoreListNode.h>
#include <qore/QoreHashNode.h>
#include <qore/QoreValue.h>

#include "connection.h"
#include "emptystatement.h"
#include "command.h"
#include "dbmodulewrap.h"
#include "utils.h"

namespace ss {

inline bool expect_row(command::ResType rt) {
    switch (rt) {
        case command::RES_ROW:
        case command::RES_PARAM:
            return true;
        default:
            return false;
    }
}

class Statement : public EmptyStatement {
    QoreHashNode *_execRes;

    bool has_res() {
        return _execRes ? true : false;
    }

    void set_res(QoreHashNode *res, ExceptionSink* xsink) {
        if (_execRes) _execRes->deref(xsink);
        _execRes = res;
    }

    QoreHashNode * release_res() {
        QoreHashNode *rv = _execRes;
        _execRes = 0;
        return rv;
    }

    ~Statement() {}

    SafePtr<command> context;
    Placeholders placeholders;
public:
    typedef connection Connection;

    Statement() : _execRes(0) {}

    static void Delete(Statement *self, ExceptionSink* xsink) {
        if (!self) return;
        self->set_res(0, xsink);
        delete self;
    }

    int exec(connection *conn,
            const QoreString *query,
            const QoreListNode *args,
            bool raw,
            ExceptionSink* xsink)
    {
        if (context.get()) context->cancel();
#ifdef _QORE_HAS_DBI_EXECRAW
        if (raw) {
            context.reset(conn->create_command(query, xsink));
        } else
#endif
        {
            context.reset(conn->create_command(query, args, xsink));
        }
        // not sure what to do with the returned value here
        context->read_next_result(xsink);
        return 0;
    }

    bool next(SQLStatement* stmt, ExceptionSink* xsink) {
        command::ResType res = context->read_next_result(xsink);
        if (expect_row(res)) {
            if (!has_res()) {
                set_res(context->fetch_row(xsink), xsink);
            }
        }

        return has_res();
    }

    QoreHashNode * fetch_row(SQLStatement* stmt, ExceptionSink* xsink) {
        return  release_res();
    }

    int define(SQLStatement* stmt, ExceptionSink* xsink) {
        return 0;
    }

    QoreListNode* fetch_rows(SQLStatement* stmt, int rows,
            ExceptionSink* xsink)
    {
        int r = rows;
        ReferenceHolder<QoreListNode> reslist(xsink);
        reslist = new QoreListNode();

        // next was already called once
        do {
            // acording the doc rows <=0 means fetch all
            if (r > 0) {
                if (rows <= 0) break;
                rows--;
            }
            if (xsink->isException()) return 0;
            ReferenceHolder<QoreHashNode> h(xsink);
            h = fetch_row(stmt, xsink);
            if (!h) continue;
            reslist->push(h.release());
        } while (next(stmt, xsink));
        return reslist.release();
    }

    QoreHashNode* get_output(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->read_cols(&placeholders, xsink);
    }

    int affected_rows(SQLStatement* stmt, ExceptionSink* xsink) {
        return context->get_row_count();
    }

    QoreHashNode* fetch_columns(SQLStatement* stmt, int rows, ExceptionSink* xsink) {
        return context->read_cols(0,  xsink);
    }

    int bind_placeholders(SQLStatement* stmt,
            const QoreListNode& l,
            ExceptionSink* xsink)
    {
        placeholders.clear();
        ConstListIterator it(l);
        while (it.next()) {
            QoreValue v(it.getValue());
            QoreStringNode *s = v.get<QoreStringNode>();
            placeholders.push_back(s->getBuffer());
        }
        return 0;
    }
};

void init(qore_dbi_method_list &methods) {
    DBModuleWrap<Statement> module(methods);
    module.reg();
}

} // namespace ss
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////
// File:        svutil.cpp
// Description: ScrollView Utilities
// Author:      Joern Wanke
// Created:     Thu Nov 29 2007
//
// (C) Copyright 2007, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////
//
// SVUtil contains the SVSync and SVNetwork classes, which are used for
// thread/process creation & synchronization and network connection.

#include <stdio.h>
#ifdef _WIN32
struct addrinfo {
  struct sockaddr* ai_addr;
  int ai_addrlen;
  int ai_family;
  int ai_socktype;
  int ai_protocol;
};
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/socket.h>
#ifdef __linux__
#include <sys/prctl.h>
#endif
#include <unistd.h>
#endif

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

// Include automatically generated configuration file if running autoconf.
#ifdef HAVE_CONFIG_H
#include "config_auto.h"
#endif

#ifndef GRAPHICS_DISABLED

#include "svutil.h"

const int kMaxMsgSize = 4096;

// Signals a thread to exit.
void SVSync::ExitThread() {
#ifdef _WIN32
  // ExitThread(0);
#else
  pthread_exit(0);
#endif
}

// Starts a new process.
void SVSync::StartProcess(const char* executable, const char* args) {
  std::string proc;
  proc.append(executable);
  proc.append(" ");
  proc.append(args);
  std::cout << "Starting " << proc << std::endl;
#ifdef _WIN32
  STARTUPINFO start_info;
  PROCESS_INFORMATION proc_info;
  GetStartupInfo(&start_info);
  if (!CreateProcess(NULL, const_cast<char*>(proc.c_str()), NULL, NULL, FALSE,
                CREATE_NO_WINDOW | DETACHED_PROCESS, NULL, NULL,
                &start_info, &proc_info))
    return;
#else
  int pid = fork();
  if (pid != 0) {   // The father process returns
  } else {
#ifdef __linux__
    // Make sure the java process terminates on exit, since its
    // broken socket detection seems to be useless.
    prctl(PR_SET_PDEATHSIG, 2, 0, 0, 0);
#endif
    char* mutable_args = strdup(args);
    int argc = 1;
    for (int i = 0; mutable_args[i]; ++i) {
      if (mutable_args[i] == ' ') {
        ++argc;
      }
    }
    char** argv = new char*[argc + 2];
    argv[0] = strdup(executable);
    argv[1] = mutable_args;
    argc = 2;
    bool inquote = false;
    for (int i = 0; mutable_args[i]; ++i) {
      if (!inquote && mutable_args[i] == ' ') {
        mutable_args[i] = '\0';
        argv[argc++] = mutable_args + i + 1;
      } else if (mutable_args[i] == '"') {
        inquote = !inquote;
        mutable_args[i] = ' ';
      }
    }
    argv[argc] = NULL;
    execvp(executable, argv);
    free(argv[0]);
    free(argv[1]);
    delete[] argv;
  }
#endif
}

SVSemaphore::SVSemaphore() {
#ifdef _WIN32
  semaphore_ = CreateSemaphore(0, 0, 10, 0);
#elif defined(__APPLE__)
  char name[50];
  snprintf(name, sizeof(name), "%ld", random());
  sem_unlink(name);
  semaphore_ = sem_open(name, O_CREAT , S_IWUSR, 0);
  if (semaphore_ == SEM_FAILED) {
    perror("sem_open");
  }
#else
  sem_init(&semaphore_, 0, 0);
#endif
}

void SVSemaphore::Signal() {
#ifdef _WIN32
  ReleaseSemaphore(semaphore_, 1, NULL);
#elif defined(__APPLE__)
  sem_post(semaphore_);
#else
  sem_post(&semaphore_);
#endif
}

void SVSemaphore::Wait() {
#ifdef _WIN32
  WaitForSingleObject(semaphore_, INFINITE);
#elif defined(__APPLE__)
  sem_wait(semaphore_);
#else
  sem_wait(&semaphore_);
#endif
}

SVMutex::SVMutex() {
#ifdef _WIN32
  mutex_ = CreateMutex(0, FALSE, 0);
#else
  pthread_mutex_init(&mutex_, NULL);
#endif
}

void SVMutex::Lock() {
#ifdef _WIN32
  WaitForSingleObject(mutex_, INFINITE);
#else
  pthread_mutex_lock(&mutex_);
#endif
}

void SVMutex::Unlock() {
#ifdef _WIN32
  ReleaseMutex(mutex_);
#else
  pthread_mutex_unlock(&mutex_);
#endif
}

// Create new thread.

void SVSync::StartThread(void *(*func)(void*), void* arg) {
#ifdef _WIN32
  LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE) func;
  DWORD threadid;
  HANDLE newthread = CreateThread(
  NULL,          // default security attributes
  0,             // use default stack size
  f,             // thread function
  arg,           // argument to thread function
  0,             // use default creation flags
  &threadid);    // returns the thread identifier
#else
  pthread_t helper;
  pthread_create(&helper, NULL, func, arg);
#endif
}

// Place a message in the message buffer (and flush it).
void SVNetwork::Send(const char* msg) {
  mutex_send_->Lock();
  msg_buffer_out_.append(msg);
  mutex_send_->Unlock();
}

// Send the whole buffer.
void SVNetwork::Flush() {
  mutex_send_->Lock();
  while (msg_buffer_out_.size() > 0) {
    int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
    msg_buffer_out_.erase(0, i);
  }
  mutex_send_->Unlock();
}

// Receive a message from the server.
// This will always return one line of char* (denoted by \n).
char* SVNetwork::Receive() {
  char* result = NULL;
#if defined(_WIN32) || defined(__CYGWIN__)
  if (has_content) { result = strtok (NULL, "\n"); }
#else
  if (buffer_ptr_ != NULL) { result = strtok_r(NULL, "\n", &buffer_ptr_); }
#endif

  // This means there is something left in the buffer and we return it.
  if (result != NULL) { return result;
  // Otherwise, we read from the stream_.
  } else {
    buffer_ptr_ = NULL;
    has_content = false;

    // The timeout length is not really important since we are looping anyway
    // until a new message is delivered.
    struct timeval tv;
    tv.tv_sec = 10;
    tv.tv_usec = 0;

    // Set the flags to return when the stream_ is ready to be read.
    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(stream_, &readfds);

    int i = select(stream_+1, &readfds, NULL, NULL, &tv);

    // The stream_ died.
    if (i == 0) { return NULL; }

    // Read the message buffer.
    i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);

    // Server quit (0) or error (-1).
    if (i <= 0) { return NULL; }
    msg_buffer_in_[i] = '\0';
    has_content = true;
#ifdef _WIN32
    return strtok(msg_buffer_in_, "\n");
#else
    // Setup a new string tokenizer.
    return strtok_r(msg_buffer_in_, "\n", &buffer_ptr_);
#endif
  }
}

// Close the connection to the server.
void SVNetwork::Close() {
#ifdef _WIN32
  closesocket(stream_);
#else
  close(stream_);
#endif
}

// The program to invoke to start ScrollView
static const char* ScrollViewProg() {
#ifdef _WIN32
  const char* prog = "java -Xms512m -Xmx1024m";
#else
  const char* prog = "sh";
#endif
  return prog;
}

// The arguments to the program to invoke to start ScrollView
static std::string ScrollViewCommand(std::string scrollview_path) {
  // The following ugly ifdef is to enable the output of the java runtime
  // to be sent down a black hole on non-windows to ignore all the
  // exceptions in piccolo. Ideally piccolo would be debugged to make
  // this unnecessary.
  // Also the path has to be separated by ; on windows and : otherwise.
#ifdef _WIN32
  const char* cmd_template = "-Djava.library.path=%s -jar %s/ScrollView.jar";

#else
  const char* cmd_template = "-c \"trap 'kill %%1' 0 1 2 ; java "
      "-Xms1024m -Xmx2048m -jar %s/ScrollView.jar"
      " & wait\"";
#endif
  int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path.c_str()) + 1;
  char* cmd = new char[cmdlen];
  const char* sv_path = scrollview_path.c_str();
  snprintf(cmd, cmdlen, cmd_template, sv_path, sv_path, sv_path, sv_path);
  std::string command(cmd);
  delete [] cmd;
  return command;
}

// Platform-independent freeaddrinfo()
static void FreeAddrInfo(struct addrinfo* addr_info) {
  #if defined(__linux__)
  freeaddrinfo(addr_info);
  #else
  delete addr_info->ai_addr;
  delete addr_info;
  #endif
}

// Non-linux version of getaddrinfo()
#if !defined(__linux__)
static int GetAddrInfoNonLinux(const char* hostname, int port,
                               struct addrinfo** addr_info) {
// Get the host data depending on the OS.
  struct sockaddr_in* address;
  *addr_info = new struct addrinfo;
  memset(*addr_info, 0, sizeof(struct addrinfo));
  address = new struct sockaddr_in;
  memset(address, 0, sizeof(struct sockaddr_in));

  (*addr_info)->ai_addr = (struct sockaddr*) address;
  (*addr_info)->ai_addrlen = sizeof(struct sockaddr);
  (*addr_info)->ai_family = AF_INET;
  (*addr_info)->ai_socktype = SOCK_STREAM;

  struct hostent *name;
#ifdef _WIN32
  WSADATA wsaData;
  WSAStartup(MAKEWORD(1, 1), &wsaData);
  name = gethostbyname(hostname);
#else
  name = gethostbyname(hostname);
#endif

  if (name == NULL) {
    FreeAddrInfo(*addr_info);
    *addr_info = NULL;
    return -1;
  }

  // Fill in the appropriate variables to be able to connect to the server.
  address->sin_family = name->h_addrtype;
  memcpy((char *) &address->sin_addr.s_addr,
         name->h_addr_list[0], name->h_length);
  address->sin_port = htons(port);
  return 0;
}
#endif

// Platform independent version of getaddrinfo()
//   Given a hostname:port, produce an addrinfo struct
static int GetAddrInfo(const char* hostname, int port,
                       struct addrinfo** address) {
#if defined(__linux__)
  char port_str[40];
  snprintf(port_str, 40, "%d", port);
  return getaddrinfo(hostname, port_str, NULL, address);
#else
  return GetAddrInfoNonLinux(hostname, port, address);
#endif
}

// Set up a connection to a ScrollView on hostname:port.
SVNetwork::SVNetwork(const char* hostname, int port) {
  mutex_send_ = new SVMutex();
  msg_buffer_in_ = new char[kMaxMsgSize + 1];
  msg_buffer_in_[0] = '\0';

  has_content = false;
  buffer_ptr_ = NULL;

  struct addrinfo *addr_info = NULL;

  if (GetAddrInfo(hostname, port, &addr_info) != 0) {
    std::cerr << "Error resolving name for ScrollView host "
              << std::string(hostname) << ":" << port << std::endl;
  }

  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);

  // If server is not there, we will start a new server as local child process.
  if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
    const char* scrollview_path = getenv("SCROLLVIEW_PATH");
    if (scrollview_path == NULL) {
#ifdef SCROLLVIEW_PATH
#define _STR(a) #a
#define _XSTR(a) _STR(a)
      scrollview_path = _XSTR(SCROLLVIEW_PATH);
#undef _XSTR
#undef _STR
#else
      scrollview_path = ".";
#endif
    }
    const char *prog = ScrollViewProg();
    std::string command = ScrollViewCommand(scrollview_path);
    SVSync::StartProcess(prog, command.c_str());

    // Wait for server to show up.
    // Note: There is no exception handling in case the server never turns up.

    stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);

    while (connect(stream_, addr_info->ai_addr,
                   addr_info->ai_addrlen) < 0) {
      std::cout << "ScrollView: Waiting for server...\n";
#ifdef _WIN32
      Sleep(1000);
#else
      sleep(1);
#endif

      stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);
    }
  }
  FreeAddrInfo(addr_info);
}

SVNetwork::~SVNetwork() {
  delete[] msg_buffer_in_;
  delete mutex_send_;
}

#endif  // GRAPHICS_DISABLED
<commit_msg>viewer/svutil: Fix resource leak<commit_after>///////////////////////////////////////////////////////////////////////
// File:        svutil.cpp
// Description: ScrollView Utilities
// Author:      Joern Wanke
// Created:     Thu Nov 29 2007
//
// (C) Copyright 2007, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////
//
// SVUtil contains the SVSync and SVNetwork classes, which are used for
// thread/process creation & synchronization and network connection.

#include <stdio.h>
#ifdef _WIN32
struct addrinfo {
  struct sockaddr* ai_addr;
  int ai_addrlen;
  int ai_family;
  int ai_socktype;
  int ai_protocol;
};
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/socket.h>
#ifdef __linux__
#include <sys/prctl.h>
#endif
#include <unistd.h>
#endif

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

// Include automatically generated configuration file if running autoconf.
#ifdef HAVE_CONFIG_H
#include "config_auto.h"
#endif

#ifndef GRAPHICS_DISABLED

#include "svutil.h"

const int kMaxMsgSize = 4096;

// Signals a thread to exit.
void SVSync::ExitThread() {
#ifdef _WIN32
  // ExitThread(0);
#else
  pthread_exit(0);
#endif
}

// Starts a new process.
void SVSync::StartProcess(const char* executable, const char* args) {
  std::string proc;
  proc.append(executable);
  proc.append(" ");
  proc.append(args);
  std::cout << "Starting " << proc << std::endl;
#ifdef _WIN32
  STARTUPINFO start_info;
  PROCESS_INFORMATION proc_info;
  GetStartupInfo(&start_info);
  if (!CreateProcess(NULL, const_cast<char*>(proc.c_str()), NULL, NULL, FALSE,
                CREATE_NO_WINDOW | DETACHED_PROCESS, NULL, NULL,
                &start_info, &proc_info))
    return;
#else
  int pid = fork();
  if (pid != 0) {   // The father process returns
  } else {
#ifdef __linux__
    // Make sure the java process terminates on exit, since its
    // broken socket detection seems to be useless.
    prctl(PR_SET_PDEATHSIG, 2, 0, 0, 0);
#endif
    char* mutable_args = strdup(args);
    int argc = 1;
    for (int i = 0; mutable_args[i]; ++i) {
      if (mutable_args[i] == ' ') {
        ++argc;
      }
    }
    char** argv = new char*[argc + 2];
    argv[0] = strdup(executable);
    argv[1] = mutable_args;
    argc = 2;
    bool inquote = false;
    for (int i = 0; mutable_args[i]; ++i) {
      if (!inquote && mutable_args[i] == ' ') {
        mutable_args[i] = '\0';
        argv[argc++] = mutable_args + i + 1;
      } else if (mutable_args[i] == '"') {
        inquote = !inquote;
        mutable_args[i] = ' ';
      }
    }
    argv[argc] = NULL;
    execvp(executable, argv);
    free(argv[0]);
    free(argv[1]);
    delete[] argv;
  }
#endif
}

SVSemaphore::SVSemaphore() {
#ifdef _WIN32
  semaphore_ = CreateSemaphore(0, 0, 10, 0);
#elif defined(__APPLE__)
  char name[50];
  snprintf(name, sizeof(name), "%ld", random());
  sem_unlink(name);
  semaphore_ = sem_open(name, O_CREAT , S_IWUSR, 0);
  if (semaphore_ == SEM_FAILED) {
    perror("sem_open");
  }
#else
  sem_init(&semaphore_, 0, 0);
#endif
}

void SVSemaphore::Signal() {
#ifdef _WIN32
  ReleaseSemaphore(semaphore_, 1, NULL);
#elif defined(__APPLE__)
  sem_post(semaphore_);
#else
  sem_post(&semaphore_);
#endif
}

void SVSemaphore::Wait() {
#ifdef _WIN32
  WaitForSingleObject(semaphore_, INFINITE);
#elif defined(__APPLE__)
  sem_wait(semaphore_);
#else
  sem_wait(&semaphore_);
#endif
}

SVMutex::SVMutex() {
#ifdef _WIN32
  mutex_ = CreateMutex(0, FALSE, 0);
#else
  pthread_mutex_init(&mutex_, NULL);
#endif
}

void SVMutex::Lock() {
#ifdef _WIN32
  WaitForSingleObject(mutex_, INFINITE);
#else
  pthread_mutex_lock(&mutex_);
#endif
}

void SVMutex::Unlock() {
#ifdef _WIN32
  ReleaseMutex(mutex_);
#else
  pthread_mutex_unlock(&mutex_);
#endif
}

// Create new thread.

void SVSync::StartThread(void *(*func)(void*), void* arg) {
#ifdef _WIN32
  LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE) func;
  DWORD threadid;
  HANDLE newthread = CreateThread(
  NULL,          // default security attributes
  0,             // use default stack size
  f,             // thread function
  arg,           // argument to thread function
  0,             // use default creation flags
  &threadid);    // returns the thread identifier
#else
  pthread_t helper;
  pthread_create(&helper, NULL, func, arg);
#endif
}

// Place a message in the message buffer (and flush it).
void SVNetwork::Send(const char* msg) {
  mutex_send_->Lock();
  msg_buffer_out_.append(msg);
  mutex_send_->Unlock();
}

// Send the whole buffer.
void SVNetwork::Flush() {
  mutex_send_->Lock();
  while (msg_buffer_out_.size() > 0) {
    int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
    msg_buffer_out_.erase(0, i);
  }
  mutex_send_->Unlock();
}

// Receive a message from the server.
// This will always return one line of char* (denoted by \n).
char* SVNetwork::Receive() {
  char* result = NULL;
#if defined(_WIN32) || defined(__CYGWIN__)
  if (has_content) { result = strtok (NULL, "\n"); }
#else
  if (buffer_ptr_ != NULL) { result = strtok_r(NULL, "\n", &buffer_ptr_); }
#endif

  // This means there is something left in the buffer and we return it.
  if (result != NULL) { return result;
  // Otherwise, we read from the stream_.
  } else {
    buffer_ptr_ = NULL;
    has_content = false;

    // The timeout length is not really important since we are looping anyway
    // until a new message is delivered.
    struct timeval tv;
    tv.tv_sec = 10;
    tv.tv_usec = 0;

    // Set the flags to return when the stream_ is ready to be read.
    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(stream_, &readfds);

    int i = select(stream_+1, &readfds, NULL, NULL, &tv);

    // The stream_ died.
    if (i == 0) { return NULL; }

    // Read the message buffer.
    i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);

    // Server quit (0) or error (-1).
    if (i <= 0) { return NULL; }
    msg_buffer_in_[i] = '\0';
    has_content = true;
#ifdef _WIN32
    return strtok(msg_buffer_in_, "\n");
#else
    // Setup a new string tokenizer.
    return strtok_r(msg_buffer_in_, "\n", &buffer_ptr_);
#endif
  }
}

// Close the connection to the server.
void SVNetwork::Close() {
#ifdef _WIN32
  closesocket(stream_);
#else
  close(stream_);
#endif
}

// The program to invoke to start ScrollView
static const char* ScrollViewProg() {
#ifdef _WIN32
  const char* prog = "java -Xms512m -Xmx1024m";
#else
  const char* prog = "sh";
#endif
  return prog;
}

// The arguments to the program to invoke to start ScrollView
static std::string ScrollViewCommand(std::string scrollview_path) {
  // The following ugly ifdef is to enable the output of the java runtime
  // to be sent down a black hole on non-windows to ignore all the
  // exceptions in piccolo. Ideally piccolo would be debugged to make
  // this unnecessary.
  // Also the path has to be separated by ; on windows and : otherwise.
#ifdef _WIN32
  const char* cmd_template = "-Djava.library.path=%s -jar %s/ScrollView.jar";

#else
  const char* cmd_template = "-c \"trap 'kill %%1' 0 1 2 ; java "
      "-Xms1024m -Xmx2048m -jar %s/ScrollView.jar"
      " & wait\"";
#endif
  int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path.c_str()) + 1;
  char* cmd = new char[cmdlen];
  const char* sv_path = scrollview_path.c_str();
  snprintf(cmd, cmdlen, cmd_template, sv_path, sv_path, sv_path, sv_path);
  std::string command(cmd);
  delete [] cmd;
  return command;
}

// Platform-independent freeaddrinfo()
static void FreeAddrInfo(struct addrinfo* addr_info) {
  #if defined(__linux__)
  freeaddrinfo(addr_info);
  #else
  delete addr_info->ai_addr;
  delete addr_info;
  #endif
}

// Non-linux version of getaddrinfo()
#if !defined(__linux__)
static int GetAddrInfoNonLinux(const char* hostname, int port,
                               struct addrinfo** addr_info) {
// Get the host data depending on the OS.
  struct sockaddr_in* address;
  *addr_info = new struct addrinfo;
  memset(*addr_info, 0, sizeof(struct addrinfo));
  address = new struct sockaddr_in;
  memset(address, 0, sizeof(struct sockaddr_in));

  (*addr_info)->ai_addr = (struct sockaddr*) address;
  (*addr_info)->ai_addrlen = sizeof(struct sockaddr);
  (*addr_info)->ai_family = AF_INET;
  (*addr_info)->ai_socktype = SOCK_STREAM;

  struct hostent *name;
#ifdef _WIN32
  WSADATA wsaData;
  WSAStartup(MAKEWORD(1, 1), &wsaData);
  name = gethostbyname(hostname);
#else
  name = gethostbyname(hostname);
#endif

  if (name == NULL) {
    FreeAddrInfo(*addr_info);
    *addr_info = NULL;
    return -1;
  }

  // Fill in the appropriate variables to be able to connect to the server.
  address->sin_family = name->h_addrtype;
  memcpy((char *) &address->sin_addr.s_addr,
         name->h_addr_list[0], name->h_length);
  address->sin_port = htons(port);
  return 0;
}
#endif

// Platform independent version of getaddrinfo()
//   Given a hostname:port, produce an addrinfo struct
static int GetAddrInfo(const char* hostname, int port,
                       struct addrinfo** address) {
#if defined(__linux__)
  char port_str[40];
  snprintf(port_str, 40, "%d", port);
  return getaddrinfo(hostname, port_str, NULL, address);
#else
  return GetAddrInfoNonLinux(hostname, port, address);
#endif
}

// Set up a connection to a ScrollView on hostname:port.
SVNetwork::SVNetwork(const char* hostname, int port) {
  mutex_send_ = new SVMutex();
  msg_buffer_in_ = new char[kMaxMsgSize + 1];
  msg_buffer_in_[0] = '\0';

  has_content = false;
  buffer_ptr_ = NULL;

  struct addrinfo *addr_info = NULL;

  if (GetAddrInfo(hostname, port, &addr_info) != 0) {
    std::cerr << "Error resolving name for ScrollView host "
              << std::string(hostname) << ":" << port << std::endl;
  }

  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);

  // If server is not there, we will start a new server as local child process.
  if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
    const char* scrollview_path = getenv("SCROLLVIEW_PATH");
    if (scrollview_path == NULL) {
#ifdef SCROLLVIEW_PATH
#define _STR(a) #a
#define _XSTR(a) _STR(a)
      scrollview_path = _XSTR(SCROLLVIEW_PATH);
#undef _XSTR
#undef _STR
#else
      scrollview_path = ".";
#endif
    }
    const char *prog = ScrollViewProg();
    std::string command = ScrollViewCommand(scrollview_path);
    SVSync::StartProcess(prog, command.c_str());

    // Wait for server to show up.
    // Note: There is no exception handling in case the server never turns up.

    Close();
    stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);

    while (connect(stream_, addr_info->ai_addr,
                   addr_info->ai_addrlen) < 0) {
      std::cout << "ScrollView: Waiting for server...\n";
#ifdef _WIN32
      Sleep(1000);
#else
      sleep(1);
#endif

      Close();
      stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
                   addr_info->ai_protocol);
    }
  }
  FreeAddrInfo(addr_info);
}

SVNetwork::~SVNetwork() {
  delete[] msg_buffer_in_;
  delete mutex_send_;
}

#endif  // GRAPHICS_DISABLED
<|endoftext|>


<commit_before>// [[Rcpp::depends(RcppArmadillo)]]

#include <RcppArmadillo.h>

using namespace Rcpp;
using namespace arma;

//' @export
// [[Rcpp::export]]
Rcpp::List returnLD(arma::vec cIndex, arma::mat gen) {

	int nCausal = cIndex.n_elem;

	// Create a list for the output to be stored in.
	// We need a list because each of the elements is a different
	// length.

	Rcpp::List output;

	for(int i = 0; i < nCausal; i++){

		// Give position of first element.
		// Remember that indexing starts at 0, not 1.
		int index = cIndex(0);

		// Return the column of base pair positions and the basepair position
		// at causal SNP i index
		arma::vec bpCol = gen.col(2);
		double bp = gen(index, 2);

		arma::uvec ldIndex = arma::find(bpCol > bp - 500000 && bpCol < bp + 500000, 0);
		// This gives us the indices of which SNPs are within 500kb of
		// the causal SNP.
		// So now we have to subset the matrix to just include these,
		// as including anything else would be useless calculation

		arma::mat subset = gen.rows(ldIndex);

		// Now that we have the collection of useful entries, we must
		// transform them into the R format
		//
		// 1. Cut off first 5 rows (but will need to save the indexes to recover
		//    these later)
	// Trying to fix the error
	//
		subset.shed_cols(0,4);
		arma::mat subset_bare = subset;

		// 2. Transpose (will have to do it at some point)

		arma::mat genT = subset_bare.t();

		// 3. Cooerce
		//
		// New output will have 1 for every three rows (with rows being the
		// old columns. It will have the same number of columns, as we aren't
		// changing the SNPs at all.

		arma::mat other(genT.n_rows / 3, genT.n_cols);

		for(int j = 0; j < genT.n_rows; j+=3){

			// The new row j / 3 (0, 1, 2, etc.) will be 0* none, 1 * 1,
			// and 2 x the double minor allele.
			other.row(j/3) = 0 * genT.row(j) + 1 * genT.row(j+1) + 2*genT.row(j+2);
		}

		// Now that this preprocessing is accomplished, we can bring in
		// the cor_gen.cpp function.
		//
		// Note that we won't directly import it, merely use the code,
		// because I don't actually know how to do that.
		//
		// Ideally I would do all this preprocessing at the same time as
		// above but I can't figure out how to do it right now.

		// We create a new vector with as many entries as there are SNPs.
		arma::vec out(other.n_cols);

		// Now create the "real" vector
		// Using the same process as above
		arma::vec causal_raw = gen.row(index);

	// Fixing error
		causal_raw.shed_rows(0,4);
		arma::vec causal_raw2 = causal_raw;

		arma::vec causal(causal_raw2.n_elem/3);

		for(int j = 0; j < causal_raw2.n_elem; j+=3){
			causal(j/3) = 0*causal(j) + 1*causal(j+1) + 2*causal(j+2);
		}

		// Now we have causal and other
		//
		// vec causal = Vector of dosage for the causal SNP that we
		//              have been looking for.
		// mat other = All the other SNP data. Note that causal IS
		// 		included in this. I will have to figure out
		// 		how to deal with this soon.
		//
		// Now move on to actually calculating the correlation.

		// For each column in the all matrix
		//
		// 1. Create a new vector out of the column
		// 2. Calculate correlation between causal and that column
		// 3. Put that into out

		for(int j = 0; j < other.n_cols; j++){

			arma::vec otherVec = other.col(j); // 1

			arma::mat temp = arma::cor(causal, otherVec); // 2

			out(j) = pow(temp(0,0),2); // 3

		}

		output[i] = out;

	}

	return output ;
}
<commit_msg>try Rcpp::NumericVector<commit_after>// [[Rcpp::depends(RcppArmadillo)]]

#include <RcppArmadillo.h>
#include<string>
#include<iostream>

using namespace Rcpp;
using namespace arma;

//' @export
// [[Rcpp::export]]
Rcpp::List returnLD(arma::vec cIndex, arma::mat gen) {

	int nCausal = cIndex.n_elem;

	// Create a list for the output to be stored in.
	// We need a list because each of the elements is a different
	// length.

	Rcpp::List output;

	for(int i = 0; i < nCausal; i++){

		// Give position of first element.
		// Remember that indexing starts at 0, not 1.
		int index = cIndex(0);

		// Return the column of base pair positions and the basepair position
		// at causal SNP i index
		arma::vec bpCol = gen.col(2);
		double bp = gen(index, 2);

		arma::uvec ldIndex = arma::find(bpCol > bp - 500000 && bpCol < bp + 500000, 0);
		// This gives us the indices of which SNPs are within 500kb of
		// the causal SNP.
		// So now we have to subset the matrix to just include these,
		// as including anything else would be useless calculation

		arma::mat subset = gen.rows(ldIndex);

		// Now that we have the collection of useful entries, we must
		// transform them into the R format
		//
		// 1. Cut off first 5 rows (but will need to save the indexes to recover
		//    these later)
	// Trying to fix the error
	//
		subset.shed_cols(0,4);
		arma::mat subset_bare = subset;

		// 2. Transpose (will have to do it at some point)

		arma::mat genT = subset_bare.t();

		// 3. Cooerce
		//
		// New output will have 1 for every three rows (with rows being the
		// old columns. It will have the same number of columns, as we aren't
		// changing the SNPs at all.

		arma::mat other(genT.n_rows / 3, genT.n_cols);

		for(int j = 0; j < genT.n_rows; j+=3){

			// The new row j / 3 (0, 1, 2, etc.) will be 0* none, 1 * 1,
			// and 2 x the double minor allele.
			other.row(j/3) = 0 * genT.row(j) + 1 * genT.row(j+1) + 2*genT.row(j+2);
		}

		// Now that this preprocessing is accomplished, we can bring in
		// the cor_gen.cpp function.
		//
		// Note that we won't directly import it, merely use the code,
		// because I don't actually know how to do that.
		//
		// Ideally I would do all this preprocessing at the same time as
		// above but I can't figure out how to do it right now.

		// We create a new vector with as many entries as there are SNPs.
		// arma::vec out(other.n_cols);

		// Now create the "real" vector
		// Using the same process as above
		arma::vec causal_raw = gen.row(index);

	// Fixing error
		causal_raw.shed_rows(0,4);
		arma::vec causal_raw2 = causal_raw;

		arma::vec causal(causal_raw2.n_elem/3);

		for(int j = 0; j < causal_raw2.n_elem; j+=3){
			causal(j/3) = 0*causal(j) + 1*causal(j+1) + 2*causal(j+2);
		}

		// Now we have causal and other
		//
		// vec causal = Vector of dosage for the causal SNP that we
		//              have been looking for.
		// mat other = All the other SNP data. Note that causal IS
		// 		included in this. I will have to figure out
		// 		how to deal with this soon.
		//
		// Now move on to actually calculating the correlation.

		// For each column in the all matrix
		//
		// 1. Create a new vector out of the column
		// 2. Calculate correlation between causal and that column
		// 3. Put that into out

		NumericVector out(other.n_cols);

		for(int j = 0; j < other.n_cols; j++){

			arma::vec otherVec = other.col(j); // 1

			arma::mat temp = arma::cor(causal, otherVec); // 2

			out(j) = pow(temp(0,0),2); // 3

		}

		cout << out << "\n";

		output[i] = out;

	}

	return output ;
}
<|endoftext|>