Beispiel #1
0
Datei: main.c Projekt: 91D2/pvpgn
extern int main(int argc, char * * argv)
#endif
{
	int pid;
	char * pidfile;
	
	eventlog_set(stderr);
	pid = config_init(argc, argv);
	if (!(pid == 0)) {
//		if (pid==1) pid=0;
		return pid;
	}
	pidfile = write_to_pidfile();
	eventlog(eventlog_level_info,__FUNCTION__,D2DBS_VERSION);
	if (init()<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to init");
		return -1;
	} else {
		eventlog(eventlog_level_info,__FUNCTION__,"server initialized");
	}
#ifndef WIN32 
	d2dbs_handle_signal_init();
#endif
	dbs_server_main();
	cleanup();
	if (pidfile) {
		if (remove(pidfile)<0)
			eventlog(eventlog_level_error,__FUNCTION__,"could not remove pid file \"%s\" (remove: %s)",pidfile,pstrerror(errno));
		xfree((void *)pidfile); /* avoid warning */
	}
	config_cleanup();
	return 0;
}
Beispiel #2
0
int main(int argc, char * * argv)
{
#ifdef USE_CHECK_ALLOC
	check_set_file(stderr);
#endif
	eventlog_set(stderr);
	if (config_init(argc, argv)<0) {
		return 1;
	}
	log_info(D2CS_VERSION);
	if (init()<0) {
		log_error("failed to init");
		return 1;
	} else {
		log_info("server initialized");
	}
	if (server_process()<0) {
		log_error("failed to run server");
		return 1;
	}
	cleanup();
	config_cleanup();
#ifdef USE_CHECK_ALLOC
	check_cleanup();
	if (memlog_fp) fclose(memlog_fp);
#endif
	return 0;
}
Beispiel #3
0
extern int main(int argc, char * * argv)
#endif
{
	int pid;
	
	eventlog_set(stderr);
	pid = config_init(argc, argv);
	if (!(pid == 0)) {
//		if (pid==1) pid=0;
		return pid;
	}
	eventlog(eventlog_level_info,__FUNCTION__,D2DBS_VERSION);
	if (init()<0) {
		eventlog(eventlog_level_error,__FUNCTION__,"failed to init");
		return -1;
	} else {
		eventlog(eventlog_level_info,__FUNCTION__,"server initialized");
	}
#ifndef WIN32 
	d2dbs_handle_signal_init();
#endif
	dbs_server_main();
	cleanup();
	config_cleanup();
	return 0;
}
Beispiel #4
0
void
xmpp_cleanup() {
    xmpp_disconnect();
    if (connection) lm_connection_unref(connection);
    xmpp_roster_cleanup();
    config_cleanup();
} /* xmpp_cleanup */
/* cleanups are only required to check for memory leaks, OS kernels will usually
   clean up after a program terminates -- especially with an init this shouldn't be much of
   a problem, since it's THE program that doesn't terminate. */
int cleanup () {
 mod_freemodules ();
 config_cleanup();

// bitch (BTCH_DL + BTCH_ERRNO);

 if (einit_startup_mode_switches != einit_default_startup_mode_switches) {
  free (einit_startup_mode_switches);
 }

 return 0;
}
Beispiel #6
0
Datei: hkd.c Projekt: sas/hkd
int main(int argc, char **argv)
{
  int     ret;
  int     fd;
  struct  input_event ev;

  config_init(argc, argv);

  while (true) {
    fd = open(config.input_device, O_RDONLY);
    if (fd == -1)
      err(EXIT_FAILURE, "%s", config.input_device);

    while (true) {
      ret = read(fd, &ev, sizeof ev);

      switch (ret) {
        case sizeof ev:
          do_stuff(&ev);
          break;

        case -1:
          /* Error occured while reading, warn and restart. */
          warn("%s", config.input_device);
        case 0:
          /* EOF reached, this should not happen. Restart. */
          goto cleanup;

        default:
          /*
           * If we did not do a full read, we can't use the contents of the
           * input_event structure. Just close everything and restart.
           */
          warnx("%s: invalid read of size %d", config.input_device, ret);
          goto cleanup;
      }
    }

cleanup:
    close(fd);
  }

  config_cleanup();

  return EXIT_SUCCESS;
}
Beispiel #7
0
int
main (int argc, char **argv)
{
  int ret;
  int c;

  FILE *pidfile;
  struct utsname sysinfo;

  machine_type machine;

  while ((c = getopt(argc, argv, "fdv")) != -1)
    {
      switch (c)
	{
	  case 'f':
	    console = 1;
	    break;

	  case 'd':
	    debug = 1;
	    console = 1;
	    break;

	  case 'v':
	    printf("pommed v" M_VERSION " Apple laptops hotkeys handler\n");
	    printf("Copyright (C) 2006-2011 Julien BLACHE <*****@*****.**>\n");

	    exit(0);
	    break;

	  default:
	    usage();

	    exit(1);
	    break;
	}
    }

  if (geteuid() != 0)
    {
      logmsg(LOG_ERR, "pommed needs root privileges to operate");

      exit(1);
    }

  if (!console)
    {
      openlog("pommed", LOG_PID, LOG_DAEMON);
    }

  logmsg(LOG_INFO, "pommed v" M_VERSION " Apple laptops hotkeys handler");
  logmsg(LOG_INFO, "Copyright (C) 2006-2011 Julien BLACHE <*****@*****.**>");

  /* Load our configuration */
  ret = config_load();
  if (ret < 0)
    {
      exit(1);
    }

  /* Identify the machine we're running on */
  machine = check_machine();
  switch (machine)
    {
      case MACHINE_MAC_UNKNOWN:
	logmsg(LOG_ERR, "Unknown Apple machine");

	exit(1);
	break;

      case MACHINE_UNKNOWN:
	logmsg(LOG_ERR, "Unknown non-Apple machine");

	exit(1);
	break;

      case MACHINE_ERROR:
	exit(1);
	break;

      default:
	if (machine < MACHINE_LAST)
	  {
#ifdef __powerpc__
	    mops = &pb_mops[machine];
#else
	    mops = &mb_mops[machine];
#endif /* __powerpc__ */
	  }
	break;
    }

  /* Runtime sanity check: catch errors in the mb_mops and pb_mops arrays */
  if (mops->type != machine)
    {
      logmsg(LOG_ERR, "machine_ops mismatch: expected %d, found %d", machine, mops->type);

      exit(1);
    }

  if (debug)
    {
      ret = uname(&sysinfo);

      if (ret < 0)
	logmsg(LOG_ERR, "uname() failed: %s", strerror(errno));
      else
	logdebug("System: %s %s %s\n", sysinfo.sysname, sysinfo.release, sysinfo.machine);
    }

  ret = evloop_init();
  if (ret < 0)
    {
      logmsg(LOG_ERR, "Event loop initialization failed");
      exit (1);
    }

  ret = mops->lcd_backlight_probe();
  if (ret < 0)
    {
      logmsg(LOG_ERR, "LCD backlight probe failed, check debug output");

      exit(1);
    }

  ret = evdev_init();
  if (ret < 1)
    {
      logmsg(LOG_ERR, "No suitable event devices found");

      exit(1);
    }

  kbd_backlight_init();

  ret = audio_init();
  if (ret < 0)
    {
      logmsg(LOG_WARNING, "Audio initialization failed, audio support disabled");
    }

  ret = mbpdbus_init();
  if (ret < 0)
    {
      logmsg(LOG_WARNING, "Could not connect to DBus system bus");
    }

  power_init();

  if (!console)
    {
      /*
       * Detach from the console
       */
      if (daemon(0, 0) != 0)
	{
	  logmsg(LOG_ERR, "daemon() failed: %s", strerror(errno));

	  evdev_cleanup();

	  exit(1);
	}
    }

  pidfile = fopen(PIDFILE, "w");
  if (pidfile == NULL)
    {
      logmsg(LOG_WARNING, "Could not open pidfile %s: %s", PIDFILE, strerror(errno));

      evdev_cleanup();

      exit(1);
    }
  fprintf(pidfile, "%d\n", getpid());
  fclose(pidfile);

  /* Spawn the beep thread */
  beep_init();

  signal(SIGINT, sig_int_term_handler);
  signal(SIGTERM, sig_int_term_handler);


  do
    {
      ret = evloop_iteration();
    }
  while (ret >= 0);

  evdev_cleanup();

  beep_cleanup();

  mbpdbus_cleanup();

  kbd_backlight_cleanup();

  power_cleanup();

  evloop_cleanup();

  config_cleanup();

  logmsg(LOG_INFO, "Exiting");

  if (!console)
    closelog();

  unlink(PIDFILE);

  return 0;
}
Beispiel #8
0
int
main(int argc, char *argv[])
{
	int r;

	char *data_file = NULL;
	char *save_file = NULL;

	int map_generator = 0;


	log_set_file(stdout);

	init_config_data();

	//- read config data
	int screen_width = get_config_int(CONFIG_SCREEN_WIDTH, DEFAULT_SCREEN_WIDTH);
	int screen_height = get_config_int(CONFIG_SCREEN_HEIGHT, DEFAULT_SCREEN_HEIGHT);
	int fullscreen = get_config_bool(CONFIG_FULLSCREEN, 0);
	int log_level = get_config_int(CONFIG_LOGGLEVEL, DEFAULT_LOG_LEVEL);
	enum_lng_t language = str_to_lagEnum((char *)get_config_string(CONFIG_LANGUAGE, "EN"));
	int play_midi = get_config_bool(CONFIG_MUSIC, 1);
	int play_SFX = get_config_bool(CONFIG_SFX, 1);
	int volume = get_config_int(CONFIG_VOLUME, 75);

	//- read command line parameters
	int opt;
	while (1) {
		opt = getopt(argc, argv, "d:fg:hl:r:t:s:");
		if (opt < 0) break;

		switch (opt) {
		case 'd':
			{
				int d = atoi(optarg);
				if (d >= 0 && d < LOG_LEVEL_MAX) {
					log_level = d;
				}
			}
			break;
		case 'f':
			fullscreen = 1;
			break;
		case 'g':
			data_file = (char *)malloc(strlen(optarg)+1);
			if (data_file == NULL) exit(EXIT_FAILURE);
			strcpy(data_file, optarg);
			break;
		case 'h':
			fprintf(stdout, HELP, argv[0]);
			exit(EXIT_SUCCESS);
			break;
		case 'l':
			save_file = (char *)malloc(strlen(optarg)+1);
			if (save_file == NULL) exit(EXIT_FAILURE);
			strcpy(save_file, optarg);
			break;
		case 'r':
			{
				char *hstr = strchr(optarg, 'x');
				if (hstr == NULL) {
					fprintf(stderr, USAGE, argv[0]);
					exit(EXIT_FAILURE);
				}
				screen_width = atoi(optarg);
				screen_height = atoi(hstr+1);
			}
			break;
		case 't':
			map_generator = atoi(optarg);
			break;
		case 's':
			{
				char *  tmp_language_str = (char *) malloc(strlen(optarg) + 1);
				if (tmp_language_str != NULL)
				{
					strcpy(tmp_language_str, optarg);
					language = str_to_lagEnum(tmp_language_str);
				}
			}
			break;
		default:
			fprintf(stderr, USAGE, argv[0]);
			exit(EXIT_FAILURE);
			break;
		}
	}

	/* Set up logging */
	log_set_level((log_level_t)log_level);

	LOGI("main", "freeserf %s", FREESERF_VERSION);

	/* load language */
	init_language_data(language);


	r = load_data_file(data_file);
	if (r < 0) {
		LOGE("main", "Could not load game data.");
		exit(EXIT_FAILURE);
	}

	free(data_file);

	gfx_data_fixup();

	LOGI("main", "SDL init...");

	r = sdl_init();
	if (r < 0) exit(EXIT_FAILURE);

	/* TODO move to right place */
	midi_play_track(MIDI_TRACK_0);
	audio_set_volume(volume);

	midi_enable(play_midi);
	sfx_enable(play_SFX);


	/*gfx_set_palette(DATA_PALETTE_INTRO);*/
	gfx_set_palette(DATA_PALETTE_GAME);

	LOGI("main", "SDL resolution %ix%i...", screen_width, screen_height);

	r = sdl_set_resolution(screen_width, screen_height, fullscreen);
	if (r < 0) exit(EXIT_FAILURE);

	game.map_generator = map_generator;

	/* Initialize global lookup tables */
	init_spiral_pattern();

	game_init();

	/* Initialize Missions*/
	init_mission("missions.xml");

	/* Initialize interface */
	interface_init(&interface);
	gui_object_set_size((gui_object_t *)&interface,
			    screen_width, screen_height);
	gui_object_set_displayed((gui_object_t *)&interface, 1);

	/* Either load a save game if specified or
	   start a new game. */
	if (save_file != NULL) {
		int r = game_load_save_game(save_file);
		if (r < 0) exit(EXIT_FAILURE);
		free(save_file);

		interface_set_player(&interface, 0);
	} else {
		int r = game_load_random_map(3, &interface.random);
		if (r < 0) exit(EXIT_FAILURE);

		/* Add default player */
		r = game_add_player(12, 64, 40, 40, 40);
		if (r < 0) exit(EXIT_FAILURE);

		interface_set_player(&interface, r);
	}

	viewport_map_reinit();

	if (save_file != NULL) {
		interface_close_game_init(&interface);
	}

	/* Start game loop */
	game_loop();

	LOGI("main", "Cleaning up...");

	/* Clean up */
	map_deinit();
	viewport_map_deinit();
	audio_cleanup();
	sdl_deinit();
	gfx_unload();
	language_cleanup();
	mission_cleanup();
	config_cleanup();

	return EXIT_SUCCESS;
}
Beispiel #9
0
int main(int argc, char *argv[])
{
	int sd = -1;
	char *conf_file = NULL;
	struct mosquitto *mosq;
	struct module *md;
	struct device *dev;
	int rc;
	int i;
	
	gbuf[0] = 0;

	if (!quiet) printf("Version: %s\n", version);

    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
	signal(SIGUSR1, handle_signal);
	signal(SIGUSR2, handle_signal);
	signal(SIGALRM, each_sec);
	
	for (i=1; i<argc; i++) {
		if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")){
			if(i==argc-1){
                fprintf(stderr, "Error: -c argument given but no file specified.\n\n");
				print_usage(argv[0]);
                return 1;
            }else{
				conf_file = argv[i+1];
			}
			i++;
		}else if(!strcmp(argv[i], "--quiet")){
				quiet = true;
		}else{
				fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]);
				print_usage(argv[0]);
				return 1;
		}
	}
	
	if (!conf_file) {
		fprintf(stderr, "Error: No config file given.\n");
		return 1;
	}

	memset(&config, 0, sizeof(struct bridge_config));
	if (config_parse(conf_file, &config)) return 1;
	
	if (quiet) config.debug = 0;
	if (config.debug != 0) printf("Debug: %d\n", config.debug);

	rc = bridge_init(&bridge, config.id, MODULES_BRIDGE_ID);
	if (rc) {
		if (config.debug) printf("Error: Failed to initialize bridge: %d\n", rc);
		return 1;
	}

	mosquitto_lib_init();
	mosq = mosquitto_new(config.id, true, NULL);
	if(!mosq){
		fprintf(stderr, "Error creating mqtt instance.\n");
		switch(errno){
			case ENOMEM:
				fprintf(stderr, " out of memory.\n");
				break;
			case EINVAL:
				fprintf(stderr, " invalid id.\n");
				break;
		}
		return 1;
	}
	snprintf(gbuf, GBUF_SIZE, "%d", PROTOCOL_TIMEOUT);
	mosquitto_will_set(mosq, bridge.bridge_dev->status_topic, strlen(gbuf), gbuf, config.mqtt_qos, MQTT_RETAIN);

	mosquitto_connect_callback_set(mosq, on_mqtt_connect);
	mosquitto_disconnect_callback_set(mosq, on_mqtt_disconnect);
	mosquitto_message_callback_set(mosq, on_mqtt_message);
	mosquitto_user_data_set(mosq, &sd);

	md = bridge_add_module(bridge.bridge_dev, MODULES_MQTT_ID, true);
	if (!md) {
		fprintf(stderr, "Failed to add MQTT module.\n");
		return 1;
	}

	if (config.scripts_folder) {
		if (access(config.scripts_folder, R_OK )) {
			fprintf(stderr, "Couldn't open scripts folder: %s\n", config.scripts_folder);
			return 1;
		}
		md = bridge_add_module(bridge.bridge_dev, MODULES_SCRIPT_ID, true);
		if (!md) {
			fprintf(stderr, "Failed to add script module.\n");
			return 1;
		}
	}

	if (config.interface) {
		//TODO: check if interface exists
		if (access("/proc/net/dev", R_OK )) {
			fprintf(stderr, "Couldn't open /proc/net/dev\n");
			return 1;
		}
		md = bridge_add_module(bridge.bridge_dev, MODULES_BANDWIDTH_ID, true);
		if (!md) {
			fprintf(stderr, "Failed to add bandwidth module.\n");
			return 1;
		}
		bandwidth = true;
	}

	if (config.serial.port) {
		sd = serialport_init(config.serial.port, config.serial.baudrate);
		if( sd == -1 ) {
			fprintf(stderr, "Couldn't open serial port.\n");
			return 1;
		} else {
			md = bridge_add_module(bridge.bridge_dev, MODULES_SERIAL_ID, true);
			if (!md) {
				fprintf(stderr, "Failed to add serial module.\n");
				return 1;
			}
			serialport_flush(sd);
			bridge.serial_ready = true;

			if (config.debug) printf("Serial ready.\n");
		}
	}

	if (config.debug > 2) bridge_print_modules(bridge.bridge_dev);

	rc = mosquitto_connect(mosq, config.mqtt_host, config.mqtt_port, 60);
	if (rc) {
		fprintf(stderr, "ERROR: %s\n", mosquitto_strerror(rc));
		return -1;
	}

	alarm(1);

	while (run) {
		if (bridge.serial_ready) {
			rc = serial_in(sd, mosq, MODULES_SERIAL_ID);
			if (rc == -1) {
				serial_hang(mosq);
			} else if (rc > 0) {
				bridge.serial_alive = DEVICE_ALIVE_MAX;
			}
		}

		if (user_signal) {
			if (config.debug > 2) printf("Signal - SIGUSR: %d\n", user_signal);
			signal_usr(sd, mosq);
		}

		rc = mosquitto_loop(mosq, 100, 1);
		if (run && rc) {
			if (config.debug > 2) printf("MQTT loop: %s\n", mosquitto_strerror(rc));
			usleep(100000);	// wait 100 msec
			mosquitto_reconnect(mosq);
		}
		usleep(20);

		if (every1s) {
			every1s = false;

			for (dev = bridge.dev_list; dev != NULL; dev = dev->next) {
				if (dev->alive) {
					dev->alive--;
					if (!dev->alive) {
						if (connected) {
							snprintf(gbuf, GBUF_SIZE, "%d", PROTOCOL_TIMEOUT);
							mqtt_publish(mosq, dev->status_topic, gbuf);
							rc = mosquitto_unsubscribe(mosq, NULL, dev->config_topic);
							if (rc)
								fprintf(stderr, "Error: MQTT unsubscribe returned: %s\n", mosquitto_strerror(rc));
						}
						if (config.debug) printf("Device: %s - Timeout.\n", dev->id);
						bridge_remove_device(&bridge, dev->id);
					}
				}
			}
		}

		if (every30s) {
			every30s = false;

			if (connected) {
				send_alive(mosq);

				if (bandwidth) {
					md = bridge_get_module(bridge.bridge_dev, MODULES_BANDWIDTH_ID);
					if (md) {
						snprintf(gbuf, GBUF_SIZE, "%.0f,%.0f", upspeed, downspeed);
						mqtt_publish(mosq, md->topic, gbuf);
						if (config.debug > 2) printf("down: %f - up: %f\n", downspeed, upspeed);
					}
				}
			} else {
				if (config.debug) printf("MQTT Offline.\n");
			}

			if (bridge.serial_alive) {
				bridge.serial_alive--;
				if (!bridge.serial_alive) {
					if (config.debug > 1) printf("Serial timeout.\n");
					serial_hang(mosq);
				}
			} else {
				if (config.serial.port && !bridge.serial_ready) {
					if (config.debug > 1) printf("Trying to reconnect serial port.\n");
					serialport_close(sd);
					sd = serialport_init(config.serial.port, config.serial.baudrate);
					if( sd == -1 ) {
						fprintf(stderr, "Couldn't open serial port.\n");
					} else {
						serialport_flush(sd);
						bridge.serial_ready = true;
						snprintf(gbuf, GBUF_SIZE, "%d", MODULES_SERIAL_OPEN);
						mqtt_publish(mosq, md->topic, gbuf);
						if (config.debug) printf("Serial reopened.\n");
					}
				}
			}
		}
	}

	if (bridge.serial_ready) {
		serialport_close(sd);
	}

	mosquitto_destroy(mosq);

	mosquitto_lib_cleanup();
	config_cleanup(&config);

	printf("Exiting..\n\n");

	return 0;
}
Beispiel #10
0
int main(int argc, char *argv[])
{
	int sd = -1;
	char *conf_file = NULL;
	struct mosquitto *mosq;
	struct module *md;
	struct device *dev;
	int rc;
	int i;
	
	if (!quiet) printf("Version: %s\n", version);

    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
	signal(SIGUSR1, handle_signal);
	signal(SIGUSR2, handle_signal);
	signal(SIGALRM, each_sec);
	
	for (i=1; i<argc; i++) {
		if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")){
			if(i==argc-1){
                fprintf(stderr, "Error: -c argument given but no file specified.\n\n");
				print_usage(argv[0]);
                return 1;
            }else{
				conf_file = argv[i+1];
			}
			i++;
		}else if(!strcmp(argv[i], "--quiet")){
				quiet = true;
		}else{
				fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]);
				print_usage(argv[0]);
				return 1;
		}
	}
	
	if(!conf_file) {
		fprintf(stderr, "Error: No config file given.\n");
		return 1;
	}

	memset(&config, 0, sizeof(struct bridge_config));
	if(config_parse(conf_file, &config)) return 1;
	
	if (quiet) config.debug = 0;
	if (config.debug != 0) printf("Debug: %d\n", config.debug);

	if (!device_isValid_id(config.id)) {
		fprintf(stderr, "Invalid id.\n");
		return -1;
	}
	if (device_init(&bridge, config.id) == -1)
		return 1;

	mosquitto_lib_init();
	mosq = mosquitto_new(config.id, true, NULL);
	if(!mosq){
		fprintf(stderr, "Error creating mqtt instance.\n");
		switch(errno){
			case ENOMEM:
				fprintf(stderr, " out of memory.\n");
				break;
			case EINVAL:
				fprintf(stderr, " invalid id.\n");
				break;
		}
		return 1;
	}
	snprintf(gbuf, GBUF_SIZE, "%d", PROTO_ST_TIMEOUT);
	mosquitto_will_set(mosq, bridge.status_topic, strlen(gbuf), gbuf, config.mqtt_qos, MQTT_RETAIN);
	mosquitto_connect_callback_set(mosq, on_mqtt_connect);
	mosquitto_disconnect_callback_set(mosq, on_mqtt_disconnect);
	mosquitto_message_callback_set(mosq, on_mqtt_message);
	mosquitto_user_data_set(mosq, &sd);

	if (config.debug > 1) printf("Subscribe topic: %s\n", bridge.config_topic);

	rc = device_add_module(&bridge, MODULE_MQTT_ID, bridge.id);				//TODO: autogen id?
	if (rc) {
		fprintf(stderr, "Failed to add mqtt module.\n");
		return 1;
	}

	if (config.scripts_folder) {
		if (access(config.scripts_folder, R_OK )) {
			fprintf(stderr, "Couldn't open scripts folder: %s\n", config.scripts_folder);
			return 1;
		}
		rc = device_add_module(&bridge, MODULE_SCRIPT_ID, bridge.id);		//TODO: autogen id?
		if (rc) {
			fprintf(stderr, "Failed to add script module.\n");
			return 1;
		}
	}
	if (config.interface) {
		//TODO: check if interface exists
		if (access("/proc/net/dev", R_OK )) {
			fprintf(stderr, "Couldn't open /proc/net/dev\n");
			return 1;
		}
		rc = device_add_module(&bridge, MODULE_BANDWIDTH_ID, bridge.id);		//TODO: autogen id?
		if (rc) {
			fprintf(stderr, "Failed to add bandwidth module.\n");
			return 1;
		}
		bandwidth = true;
	}
	if (config.serial.port) {
		sd = serialport_init(config.serial.port, config.serial.baudrate);
		if( sd == -1 ) {
			fprintf(stderr, "Couldn't open serial port.\n");
			return 1;
		} else {
			rc = device_add_module(&bridge, MODULE_SERIAL_ID, bridge.id);		//TODO: autogen id?
			if (rc) {
				fprintf(stderr, "Failed to add serial module.\n");
				return 1;
			}
			serialport_flush(sd);
			bridge.serial_ready = true;

			if (config.debug) printf("Serial ready.\n");
		}
	}

	rc = device_add_module(&bridge, MODULE_SIGUSR1_ID, bridge.id);			//TODO: autogen id?
	if (rc) {
		fprintf(stderr, "Failed to add sigusr1 module.\n");
		return 1;
	}

	rc = device_add_module(&bridge, MODULE_SIGUSR2_ID, bridge.id);			//TODO: autogen id?
	if (rc) {
		fprintf(stderr, "Failed to add sigusr2 module.\n");
		return 1;
	}

	device_print_modules(&bridge);

	rc = mosquitto_connect(mosq, config.mqtt_host, config.mqtt_port, 60);
	if (rc) {
		fprintf(stderr, "Wrong MQTT parameters. Check your config.\n");
		return -1;
	}

	alarm(1);

	while (run) {
		if (bridge.serial_ready) {
			rc = serial_in(sd, mosq, MODULE_SERIAL_ID);
			if (rc == -1) {
				serial_hang(mosq);
			} else if (rc > 0) {
				bridge.serial_alive = ALIVE_CNT;
			}
		}

		if (user_signal) {
			if (config.debug > 1) printf("Signal - SIGUSR: %d\n", user_signal);
			signal_usr(sd, mosq);
		}

		rc = mosquitto_loop(mosq, -1, 1);
		if (run && rc) {
			if (config.debug > 2) printf("MQTT loop: %s\n", mosquitto_strerror(rc));
			usleep(100000);	// wait 100 msec
			mosquitto_reconnect(mosq);
		}

		if (every30s) {
			every30s = false;

			bridge.controller = false;
			for (i = 0; i < bridge.devices_len; i++) {
				dev = &bridge.devices[i];
				if (dev->alive) {
					dev->alive--;
					if (!dev->alive) {
						snprintf(gbuf, GBUF_SIZE, "%d,%s", PROTO_ST_TIMEOUT, dev->id);
						mqtt_publish(mosq, bridge.status_topic, gbuf);

						if (dev->md_deps->type == MODULE_MQTT && dev->type == DEVICE_TYPE_NODE) {
							snprintf(gbuf, GBUF_SIZE, "status/%s", dev->id);
							rc = mosquitto_unsubscribe(mosq, NULL, gbuf);
							if (rc)
								fprintf(stderr, "Error: MQTT unsubscribe returned: %s\n", mosquitto_strerror(rc));
						}

						if (config.debug) printf("Device timeout - id: %s\n", dev->id);
					} else {
						if (dev->type == DEVICE_TYPE_CONTROLLER)
							bridge.controller = true;
					}
				}
			}

			if (!bridge.controller)
				bridge.modules_update = false;

			if (connected) {
				snprintf(gbuf, GBUF_SIZE, "%d,%d", PROTO_ST_ALIVE, bridge.modules_len);
				mqtt_publish(mosq, bridge.status_topic, gbuf);

				if (bridge.modules_update) {
					snprintf(gbuf, GBUF_SIZE, "%d", PROTO_ST_MODULES_UP);
					if (mqtt_publish(mosq, bridge.status_topic, gbuf))
						bridge.modules_update = false;
				}

				if (bandwidth) {
					md = device_get_module(&bridge, MODULE_BANDWIDTH_ID);
					if (md) {
						if (mqtt_publish_bandwidth(mosq, md->topic) == -1)
							break;
					}
				}
			} else {
				if (config.debug != 0) printf("MQTT Offline.\n");
			}

			if (bridge.serial_alive) {
				bridge.serial_alive--;
				if (!bridge.serial_alive) {
					if (config.debug > 1) printf("Serial timeout.\n");
					serial_hang(mosq);
				}
			} else {
				if (config.serial.port && !bridge.serial_ready) {
					if (config.debug > 1) printf("Trying to reconnect serial port.\n");
					serialport_close(sd);
					sd = serialport_init(config.serial.port, config.serial.baudrate);
					if( sd == -1 )
						fprintf(stderr, "Couldn't open serial port.\n");
					else {
						serialport_flush(sd);
						bridge.serial_ready = true;
						if (config.debug) printf("Serial reopened.\n");
					}
				}
			}
		}
		usleep(20);
	}

	if (bridge.serial_ready) {
		serialport_close(sd);
	}

	mosquitto_destroy(mosq);

	mosquitto_lib_cleanup();
	config_cleanup(&config);

	printf("Exiting..\n\n");

	return 0;
}