/* * modbuslog * * Copyright (C) 2011 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 . */ // gcc modbuslog.c -o modbuslog `pkg-config --libs --cflags libmodbus libconfig` #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // handle SIGALRM by resetting it void minute_check(int signum) { alarm(60); } // get mac address of primary interface eth0 char *mac_address() { int s; struct ifreq ifr; s = socket(PF_INET, SOCK_DGRAM, 0); memset(&ifr, 0x00, sizeof(ifr)); strcpy(ifr.ifr_name, "eth0"); ioctl(s, SIOCGIFHWADDR, &ifr); close(s); static char mac_address[12]; sprintf(mac_address, "%.2X%.2X%.2X%.2X%.2X%.2X", (unsigned char) ifr.ifr_hwaddr.sa_data[0], (unsigned char) ifr.ifr_hwaddr.sa_data[1], (unsigned char) ifr.ifr_hwaddr.sa_data[2], (unsigned char) ifr.ifr_hwaddr.sa_data[3], (unsigned char) ifr.ifr_hwaddr.sa_data[4], (unsigned char) ifr.ifr_hwaddr.sa_data[5]); return mac_address; } int main(int argc, char *argv[]) { int DEBUG = 0; 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) { DEBUG = 1; SYSLOG_CONSOLE_OUTPUT = LOG_PERROR; } } openlog("modbuslog", SYSLOG_CONSOLE_OUTPUT | LOG_PID | LOG_CONS, LOG_USER); syslog(LOG_INFO, "modbuslog starting"); const char *configfile = "/etc/modbuslog.cfg"; config_t cfg; //config_setting_t *setting; const char *modbus_device_address; int modbus_baud_rate; int modbus_data_bits; const char *modbus_parity; int modbus_stop_bits; int modbus_retry; 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, "modbus.device", &modbus_device_address) && config_lookup_int(&cfg, "modbus.baud", &modbus_baud_rate) && config_lookup_int(&cfg, "modbus.data_bits", &modbus_data_bits) && config_lookup_string(&cfg, "modbus.parity", &modbus_parity) && config_lookup_int(&cfg, "modbus.stop_bits", &modbus_stop_bits) && config_lookup_int(&cfg, "modbus.retry", &modbus_retry))) { syslog(LOG_ERR, "Incomplete modbus configuration. Check configuration file"); closelog(); return -1; } syslog(LOG_INFO, "%s %s %d %c %d %d", mac_address(), modbus_device_address, modbus_baud_rate, modbus_parity[0], modbus_data_bits, modbus_stop_bits); modbus_t *ctx; uint16_t tab_reg[4]; uint8_t byte[8]; int rc; int i; // 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(60); for (;;) { // block until SIGARLM select(0, NULL, NULL, NULL, NULL); time_t t = time(NULL); time_t unixtime_min = (((int) t) / 60 * 60); //int unixtime = (int) t; //printf("%d\n", unixtime); config_setting_t *readings; readings = config_lookup(&cfg, "reading"); // find number of required readings unsigned int num_readings = config_setting_length(readings); int i; // cycle through each reading and pull info from config file for (i = 0; i < num_readings; ++i) { config_setting_t *register_element = config_setting_get_elem( readings, i); int slaveid; config_setting_lookup_int(register_element, "slaveid", &slaveid); int intervalvalue; config_setting_lookup_int(register_element, "intervalvalue", &intervalvalue); //printf("%d", intervalvalue); int registertype; config_setting_lookup_int(register_element, "registertype", ®istertype); int startaddress; config_setting_lookup_int(regist
# Channel table for Cardoso - SP - Brazil
# Source: http://www.portalbsd.com.br/terrestres_channels.php?channels=2948

# Physical channel 26
[TV Tem Rio Preto]
	DELIVERY_SYSTEM = ISDBT
	BANDWIDTH_HZ = 6000000
	FREQUENCY = 545142857
	INVERSION = AUTO
	GUARD_INTERVAL = AUTO
	TRANSMISSION_MODE = AUTO
	INVERSION = AUTO
	GUARD_INTERVAL = AUTO
	TRANSMISSION_MODE = AUTO
	ISDBT_LAYER_ENABLED = 7
	ISDBT_SOUND_BROADCASTING = 0
	ISDBT_SB_SUBCHANNEL_ID = 0
	ISDBT_SB_SEGMENT_IDX = 0
	ISDBT_SB_SEGMENT_COUNT = 0
	ISDBT_LAYERA_FEC = AUTO
	ISDBT_LAYERA_MODULATION = QAM/AUTO
	ISDBT_LAYERA_SEGMENT_COUNT = 0
	ISDBT_LAYERA_TIME_INTERLEAVING = 0
	ISDBT_LAYERB_FEC = AUTO
	ISDBT_LAYERB_MODULATION = QAM/AUTO
	ISDBT_LAYERB_SEGMENT_COUNT = 0
	ISDBT_LAYERB_TIME_INTERLEAVING = 0
	ISDBT_LAYERC_FEC = AUTO
	ISDBT_LAYERC_MODULATION = QAM/AUTO
	ISDBT_LAYERC_SEGMENT_COUNT = 0
	ISDBT_LAYERC_TIME_INTERLEAVING = 0

# Physical channel 31
[Rede Vida]
	DELIVERY_SYSTEM = ISDBT
	BANDWIDTH_HZ = 6000000
	FREQUENCY = 575142857
	INVERSION = AUTO
	GUARD_INTERVAL = AUTO
	TRANSMISSION_MODE = AUTO
	INVERSION = AUTO
	GUARD_INTERVAL = AUTO
	TRANSMISSION_MODE = AUTO
	ISDBT_LAYER_ENABLED = 7
	ISDBT_SOUND_BROADCASTING = 0
	ISDBT_SB_SUBCHANNEL_ID = 0
	ISDBT_SB_SEGMENT_IDX = 0
	ISDBT_SB_SEGMENT_COUNT = 0
	ISDBT_LAYERA_FEC = AUTO
	ISDBT_LAYERA_MODULATION = QAM/AUTO
	ISDBT_LAYERA_SEGMENT_COUNT = 0
	ISDBT_LAYERA_TIME_INTERLEAVING = 0
	ISDBT_LAYERB_FEC = AUTO
	ISDBT_LAYERB_MODULATION = QAM/AUTO
	ISDBT_LAYERB_SEGMENT_COUNT = 0
	ISDBT_LAYERB_TIME_INTERLEAVING = 0
	ISDBT_LAYERC_FEC = AUTO
	ISDBT_LAYERC_MODULATION = QAM/AUTO
	ISDBT_LAYERC_SEGMENT_COUNT = 0
	ISDBT_LAYERC_TIME_INTERLEAVING = 0