Example #1
0
/**
 * @brief Read 1 or more bytes from the I2C slave at the specified memory address
 * @param device_address The address of the device to read from
 * @param start_address The memory address to read from
 * @param data The allocated array to read into
 * @param data_bytes The number of bytes to read
 */
void SoftwareI2C::randomRead(char device_address, char start_address, char* data, char data_bytes) {
	if (data == 0 || data_bytes == 0) return;

	device_address = device_address & 0xFE;
	start();
	putByte(device_address);
	if (!getAck()) {
		return;
	}
	putByte(start_address);
	if (!getAck()) {
		return;
	}

	device_address=device_address | 0x01;
	start();
	putByte(device_address);
	if (!getAck()) {
		return;
	}
	for ( int x = 0; x < data_bytes; ++x) {
		data[x] = getByte();
		if (x != (data_bytes - 1)) giveAck();
	}
	stop();
}
Example #2
0
/**
 * @brief Write 1 byte to the I2C slave
 * @param device_address The address of the device to write to
 * @param byte The data to write
 */
void SoftwareI2C::write(uint8_t device_address, uint8_t byte) {
    device_address = device_address & 0xFE;
    start();
    putByte(device_address);
    getAck();
    putByte(byte);
    getAck();
    stop();
}
Example #3
0
/**
 * @brief Write 1 byte to the I2C slave
 * @param device_address The address of the device to write to
 * @param byte The data to write
 */
void SoftwareI2C::write(char device_address, char byte) {
	device_address = device_address & 0xFE;
	start();
	putByte(device_address);
	getAck();
	putByte(byte);
	getAck();
	stop();
}
Example #4
0
/**
 * @brief Write 1 or more bytes to the I2C slave
 * @param device_address The address of the device to write to
 * @param data An array to write the data from
 * @param data_bytes Number of bytes to write from array
 */
void SoftwareI2C::write(char device_address, char* data,  char data_bytes) {
	if (data == 0 || data_bytes == 0) return;

	device_address = device_address & 0xFE;
	start();
	putByte(device_address);
	getAck();
	for ( int x = 0; x < data_bytes; ++x ) {
		putByte(data[x]);
		getAck();
	}
	stop();
}
Example #5
0
/**
 * @brief Write 1 or more bytes to the I2C slave at the specified memory address
 * @param device_address The address of the device to write to
 * @param start_address The memory address to write to
 * @param data The data to write
 * @param data_bytes The number of bytes to write
 */
void SoftwareI2C::randomWrite(uint8_t device_address, uint8_t start_address, uint8_t* data, uint8_t data_bytes) {
    if (data == 0 || data_bytes == 0) return;

    device_address = device_address & 0xFE;
    start();
    putByte(device_address);
    getAck();
    putByte(start_address);
    getAck();
    for ( int x = 0; x <= data_bytes; ++x ) {
        putByte(data[x]);
        getAck();
    }
    stop();
}
bufferStruct receiveSendData(bufferStruct buffer){
	bufferStruct result;
	if(getAck(buffer.bufferLength, buffer.buffer) & NEED_ACK > 0){
		#if STATE_UART_DEBUG >= 2
			uart_putstr ("seAck\r\n");
		#endif
		state = STATE_SENDING_ACK;
		
		backupData.bufferLength = buffer.bufferLength;
		memcpy(backupData.buffer, buffer.buffer, buffer.bufferLength);
		
		sendAck(buffer);
	} else {
		result.bufferLength = getPayloadLength(buffer.bufferLength, buffer.buffer);
		memcpy(result.buffer, getPayload(buffer.bufferLength, buffer.buffer), result.bufferLength);
		
		#if STATE_UART_DEBUG >= 3
		uart_putc('%');
		uart_putc(result.bufferLength);
		uart_putc('%');
		for(uint8_t i = 0; i < result.bufferLength; ++i){
			uart_putc(result.buffer[i]);
		}
		uart_putc('%');
		#endif
	}	
	return result;
}
Example #7
0
int clientSlidingWindow( UdpSocket &sock, const int max, int message[], int windowSize ) {
	cerr << "Sliding-window test:" << endl;
	int lar = -1;										// last acknowledgment received
	int seq = 0;										// current seq #
	int retransmits = 0;
	if(sock.pollRecvFrom() > 0) {						// check for any old acks
		sock.recvFrom( ( char * ) message, MSGSIZE );		// clean out the socket
	}
	vector<int> window(windowSize);
	for(int i = 0; i < windowSize; i++) { 				//init window
		window[i] = -1;
	}
	Timer t;
	while( seq < max) {
		while(seq - lar <= windowSize && seq < max) {		// while seq is within window
			message[0] = seq;									// append seq to message
			sock.sendTo((char*) message, MSGSIZE);				// send message
			seq++;												// increment seq
		}
		long lap;
		t.start();											// timer start
		while ((lap = t.lap()) < 1500) {
			if(sock.pollRecvFrom() > 0) {					// while not timed out
				getAck(lar, sock);								// check for an ack
				break;
			}
		}
		if (lap >=1500) {									// if no ack
			seq = lar+1;										// reset sequence #
			retransmits++;
		}
	}
	return retransmits;
}
Example #8
0
/**
 * Send a message.
 * Waits for the firmware to acknowlge and resends the packet
 * a few timew if not acknowledged.
 * @param m The message to send
 * @throw   Transport::Exception if never acknowledged.
 */
void Transport::send(Message *m)
{
    CHECK_THROW_CONFIGURED();

    char skip_send = 0;
    Message* ack = NULL;
    int transmit_times = 0;
    short result_code;

    poll();

    while(1) {
        // We have exceeded our retry numbers
        if (transmit_times > this->retries) {
            break;
        }
        // Write output
        if (!skip_send) WriteData(serial, (char*)(m->data), m->total_len);

        // Wait up to 100 ms for ack
        for(int i = 0; i<RETRY_DELAY_MS; ++i) {
            usleep(1000);
            if( (ack=getAck()) ) break;
        }

        // No message - resend
        if (ack == NULL) {
            skip_send = 0;
            //cout << "No message received yet" << endl;
            transmit_times++;
            continue;
        }

        // Check result code
        // If the result code is bad, the message was still transmitted
        // successfully
        result_code = btou(ack->getPayloadPointer(), 2);
        if (result_code > 0) {
            throw new BadAckException(result_code);
        } else {
            // Everything's good - return
            break;
        }
        // Other failure
        transmit_times++;
    }
    if( ack == NULL ) {
        throw new TransportException("Unacknowledged send", TransportException::UNACKNOWLEDGED_SEND);
    } 
    delete ack;

    m->is_sent = true;
}
Example #9
0
/**
 * @brief Read 1 or more bytes from the I2C slave
 * @param device_address The address of the device to read from
 * @param data An allocated array to read the data into
 * @param data_bytes Number of bytes to read (must be equal to or less then the allocated memory in data)
 */
void SoftwareI2C::read(char device_address, char* data, char data_bytes) {
	if (data == 0 || data_bytes == 0) return;

	device_address = device_address | 0x01;
	start();
	putByte(device_address);
	getAck();
	for (int x = 0; x < data_bytes; ++x) {
		data[x] = getByte();
		if ( x < (data_bytes -1)) { //ack all but the final byte
			giveAck();
		}
	}
	stop();
}
Example #10
0
// Put a byte across the wire
// Return true if the slave acknowledges
static boolean putByte(const I2C_ABSTRACT_BUS* bus, uint8_t b){
	const I2C_SOFTWARE_BUS* i2c = (const I2C_SOFTWARE_BUS*)bus;
	int8_t i;

	for(i=7; i>=0; i--){
		if( b & 0x80 ){
			sda_high(i2c);
		}else{
			sda_low(i2c);
		}
		scl_high(i2c);
		b <<= 1;
		scl_low(i2c);
	}
	return getAck(i2c);						// return ACK value
}
void MUXSender(BCSPStack * stack)
{
	Packet * pkt = null ;

	while(1) 
	{
		//wait for the slip-sender to be available - (the slip-sender only has one packet
		//slot rather than a queue to prevent problems with window-rollbacks.

		if (stack->SLIPInputPacket) SYNCBLKwaitSignal(stack,&stack->SLIPSendAvailableSignal) ;

		//we prefer to send an unreliable packet if one is available
		pkt=ASYNCBLKgetPacketFromBuffer(stack,&stack->MUXUnreliableInput) ;


		//otherwise, we'll take a reliable one if one is available
		if (!pkt) pkt = ASYNCBLKremoveFirstUnsentPacketFromWindow(stack,&stack->theXMITWindow) ;

		//the last resort is to send a dedicated ack packet but we only need 
		//to do this if an ack is definitely required
		if (!pkt)
		{
			if (!stack->ackRequired) SYNCBLKwaitSignal(stack,&stack->txackSignal) ; 
			//blocking on the signal has the side-effect of also blocking on the
			//previous conditions so we'll be woken up by anything
			stack->ackRequired = false ;
			pkt = &stack->theAckPacket ; //use the dedicated ack packet
		}

		//ok - at this point we have a packet and we're intent on sending it

		setAck(pkt, stack->txack) ; //set the correct acknowledgement number
		
		//add the checksum to the header after setting crc
		if (stack->configuration->useCRC) setPacketHasCRC(pkt) ;
		setPacketChecksum(pkt) ;

		//pass it on to SLIP layer
        // JBS: no GetTickCount on POSIX
        //   BTRACE5(MUX,"MUX sending pkt %p seq %d ack %d len %d time %d\n",pkt,getSeq(pkt),getAck(pkt),getLength(pkt), GetTickCount() ) ;
		BTRACE4(MUX,"MUX sending pkt %p seq %d ack %d len %d\n",pkt,getSeq(pkt),getAck(pkt),getLength(pkt)) ;
		
		stack->SLIPInputPacket = pkt ;
		setSignal(stack,&stack->MUXHasPacketForSLIPSignal) ;
	}
}
Example #12
0
bufferStruct checkReceiveData(bufferStruct buffer){
	rfm12_tick();  //periodic tick function - call that one once in a while
	switch(state){
		case STATE_TIMEOUT:
			#if STATE_UART_DEBUG >= 2
				uart_putstr ("tiOu\r\n");
			#endif
			++timoutCounter;
			if(timoutCounter > 5){
				#if STATE_UART_DEBUG >= 2
					uart_putstr ("tiOuOverl\r\n");
				#endif
				state = STATE_FREE;
				stopTimer();
				timoutCounter = 0;
			} else {
				processNack();
			}			
			break;
		case STATE_SENDING_ACK:
			if(rfm12_tx_status() == STATUS_FREE){
				state = STATE_SENDING_DATA;
				#if STATE_UART_DEBUG >= 2
					uart_putstr ("finSeAck\r\n");
				#endif
				
				bufferStruct result;
				result.bufferLength = getPayloadLength(backupData.bufferLength, backupData.buffer);
				memcpy(result.buffer, getPayload(backupData.bufferLength, backupData.buffer), result.bufferLength);
				
				uart_putc('%');
				uart_putc(result.bufferLength);
				uart_putc('%');
				for(uint8_t i = 0; i < result.bufferLength; ++i){
					uart_putc(result.buffer[i]);
				}
				uart_putc('%');
				
				return result;
			}
		case STATE_SENDING_DATA:
			if(rfm12_tx_status() == STATUS_FREE){
				#if STATE_UART_DEBUG >= 2
					uart_putstr ("finSeData\r\n");
				#endif
				state = STATE_FREE;
			}				
			
	}
//uart_putstr (rfm12_rx_status());
	if (rfm12_rx_status() == STATUS_COMPLETE){
	
		bufferStruct tempBuffer;
		tempBuffer.bufferLength = rfm12_rx_len();
		memcpy(tempBuffer.buffer, rfm12_rx_buffer(), tempBuffer.bufferLength);
		
		if(validateCrc(tempBuffer)){
			#if STATE_UART_DEBUG >= 2
				uart_putstr ("crcAck\r\n");
			#endif
		} else {
			#if STATE_UART_DEBUG >= 2
				uart_putstr ("crcNack\r\n");
			#endif
			rfm12_rx_clear();
			sendNack(tempBuffer);
			return buffer;
		}

		if(state > STATE_FREE){
			if(getAck(tempBuffer.bufferLength, tempBuffer.buffer) & ACK){
				#if STATE_UART_DEBUG >= 2
				uart_putstr ("rxAck\r\n");
				#endif
				processAck();
			} else if(getType(tempBuffer.bufferLength, tempBuffer.buffer) & NACK){
				#if STATE_UART_DEBUG >= 2
				uart_putstr ("rxNack\r\n");
				#endif
				processNack();

			}				
		}		
		if(state == STATE_FREE){
			switch(getType(tempBuffer.bufferLength, tempBuffer.buffer)){
				case SEND_DATA:
					#if STATE_UART_DEBUG >= 2
						uart_putstr ("send\r\n");
					#endif
					buffer = receiveSendData(tempBuffer);
					break;
			// here we should implement the cases of repeating data therefore we would have to know all last data sent
			// here we should implement the get back to in -> timeframe not yet implemented		
			}
		}	
		// tell the implementation that the buffer
		// can be reused for the next data.
		rfm12_rx_clear();
	}
	return buffer;
}
Example #13
0
void CAnalogueRepeaterApp::createThread()
{
	CAnalogueRepeaterThread* thread = new CAnalogueRepeaterThread;

	wxString openId, closeId, beacon1, beacon2;
	unsigned int speed, freq;
	wxFloat32 level1, level2;
	AUDIO_SOURCE openIdSource, closeIdSource, beacon1Source, beacon2Source;
	getCallsign(openIdSource, openId, closeIdSource, closeId, beacon1Source, beacon1, beacon2Source, beacon2, speed, freq, level1, level2);
	wxLogInfo(wxT("Open ID source: %d, value: \"%s\", close ID source: %d, value: \"%s\", beacon 1 source: %d, value: \"%s\", beacon 2 source: %d, value: \"%s\", speed: %u WPM, freq: %u Hz, level1: %.3f, level2: %.3f"), int(openIdSource), openId.c_str(), int(closeIdSource), closeId.c_str(), int(beacon1Source), beacon1.c_str(), int(beacon2Source), beacon2.c_str(), speed, freq, level1, level2);

	IFixedAudioSource* openIdAudio  = NULL;
	IFixedAudioSource* closeIdAudio = NULL;
	IFixedAudioSource* beacon1Audio = NULL;
	IFixedAudioSource* beacon2Audio = NULL;

	switch (openIdSource) {
		case AS_CW_KEYER:
			openIdAudio = new CCWKeyer(openId, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(openId, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					openIdAudio = audio;
			}
			break;
	}

	switch (closeIdSource) {
		case AS_CW_KEYER:
			closeIdAudio = new CCWKeyer(closeId, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(closeId, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					closeIdAudio = audio;
			}
			break;
	}

	switch (beacon1Source) {
		case AS_CW_KEYER:
			beacon1Audio = new CCWKeyer(beacon1, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(beacon1, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					beacon1Audio = audio;
			}
			break;
	}

	switch (beacon2Source) {
		case AS_CW_KEYER:
			beacon2Audio = new CCWKeyer(beacon2, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(beacon2, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					beacon2Audio = audio;
			}
			break;
	}

	thread->setCallsign(openIdAudio, closeIdAudio, beacon1Audio, beacon2Audio, level1, level2);

	wxString radioAck, extAck, batteryAck;
	unsigned int ack, minimum;
	wxFloat32 level;
	AUDIO_SOURCE radioAckSource, extAckSource, batteryAckSource;
	getAck(radioAckSource, radioAck, extAckSource, extAck, batteryAckSource, batteryAck, speed, freq, level, ack, minimum);
	wxLogInfo(wxT("Radio ack source: %d, radio ack: \"%s\", network ack source: %d, network ack: \"%s\", battery ack source: %d, battery ack: \"%s\", speed: %u WPM, freq: %u Hz, level: %.3f, ack: %u ms, minimum: %u ms"), int(radioAckSource), radioAck.c_str(), int(extAckSource), extAck.c_str(), int(batteryAckSource), batteryAck.c_str(), speed, freq, level, ack, minimum);

	IFixedAudioSource* radioAckAudio   = NULL;
	IFixedAudioSource* extAckAudio     = NULL;
	IFixedAudioSource* batteryAckAudio = NULL;

	switch (radioAckSource) {
		case AS_CW_KEYER:
			radioAckAudio = new CCWKeyer(radioAck, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(radioAck, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					radioAckAudio = audio;
			}
			break;
	}

	switch (extAckSource) {
		case AS_CW_KEYER:
			extAckAudio = new CCWKeyer(extAck, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(extAck, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					extAckAudio = audio;
			}
			break;
	}

	switch (batteryAckSource) {
		case AS_CW_KEYER:
			batteryAckAudio = new CCWKeyer(batteryAck, speed, freq, ANALOGUE_RADIO_SAMPLE_RATE);
			break;
		case AS_WAV_FILE: {
				CWAVFileStore* audio = new CWAVFileStore;
				bool res = audio->load(extAck, ANALOGUE_RADIO_SAMPLE_RATE);
				if (!res)
					delete audio;
				else
					batteryAckAudio = audio;
			}
			break;
	}

	thread->setAck(radioAckAudio, extAckAudio, batteryAckAudio, level, ack, minimum);

	unsigned int callsignTime, timeout, lockoutTime, hangTime, latchTime;
	getTimes(callsignTime, timeout, lockoutTime, hangTime, latchTime);
	thread->setTimes(callsignTime, timeout, lockoutTime, hangTime, latchTime);
	wxLogInfo(wxT("Times set to: callsign time: %u secs, timeout: %u secs, lockout time: %u secs, hang time: %u secs, latch time: %u secs"), callsignTime, timeout, lockoutTime, hangTime, latchTime);

	bool tbEnable, ctcssInternal;
	wxFloat32 tbThreshold, ctcssFreq, ctcssThresh, ctcssLevel;
	unsigned int ctcssHangTime;
	ANALOGUE_CTCSS_OUTPUT ctcssOutput;
	getTones(tbEnable, tbThreshold, ctcssFreq, ctcssInternal, ctcssThresh, ctcssLevel, ctcssHangTime, ctcssOutput);
	thread->setTones(tbEnable, tbThreshold, ctcssFreq, ctcssInternal, ctcssThresh, ctcssLevel, ctcssHangTime, ctcssOutput);
	wxLogInfo(wxT("Tones set to: toneburst enable: %u, threshold: %.3f, CTCSS freq: %.1f Hz, internal: %u, threshold: %.3f, level: %.3f, hang time: %u ms, output: %d"), tbEnable, tbThreshold, ctcssFreq, ctcssInternal, ctcssThresh, ctcssLevel, ctcssHangTime * 20U, ctcssOutput);

	ANALOGUE_CALLSIGN_START callsignAtStart;
	unsigned int callsignStartDelay;
	bool callsignAtEnd;
	ANALOGUE_TIMEOUT_TYPE timeoutType;
	ANALOGUE_CALLSIGN_HOLDOFF callsignHoldoff;
	getFeel(callsignAtStart, callsignStartDelay, callsignAtEnd, timeoutType, callsignHoldoff);
	thread->setFeel(callsignAtStart, callsignStartDelay, callsignAtEnd, timeoutType, callsignHoldoff);
	wxLogInfo(wxT("Feel set to: callsignAtStart: %d, callsignStartDelay: %u s, callsignAtEnd: %u, timeoutType: %d, callsignHoldoff: %d"), callsignAtStart, callsignStartDelay, callsignAtEnd, timeoutType, callsignHoldoff);

	wxString readDevice, writeDevice;
	unsigned int audioDelay;
	bool deEmphasis, preEmphasis, vogad;
	getRadio(readDevice, writeDevice, audioDelay, deEmphasis, preEmphasis, vogad);
	wxLogInfo(wxT("Radio soundcard set to %s:%s, delay: %u ms, de-emphasis: %d, pre-emphasis %d, vogad: %d"), readDevice.c_str(), writeDevice.c_str(), audioDelay * 20U, int(deEmphasis), int(preEmphasis), int(vogad));

	if (!readDevice.IsEmpty() && !writeDevice.IsEmpty()) {
		CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(readDevice, writeDevice, ANALOGUE_RADIO_SAMPLE_RATE, ANALOGUE_RADIO_BLOCK_SIZE);
		soundcard->setCallback(thread, SOUNDCARD_RADIO);

		bool res = soundcard->open();
		if (!res)
			wxLogError(wxT("Cannot open the radio sound card"));
		else
			thread->setRadio(soundcard, audioDelay, deEmphasis, preEmphasis, vogad);
	}

	wxString type;
	unsigned int pttDelay, squelchDelay, cfg;
	bool pttInvert, squelchInvert;
	getController(type, cfg, pttDelay, squelchDelay, pttInvert, squelchInvert);
	wxLogInfo(wxT("Controller set to %s, config: %u, ptt delay: %u ms, squelch delay: %u ms, ptt invert: %d, squelch invert: %d"), type.c_str(), cfg, pttDelay * 20U, squelchInvert * 20U, pttInvert, squelchInvert);

	CExternalController* controller = NULL;

	wxString port;
	if (type.StartsWith(wxT("Velleman K8055 - "), &port)) {
		unsigned long num;
		port.ToULong(&num);
		controller = new CExternalController(new CK8055Controller(num), pttInvert, squelchInvert);
	} else if (type.StartsWith(wxT("Serial - "), &port)) {
		controller = new CExternalController(new CSerialLineController(port, cfg), pttInvert, squelchInvert);
	} else if (type.StartsWith(wxT("Arduino - "), &port)) {
		controller = new CExternalController(new CArduinoController(port), pttInvert, squelchInvert);
#if defined(GPIO)
	} else if (type.IsSameAs(wxT("GPIO"))) {
		controller = new CExternalController(new CGPIOController(cfg), pttInvert, squelchInvert);
#endif
	} else {
		controller = new CExternalController(new CDummyController, pttInvert, squelchInvert);
	}

	bool res = controller->open();
	if (!res)
		wxLogError(wxT("Cannot open the hardware interface - %s"), type.c_str());
	else
		thread->setController(controller, pttDelay, squelchDelay);

	ANALOGUE_EXTERNAL_MODE mode;
	wxString device;
	SERIALPIN txPin, rxPin;
	bool background;
	getExternal(mode, readDevice, writeDevice, audioDelay, deEmphasis, preEmphasis, vogad, device, txPin, rxPin, background);
	wxLogInfo(wxT("External mode: %d, soundcard set to %s:%s, delay: %u ms, de-emphasis: %d, pre-emphasis %d, vogad: %u, interface set to %s, tx %d, rx %d, background: %d"), mode, readDevice.c_str(), writeDevice.c_str(), audioDelay * 20U, int(deEmphasis), int(preEmphasis), int(vogad), device.c_str(), txPin, rxPin, int(background));

	if (mode != AEM_DISABLED) {
		CSoundCardReaderWriter* soundcard = new CSoundCardReaderWriter(readDevice, writeDevice, ANALOGUE_RADIO_SAMPLE_RATE, ANALOGUE_RADIO_BLOCK_SIZE);
		soundcard->setCallback(thread, SOUNDCARD_EXTERNAL);

		bool res = soundcard->open();
		if (!res) {
			wxLogError(wxT("Cannot open the external sound card"));
		} else {
			// This works even for an empty device name
			CNetworkController* controller = new CNetworkController(device, txPin, rxPin);

			res = controller->open();
			if (!res)
				wxLogError(wxT("Cannot open serial port - %s"), device.c_str());
			else
				thread->setExternal(mode, soundcard, audioDelay, deEmphasis, preEmphasis, vogad, controller, background);
		}
	}

	bool out1, out2, out3, out4;
	getOutputs(out1, out2, out3, out4);
	thread->setOutputs(out1, out2, out3, out4);
	m_frame->setOutputs(out1, out2, out3, out4);
	wxLogInfo(wxT("Output 1: %d, output 2: %d, output 3: %d, output 4: %d"), out1, out2, out3, out4);

	bool dtmfRadio, dtmfExternal;
	wxString dtmfShutdown, dtmfStartup, dtmfTimeout, dtmfTimeReset, dtmfOutput1, dtmfOutput2, dtmfOutput3, dtmfOutput4;
	wxString dtmfCommand1, dtmfCommand1Line, dtmfCommand2, dtmfCommand2Line;
	wxFloat32 dtmfThreshold;
	getDTMF(dtmfRadio, dtmfExternal, dtmfShutdown, dtmfStartup, dtmfTimeout, dtmfTimeReset, dtmfCommand1, dtmfCommand1Line, dtmfCommand2, dtmfCommand2Line, dtmfOutput1, dtmfOutput2, dtmfOutput3, dtmfOutput4, dtmfThreshold);
	thread->setDTMF(dtmfRadio, dtmfExternal, dtmfShutdown, dtmfStartup, dtmfTimeout, dtmfTimeReset, dtmfCommand1, dtmfCommand1Line, dtmfCommand2, dtmfCommand2Line, dtmfOutput1, dtmfOutput2, dtmfOutput3, dtmfOutput4, dtmfThreshold);
	wxLogInfo(wxT("DTMF: Radio: %d, External: %d, Shutdown: %s, Startup: %s, Timeout: %s, Time Reset: %s, Command1: %s = %s, Command2: %s = %s, Output1: %s, Output2: %s, Output3: %s, Output4: %s, Threshold: %f"), dtmfRadio, dtmfExternal, dtmfShutdown.c_str(), dtmfStartup.c_str(), dtmfTimeout.c_str(), dtmfTimeReset.c_str(), dtmfCommand1.c_str(), dtmfCommand1Line.c_str(), dtmfCommand2.c_str(), dtmfCommand2Line.c_str(), dtmfOutput1.c_str(), dtmfOutput2.c_str(), dtmfOutput3.c_str(), dtmfOutput4.c_str(), dtmfThreshold);

	unsigned int activeHangTime;
	getActiveHang(activeHangTime);
	thread->setActiveHang(activeHangTime);
	wxLogInfo(wxT("Active Hang: time: %u"), activeHangTime);

	// Convert the worker class into a thread
	m_thread = new CAnalogueRepeaterThreadHelper(thread);
	m_thread->start();
}
Example #14
0
int main(int argc, char *argv[])
{
    double probLoss, probCorruption;
    int sockfd, newsockfd, portno, pid, CWnd;
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;
    struct Header packetHeader;
    struct sigaction sa;

    time_t t;
    srand((unsigned)time(&t));

    if (argc < 5) {
        fprintf(stderr, "ERROR, missing argument\n");
        exit(1);
    }

    CWnd = atoi(argv[2]);
    probLoss = atoi(argv[3]);
    probCorruption = atoi(argv[4]);

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");
    memset(&serv_addr, 0, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR on binding");

    int n, loss = 0, corruption = 0, base = 0, nextSeqnum = 0, seq = 0,
           ack = 0, numUnacked = 0, i, j, k, len, cumAck, sizeCliAddr;
    char buffer[1024];
    char packetBuffer[packetBufferSize][maxPacketSize + 1];
    int nxtPtr = 0, nxtFree = 0, count = 0;
    char unacked[CWnd][maxPacketSize + 1];
    struct Header recvAck, data;
    char filename[1024];
    FILE * fp;
    char packet[maxPacketSize + 1];
    int cur;
    //col 1: 0 unacked, 1 acked or unused
    //col 2: window seq num
    //col 3: expected ack
    int window[CWnd][3];

    memset(packet, 0, sizeof(packet));
    for (i = 0; i < CWnd; i++)
    {
        window[i][0] = 1;
        window[i][1] = 0;
        window[i][2] = 0;
    }

    memset((struct sigaction *) &sa, 0, sizeof(sa));
    sa.sa_handler = setTimeout;
    sa.sa_flags = SA_SIGINFO;
    sigaction(SIGALRM, &sa, NULL);
    //eventually, it seems here that the loop eventually stops sending
    //packets to the receiver and the receiver is just left hanging...
    while (1)
    {
        memset(buffer, 0, 1024);

        // read if timeout has not occured
        if (timeout != 1)
        {
            sizeCliAddr = sizeof(cli_addr);
            n = recvfrom(sockfd, buffer, sizeof(buffer), 0,
                         (struct sockaddr *) &cli_addr, &sizeCliAddr);
        }
        else errno = EINTR;

        if (errno == EINTR)
        {
            if (timeout == 1)
            {
                timeout = 0;

                k = base + CWnd;
                for (i = base; i < k; i++)
                    for (j = 0; j < CWnd; j++)
                        if (window[j][0] == 0 && window[j][1] == i)
                        {
                            n = sendto(sockfd, unacked[j], sizeof(unacked[j]), 0,
                                       (struct sockaddr *) &cli_addr, sizeof(cli_addr));
                            if (n < 0)
                                error("ERROR reading from socket");

                            printf("\nPacket Sent: \n");
                            printPacket(unacked[j]);
                            break;
                        }

                alarm(dur);
                errno = 0;
                continue;
            }
            else
                error("ERROR reading from socket");
        }
        else if (n < 0)
            error("ERROR reading from socket");

        // if no loss or corruption
        loss = isHit(probLoss);
        corruption = isHit(probCorruption);
        if (loss != 1 && corruption != 1)
        {
            // if client asks for file
            if (getDataLen(buffer) > 0)
            {
                //eventually, this block of code never gets called but there are still text left to transmit...a mystery...
                printPacket(buffer);
                memset(filename, 0, 1024);
                getFileName(buffer, filename);
                printf("File Requested: %s\n", filename);

                fp = fopen(filename, "r");
                if (fp == NULL)
                    error("Failed to open file");

                cur = fgetc(fp);
                len = 0;
                data.srcPort = ntohs(serv_addr.sin_port);
                data.destPort = ntohs(cli_addr.sin_port);
                data.ack = 0;
                data.flag = 0;
                i = headerLen;
                while (1)
                {
                    if (len < maxPacketSize - headerLen && cur != EOF)
                    {
                        packet[i] = (char)cur;
                        cur = fgetc(fp);
                        len++;
                        i++;
                    }
                    if (len == maxPacketSize - headerLen || cur == EOF)
                    {
                        data.seq = seq;
                        data.dataLen = (short)len;
                        data.checkSum = (short)1;
                        if (cur == EOF)
                            data.flag = 1;
                        memcpy(packet, (struct Header *) &data, headerLen);
                        if (nextSeqnum < base + CWnd)
                        {
                            for (i = 0; i < CWnd; i++)
                                if (window[i][0] == 1)
                                {
                                    window[i][0] = 0;
                                    window[i][1] = nextSeqnum;
                                    window[i][2] = ack + len;

                                    n = sendto(sockfd, packet, sizeof(packet), 0,
                                               (struct sockaddr *) &cli_addr, sizeof(cli_addr));
                                    if (n < 0)
                                        error("ERROR writing to socket");

                                    if (nextSeqnum == base)
                                        alarm(dur);

                                    printf("\nPacket sent:\n");
                                    printPacket(packet);
                                    memcpy(&unacked[i][0], &packet[0], sizeof(packet));

                                    seq += len;
                                    ack += len;
                                    i = headerLen;
                                    len = 0;
                                    nextSeqnum++;

                                    break;
                                }
                        }
                        else
                        {
                            memcpy(packetBuffer[nxtFree], packet,
                                   maxPacketSize);
                            nxtFree++;
                            count++;
                            //adding this helped a bit but not entirely if the file is very large
                            seq += len;
                            ack += len;
                            len = 0;
                            i = headerLen;
                        }
                        memset(packet, 0, sizeof(packet));
                        if (cur == EOF)
                        {
                            data.flag = 0;
                            break;
                        }
                    }
                }

                fclose(fp);
                fileRequest = 0;
            }
            // if client sends ACK
            else
            {
                //this isn't run until all the packets have been sent in the first window
                //that is, if the CWnd is 10, then nextSeqnum only goes up until 10 and then
                //the packets go into packetBuffer
                //the packets in packetBuffer, after all the first set of packets are sent, are now being sent
                //but what happens after the packets in packetBuffer are all sent?
                printf("\nPacket Received:\n");
                printPacket(buffer);
                cumAck = getAck(buffer);
                j = 0;
                for (i = 0; i < CWnd; i++)
                {
                    if (window[i][1] >= base && cumAck >= window[i][2] &&
                            window[i][0] == 0)
                    {
                        j++;
                        window[i][0] = 1;

                        if (window[i][1] == base)
                            alarm(dur);

                        if (count > 0)
                        {
                            count--;
                            //printf("Sending in the other else branch.\n");

                            n = sendto(sockfd, packetBuffer[nxtPtr],
                                       sizeof(packetBuffer[nxtPtr]), 0,
                                       (struct sockaddr *) &cli_addr, sizeof(cli_addr));

                            if (n < 0)
                                error("ERROR writing to socket");
                            printPacket(packetBuffer[nxtPtr]);

                            nxtPtr = (nxtPtr + 1) % packetBufferSize;
                            nxtFree = (nxtFree + 1) % packetBufferSize;

                            // TODO: add stuff regarding window
                        }
                    }
                }
                base += j;
            }
        }
        // if loss or corruption do nothing
        else
        {
            if (loss == 1 && corruption == 0)
                printf("Packet Lost:\n");
            else if (corruption == 1 && loss == 0)
                printf("Packet Corrupted:\n");
            else printf("Packet Corrupted and Lost:\n");

            loss = 0;
            corruption = 0;

            printPacket(buffer);
        }
    }
    close(sockfd);

    return 0;
}