예제 #1
0
bool
PaceFilter::setup()
{
  if (findFilter("queue", true) == nullptr
      && std::dynamic_pointer_cast<LinkConnect>(conn.lock()) != nullptr)
    ERRORPRINTF(t, E_NOTICE, "The 'pace' filter without a queue acts globally.");
  if (!Filter::setup())
    return false;
  delay = cfg->value("delay",15)/1000.;
  if (delay <= 0)
    {
      ERRORPRINTF(t, E_ERROR, "The delay must be >0");
      return false;
    }
  byte_delay = cfg->value("delay-per-byte",1)/1000.;
  if (byte_delay < 0)
    {
      ERRORPRINTF(t, E_ERROR, "The delay must be >0");
      return false;
    }
  factor_in = cfg->value("incoming",0.75);
  if (factor_in < 0)
    {
      ERRORPRINTF(t, E_ERROR, "The factor for incoming packets must be >=0");
      return false;
    }
  return true;
}
예제 #2
0
파일: fdmap.c 프로젝트: carverdamien/ioapps
void insert_parent_fd(fd_item_t * fd_item, int fd) {
	int i;
	int index = -1;
	int * parents = fd_item->fd_map->parent_fds;

	for(i = 0; i < MAX_PARENT_IDS; i++) {
		if (parents[i] == fd) {			
			ERRORPRINTF("Fd %d is already present in parent fds array...\n", fd);
			assert(1 == 0);
			return;
		}
		if (parents[i] == -1) {
			index = i;
			break;
		}
	}

	if (index != -1) {
		parents[index] = fd;
		fd_item->fd_map->last_par_index++;
	} else {
		ERRORPRINTF("Array of parrent fds is full! My_fd is: :%d\n", fd_item->fd_map->my_fd);
	}

}
예제 #3
0
파일: fdmap.c 프로젝트: carverdamien/ioapps
int delete_parent_fd(fd_item_t * fd_item, int fd) {
	int i;
	int * parents = fd_item->fd_map->parent_fds;

	for(i = 0; i < MAX_PARENT_IDS; i++) {
		if (parents[i] == fd) {
			int idx = fd_item->fd_map->last_par_index;
			if ( i == fd_item->fd_map->last_par_index ) { //last item in the list
				parents[i] = -1;
			} else if ( idx > 0 ) {
				parents[i] = parents[idx];
				parents[idx] = -1;
			} else {
				ERRORPRINTF("Sanity check error: last_par_index out of bounds: %d\n", idx);
				assert(1 == 0);
			}
			fd_item->fd_map->last_par_index--;
			break;
		}

		if (parents[i] == -1) {
			ERRORPRINTF("Didn't find fd %d in parent fds\n", fd);
			assert(1 == 0);
			break;
		}
	}
	return fd_item->fd_map->last_par_index == -1;
}
예제 #4
0
파일: ipc.c 프로젝트: luite/uds-plugin-djvu
gboolean ipc_sys_is_in_portrait_mode(void)
{

    gboolean result = TRUE;

    eripc_error_t retval;
    eripc_event_info_t* info = NULL;

    LOGPRINTF("entry");

    retval = eripc_send_varargs_and_wait(eripcClient->context,
            &info,
            ERIPC_BUS_SESSION,
            DBUS_SERVICE_SYSTEM_CONTROL,
            "sysGetOrientation",
            ERIPC_TYPE_INVALID);

    if (retval != ERIPC_ERROR_SUCCESS)
    {
        ERRORPRINTF("Error launching eripc handler");
    }
    else if (info == NULL || info->args == NULL)
    {
        ERRORPRINTF("sysd returns OK but no reply structure");
    }
    else
    {
        const eripc_arg_t *arg_array = info->args;

        if (arg_array[0].type == ERIPC_TYPE_STRING)
        {
            if ( strcmp("portrait", arg_array[0].value.s) == 0 )
            {
                result = TRUE;
            }
            else
            {
                result = FALSE;
            }
        }
        else
        {
            result = FALSE ;
        }
    }
    eripc_event_info_free(eripcClient->context, info);
    return result;
}
예제 #5
0
파일: eibnettunnel.cpp 프로젝트: knxd/knxd
bool
EIBNetIPTunnel::setup()
{
  // Force queuing so that a broken or unreachable server can't disable the whole system
  if (!assureFilter("queue", true))
    return false;

  if (!BusDriver::setup())
    return false;
  dest = cfg->value("ip-address","");
  if (!dest.size()) 
    {
      ERRORPRINTF (t, E_ERROR | 23, "The 'ipt' driver, section %s, requires an 'ip-address=' option", cfg->name);
      return false;
    }
  port = cfg->value("dest-port",3671);
  sport = cfg->value("src-port",0);
  NAT = cfg->value("nat",false);
  monitor = cfg->value("monitor",false);
  if(NAT)
    {
      srcip = cfg->value("nat-ip","");
      dataport = cfg->value("data-port",0);
    }
  heartbeat_time = cfg->value("heartbeat-timer",30);
  heartbeat_limit = cfg->value("heartbeat-retries",3);
  return true;
}
예제 #6
0
파일: fdmap.c 프로젝트: carverdamien/ioapps
void delete_process_ht(hash_table_t * fd_mappings, int32_t pid) {
	item_t * process_ht_item;

	if ( (process_ht_item = hash_table_find(fd_mappings, &pid)) != NULL ) {
		hash_table_remove(fd_mappings, &pid);
	} else {
		ERRORPRINTF("Can not find pid %"PRIi32" when removing delete_process_ht\n", pid);
	}
}
예제 #7
0
파일: fqueue.cpp 프로젝트: ascillato/knxd
bool
QueueFilter::setup()
{
  if(std::dynamic_pointer_cast<LinkConnect>(conn.lock()) == nullptr)
    {
      ERRORPRINTF(t, E_ERROR, "You can't use the 'queue' filter globally");
      return false;
    }
  if (findFilter("queue", true) != nullptr)
    {
      ERRORPRINTF(t, E_WARNING, "Two queue filters on a link does not make sense");
      return false;
    }
  if (!Filter::setup())
    return false;
  // XXX options?
  return true;
}
예제 #8
0
파일: fqueue.cpp 프로젝트: ascillato/knxd
void
QueueFilter::send_Next()
{
  switch(state)
    {
    case Q_DOWN:
      ERRORPRINTF(t, E_WARNING, "send_Next while down");
      break;
    case Q_IDLE:
      ERRORPRINTF(t, E_WARNING, "spurious send_Next");
      break;
    case Q_BUSY:
      trigger.send();
      // fall thru
    case Q_SENDING:
      state = Q_IDLE;
      break;
    }
}
예제 #9
0
파일: tpuart.cpp 프로젝트: ascillato/knxd
bool
TPUARTwrap::setup()
{
  ackallgroup = cfg->value("ack-group",false);
  ackallindividual = cfg->value("ack-individual",false);
  monitor = cfg->value("monitor",false);

  if (cfg->value("device","").length() > 0)
    {
      if (cfg->value("ip-address","").length() > 0 ||
          cfg->value("port",-1) != -1)
        {
          ERRORPRINTF (t, E_ERROR, "Don't specify both device and IP options!");
          return false;
        }
      iface = create_serial(this, cfg);
    }
  else
    {
      if (cfg->value("baudrate",-1) != -1)
        {
          ERRORPRINTF (t, E_ERROR, "Don't specify both device and IP options!");
          return false;
        }
      iface = new LLtcp(this, cfg);
    }

  if (t->ShowPrint(0))
    iface = new LLlog (this,cfg, iface);

  FilterPtr single = findFilter("single");
  if (single != nullptr)
    {
      std::shared_ptr<NatL2Filter> f = std::dynamic_pointer_cast<NatL2Filter>(single);
      if (f)
        my_addr = f->addr;
    }
  
  if (!LowLevelFilter::setup())
    return false;

  return true;
}
예제 #10
0
파일: ipc.c 프로젝트: luite/uds-plugin-djvu
gboolean ipc_sys_is_pageturn_inverted()
{
    gboolean result = FALSE;

    eripc_error_t retval;
    eripc_event_info_t* info = NULL;

    LOGPRINTF("entry");

    retval = eripc_send_varargs_and_wait(eripcClient->context,
            &info,
            ERIPC_BUS_SESSION,
            DBUS_SERVICE_SYSTEM_CONTROL,
            "sysGetPageturnInverted",
            ERIPC_TYPE_INVALID);

    if (retval != ERIPC_ERROR_SUCCESS)
    {
        ERRORPRINTF("Error launching eripc handler");
    }
    else if (info == NULL || info->args == NULL)
    {
        ERRORPRINTF("sysd returns OK but no reply structure");
    }
    else
    {
        const eripc_arg_t *arg_array = info->args;

        if (arg_array[0].type == ERIPC_TYPE_BOOL)
        {
            result = (gboolean) arg_array[0].value.b;
        }
        else 
        {
            result = FALSE ;
        }
    }

    eripc_event_info_free(eripcClient->context, info);
    return result; 
}
예제 #11
0
파일: lltcp.cpp 프로젝트: ascillato/knxd
bool
LLtcp::setup()
{
  if(!FDdriver::setup())
    return false;

  dest = cfg->value("ip-address","");
  port = cfg->value("dest-port",0);
  if (dest.size() == 0)
    {
      ERRORPRINTF (t, E_ERROR | 52, "%s: 'ip-address=<host>' required", cfg->name);
      return false;
    }
  if (port == 0)
    {
      ERRORPRINTF (t, E_ERROR | 52, "%s: 'port=<num>' required", cfg->name);
      return false;
    }

  return true;
}
예제 #12
0
파일: lltcp.cpp 프로젝트: ascillato/knxd
void
LLtcp::start()
{
  int reuse = 1;
  int nodelay = 1;
  struct sockaddr_in addr;

  if (!GetHostIP (t, &addr, dest.c_str()))
    {
      ERRORPRINTF (t, E_ERROR | 52, "Lookup of %s failed: %s", dest, strerror(errno));
      goto ex1;
    }
  addr.sin_port = htons (port);

  fd = socket (AF_INET, SOCK_STREAM, 0);
  if (fd == -1)
    {
      ERRORPRINTF (t, E_ERROR | 52, "Opening %s:%d failed: %s", dest,port, strerror(errno));
      goto ex1;
    }

  if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
    {
      ERRORPRINTF (t, E_ERROR | 53, "Connect %s:%d: connect: %s", dest,port, strerror(errno));
      goto ex2;
    }
  setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));
  setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof (nodelay));

  TRACEPRINTF (t, 2, "Opened");
  FDdriver::start();
  return;

ex2:
  close (fd);
  fd = -1;
ex1:
  stopped();
}
예제 #13
0
파일: fqueue.cpp 프로젝트: ascillato/knxd
void
QueueFilter::started()
{
  switch(state)
    {
    case Q_DOWN:
      state = Q_IDLE;
      break;
    default:
      ERRORPRINTF(t, E_WARNING, "state %d??", state);
      break;
    }
  Filter::started();
}
예제 #14
0
void
PaceFilter::started()
{
  switch(state)
    {
    case P_DOWN:
      if (want_next)
        Filter::send_Next();
      state = P_IDLE;
      break;
    default:
      ERRORPRINTF(t, E_WARNING, "state %d??", state);
      break;
    }
  Filter::started();
}
예제 #15
0
SystemdServer::SystemdServer (Layer3 * la3, Trace * tr, int systemd_fd):
Server (la3, tr)
{
  TRACEPRINTF (tr, 8, this, "OpenSystemdSocket");

  fd = systemd_fd;
  if (listen (fd, 10) == -1)
    {
      ERRORPRINTF (tr, E_ERROR | 18, this, "OpenSystemdSocket: listen: %s", strerror(errno));
      close (fd);
      fd = -1;
      return;
    }

  TRACEPRINTF (tr, 8, this, "SystemdSocket opened");
  Start ();
}
예제 #16
0
파일: eibnetrouter.cpp 프로젝트: knxd/knxd
void
EIBNetIPRouter::start()
{
  struct sockaddr_in baddr;
  struct ip_mreq mcfg;
  TRACEPRINTF (t, 2, "Open");
  memset (&baddr, 0, sizeof (baddr));
#ifdef HAVE_SOCKADDR_IN_LEN
  baddr.sin_len = sizeof (baddr);
#endif
  baddr.sin_family = AF_INET;
  baddr.sin_port = htons (port);
  baddr.sin_addr.s_addr = htonl (INADDR_ANY);
  sock = new EIBNetIPSocket (baddr, 1, t);
  if (!sock->init ())
    goto err_out;
  sock->on_recv.set<EIBNetIPRouter,&EIBNetIPRouter::read_cb>(this);

  if (! sock->SetInterface(interface))
    {
      ERRORPRINTF (t, E_ERROR | 58, "interface %s not recognized", interface);
      goto err_out;
    }

  sock->recvall = 2;
  if (GetHostIP (t, &sock->sendaddr, multicastaddr) == 0)
    goto err_out;
  sock->sendaddr.sin_port = htons (port);
  if (!GetSourceAddress (t, &sock->sendaddr, &sock->localaddr))
    goto err_out;
  sock->localaddr.sin_port = sock->sendaddr.sin_port;

  mcfg.imr_multiaddr = sock->sendaddr.sin_addr;
  mcfg.imr_interface.s_addr = htonl (INADDR_ANY);
  if (!sock->SetMulticast (mcfg))
    goto err_out;
  TRACEPRINTF (t, 2, "Opened");
  BusDriver::start();
  return;

err_out:
  delete sock;
  sock = 0;
  stopped();
}
예제 #17
0
void PluginViewImpl::handle_page_ready(RenderResultPtr result, RenderStatus stat)
{
    if (result == 0)
    {
        // the render result cannot be NULL
        return;
    }

    PluginEventAttrs attrs;

    // set reference id
    attrs.render_end.rid = result->get_ref_id();

    // set render result
    attrs.render_end.result = static_cast<IPluginUnknown *>(result);

    switch (stat)
    {
    case TASK_RENDER_DONE:
        {
            // render done
            attrs.render_end.status = RENDER_DONE;
        }
        break;
    case TASK_RENDER_OOM:
        {
            // out of memory
            attrs.render_end.status = RENDER_OUT_OF_MEMORY;

            WARNPRINTF("Tell UDS out of memory, task %ld is aborted", attrs.render_end.rid);
        }
        break;
    case TASK_RENDER_INVALID_PAGE:
        {
            // it is an invalid page
            attrs.render_end.status = RENDER_INVALID_PAGE;

            ERRORPRINTF("Cannot render an invalid page");
        }
    default:
        break;
    }

    listeners.broadcast(this, EVENT_RENDERING_END, &attrs);
}
예제 #18
0
파일: fdmap.c 프로젝트: carverdamien/ioapps
inline int decrease_fd_usage(hash_table_t * ht, int fd) {
	item_t * item = hash_table_find(ht, &fd);
	fd_usage_t * fd_usage;

	if (item == NULL) { //was not opened before
		ERRORPRINTF("Trying to decrease usage of fd:%d, which doesn't exist!\n", fd);
		assert(1 == 0);
		return -1;
	} else { //we have it already
		fd_usage = hash_table_entry(item, fd_usage_t, item);
		fd_usage->usage--;
		if (fd_usage->usage == 0) {
			hash_table_remove(ht, &fd);
			return 1;
		}
	}
	return 0;
}
예제 #19
0
void
PaceFilter::send_Next()
{

  switch(state)
    {
    case P_DOWN:
      want_next = true;
      break;
    case P_IDLE:
      state = P_BUSY;
      timer.start(last_len*byte_delay + delay);
      break;
    case P_BUSY:
      ERRORPRINTF(t, E_WARNING, "send_next on busy pacer?");
      break;
    }
}
예제 #20
0
void PDFRenderTask::execute()
{
    // don't execute the prerender task if the page is out of date
    if (is_page_out_of_date())
    {
        return;
    }

    PDFRenderer *renderer = doc_ctrl->get_renderer();

    // estimate whether the page has been cached
    // it is necessary here although there is same estimation
    // in main thread, because the same page might be constructed
    // in other tasks.
    if (page == 0)
    {
        page = doc_ctrl->get_page(page_number);

        if (page == 0)
        {   
            page = renderer->gen_page(page_number, page_render_attr);
        }
    }

    //assert(page);
    if (page == 0)
    {
        ERRORPRINTF("Cannot Create New Page");
        return;
    }

    // set the reference id, this operation is thread-safe now
    // NOTE: this function must be called before setting render attributes
    // because the main thread would update the ref id if the render attributes
    // changes.
    page->set_ref_id(ref_id);

    // if it is ZOOM_AUTO_CROP mode, it means it is necessary to get the content
    // area of the page
    double real_zoom = page_render_attr.get_real_zoom_value();
    if (real_zoom == PLUGIN_ZOOM_TO_CROP_BY_PAGE ||
        real_zoom == PLUGIN_ZOOM_TO_CROP_BY_WIDTH)
    {
        RenderArea content_area;
        if (!page->get_content_area(renderer, content_area))
        {
            ERRORPRINTF("Cannot get content area of page:%d", page_number);
            return;
        }
        PDFRenderAttributes origin_attr = page_render_attr;
        renderer->calc_real_zoom(page_number, origin_attr, page_render_attr);
        real_zoom = page_render_attr.get_real_zoom_value();
    }

    // if the page is cached and the bitmap has been rendered
    // calculate the delta value. Becuase the old bitmap would
    // be destroyed and new one is going to be rendered in the following
    // step
    int page_len = static_cast<int>(page->length());

    page_len = static_cast<int>(PDFPage::try_calc_length(real_zoom,
                                doc_ctrl->get_page_crop_width(page_number),
                                doc_ctrl->get_page_crop_height(page_number))) -
               page_len;

    PDFPage::RenderStatus cur_status = page->get_render_status();
    if (!(page->get_render_attr() == page_render_attr))
    {
        // if the render attributes change, re-render the page
        // DO NOT update the render setting here, because it might
        // change the length of page
        // DO NOT change the status of page at this moment
        cur_status = PDFPage::RENDER_STOP;
    }
    
    bool render_done = true;

    // render bitmap
    if (cur_status != PDFPage::RENDER_DONE)
    {
        TRACE("Task, Render Page:%d, Ref ID:%d, Current Task:%p\n\n", page_number, ref_id, this);
        // update the page cache to make sure there is enough memory
        // if page_len < 0, it means the page is going to shrink, the memory
        // must be enough
        // TODO. Add the page number as one parameter for making enough memory
        // The pages with lower priorites would be released.
        if (page_len > 0 &&
            !PDFLibrary::instance().make_enough_memory(doc_ctrl,
                                                       page_number,
                                                       page_len))
        {
            WARNPRINTF("Cannot make enough memory to implement rendering");

            // notify uds that it is out of memory that the page rendering
            // is aborted
            renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM);
            return;
        }

        // update the render status
        page->set_render_status(cur_status);

        // only set the render attributes
        page->set_render_attr(page_render_attr);

        render_done = page->render_splash_map(renderer
            , static_cast<void*>(this));

        // render the text page when the render is done
        if (render_done)
        {
            page->render_text(renderer);
        }
    }

    if (render_done)
    {
        // set the render status at last
        page->set_render_status(PDFPage::RENDER_DONE);

        if (render_result != 0)
        {
            // set the page into render result
            render_result->set_page(page);
        }

        // notify uds that the page is ready
        renderer->handle_page_ready(render_result, page, TASK_RENDER_DONE);
    }
    else
    {
        if (render_result != 0 && is_aborted())
        {
            // if the task is aborted, set the render result to "Discard"
            render_result->set_discard(true);
        }
        else
        {
            renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM);
        }
    }

}
예제 #21
0
파일: eibnettunnel.cpp 프로젝트: knxd/knxd
void
EIBNetIPTunnel::error_cb ()
{
  ERRORPRINTF (t, E_ERROR | 20, "Communication error: %s", strerror(errno));
  errored();
}
예제 #22
0
파일: knxd.cpp 프로젝트: 1stsetup/knxd
int
main (int ac, char *ag[])
{
  int index;
  pth_init ();

  argp_parse (&argp, ac, ag, ARGP_IN_ORDER, &index, &arg);

  // if you ever want this to be fatal, doing it here would be too late
  if (getuid () == 0)
    ERRORPRINTF (arg.tracer(), E_WARNING | 20, 0, "EIBD should not run as root");

  signal (SIGPIPE, SIG_IGN);

  if (arg.daemon)
    {
      int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE);
      if (fd == -1)
	die ("Can not open file %s", arg.daemon);
      int i = fork ();
      if (i < 0)
	die ("fork failed");
      if (i > 0)
	exit (0);
      close (1);
      close (2);
      close (0);
      dup2 (fd, 1);
      dup2 (fd, 2);
      close (fd);
      setsid ();
    }

  FILE *pidf;
  if (arg.pidfile)
    if ((pidf = fopen (arg.pidfile, "w")) != NULL)
      {
	fprintf (pidf, "%d", getpid ());
	fclose (pidf);
      }


  signal (SIGINT, SIG_IGN);
  signal (SIGTERM, SIG_IGN);

  // main loop
#ifdef HAVE_SYSTEMD
  sd_notify(0,"READY=1");
#endif
  int sig;
  if (! arg.stop_now)
    do {
      sigset_t t1;
      sigemptyset (&t1);
      sigaddset (&t1, SIGINT);
      sigaddset (&t1, SIGHUP);
      sigaddset (&t1, SIGTERM);

      pth_sigwait (&t1, &sig);

      if (sig == SIGHUP && arg.daemon)
	{
	  int fd =
	    open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE);
	  if (fd == -1)
	    {
	      ERRORPRINTF (arg.tracer(), E_ERROR | 21, 0, "can't open log file %s",
			   arg.daemon);
	      continue;
	    }
	  close (1);
	  close (2);
	  dup2 (fd, 1);
	  dup2 (fd, 2);
	  close (fd);
	}

    } while (sig == SIGHUP);
#ifdef HAVE_SYSTEMD
  sd_notify(0,"STOPPING=1");
#endif

  signal (SIGINT, SIG_DFL);
  signal (SIGTERM, SIG_DFL);

#ifdef HAVE_GROUPCACHE
  DeleteGroupCache ();
#endif

  arg.free_l3();

  if (arg.pidfile)
    unlink (arg.pidfile);

  pth_yield (0);
  pth_yield (0);
  pth_yield (0);
  pth_yield (0);
  pth_exit (0);
  return 0;
}
예제 #23
0
파일: ft12.cpp 프로젝트: 1stsetup/knxd
void
FT12LowLevelDriver::Run (pth_sem_t * stop1)
{
  CArray last;
  int i;
  uchar buf[255];

  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal);
  pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (0, 100000));
  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      pth_event_isolate (input);
      pth_event_isolate (timeout);
      if (mode == 0)
	pth_event_concat (stop, input, NULL);
      if (mode == 1)
	pth_event_concat (stop, timeout, NULL);

      i = pth_read_ev (fd, buf, sizeof (buf), stop);
      if (i > 0)
	{
	  t->TracePacket (0, this, "Recv", i, buf);
	  akt.setpart (buf, akt (), i);
	}

      while (akt.len () > 0)
	{
	  if (akt[0] == 0xE5 && mode == 1)
	    {
	      pth_sem_dec (&in_signal);
	      inqueue.get ();
	      if (inqueue.isempty ())
		pth_sem_set_value (&send_empty, 1);
	      akt.deletepart (0, 1);
	      mode = 0;
	      repeatcount = 0;
	    }
	  else if (akt[0] == 0x10)
	    {
	      if (akt () < 4)
		break;
	      if (akt[1] == akt[2] && akt[3] == 0x16)
		{
		  uchar c1 = 0xE5;
		  t->TracePacket (0, this, "Send Ack", 1, &c1);
		  if(write (fd, &c1, 1) != 1)
		    {
		      ERRORPRINTF (t, E_ERROR | 10, this, "write error (%s)", strerror(errno));
		      break;
		    }
		  if ((akt[1] == 0xF3 && !recvflag) ||
		      (akt[1] == 0xD3 && recvflag))
		    {
		      //right sequence number
		      recvflag = !recvflag;
		    }
		  if ((akt[1] & 0x0f) == 0)
		    {
		      const uchar reset[1] = { 0xA0 };
		      CArray *c = new CArray (reset, sizeof (reset));
		      t->TracePacket (0, this, "RecvReset", *c);
		      outqueue.put (c);
		      pth_sem_inc (&out_signal, TRUE);
		    }
		}
	      akt.deletepart (0, 4);
	    }
	  else if (akt[0] == 0x68)
	    {
	      int len;
	      uchar c1;
	      if (akt () < 7)
		break;
	      if (akt[1] != akt[2] || akt[3] != 0x68)
		{
		  //receive error, try to resume
		  akt.deletepart (0, 1);
		  continue;
		}
	      if (akt () < akt[1] + 6U)
		break;

	      c1 = 0;
	      for (i = 4; i < akt[1] + 4U; i++)
		c1 += akt[i];
	      if (akt[akt[1] + 4] != c1 || akt[akt[1] + 5] != 0x16)
		{
		  len = akt[1] + 6;
		  //Forget wrong short frame
		  akt.deletepart (0, len);
		  continue;
		}

	      c1 = 0xE5;
	      t->TracePacket (0, this, "Send Ack", 1, &c1);
	      i = write (fd, &c1, 1);

	      if ((akt[4] == 0xF3 && recvflag) ||
		  (akt[4] == 0xD3 && !recvflag))
		{
		  if (CArray (akt.array () + 5, akt[1] - 1) != last)
		    {
		      TRACEPRINTF (t, 0, this, "Sequence jump");
		      recvflag = !recvflag;
		    }
		  else
		    TRACEPRINTF (t, 0, this, "Wrong Sequence");
		}

	      if ((akt[4] == 0xF3 && !recvflag) ||
		  (akt[4] == 0xD3 && recvflag))
		{
		  recvflag = !recvflag;
		  CArray *c = new CArray;
		  len = akt[1] + 6;
		  c->setpart (akt.array () + 5, 0, len - 7);
		  last = *c;
		  outqueue.put (c);
		  pth_sem_inc (&out_signal, TRUE);
		}
              // XXX TODO otherwise set 'len' to what? Or continue?
	      akt.deletepart (0, len);
	    }
	  else
	    //Forget unknown byte
	    akt.deletepart (0, 1);
	}

      if (mode == 1 && pth_event_status (timeout) == PTH_STATUS_OCCURRED)
	mode = 0;

      if (mode == 0 && !inqueue.isempty ())
	{
	  const CArray & c = inqueue.top ();
	  t->TracePacket (0, this, "Send", c);
	  repeatcount++;
	  i = pth_write_ev (fd, c.array (), c (), stop);
	  if (i == c ())
	    {
	      mode = 1;
	      timeout =
		pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout,
			   pth_time (0, 100000));
	    }
	}
    }
  pth_event_free (stop, PTH_FREE_THIS);
  pth_event_free (timeout, PTH_FREE_THIS);
  pth_event_free (input, PTH_FREE_THIS);
}
예제 #24
0
파일: eibnetserver.cpp 프로젝트: knxd/knxd
void
EIBnetServer::start()
{
  struct sockaddr_in baddr;
  LinkConnectClientPtr mcast_conn;

  TRACEPRINTF (t, 8, "Open");

  sock_mac = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  if (sock_mac < 0)
  {
    ERRORPRINTF (t, E_ERROR | 27, "Lookup socket creation failed");
    goto err_out0;
  }
  memset (&baddr, 0, sizeof (baddr));
#ifdef HAVE_SOCKADDR_IN_LEN
  baddr.sin_len = sizeof (baddr);
#endif
  baddr.sin_family = AF_INET;
  baddr.sin_addr.s_addr = htonl (INADDR_ANY);
  baddr.sin_port = single_port ? htons(port) : 0;

  sock = new EIBNetIPSocket (baddr, 1, t);
  if (!sock)
  {
    ERRORPRINTF (t, E_ERROR | 41, "EIBNetIPSocket creation failed");
    goto err_out1;
  }
  sock->SetInterface(interface);

  if (!sock->init ())
    goto err_out2;

  sock->on_recv.set<EIBnetServer,&EIBnetServer::recv_cb>(this);
  sock->on_error.set<EIBnetServer,&EIBnetServer::error_cb>(this);

  sock->recvall = 1;
  Port = sock->port ();

  mcast_conn = LinkConnectClientPtr(new LinkConnectClient(std::dynamic_pointer_cast<EIBnetServer>(shared_from_this()), router_cfg, t));
  mcast = EIBnetDriverPtr(new EIBnetDriver (mcast_conn, multicastaddr, single_port ? 0 : port, interface));
  if (!mcast)
    {
      ERRORPRINTF (t, E_ERROR | 42, "EIBnetDriver creation failed");
      goto err_out2;
    }
  mcast_conn->set_driver(mcast);
  if (!mcast_conn->setup ())
    goto err_out3;
  if (route && !static_cast<Router &>(router).registerLink(mcast_conn))
    goto err_out3;

  TRACEPRINTF (t, 8, "Opened");

  Server::start();
  return;

err_out3:
  mcast.reset();
err_out2:
  delete sock;
  sock = NULL;
err_out1:
  close (sock_mac);
  sock_mac = -1;
err_out0:
  Server::stop();
}
예제 #25
0
파일: cemi.cpp 프로젝트: knxd/knxd
void CEMIDriver::reset_timer_cb(ev::timer &w, int revents)
{
  ERRORPRINTF(t, E_ERROR | 44, "reset timed out");
  errored();
}
예제 #26
0
파일: eibnetserver.cpp 프로젝트: knxd/knxd
EIBnetDriver::EIBnetDriver (LinkConnectClientPtr c,
                            std::string& multicastaddr, int port, std::string& intf)
  : SubDriver(c)
{
  struct sockaddr_in baddr;
  struct ip_mreq mcfg;
  sock = 0;
  t->setAuxName("driver");

  TRACEPRINTF (t, 8, "OpenD");

  if (GetHostIP (t, &maddr, multicastaddr) == 0)
    {
      ERRORPRINTF (t, E_ERROR | 11, "Addr '%s' not resolvable", multicastaddr);
      goto err_out;
    }

  if (port)
    {
      maddr.sin_port = htons (port);
      memset (&baddr, 0, sizeof (baddr));
#ifdef HAVE_SOCKADDR_IN_LEN
      baddr.sin_len = sizeof (baddr);
#endif
      baddr.sin_family = AF_INET;
      baddr.sin_addr.s_addr = htonl (INADDR_ANY);
      baddr.sin_port = htons (port);

      sock = new EIBNetIPSocket (baddr, 1, t);
      if (!sock->SetInterface(intf))
        goto err_out;
      if (!sock->init ())
        goto err_out;
      sock->on_recv.set<EIBnetDriver,&EIBnetDriver::recv_cb>(this);
      sock->on_error.set<EIBnetDriver,&EIBnetDriver::error_cb>(this);
    }
  else
    {
      EIBnetServer &parent = *std::static_pointer_cast<EIBnetServer>(server);
      maddr.sin_port = parent.Port;
      sock = parent.sock;
    }

  mcfg.imr_multiaddr = maddr.sin_addr;
  mcfg.imr_interface.s_addr = htonl (INADDR_ANY);
  if (!sock->SetMulticast (mcfg))
    goto err_out;

  /** This causes us to ignore multicast packets sent by ourselves */
  if (!GetSourceAddress (t, &maddr, &sock->localaddr))
    goto err_out;
  sock->localaddr.sin_port = std::static_pointer_cast<EIBnetServer>(server)->Port;
  sock->recvall = 2;

  TRACEPRINTF (t, 8, "OpenedD");
  return;

err_out:
  if (sock && port)
    delete (sock);
  sock = 0;
  return;
}
예제 #27
0
파일: knxd.cpp 프로젝트: RichiH/knxd
int
main (int ac, char *ag[])
{
  int index;
  Queue < Server * >server;
  Server *s;
  Layer2Interface *l2;
  Layer3 *l3;
#ifdef HAVE_EIBNETIPSERVER
  EIBnetServer *serv = 0;
#endif

  memset (&arg, 0, sizeof (arg));
  arg.addr = 0x0001;
  arg.errorlevel = LEVEL_WARNING;

  argp_parse (&argp, ac, ag, 0, &index, &arg);
  if (index > ac - 1)
    die ("url expected");
  if (index < ac - 1)
    die ("unexpected parameter");

  if (arg.port == 0 && arg.name == 0 && arg.serverip == 0)
    die ("No listen-address given");

  signal (SIGPIPE, SIG_IGN);
  pth_init ();

  Trace t;
  t.SetTraceLevel (arg.tracelevel);
  t.SetErrorLevel (arg.errorlevel);

  /*
  if (getuid () == 0)
    ERRORPRINTF (&t, 0x37000001, 0, "EIBD should not run as root");
  */

  if(arg.eibnetname)
  {
      if(arg.eibnetname[0] == '=')
          arg.eibnetname++;
      if(strlen(arg.eibnetname) >= 30)
          die("EIBnetServer/IP name can't be longer then 30 char");
  }

  if (arg.daemon)
    {
      int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE);
      if (fd == -1)
	die ("Can not open file %s", arg.daemon);
      int i = fork ();
      if (i < 0)
	die ("fork failed");
      if (i > 0)
	exit (0);
      close (1);
      close (2);
      close (0);
      dup2 (fd, 1);
      dup2 (fd, 2);
      close (fd);
      setsid ();
    }


  FILE *pidf;
  if (arg.pidfile)
    if ((pidf = fopen (arg.pidfile, "w")) != NULL)
      {
	fprintf (pidf, "%d", getpid ());
	fclose (pidf);
      }

  l2 = Create (ag[index], arg.backendflags, &t);
  if (!l2 || !l2->init ())
    die ("initialisation of the backend failed");
  l3 = new Layer3 (l2, &t);
  if (arg.port)
    {
      s = new InetServer (l3, &t, arg.port);
      if (!s->init ())
    die ("initialisation of the knxd inet protocol failed");
      server.put (s);
    }
  if (arg.name)
    {
      s = new LocalServer (l3, &t, arg.name);
      if (!s->init ())
	die ("initialisation of the knxd unix protocol failed");
      server.put (s);
    }
#ifdef HAVE_EIBNETIPSERVER
  serv = startServer (l3, &t, arg.eibnetname);
#endif
#ifdef HAVE_GROUPCACHE
  if (!CreateGroupCache (l3, &t, arg.groupcache))
    die ("initialisation of the group cache failed");
#endif

  signal (SIGINT, SIG_IGN);
  signal (SIGTERM, SIG_IGN);

  int sig;
  do
    {
      sigset_t t1;
      sigemptyset (&t1);
      sigaddset (&t1, SIGINT);
      sigaddset (&t1, SIGHUP);
      sigaddset (&t1, SIGTERM);

      pth_sigwait (&t1, &sig);

      if (sig == SIGHUP && arg.daemon)
	{
	  int fd =
	    open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE);
	  if (fd == -1)
	    {
	      ERRORPRINTF (&t, 0x27000002, 0, "can't open log file %s",
			   arg.daemon);
	      continue;
	    }
	  close (1);
	  close (2);
	  dup2 (fd, 1);
	  dup2 (fd, 2);
	  close (fd);
	}

    }
  while (sig == SIGHUP);

  signal (SIGINT, SIG_DFL);
  signal (SIGTERM, SIG_DFL);
  while (!server.isempty ())
    delete server.get ();
#ifdef HAVE_EIBNETIPSERVER
  if (serv)
    delete serv;
#endif
#ifdef HAVE_GROUPCACHE
  DeleteGroupCache ();
#endif

  delete l3;
  if (Cleanup)
    Cleanup ();

  if (arg.pidfile)
    unlink (arg.pidfile);

  pth_exit (0);
  return 0;
}