#include <stdio.h>
#include <assert.h>

#include "../hubolib.h"
#include "CSC5262.h"

using namespace HuboLib;
using namespace BCM2835;

/*
Compile and link:
	g++ RCSocket.cpp CSC5262.cpp -L../ -lhubo -lpthread -lrt -o RCSocket.out
Run:
	sudo ./RCSocket.out <system-code> <socket number> <0|1>
Purpose:
	The demo shows how the GPIO interface can be used to bit bang an output in order to
	use an 433MHz transmission module for controlling a RC socket.
*/


// Switch Coding (x is not being used and should be set to 0)
// System-Code			Receiver-Socket
// x x x 1 2 3 4 5 		x x x A B C D E

// Example 1
// System-Code			Receiver-Socket
// x x x 1 2 3 4 5 		x x x A B C D E
// 0 0 0 0 0 1 0 1      0 0 0 0 0 0 1 0
// 0x05					0x02
// SwitchSocket(0x05,   0x02, true... ) switches socket D of system 00101 on.
// SwitchSocket(0x05, 	0x02, false...) switches socket D of system 00101 off.

// Example 2
// System-Code			Receiver-Socket
// x x x 1 2 3 4 5 		x x x A B C D E
// 0 0 0 1 0 0 1 1      0 0 0 1 0 0 0 0
// 0x13					0x10
// SwitchSocket(0x13,   0x10, true... ) switches socket A of system 10011 on.
// SwitchSocket(0x13, 	0x10, false...) switches socket A of system 10011 off.


bool strToUChar(char* str, unsigned char& value);
void BoostThreadPriority();


int main(int argc, char *argv[])
{
	unsigned char systemCode, socketNumber, value;
	if (argc!=4 || !strToUChar(argv[1], systemCode) || !strToUChar(argv[2], socketNumber) || !strToUChar(argv[3], value))
	{
		printf (
				"Usage:\n"
				"RCSocket.out <system-code> <socket number> <0|1>\n"
				"system-code: 0..31\n"
				"socket number: 0..31 (whereas A=16, B=8, C=4, D=2 and E=1)\n"
				"0=off, 1=on\n"
				);
		return -1;
	}

	// This program requires high priority in order to successfully bit bang over the GPIO.
	BoostThreadPriority();

	// If this call doesn't return true then we must not use the GPIO part of Hubo library!
	if (!IsGPIOInitialized ())
	{
		printf ("GPIO not properly initialized. Are you running the program as sudoer?\n");
		return -1;
	}

	// Let's use a bit-length of 350µs (that's what the remote control sends) and BCM2835 pin 17 (= GPIO0).
	// Experiments have shown a minimum of 150µs and a maximum of 580µs for the bit length.
	CSC5262 mySwitch(350, 17);

	// While the switches seem to require at least 3 successive transmissions in a series - repeating it
	// at least 4 times seems to improve transmission stability. After 10 retries in total we stop.
	mySwitch.SwitchSocket(systemCode, socketNumber, value>0, 4, 10);

	return 0;
}

#include <pthread.h>    
#include <assert.h>    
void BoostThreadPriority()
{
	// Scheduling params.
	sched_param param;
	int			policy;
	int			ret;
	pthread_t	threadHandle = pthread_self();

	// Get current scheduling parameters of thread.
	ret				= pthread_getschedparam (threadHandle, &policy, &param);
	assert (ret == 0);

	// Set scheduling parameters of thread to real time values (FIFO scheduling type and max prio).
	policy				 = SCHED_FIFO; // SCHED_RR;
	param.sched_priority = sched_get_priority_max(policy); // New max priority for new scheduling concept.
	ret					 = pthread_setschedparam(threadHandle, policy, &param);
	assert (ret == 0);
}

bool strToUChar(char* str, unsigned char& value)
{
	unsigned long v;
	if (sscanf(str, "%lu", &v) != 1)
		return false;
	value = (unsigned char)v;
	if (value != (unsigned long)v)
		return false;
	return true;
}

