/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
/*
* TCF Value Add main module.
*
* This implementation of Value Add provides only few services,
* but it supports Locator.redirect command, which can forward TCF traffic to other TCF agents.
*
* The code is intended to be an example of service proxing implementation.
*/
#include <tcf/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <tcf/framework/asyncreq.h>
#include <tcf/framework/events.h>
#include <tcf/framework/trace.h>
#include <tcf/framework/myalloc.h>
#include <tcf/framework/json.h>
#include <tcf/framework/channel.h>
#include <tcf/framework/protocol.h>
#include <tcf/framework/proxy.h>
#include <tcf/framework/errors.h>
#include <tcf/framework/plugins.h>
#include <tcf/services/discovery.h>
static const char * progname;
static Protocol * proto;
static ChannelServer * serv;
static TCFBroadcastGroup * bcg;
static void channel_new_connection(ChannelServer * serv, Channel * c) {
protocol_reference(proto);
c->protocol = proto;
channel_set_broadcast_group(c, bcg);
channel_start(c);
}
#if defined(_WRS_KERNEL)
int tcf_va(void) {
#else
int main(int argc, char ** argv) {
int c;
int ind;
const char * log_level = NULL;
const char * log_name = NULL;
#endif
const char * url = "TCP:";
PeerServer * ps;
ini_mdep();
ini_trace();
ini_events_queue();
ini_asyncreq();
#if defined(_WRS_KERNEL)
progname = "tcf";
open_log_file("-");
log_mode = 0;
#else
progname = argv[0];
/* Parse arguments */
for (ind = 1; ind < argc; ind++) {
const char * s = argv[ind];
if (*s != '-') {
break;
}
s++;
while ((c = *s++) != '\0') {
switch (c) {
case 'l':
case 'L':
case 's':
#if ENABLE_Plugins
case 'P':
#endif
if (*s == '\0') {
if (++ind >= argc) {
fprintf(stderr, "%s: error: no argument given to option '%c'\n", progname, c);
exit(1);
}
s = argv[ind];
}
switch (c) {
case 'l':
log_level = s;
parse_trace_mode(log_level, &log_mode);
break;
case 'L':
log_name = s;
break;
case 's':
url = s;
break;
#if ENABLE_Plugins
case 'P':
plugins_path = s;
break;
#endif
default:
fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
exit(1);
}
s = "";
break;
default:
fprintf(stderr, "%s: error: illegal option '%c'\n", progname, c);
exit(1);
}
}
}
open_log_file(log_name);
#endif
bcg = broadcast_group_alloc();
proto = protocol_alloc();
#if SERVICE_Locator
ini_locator_service(proto, bcg);
#endif
ps = channel_peer_from_url(url);
if (ps == NULL) {
fprintf(stderr, "%s: invalid server URL (-s option value): %s\n", progname, url);
exit(1);
}
peer_server_addprop(ps, loc_strdup("Name"), loc_strdup("TCF Proxy"));
peer_server_addprop(ps, loc_strdup("Proxy"), loc_strdup(""));
serv = channel_server(ps);
if (serv == NULL) {
fprintf(stderr, "%s: cannot create TCF server: %s\n", progname, errno_to_str(errno));
exit(1);
}
serv->new_conn = channel_new_connection;
#if ENABLE_Plugins
/* Load dynamic libraries */
plugins_load(proto, NULL);
#endif
/* Reparse log level in case initialization cause additional
* levels to be registered */
if (parse_trace_mode(log_level, &log_mode) != 0) {
fprintf(stderr, "Cannot parse log level: %s\n", log_level);
exit(1);
}
discovery_start();
/* Process events - must run on the initial thread since ptrace()
* returns ECHILD otherwise, thinking we are not the owner. */
run_event_loop();
#if ENABLE_Plugins
/* Cleanup any loaded libraries */
plugins_destroy();
#endif
return 0;
}