summaryrefslogtreecommitdiffstats
path: root/dvb-t/uk-Midhurst
blob: ca258bffe32c81707044b7cd7ba10a887d4c32ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#----------------------------------------------------------------------------------------------
# Auto-generated from:
# <http://www.digitaluk.co.uk/coveragechecker/main/tradeexport/GU28�9EA/NA/0/>
#----------------------------------------------------------------------------------------------
# location and provider: UK, Midhurst
# date (yyyy-mm-dd)    : 2014-03-25
#
# T[2] <freq> <bw> <fec_hi> <fec_lo> <mod> <tm> <guard> <hi> [<plp_id>] [# comment]
#----------------------------------------------------------------------------------------------
T 746000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE         # C55 BBC A
T 754000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE         # C56 D3&4
T 738000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE         # C54 SDN
T 778000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE         # C59 ARQ A
T 706000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE         # C50 ARQ B
T2 770000000 8MHz 2/3 NONE QAM256 32k 1/128 NONE 0   # C58 BBC B HD
>241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
/* 
 * lightingcontrol
 *
 * Copyright (C) 2012 Jonathan McCrohan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// gcc lightingcontrol.c -o lightingcontrol -lm `pkg-config --libs --cflags libconfig`

#ifndef VERSION_STRING
#define VERSION_STRING "[undefined version]"
#endif

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/select.h>
#include <signal.h>
#include <fcntl.h>

#include <libconfig.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <string.h>

#include <syslog.h>

#include <termios.h>
#include <fcntl.h>

// handle SIGALRM by resetting it
void
minute_check (int signum)
{
  syslog (LOG_DEBUG, "SIGALRM");
  alarm (60);
}

int
main (int argc, char *argv[])
{

  int SYSLOG_CONSOLE_OUTPUT = 0;
  int k;

  // check the argv array for strings matching -d
  for (k = 1; k < argc; k++)
    {
      if (strcmp (argv[k], "-d") == 0)
	{
	  SYSLOG_CONSOLE_OUTPUT = LOG_PERROR;
	}
    }

  openlog ("lightingcontrol", SYSLOG_CONSOLE_OUTPUT | LOG_PID | LOG_CONS,
	   LOG_USER);

  syslog (LOG_INFO, "");
  syslog (LOG_INFO, "lightingcontrol [%s] starting", VERSION_STRING);
  syslog (LOG_INFO, "");

  const char *configfile = "lightingcontrol.cfg";
  config_t cfg;

  const char *serial_device_address;
  int serial_baud_rate;
  int serial_data_bits;
  const char *serial_parity;
  int serial_stop_bits;
  char *p;

  config_init (&cfg);

  // attempt to read config
  // loads entire file to memory and destroys file descriptor
  if (!config_read_file (&cfg, configfile))
    {
      fprintf (stderr, "%s:%d - %s\n", config_error_file (&cfg),
	       config_error_line (&cfg), config_error_text (&cfg));
      config_destroy (&cfg);
      syslog (LOG_ERR, "Unable to find configfile");
      return -1;
    }
  else
    {
      syslog (LOG_INFO, "configfile found successfully");
    }

  // die if core config file options aren't there
  if (!(config_lookup_string (&cfg, "serial.device", &serial_device_address)
	&& config_lookup_int (&cfg, "serial.baud", &serial_baud_rate)
	&& config_lookup_int (&cfg, "serial.data_bits", &serial_data_bits)
	&& config_lookup_string (&cfg, "serial.parity", &serial_parity)
	&& config_lookup_int (&cfg, "serial.stop_bits", &serial_stop_bits)))
    {
      syslog (LOG_ERR,
	      "Incomplete serial configuration. Check configuration file");
      closelog ();
      return -1;
    }

  syslog (LOG_INFO, "Serial Port=[%s]", serial_device_address);
  syslog (LOG_INFO, "Serial Port Parameters=[%d %d %c %d]", serial_baud_rate,
	  serial_data_bits, serial_parity[0], serial_stop_bits);

  // SIGALRM used to wake for loop up every 60 secs
  // sleep puts whole thread to sleep which isn't what we want
  // other methods involve CPU spinlocks which are inefficient
  signal (SIGALRM, minute_check);
  alarm (1);

  for (;;)
    {
      // block until SIGARLM
      select (0, NULL, NULL, NULL, NULL);

      time_t t = time (NULL);
      struct tm unixtime_min_time_t = *localtime (&t);

      config_setting_t *schedules;

      schedules = config_lookup (&cfg, "schedule");

      // find number of schedules
      unsigned int num_schedules = config_setting_length (schedules);

      syslog (LOG_DEBUG, "num_schedules=[%d]", num_schedules);

      int i;
      // cycle through each schedule and pull info from config file
      for (i = 0; i < num_schedules; ++i)
	{
	  config_setting_t *scene_element =
	    config_setting_get_elem (schedules, i);
	  int sceneid;
	  config_setting_lookup_int (scene_element, "sceneid", &sceneid);
	  syslog (LOG_DEBUG, "sceneid=[%d]", sceneid);
	  const char *scene_day;
	  char scene_day_lower[20];
	  config_setting_lookup_string (scene_element, "day", &scene_day);
	  strcpy (scene_day_lower, scene_day);
	  p = scene_day_lower;
	  // convert strings to lower case
	  for (; *p; ++p)
	    *p = tolower (*p);
	  syslog (LOG_DEBUG, "scene_day=[%s]", scene_day_lower);

	  const char *scene_time;
	  config_setting_lookup_string (scene_element, "time", &scene_time);
	  syslog (LOG_DEBUG, "scene_time=[%s]", scene_time);

	  char daystring[20];
	  char timestring[20];

	  strftime (daystring, 20, "%A", &unixtime_min_time_t);
	  strftime (timestring, 20, "%H:%M", &unixtime_min_time_t);
	  p = daystring;
	  // convert strings to lower case
	  for (; *p; ++p)
	    *p = tolower (*p);

	  syslog (LOG_DEBUG, "current_day=[%s]", daystring);
	  syslog (LOG_DEBUG, "current_time=[%s]", timestring);
	  if ((strcmp (scene_day_lower, daystring) == 0)
	      && (strcmp (scene_time, timestring) == 0))

	    {

	      // attempt to create new serial connection
	      struct termios term;
	      int serialport = open (serial_device_address,
				     O_RDWR | O_NOCTTY | O_NONBLOCK);
	      if (serialport < 0)
		{
		  syslog (LOG_ERR, "Unable to create serial object");
		}

	      syslog (LOG_INFO, "serialport=[%d]", serialport);

	      if (serial_baud_rate == 115200)
		{
		  term.c_cflag = B115200;
		}
	      else if (serial_baud_rate == 57600)
		{
		  term.c_cflag = B57600;
		}
	      else if (serial_baud_rate == 38400)
		{
		  term.c_cflag = B38400;
		}
	      else if (serial_baud_rate == 19200)
		{
		  term.c_cflag = B19200;
		}
	      else if (serial_baud_rate == 9600)
		{
		  term.c_cflag = B9600;
		}
	      else if (serial_baud_rate == 4800)
		{
		  term.c_cflag = B4800;
		}
	      else if (serial_baud_rate == 2400)
		{
		  term.c_cflag = B2400;
		}
	      else if (serial_baud_rate == 1800)
		{
		  term.c_cflag = B1800;
		}
	      else if (serial_baud_rate == 1200)
		{
		  term.c_cflag = B1200;
		}


	      if (serial_data_bits == 5)
		{
		  term.c_cflag |= CS5;
		}
	      else if (serial_data_bits == 6)
		{
		  term.c_cflag |= CS6;
		}
	      else if (serial_data_bits == 7)
		{
		  term.c_cflag |= CS7;
		}
	      else
		{
		  term.c_cflag |= CS8;
		}

	      if (serial_parity == "E")
		{
		  term.c_cflag |= PARENB;
		}
	      else if (serial_parity == "O")
		{
		  term.c_cflag |= PARENB | PARODD;
		}

	      if (serial_stop_bits == 2)
		{
		  term.c_cflag |= CSTOPB;
		}
	      term.c_iflag = 0;
	      term.c_oflag = 0;
	      term.c_lflag = 0;

	      tcflush (serialport, TCIFLUSH);
	      tcsetattr (serialport, TCSANOW, &term);

	      config_setting_t *messagearray;
	      messagearray =
		config_setting_get_member (scene_element, "message");

	      int j, k;
	      // eight byte messages
	      unsigned char serialmsg[8];
	      int nummessages;

	      // count number of messages to send
	      nummessages = config_setting_length (messagearray);

	      for (j = 0; j < nummessages; j++)
		{
		  config_setting_t *message;
		  // iterate over each message
		  message = config_setting_get_elem (messagearray, j);
		  // ensure checksum byte is zero'd before calculation
		  serialmsg[7] = 0;
		  for (k = 0; k < 7; k++)
		    {
		      serialmsg[k] = config_setting_get_int_elem (message, k);
		      serialmsg[7] += serialmsg[k];
		    }
		  // checksum calculation
		  serialmsg[7] = (~serialmsg[7] & 0xff) + 1;

		  // write message out over serial port
		  write (serialport, serialmsg, sizeof (serialmsg));
		  syslog (LOG_INFO, "MESSAGE SENT");
		  syslog (LOG_INFO,
			  "[%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x]",
			  serialmsg[0], serialmsg[1], serialmsg[2],
			  serialmsg[3], serialmsg[4], serialmsg[5],
			  serialmsg[6], serialmsg[7]);
		  syslog (LOG_INFO, "SCENEID=[%d] SENT", sceneid);
		  syslog (LOG_INFO, "current_day=[%s]", daystring);
		  syslog (LOG_INFO, "current_time=[%s]", timestring);
		  syslog (LOG_INFO, "nummessages=[%d]", nummessages);
		  usleep (100);
		}


	      close (serialport);

	      sleep (1);

	    }
	}
    }
}