summaryrefslogtreecommitdiff
path: root/ntpshm.c
blob: b569df0a5fa8838cf1a4c3c01d1ec845ccd2ddc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* 
 * ntpshm.c - put time information in SHM segment for xntpd
 * struct shmTime and getShmTime from file in the xntp distribution:
 */

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#include "gpsd.h"
#ifdef NTPSHM_ENABLE

#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif

#include <sys/ipc.h>
#include <sys/shm.h>

#define NTPD_BASE	0x4e545030	/* "NTP0" */
#define SHM_UNIT	0		/* SHM driver unit number (0..3) */

struct shmTime {
    int    mode; /* 0 - if valid set
		  *       use values, 
		  *       clear valid
		  * 1 - if valid set 
		  *       if count before and after read of values is equal,
		  *         use values 
		  *       clear valid
		  */
    int    count;
    time_t clockTimeStampSec;
    int    clockTimeStampUSec;
    time_t receiveTimeStampSec;
    int    receiveTimeStampUSec;
    int    leap;
    int    precision;
    int    nsamples;
    int    valid;
    int    pad[10];
};

static struct shmTime *getShmTime(int unit)
{
    int shmid=shmget (NTPD_BASE+unit, sizeof (struct shmTime), IPC_CREAT|0700);
    if (shmid == -1) {
	gpsd_report(1, "shmget failed\n");
	return NULL;
    } else {
	struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
	if ((int)(long)p == -1) {
	    gpsd_report(1, "shmat failed\n");
	    p=0;
	}
	return p;
    }
}

int ntpshm_init(struct gps_context_t *context)
{
    if ((context->shmTime = getShmTime(SHM_UNIT)) == NULL)
	return 0;

    memset((void *)context->shmTime,0,sizeof(struct shmTime));
    context->shmTime->mode = 1;

    return 1;
}

int ntpshm_put(struct gps_context_t *context, double fixtime)
{
    struct timeval tv;
    double seconds,microseconds;

    if (context->shmTime == NULL)
	return 0;

    gettimeofday(&tv,NULL);
    microseconds = 1000000.0 * modf(fixtime,&seconds);

    context->shmTime->count++;
    context->shmTime->clockTimeStampSec = seconds;
    context->shmTime->clockTimeStampUSec = microseconds;
    context->shmTime->receiveTimeStampSec = tv.tv_sec;
    context->shmTime->receiveTimeStampUSec = tv.tv_usec;
    context->shmTime->precision = -1;	/* this needs work */
    context->shmTime->count++;
    context->shmTime->valid = 1;

    return 1;
}

#endif /* defined(SHM_H) && defined(IPC_H) */