unix-startup.c 2.95 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 28 29 30 31 32 33
/* ppg and fields */
static struct pp_globals ppg_static;
static DSDefault defaultDS;
static DSCurrent currentDS;
static DSParent parentDS;
static DSTimeProperties timePropertiesDS;
static struct pp_servo servo;

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

42
	setbuf(stdout, NULL);
43

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

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

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

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

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

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

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

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

85
	for (i = 0; i < ppg->nlinks; i++) {
86

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

91
		ppi->glbs = ppg;
92
		ppi->vlans_array_len = CONFIG_VLAN_ARRAY_SIZE,
93
		ppi->iface_name = ppi->cfg.iface_name;
94
		ppi->port_name = ppi->cfg.port_name;
95
		ppi->mech = ppi->cfg.mech;
96

97 98 99
		/* The following default names depend on TIME= at build time */
		ppi->n_ops = &DEFAULT_NET_OPS;
		ppi->t_ops = &DEFAULT_TIME_OPS;
100

101 102 103
		ppi->portDS = calloc(1, sizeof(*ppi->portDS));
		ppi->__tx_buffer = malloc(PP_MAX_FRAME_LENGTH);
		ppi->__rx_buffer = malloc(PP_MAX_FRAME_LENGTH);
104

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

112 113 114 115 116
	seed = time(NULL);
	if (getenv("PPSI_DROP_SEED"))
		seed = atoi(getenv("PPSI_DROP_SEED"));
	ppsi_drop_init(ppg, seed);

117
	unix_main_loop(ppg);
118 119
	return 0; /* never reached */
}