summaryrefslogtreecommitdiff
path: root/cleopatre/devkit/plcd/src/plcd.c
blob: e3340c94062bd1db9ee5654a298848d067fbeecd (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* SPC300 bundle {{{
 *
 * Copyright (C) 2009 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    devkit/plcd/src/plcd.c
 * \brief   PLC daemon for AV stack management
 * \ingroup plcd
 *
 * This PLC daemon is responsible for the initialization of
 * the AV stack : start, parameter sending, status watching.
 * It is also responsible for any configuration change from
 * the ethernet / plc side through MME messages.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <syslog.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>         /* for getpid() */
#include "libmme.h"
#include "libspid.h"
#include "plcd.h"

#ifdef __UTESTS__
    #include "plcd_utests.h"
#endif

static spc300_nvram_t g_nvram;

static void print_usage (const char *cmd)
{
    fprintf (stderr, "Usage : %s "                  \
             "[ -h --hw_file hardware_info_file ]"  \
             "[ -c --conf_file hpav_conf_file ]"    \
             "[ -i --info_file hpav_info_file ]\n",
             cmd);
}

int plcd_init (plcd_ctx_t *ctx)
{
    assert(ctx != NULL);
    memset (ctx, '\0', sizeof(plcd_ctx_t));
    ctx->hardware_info_path = LIBSPID_HARDWARE_INFO_PATH;
    ctx->hpav_info_path = LIBSPID_HPAV_INFO_PATH;
    ctx->hpav_conf_path = LIBSPID_HPAV_CONF_PATH;

    /* open netlink socket */
    if(0 > (ctx->plc_sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_PLC)))
    {
        perror ("netlink socket open");
        return -1;
    }
    memset(&ctx->plcd_addr, 0, sizeof(ctx->plcd_addr));
    ctx->plcd_addr.nl_family = AF_NETLINK;
    ctx->plcd_addr.nl_pid = getpid();  /* self pid */
    ctx->plcd_addr.nl_groups = 0;  /* not in mcast group */
    if (0 > bind(ctx->plc_sock, (struct sockaddr *)&ctx->plcd_addr, sizeof(ctx->plcd_addr)))
    {
        perror("netlink socket bind");
        return -1;
    }

    /* get NVRAM data */
    ctx->nvram = &g_nvram;
#ifdef __UTESTS__
    if(LIBSPID_SUCCESS != utests_libspid_system_get_nvram (ctx->nvram))
#else
    if(LIBSPID_SUCCESS != libspid_system_get_nvram (ctx->nvram))
#endif
    {
        perror ("NVRAM content read");
        return -1;
    }

    return 0;
}

void plcd_uninit(plcd_ctx_t *ctx)
{
    close(ctx->plc_sock);
}

#ifdef __UTESTS__
    int utests_main (int argc, char **argv)
#else
    int main (int argc, char **argv)
#endif
{
    plcd_ctx_t ctx; /* main context */
    char buffer[1024];
    int c, opt_index = 0;

    struct option long_opts[] =
        { { "hw_file",     required_argument, NULL, 'h' },
          { "conf_file",   required_argument, NULL, 'c' },
          { "info_file",   required_argument, NULL, 'i' }
        };

    /* init context */
    if ( 0 != plcd_init (&ctx) )
    {
        exit(1);
    }

    /* open log process */
    openlog (argv[0], 0, LOG_DAEMON);

    /*process options */
    while((c = getopt_long_only (argc, argv,
                                 "h:c:i:",
                                 long_opts, &opt_index)) != -1)
    {
        switch(c)
        {
        case 'h': /* hardware info file */
            ctx.hardware_info_path = optarg;
            break;
        case 'c': /* HP AV config file */
            ctx.hpav_conf_path = optarg;
            break;
        case 'i': /* HP AV info file */
            ctx.hpav_info_path = optarg;
            break;
        default:
            print_usage (argv[0]);
            return 1;
        }
    }

    /* set the current PID to info file */
    sprintf (buffer, "%d", getpid ());
    if(LIBSPID_SUCCESS != libspid_config_write_item (ctx.hpav_info_path, LIBSPID_HPAV_INFO_LABEL_PLCD_PID, buffer))
    {
        syslog (LOG_WARNING, "plcd: write pid to %s failed", ctx.hpav_info_path);
    }

    /* initialize the AV stack and loopback until successful init */
    //while(0 > hpav_init (&ctx));
    if(hpav_init (&ctx) < 0)
    {
        syslog (LOG_WARNING, "plcd: plc init failed\n");
        return 1;
    }

    /* now get all events : DRV MMEs from plcdrv or config file
       changes (from managerd) */
    while (1)
    {
        event_process (&ctx);
    }
    //plcd_uninit(&ctx);

    return 0;
}