unix-startup.c 3.05 KB
Newer Older
1
/*
2 3 4 5
 * Copyright (C) 2011 CERN (www.cern.ch)
 * Author: Alessandro Rubini
 *
 * Released to the public domain
6 7 8 9 10 11
 */

/*
 * This is the startup thing for hosted environments. It
 * defines main and then calls the main loop.
 */
12
#include <stdio.h>
13 14 15
#include <stdlib.h>
#include <string.h>
#include <errno.h>
16 17 18 19
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
20
#include <time.h>
21
#include <sys/timex.h>
22

Alessandro Rubini's avatar
Alessandro Rubini committed
23
#include <ppsi/ppsi.h>
24
#include "ppsi-unix.h"
25

26 27
/* ppg and fields */
static struct pp_globals ppg_static;
28 29
static defaultDS_t defaultDS;
static currentDS_t currentDS;
30
static parentDS_t parentDS;
31
static timePropertiesDS_t timePropertiesDS;
32 33
static struct pp_servo servo;

34 35
extern struct pp_ext_hooks pp_hooks;

36 37
int main(int argc, char **argv)
{
38
	struct pp_globals *ppg;
39
	struct pp_instance *ppi;
40
	unsigned long seed;
41
	struct timex t;
42
	int i;
43

44
	setbuf(stdout, NULL);
45

46 47
	pp_printf("PPSi. Commit %s, built on " __DATE__ "\n", PPSI_VERSION);

48 49 50 51 52 53
	ppg = &ppg_static;
	ppg->defaultDS = &defaultDS;
	ppg->currentDS = &currentDS;
	ppg->parentDS = &parentDS;
	ppg->timePropertiesDS = &timePropertiesDS;
	ppg->servo = &servo;
54
	ppg->rt_opts = &__pp_default_rt_opts;
55

56
	/* We are hosted, so we can allocate */
57
	ppg->max_links = PP_MAX_LINKS;
58
	ppg->arch_data = calloc(1, sizeof(struct unix_arch_data));
59
	ppg->pp_instances = calloc(ppg->max_links, sizeof(struct pp_instance));
60 61 62 63 64 65 66

	if ((!ppg->arch_data) || (!ppg->pp_instances)) {
		fprintf(stderr, "ppsi: out of memory\n");
		exit(1);
	}

	/* Before the configuration is parsed, set defaults */
67 68 69 70
	for (i = 0; i < ppg->max_links; i++) {
		ppi = INST(ppg, i);
		ppi->proto = PP_DEFAULT_PROTO;
		ppi->role = PP_DEFAULT_ROLE;
71
		ppi->delayMechanism = E2E;
72
	}
73

74 75 76 77
	/* Set offset here, so config parsing can override it */
	if (adjtimex(&t) >= 0)
		timePropertiesDS.currentUtcOffset = t.tai;

78 79 80 81
	if (pp_parse_cmdline(ppg, argc, argv) != 0)
		return -1;

	/* If no item has been parsed, provide a default file or string */
82
	if (ppg->cfg.cfg_items == 0)
83
		pp_config_file(ppg, 0, PP_DEFAULT_CONFIGFILE);
84
	if (ppg->cfg.cfg_items == 0)
85
		pp_config_string(ppg, strdup("link 0; iface eth0; proto udp"));
86

87
	for (i = 0; i < ppg->nlinks; i++) {
88

89
		ppi = INST(ppg, i);
90 91
		ppi->ch[PP_NP_EVT].fd = -1;
		ppi->ch[PP_NP_GEN].fd = -1;
92

93
		ppi->glbs = ppg;
94
		ppi->vlans_array_len = CONFIG_VLAN_ARRAY_SIZE,
95
		ppi->iface_name = ppi->cfg.iface_name;
96
		ppi->port_name = ppi->cfg.port_name;
97
		ppi->delayMechanism = ppi->cfg.delayMechanism;
98
		ppi->ext_hooks= &pp_hooks;
99

100 101 102
		/* The following default names depend on TIME= at build time */
		ppi->n_ops = &DEFAULT_NET_OPS;
		ppi->t_ops = &DEFAULT_TIME_OPS;
103

104 105 106
		ppi->portDS = calloc(1, sizeof(*ppi->portDS));
		ppi->__tx_buffer = malloc(PP_MAX_FRAME_LENGTH);
		ppi->__rx_buffer = malloc(PP_MAX_FRAME_LENGTH);
107

108 109 110 111 112
		if (!ppi->portDS || !ppi->__tx_buffer || !ppi->__rx_buffer) {
			fprintf(stderr, "ppsi: out of memory\n");
			exit(1);
		}
	}
113
	pp_init_globals(ppg, &__pp_default_rt_opts);
114

115 116 117 118 119
	seed = time(NULL);
	if (getenv("PPSI_DROP_SEED"))
		seed = atoi(getenv("PPSI_DROP_SEED"));
	ppsi_drop_init(ppg, seed);

120
	unix_main_loop(ppg);
121 122
	return 0; /* never reached */
}