📄 alarm_d.cxx
字号:
/* * Copyright (c) 2003 Century Software, Inc. All Rights Reserved. * * This file is part of the PIXIL Operating Environment * * The use, copying and distribution of this file is governed by one * of two licenses, the PIXIL Commercial License, or the GNU General * Public License, version 2. * * Licensees holding a valid PIXIL Commercial License may use this file * in accordance with the PIXIL Commercial License Agreement provided * with the Software. Others are governed under the terms of the GNU * General Public License version 2. * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free * Software Foundation and appearing in the file LICENSE.GPL included * in the packaging of this file. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. * * RESTRICTED RIGHTS LEGEND * * Use, duplication, or disclosure by the government is subject to * restriction as set forth in paragraph (b)(3)(b) of the Rights in * Technical Data and Computer Software clause in DAR 7-104.9(a). * * See http://www.pixil.org/gpl/ for GPL licensing * information. * * See http://www.pixil.org/license.html or * email cetsales@centurysoftware.com for information about the PIXIL * Commercial License Agreement, or if any conditions of this licensing * are not clear to you. */#include <stdlib.h>#include <sys/ioctl.h>#include <time.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#ifdef CONFIG_NANOX#include <wm/scrtoplib.h>#endif#include "alarm_d.h"#include "rtc.h"#define RECNO 0#define NAME 1#define NAME_RECNO 2#define DESCRIPTION 3#define START_TIME 4#define END_TIME 5#define ALARM_TIME 6#define STATUS 7#define NUM_FIELDS 8#ifdef DEBUG#define DPRINT(str, args...) printf("DEBUG: Alarmd: " str, ## args)#else#define DPRINT(str, args...)#endif///////////// Database// Alarmfield cFields[] = { {'i', 1, 0} , // Field 0:RECNO {'c', APP_NAME, 0} , // 1:NAME {'i', 1, 0} , // 2:NAME_RECNO {'c', DESC, 0} , // 3:DESCRIPTION {'l', 1, 0} , // 4:START_TIME {'l', 1, 0} , // 5:END_TIME {'l', 1, 0} , // 6:ALARM_TIME {'i', 1, 0} , // 7:STATUS {0}};// Databasefildes cFile = { // system file 0, 0, 0, // database file "dbf", // extension NUM_FIELDS, // nFields &cFields[0] // fieldlist};char *path = "/var/run/alarmd.pid";Alarm_d * Alarm_d::instance_ = 0;Alarm_d::Alarm_d(int argc, char **argv){ pid_t pid = 0; int pathfd_; char buf[512]; int ret; memset(buf, 0, sizeof(buf)); pid = getpid(); pathfd_ = open(path, O_RDWR | O_TRUNC | O_CREAT); if (-1 == pathfd_) { perror("open(): /var/run/alarmd.pid"); exit(errno); } sprintf(buf, "%d", pid); ret = write(pathfd_, buf, strlen(buf)); if (-1 == ret) { perror("write(): pid"); exit(errno); } close(pathfd_); alarm_db_ = new NxDb(argc, argv); optind = 1; inidir = alarm_db_->GetPath(); OpenAlarmDatabase(); desc_.fd = -1; desc_.alarm_recno = -1; desc_.recno = -1; memset(desc_.appname, 0, sizeof(desc_.appname)); memset(desc_.desc, 0, sizeof(desc_.desc)); flags_ = 0; cur_time_ = -1; alarm_time_ = -1; time_interval_ = -1; fd_ = -1; rtcfd_ = -1; error_ = 0; SetId(); instance_ = this; status_ = STATUS_CLEAR;}Alarm_d *Alarm_d::Instance(){ if (0 == instance_) { DPRINT("instance_ is messed up BAIL!!!\n"); exit(-1); } return instance_;}voidAlarm_d::HandleSignal(int signal){ DPRINT("Recieved signal [%d]\n", signal); if (SIGUSR1 == signal) { // going to suspend need to set /dev/rtc Alarm_d::Instance()->SetAlarm(Alarm_d::Instance()->alarm_time_); Alarm_d::Instance()->SetStatus(STATUS_RTC_SET); } else if (SIGUSR2 == signal) { // coming back from suspend close /dev/rtc Alarm_d::Instance()->ClearRtc(); Alarm_d::Instance()->SetStatus(STATUS_RTC_CLEAR); } else if (SIGPIPE == signal) { switch (Alarm_d::Instance()->GetStatus()) { case STATUS_READ: Alarm_d::Instance()->WaitCol(WAIT_RECONNECT); break; case STATUS_WRITE_MSG: DPRINT("Error: Not able to send message!\n"); Alarm_d::Instance()->MarkEntry(ERROR_SEND); break; case STATUS_WRITE_ERR: DPRINT("Error: Message being Dropped!\n"); break; default: DPRINT("Error: Unknown Status!\n"); Alarm_d::Instance()->SetStatus(STATUS_UNKNOWN); break; } } else { Alarm_d::Instance()->~Alarm_d(); exit(0); }}voidAlarm_d::CloseDB(){ alarm_db_->Close(ALARM_DATABASE);}intAlarm_d::Monitor(){ int err = 0; struct timeval tv; int retval = 0; int maxfd; WaitCol(WAIT_CONNECT); if (0 > fd_) { DPRINT("Unable to register %s\n", ALARM_D); exit(-1); } while (1) { if (status_ == STATUS_READ || status_ == STATUS_WRITE_ERR) WaitCol(WAIT_RECONNECT); FD_ZERO(&fds_); FD_SET(fd_, &fds_); maxfd = fd_; alarm_time_ = GetNextAlarm(); DPRINT("in monitor loop: alarm_time = %ld\n", alarm_time_); if (0 == alarm_time_) { retval = select(maxfd + 1, &fds_, NULL, NULL, NULL); if (EINTR == errno && -1 == retval) { DPRINT("select: NULL\n"); continue; } } else if (alarm_time_ > 0) { cur_time_ = time(NULL); time_interval_ = alarm_time_ - cur_time_; if (0 >= time_interval_) { err = SendMsg(); continue; } if (0 < time_interval_) { tv.tv_sec = time_interval_; tv.tv_usec = 0; DPRINT("time_interval_: [%ld]\n", time_interval_); retval = select(maxfd + 1, &fds_, NULL, NULL, &tv); if (EINTR == errno && -1 == retval) { DPRINT("select: time_interval_\n"); continue; } } } if (FD_ISSET(fd_, &fds_)) { err = ReadMsg(); if (0 > err) { WaitCol(WAIT_RECONNECT); continue; } } else if (!FD_ISSET(fd_, &fds_)) { err = SendMsg(); if (0 > err) continue; } else continue; }}voidAlarm_d::WaitCol(int flag){ int temp_fd; flags_ = 0; temp_fd = fd_; close(fd_); if (WAIT_RECONNECT == flag) { fd_ = ClReconnect((unsigned char *) ALARM_D); while (0 > fd_) { sleep(1); DPRINT("Waiting for colosseum reconnect\n"); fd_ = ClReconnect((unsigned char *) ALARM_D); if (CL_CLIENT_CONNECTED == fd_) { fd_ = temp_fd; break; } } } if (WAIT_CONNECT == flag) { fd_ = ClRegister((unsigned char *) ALARM_D, &flags_); while (0 >= fd_) { sleep(1); DPRINT("Waiting for colosseum\n"); fd_ = ClRegister((unsigned char *) ALARM_D, &flags_); if (CL_CLIENT_CONNECTED == fd_) { fd_ = temp_fd; break; } } }}voidAlarm_d::ClearRtc(){ int ret = 0; DPRINT("Clearing rtc\n"); if (0 > rtcfd_) { DPRINT("rtcfd_ [%d]\n", rtcfd_); return; } ret = ioctl(rtcfd_, RTC_AIE_OFF, 0); if (-1 == ret) { perror("ioctl: RTC_AIE_OFF"); //exit(errno); } close(rtcfd_); DPRINT("closed rtcfd_\n"); rtcfd_ = -1;}voidAlarm_d::SetAlarm(time_t alarm_time){ time_t time_now; tm *tt; rtc_time rtc_tm; int ret = 0; if (0 >= alarm_time) return; rtcfd_ = open("/dev/rtc", O_RDWR); DPRINT("rtcfd_ [%d]\n", rtcfd_); if (-1 == rtcfd_) { perror("Unable to open /dev/rtc"); if (errno) return; } time_now = time(NULL); tt = gmtime(&time_now); rtc_tm.tm_sec = tt->tm_sec; rtc_tm.tm_min = tt->tm_min; rtc_tm.tm_hour = tt->tm_hour; rtc_tm.tm_mday = tt->tm_mday; rtc_tm.tm_mon = tt->tm_mon; rtc_tm.tm_year = tt->tm_year; ret = ioctl(rtcfd_, RTC_SET_TIME, &rtc_tm); if (-1 == ret) { perror("ioctl: RTC_SET_TIME"); close(rtcfd_); return; //exit(errno); } DPRINT("set rtc to %d-%d-%d, %02d:%02d:%02d \n", rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); if (alarm_time > 2) { // give few second headstart on wake-up alarm_time -= 2; tt = gmtime(&alarm_time); rtc_tm.tm_sec = tt->tm_sec; rtc_tm.tm_min = tt->tm_min; rtc_tm.tm_hour = tt->tm_hour; rtc_tm.tm_mday = tt->tm_mday; rtc_tm.tm_mon = tt->tm_mon; rtc_tm.tm_year = tt->tm_year; ret = ioctl(rtcfd_, RTC_ALM_SET, &rtc_tm); if (-1 == ret) { perror("ioctl: RTC_ALM_SET"); close(rtcfd_); return; //exit(errno); } DPRINT("set alarm date/time %d-%d-%d, %02d:%02d:%02d\n", rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); } ret = ioctl(rtcfd_, RTC_ALM_READ, &rtc_tm); if (-1 == ret) { perror("ioctl: RTC_ALM_READ"); close(rtcfd_); return; //exit(errno); } DPRINT("rtc Alarm set to %02d:%02d:%02d\n", rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); ret = ioctl(rtcfd_, RTC_AIE_ON, 0); if (-1 == ret) { perror("ioctl: RTC_AIE_ON"); close(rtcfd_); return; //exit(errno); } DPRINT("Set interrupts for RTC\n");}longAlarm_d::GetNextAlarm(){ int rec_array[MAX_RECS]; int idx = 0; int small_rec = -1; char c_value[16]; long l_value = LONG_MAX; long temp_value = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -