Beispiel #1
0
static void
ok_button_clicked(GtkButton *b, gpointer d)
{
	UINT8 calendar_buf[8];
	const gchar *entryp;
	BOOL renewal;
	UINT8 val;
	int i;

	renewal = FALSE;
	if (np2cfg.calendar != calendar_kind) {
		renewal = TRUE;
	}
	if (!np2cfg.calendar) {
		memset(calendar_buf, 0, sizeof(calendar_buf));
		for (i = 0; i < NELEMENTS(vircal); i++) {
			entryp = gtk_entry_get_text(GTK_ENTRY(vircal[i].entry));
			val = getbcd(entryp, 2);
			if (val >= vircal[i].min && val <= vircal[i].max) {
				if (i == 1) {
					val = ((val & 0x10) * 10) + (val << 4);
				}
				calendar_buf[i] = (UINT8)val;
			} else {
				break;
			}
		}
		if (i == NELEMENTS(vircal)) {
			calendar_set(calendar_buf);
		} else {
			renewal = FALSE;
		}
	}

	if (renewal) {
		np2cfg.calendar = calendar_kind;
		sysmng_update(SYS_UPDATECFG);
	}

	gtk_widget_destroy((GtkWidget *)d);
}
Beispiel #2
0
LRESULT CALLBACK ClndDialogProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {

    TCHAR	work[32];
    UINT8	b;
    int		i;
    HWND	subwnd;

    switch (msg) {
    case WM_INITDIALOG:
        // 時間をセット。
        calendar_getvir(cbuf);
        set_cal2dlg(hWnd, cbuf);
        if (np2cfg.calendar) {
            vircalendar(hWnd, FALSE);
            subwnd = GetDlgItem(hWnd, IDC_CLNDREAL);
        }
        else {
            vircalendar(hWnd, TRUE);
            subwnd = GetDlgItem(hWnd, IDC_CLNDVIR);
        }
        SendMessage(subwnd, BM_SETCHECK, TRUE, 0);
        SetFocus(subwnd);
        return(FALSE);

    case WM_COMMAND:
        switch(LOWORD(wp)) {
        case IDOK:
            b = (UINT8)GetDlgItemCheck(hWnd, IDC_CLNDREAL);
            if (np2cfg.calendar != b) {
                np2cfg.calendar = b;
                sysmng_update(SYS_UPDATECFG);
            }
            for (i=0; i<6; i++) {
                GetDlgItemText(hWnd, vircal[i].res,
                               work, NELEMENTS(work));
                b = getbcd(work, 2);
                if ((b >= vircal[i].min) && (b <= vircal[i].max)) {
                    if (i == 1) {
                        b = ((b & 0x10) * 10) + (b << 4);
                    }
                    cbuf[i] = b;
                }
            }
            calendar_set(cbuf);
            EndDialog(hWnd, IDOK);
            break;

        case IDCANCEL:
            EndDialog(hWnd, IDCANCEL);
            break;

        case IDC_CLNDVIR:
            vircalendar(hWnd, TRUE);
            return(FALSE);

        case IDC_CLNDREAL:
            vircalendar(hWnd, FALSE);
            return(FALSE);

        case IDC_SETNOW:
            calendar_getreal(cbuf);
            set_cal2dlg(hWnd, cbuf);
            return(FALSE);

        default:
            return(FALSE);
        }
        break;

    case WM_CLOSE:
        PostMessage(hWnd, WM_COMMAND, IDCANCEL, 0);
        break;

    default:
        return(FALSE);
    }
    return(TRUE);
}
uint32_t
decode_time(uint8_t init_min, uint8_t minlen, uint32_t acc_minlen,
    const uint8_t * const buffer, struct tm * const time)
{
	struct tm newtime;
	uint32_t rval = 0;
	int16_t increase, i;
	uint8_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, utchour;
	int8_t centofs;
	bool generr, p1, p2, p3, ok;
	static uint32_t acc_minlen_partial, old_acc_minlen;
	static bool olderr, prev_toolong;

	memset(&newtime, 0, sizeof(newtime));
	/* Initially, set time offset to unknown */
	if (init_min == 2)
		time->tm_isdst = -1;
	newtime.tm_isdst = time->tm_isdst; /* save DST value */

	if (minlen < 59)
		rval |= DT_SHORT;
	if (minlen > 60)
		rval |= DT_LONG;

	if (buffer[0] == 1)
		rval |= DT_B0;
	if (buffer[20] == 0)
		rval |= DT_B20;

	if (buffer[17] == buffer[18])
		rval |= DT_DSTERR;

	generr = (rval != 0); /* do not decode if set */

	if (buffer[15] == 1)
		rval |= DT_XMIT;

	/* See if there are any partial / split minutes to be combined: */
	if (acc_minlen <= 59000) {
		acc_minlen_partial += acc_minlen;
		if (acc_minlen_partial >= 60000) {
			acc_minlen = acc_minlen_partial;
			acc_minlen_partial %= 60000;
		}
	}
	/* Calculate number of minutes to increase time with: */
	if (prev_toolong)
		increase = (int16_t)((acc_minlen - old_acc_minlen) / 60000);
	else
		increase = (int16_t)(acc_minlen / 60000);
	if (acc_minlen >= 60000)
		acc_minlen_partial %= 60000;
	/* Account for complete minutes with a short acc_minlen: */
	if (acc_minlen % 60000 > 59000) {
		increase++;
		acc_minlen_partial %= 60000;
	}

	prev_toolong = (minlen == 0xff);
	old_acc_minlen = acc_minlen - (acc_minlen % 60000);

	/* There is no previous time on the very first (partial) minute: */
	if (init_min < 2) {
		for (i = increase; increase > 0 && i > 0; i--)
			add_minute(time, true);
		for (i = increase; increase < 0 && i < 0; i++)
			substract_minute(time, false);
	}

	p1 = getpar(buffer, 21, 28);
	tmp0 = getbcd(buffer, 21, 24);
	tmp1 = getbcd(buffer, 25, 27);
	if (!p1 || tmp0 > 9 || tmp1 > 5) {
		rval |= DT_MIN;
		p1 = false;
	}
	if ((init_min == 2 || increase != 0) && p1 && !generr) {
		newtime.tm_min = (int)(tmp0 + 10 * tmp1);
		if (init_min == 0 && time->tm_min != newtime.tm_min)
			rval |= DT_MINJUMP;
	}

	p2 = getpar(buffer, 29, 35);
	tmp0 = getbcd(buffer, 29, 32);
	tmp1 = getbcd(buffer, 33, 34);
	if (!p2 || tmp0 > 9 || tmp1 > 2 || tmp0 + 10 * tmp1 > 23) {
		rval |= DT_HOUR;
		p2 = false;
	}
	if ((init_min == 2 || increase != 0) && p2 && !generr) {
		newtime.tm_hour = (int)(tmp0 + 10 * tmp1);
		if (init_min == 0 && time->tm_hour != newtime.tm_hour)
			rval |= DT_HOURJUMP;
	}

	p3 = getpar(buffer, 36, 58);
	tmp0 = getbcd(buffer, 36, 39);
	tmp1 = getbcd(buffer, 40, 41);
	tmp2 = getbcd(buffer, 42, 44);
	tmp3 = getbcd(buffer, 45, 48);
	tmp4 = getbcd(buffer, 50, 53);
	tmp5 = getbcd(buffer, 54, 57);
	if (!p3 || tmp0 > 9 || tmp0 + 10 * tmp1 == 0 ||
	    tmp0 + 10 * tmp1 > 31 || tmp2 == 0 || tmp3 > 9 ||
	    tmp3 + 10 * buffer[49] == 0 || tmp3 + 10 * buffer[49] > 12 ||
	    tmp4 > 9 || tmp5 > 9) {
		rval |= DT_DATE;
		p3 = false;
	}
	if ((init_min == 2 || increase != 0) && p3 && !generr) {
		newtime.tm_mday = (int)(tmp0 + 10 * tmp1);
		newtime.tm_mon = (int)(tmp3 + 10 * buffer[49]);
		newtime.tm_year = (int)(tmp4 + 10 * tmp5);
		newtime.tm_wday = (int)tmp2;
		if (init_min == 0 && time->tm_mday != newtime.tm_mday)
			rval |= DT_MDAYJUMP;
		if (init_min == 0 && time->tm_wday != newtime.tm_wday)
			rval |= DT_WDAYJUMP;
		if (init_min == 0 && time->tm_mon != newtime.tm_mon)
			rval |= DT_MONTHJUMP;
		centofs = century_offset(newtime);
		if (centofs == -1) {
			rval |= DT_DATE;
			p3 = false;
		} else {
			if (init_min == 0 && time->tm_year !=
			    (int)(BASEYEAR + 100 * centofs + newtime.tm_year))
				rval |= DT_YEARJUMP;
			newtime.tm_year += BASEYEAR + 100 * centofs;
			if (newtime.tm_mday > (int)lastday(newtime)) {
				rval |= DT_DATE;
				p3 = false;
			}
		}
	}

	ok = !generr && p1 && p2 && p3; /* shorthand */

	utchour = get_utchour(*time);

	/*
	 * h==23, last day of month (UTC) or h==0, first day of next month (UTC)
	 * according to IERS Bulletin C
	 * flag still set at 00:00 UTC, prevent DT_LEAPERR
	 */
	if (buffer[19] == 1 && ok) {
		if (time->tm_mday == 1 && is_leapsecmonth(*time) &&
		    ((time->tm_min > 0 && utchour == 23) ||
		    (time->tm_min == 0 && utchour == 0)))
			announce |= ANN_LEAP;
		else {
			announce &= ~ANN_LEAP;
			rval |= DT_LEAPERR;
		}
	}

	/* process possible leap second, always reset announcement at hh:00 */
	if (((announce & ANN_LEAP) == ANN_LEAP) && time->tm_min == 0) {
		announce &= ~ANN_LEAP;
		rval |= DT_LEAP;
		if (minlen == 59) {
			/* leap second processed, but missing */
			rval |= DT_SHORT;
			ok = false;
			generr = true;
		} else if (minlen == 60 && buffer[59] == 1)
			rval |= DT_LEAPONE;
	}
	if ((minlen == 60) && ((rval & DT_LEAP) == 0)) {
		/* leap second not processed, so bad minute */
		rval |= DT_LONG;
		ok = false;
		generr = true;
	}

	/* h==0 (UTC) because sz->wz -> h==2 and wz->sz -> h==1,
	 * last Sunday of month (reference?) */
	if (buffer[16] == 1 && ok) {
		if ((time->tm_wday == 7 && time->tm_mday > (int)(lastday(*time) - 7) &&
		    (time->tm_mon == (int)summermonth ||
		    time->tm_mon == (int)wintermonth)) && ((time->tm_min > 0 &&
		    utchour == 0) || (time->tm_min == 0 &&
		    utchour == 1 + buffer[17] - buffer[18])))
			announce |= ANN_CHDST; /* time zone just changed */
		else {
			announce &= ~ANN_CHDST;
			rval |= DT_CHDSTERR;
		}
	}

	if ((int)buffer[17] != time->tm_isdst || (int)buffer[18] == time->tm_isdst) {
		/* Time offset change is OK if:
		 * announced and time is Sunday, lastday, 01:00 UTC
		 * there was an error but not any more (needed if decoding at
		 *   startup is problematic)
		 * initial state (otherwise DST would never be valid)
		 */
		if ((((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) ||
		    (olderr && ok) ||
		    ((rval & DT_DSTERR) == 0 && time->tm_isdst == -1))
			newtime.tm_isdst = (int)buffer[17]; /* expected change */
		else {
			if ((rval & DT_DSTERR) == 0)
				rval |= DT_DSTJUMP; /* sudden change, ignore */
			ok = false;
		}
	}
	/* check if DST is within expected date range */
	if ((time->tm_mon > (int)summermonth && time->tm_mon < (int)wintermonth) ||
	    (time->tm_mon == (int)summermonth && time->tm_wday < 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7) ||
	    (time->tm_mon == (int)summermonth && time->tm_wday == 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7 && utchour > 0) ||
	    (time->tm_mon == (int)wintermonth && time->tm_wday < 7 &&
	      (int)(lastday(*time)) - time->tm_mday >= 7) ||
	    (time->tm_mon == (int)wintermonth && time->tm_wday == 7 &&
	      (int)(lastday(*time)) - time->tm_mday < 7 &&
		(utchour >= 22 /* previous day */ || utchour == 0))) {
		/* expect DST */
		if (newtime.tm_isdst == 0 && (announce & ANN_CHDST) == 0 &&
		    utchour < 24) {
			rval |= DT_DSTJUMP; /* sudden change */
			ok = false;
		}
	} else {
		/* expect non-DST */
		if (newtime.tm_isdst == 1 && (announce & ANN_CHDST) == 0 &&
		    utchour < 24) {
			rval |= DT_DSTJUMP; /* sudden change */
			ok = false;
		}
	}
	/* done with DST */
	if (((announce & ANN_CHDST) == ANN_CHDST) && time->tm_min == 0) {
		announce &= ~ANN_CHDST;
		rval |= DT_CHDST;
	}
	newtime.tm_gmtoff = 3600 * (newtime.tm_isdst + 1);

	if (olderr && ok)
		olderr = false;
	if (!generr) {
		if (p1)
			time->tm_min = newtime.tm_min;
		if (p2)
			time->tm_hour = newtime.tm_hour;
		if (p3) {
			time->tm_mday = newtime.tm_mday;
			time->tm_mon = newtime.tm_mon;
			time->tm_year = newtime.tm_year;
			time->tm_wday = newtime.tm_wday;
		}
		if ((rval & DT_DSTJUMP) == 0) {
			time->tm_isdst = newtime.tm_isdst;
			time->tm_gmtoff = newtime.tm_gmtoff;
		}
	}
	if (!ok)
		olderr = true;

	return rval | announce;
}