/*
 * Copyright (c) 2017 FH Dortmund and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Description:
 *    Bluetooth RFCOMM communication task to read 'driving information' from connection
 *    (Adapted and improved upon http://people.csail.mit.edu/albert/bluez-intro/x502.html)
 *    For Eclipse APP4MC Rover
 *
 * Contributors:
 *    M.Ozcelikors <mozcelikors@gmail.com>, created 04.10.2017
 *    M.Ozcelikors <mozcelikors@gmail.com>, bluetooth setup instructions added 10.10.2017
 *
 * Usage Instructions:
 *    1) Set-up bluetooth on Raspberry Pi
 *         sudo apt-get install pi-bluetooth bluez bluez-tools blueman
 *         sudo systemctl start bluetooth
 *         Now, the following should work:
 *             hcitool scan
 *
 *    1.O) WARNING: OPTIONAL: Use them at your own RISK.. (ref: Raspberry Pi Forums)
 *         If the command above (hcitool scan) still do not work:
 *         Execute the following commands:
 *             sudo apt-get update
 *             sudo apt-get dist-upgrade
 *             sudo rm /etc/udev/rules.d/99-com.rules
 *             sudo apt-get -o Dpkg::Options::="--force-confmiss" install --reinstall raspberrypi-sys-mods
 *             (if the above does not work) sudo apt-get install raspberrypi-sys-mods (Enter Y to install rules)
 *             sudo systemctl reboot
 *             (Downgrading the kernel to 4.4.50)  sudo rpi-update 52241088c1da59a359110d39c1875cda56496764
 *
 *         Add the following to your /etc/rc.local and reboot:
 *             btuart
 *
 *         NOTE: This approach is only intended for Raspbian Jessie distributions that does not involve
 *               bluetooth installed. If you use the latest Raspbian Jessie distribution, you can skip
 *               these instructions. To check if the bluetooth is working, simply use following two
 *               commands:
 *                    service bluetooth status
 *                    hcitool scan
 *    2) Prepare libraries for cross compilation (if you use cross-compilation with Eclipse IDE)
 *         Please note that in order to use Bluetooth stack for the cross compilation on Raspberry Pi,
 *         download bluez stack and add the lib directory content to drivers/bluetooth_drivers/,
 *         with inclusion paths corrected.
 *         i.e. #include <bluetooth/bluetooth.h> -> #include "bluetooth.h"
 *
 *         This code is tested with bluez-5.9
 *         Download bluez-5.9/lib from: https://www.kernel.org/pub/linux/bluetooth/
 *
 */

#include <tasks/bluetooth_task.h>

#include <wiringPi.h>
#include <ctime>
#include <unistd.h>
#include <libraries/timing/timing.h>
#include <api/basic_psys_rover.h>
#include <interfaces.h>
#include <pthread.h>
#include <roverapp.h>

#include <libraries/pthread_monitoring/collect_thread_name.h>

#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
/* Important Note: RFCOMM socket type is supported by Android API, so we chose to use it */
#include <bluetooth/rfcomm.h>


void *Bluetooth_Task (void * arg)
{
	timing bluetooth_task_tmr;
	bluetooth_task_tmr.setTaskID("BLE");
	bluetooth_task_tmr.setDeadline(1);
	bluetooth_task_tmr.setPeriod(1);

	CollectThreadName("BLE_Task");

	/* Bluetooth Setup (RFCOMM socket, server) */
	struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
	char buf[1024] = { 0 };
	int s, client, bytes_read;
	socklen_t opt = sizeof(rem_addr);

	/* To avoid getting error:taking address of temporary [-fpermissive] */
	//bdaddr_t bdaddr_temporary = {0xD8, 0x50, 0xE6, 0x30, 0xA3, 0xBE}; // Android device
	bdaddr_t bdaddr_temporary = {0, 0, 0, 0, 0, 0};

	/* Allocate socket */
	s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

	/* Bind socket to port 1 of the first available local bluetooth adapter */
	loc_addr.rc_family = AF_BLUETOOTH;
	loc_addr.rc_bdaddr = bdaddr_temporary; //*BDADDR_ANY;
	loc_addr.rc_channel = (uint8_t) 1;
	bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr));

	/* Put socket into listening mode */
	listen(s, 1);

	/* Accept one connection */
	client = accept(s, (struct sockaddr *) &rem_addr, &opt);

	ba2str( &rem_addr.rc_bdaddr, buf );
	fprintf(stderr, "Accepted connection from %s\n", buf);
	memset(buf, 0, sizeof(buf));

	/* Read data from the client */
	bytes_read = read(client, buf, sizeof(buf));
	if( bytes_read > 0 ) {
		printf("received [%s]\n", buf);
	}

	/* Close connection */
	close(client);
	close(s);

	while (1)
	{
		bluetooth_task_tmr.recordStartTime();
		bluetooth_task_tmr.calculatePreviousSlackTime();

		//Task content starts here -----------------------------------------------



		//Task content ends here -------------------------------------------------

		bluetooth_task_tmr.recordEndTime();
		bluetooth_task_tmr.calculateExecutionTime();
		bluetooth_task_tmr.calculateDeadlineMissPercentage();
		bluetooth_task_tmr.incrementTotalCycles();
		pthread_mutex_lock(&bluetooth_task_ti_l);
			bluetooth_task_ti.deadline = bluetooth_task_tmr.getDeadline();
			bluetooth_task_ti.deadline_miss_percentage = bluetooth_task_tmr.getDeadlineMissPercentage();
			bluetooth_task_ti.execution_time = bluetooth_task_tmr.getExecutionTime();
			bluetooth_task_ti.period = bluetooth_task_tmr.getPeriod();
			bluetooth_task_ti.prev_slack_time = bluetooth_task_tmr.getPrevSlackTime();
			bluetooth_task_ti.task_id = bluetooth_task_tmr.getTaskID();
			bluetooth_task_ti.start_time = bluetooth_task_tmr.getStartTime();
			bluetooth_task_ti.end_time = bluetooth_task_tmr.getEndTime();
		pthread_mutex_unlock(&bluetooth_task_ti_l);
		bluetooth_task_tmr.sleepToMatchPeriod();
	}

	/* the function must return something - NULL will do */
	return NULL;
}
