/*
 * outputserial.c: Serial output for the Atmolight-plugin
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <vdr/tools.h>

#include "defs.h"
#include "output.h"
#include "outputserial.h"

// --- cOutputSerial -----------------------------------------------------------

cOutputSerial::cOutputSerial()
{
 dev_handle = -1;
}

bool cOutputSerial::Open(const char* param)
{
 int bconst = B38400; // DONT'T DELETTE fishbonev: B19200

 if (param != NULL)
 {
   // open serial port
   dev_handle = open(param, O_RDWR | O_NOCTTY);
   if (0 > dev_handle)
   {
     char buf[128];
     if (0 == strerror_r(errno, buf, sizeof(buf)))
     {
       esyslog("Atmolight: Could not open serial port: %s!", buf);
     }
     else
     {
       esyslog("Atmolight: Could not open serial port: %d!", errno);
     }
     return false;
   }

   struct termios tio;
   memset(&tio,0,sizeof(tio));
   tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
   tio.c_iflag = (INPCK | BRKINT);
   // tio.c_cc[VMIN] = 1; // read 1 character blocking
   cfsetispeed(&tio, bconst);
   cfsetospeed(&tio, bconst);

   if(!tcsetattr(dev_handle, TCSANOW, &tio))
   {
     CHECK(tcflush(dev_handle, TCIOFLUSH)); // Flush
   }
   else
   {
     char buf[128];
     if (0 == strerror_r(errno, buf, sizeof(buf)))
     {
       esyslog("Atmolight: tcsetattr failed : %s!", buf);
     }
     else
     {
       esyslog("Atmolight: tcsetattr failed : %d!", errno);
     }
     close(dev_handle);
     dev_handle = -1;
     return false;
   }
 }
 else
 {
   esyslog("Atmolight: Parameter missing: Don't know which serial port to open!");
   return false;
 }
 return true;
}

bool cOutputSerial::Close()
{
 if (0 <= dev_handle)
 {
   close(dev_handle);
   dev_handle = -1;
   return true;
 }
 return false;
}

bool cOutputSerial::OutputColors(const tColorPacket col)
{
 static char msg[20];
 static int  msg_len = 19;
 bool retcode = false;

 // create string to send
 msg[0] = 0xFF; // startbyte
 msg[1] = 0x00; // startchannel low byte
 msg[2] = 0x00; // startchannel high byte
 msg[3] = 0x0F; // number of channels

 for (int i = 0; i < 5; i++) // 5 channels (c, l, r, t, b)
 {
   msg[i*3+4] = col.channel[i].r;
   msg[i*3+5] = col.channel[i].g;
   msg[i*3+6] = col.channel[i].b;
 }

 // send data to target
 if (0 <= dev_handle)
 {
   retcode = (msg_len == write(dev_handle, msg, msg_len));
   tcdrain(dev_handle); // write buffer to device
 }

 return retcode;
}
