Example #1
0
void RemoteSync::syncReply(WP::err code)
{
    if (code != WP::kOk)
        return;

    QByteArray data = fServerReply->readAll();
    fServerReply = NULL;

    IqInStanzaHandler iqHandler(kResult);
    SyncPullData syncPullData;
    SyncPullHandler *syncPullHandler = new SyncPullHandler(&syncPullData);
    iqHandler.addChildHandler(syncPullHandler);

    ProtocolInStream inStream(data);
    inStream.addHandler(&iqHandler);

    inStream.parse();

    QString localBranch = fDatabase->branch();
    QString localTipCommit = fDatabase->getTip();
    QString lastSyncCommit = fDatabase->getLastSyncCommit(fRemoteStorage->getUid(), localBranch);

    if (!syncPullHandler->hasBeenHandled() || syncPullData.branch != localBranch) {
        // error occured, the server should at least send back the branch name
        // TODO better error message
        emit syncFinished(WP::kBadValue);
        return;
    }
    if (syncPullData.tip == localTipCommit) {
        // done
        emit syncFinished(WP::kOk);
        return;
    }
    // see if the server is ahead by checking if we got packages
    if (syncPullData.pack.size() != 0) {
        fSyncUid = syncPullData.tip;
        WP::err error = fDatabase->importPack(syncPullData.pack, lastSyncCommit,
                                              syncPullData.tip);
        if (error != WP::kOk) {
            emit syncFinished(error);
            return;
        }

        localTipCommit = fDatabase->getTip();
        // done? otherwise it was a merge and we have to push our merge
        if (localTipCommit == lastSyncCommit) {
            emit syncFinished(WP::kOk);
            return;
        }
    }

    // we are ahead of the server: push changes to the server
    QByteArray pack;
    WP::err error = fDatabase->exportPack(pack, lastSyncCommit, localTipCommit, fSyncUid);
    if (error != WP::kOk) {
        emit syncFinished(error);
        return;
    }
    fSyncUid = localTipCommit;

    QByteArray outData;
    ProtocolOutStream outStream(&outData);

    IqOutStanza *iqStanza = new IqOutStanza(kSet);
    outStream.pushStanza(iqStanza);
    OutStanza *pushStanza = new OutStanza("sync_push");
    pushStanza->addAttribute("branch", localBranch);
    pushStanza->addAttribute("start_commit", syncPullData.tip);
    pushStanza->addAttribute("last_commit", localTipCommit);
    outStream.pushChildStanza(pushStanza);
    OutStanza *pushPackStanza = new OutStanza("pack");
    pushPackStanza->setText(pack.toBase64());
    outStream.pushChildStanza(pushPackStanza);

    outStream.flush();

    fServerReply = fRemoteConnection->send(outData);
    connect(fServerReply, SIGNAL(finished(WP::err)), this, SLOT(syncPushReply(WP::err)));
}
Example #2
0
int main( int argc, char **argv)
{
    const char *multicastAddress = "236.0.0.1";
    const char *multicastPort = "3636";
    const char *multicastInterface = "127.0.0.1";

    // Handle options
    for(;;) {
	int optionIndex = 0;
	static struct option options[] = {
	    { "verbose", no_argument, 0, 'v' },
	    { "help",    no_argument, 0, 'h' },
	    { "frequency", required_argument, 0, 'f' },
	    { "multicast-address", required_argument, 0, 'a'},
	    { "multicast-port", required_argument, 0, 'p' },
	    { "multicast-interface", required_argument, 0, 'i' },
	    { "min-packet", required_argument, 0, 'm' },
	    { "read-file", required_argument, 0, 'r' },
	    { "histogram", no_argument, 0, 'H' },
	    { "modes", no_argument, 0, 'M' },
	    { 0,0,0,0}
	};

	int c = getopt_long( argc, argv, "vh?HMf:a:p:i:m:r:", options, &optionIndex );
	if ( c == -1) break;

	switch(c) {
	  case 'h':
	  case '?':
	    showHelp(stdout);
	    return 0;
	  case 'v':
	    verbose = 1;
	    break;
	  case 'H':
	    showHistogram = 1;
	    break;
	  case 'M':
	    showModes = 1;
	    break;
	  case 'f':
	    // set frequency to optarg
	      {
		  unsigned f = atoi( optarg);
		  if (f==0) {
		      fprintf(stderr,"Bad frequency: %s\n", optarg);
		      exit(1);
		  }
		  centerFrequency = f;
	      }
	    break;
	  case 'm':
	    minPacket = atoi(optarg);
	    break;
	  case 'a':
	    multicastAddress = optarg;
	    break;
	  case 'i':
	    multicastInterface = optarg;
	    break;
	  case 'p':
	    multicastPort = optarg;
	    break;
	  case 'r':
	    inputFileName = optarg;
	    break;
	  default:
	    fprintf(stderr,"Illegal option\n");
	    showHelp(stderr);
	    exit(1);
	}
    }

    setupNetworking(multicastAddress, multicastPort, multicastInterface);

    signal(SIGINT, exitNicely);

    if ( inputFileName == 0) {
	struct rtldev *rtl = rtlOpen(NULL,0);
	if ( !rtl) {
	    fprintf(stderr,"Failed to open RTL SDR device\n");
	    exit(1);
	}

	if ( rtlSetup( rtl, centerFrequency, sampleRate) < 0) {
	    fprintf(stderr,"Failed to setup RTL SDR for %uHz %usamp/sec\n", centerFrequency, sampleRate);
	}

	// something must call rtlStop(rtl) to kill this, to this end we stash in a global, ick
	rtlToStop = rtl;
	if ( rtlRun( rtl, iqHandler, 0)) {
	    fprintf(stderr, "Failed to run iqHandler\n");
	}
	rtlToStop = 0;

	rtlClose(rtl);
    } else {
	FILE *in = fopen( inputFileName, "r");
	if ( !in) {
	    fprintf(stderr, "Failed to open input file '%s': %s\n", inputFileName, strerror(errno));
	    exit(1);
	}

	for(;;) {
	    unsigned char buf[16384];
	    size_t got = fread( buf, 1, sizeof(buf), in);
	    if ( got == 0 && feof(in)) break;
	    if ( got == 0) {
		fprintf(stderr, "Error while reading input file: %s\n", strerror(errno));
		exit(1);
	    }
	    iqHandler( buf, got, 0, 0);
	}

	fclose(in);
    }

    //
    // the rest of this is just in case someone is running a leak detector on us.
    //
    if ( multicastSocket != -1) {
	close(multicastSocket);
	multicastSocket = -1;
    }
    if ( multicastSockaddr) {
	free(multicastSockaddr);
	multicastSockaddr = 0;
	multicastSockaddrLen = 0;
    }

    return 0;
}