Example #1
0
// read mailbox and write to modbus
void *reader(void *arg)
{
  int ret,slave,function,buflen;
  unsigned char buf[256+1];

  mbx.clear(); // clear old messages
  while((buflen = mbx.read(buf,sizeof(buf))) > 0)
  {
    slave        = buf[0];
    function     = buf[1];
    thread.lock();
    rlsleep(MODBUS_IDLETIME);
    ret = modbus.write( slave, function, &buf[2], buflen-2);
    ret = modbus.response( &slave, &function, buf);
    if(ret != rlModbus::MODBUS_SUCCESS) sock.disconnect();
    rlsleep(MODBUS_IDLETIME);
    thread.unlock();
    if(ret < 0)
    {
      writeErrorCount++;
      if(writeErrorCount >= 256*128) writeErrorCount = 0;
      shm.write(modbusdaemon_WRITE_ERROR_COUNT_BASE,&writeErrorCount,2);
    }
    printf("mbx ret=%d slave=%d function=%d buf[2]=%d\n",ret,slave,function,buf[2]);
  }
  return arg;
}
Example #2
0
int main(int argc,char *argv[])
{
  rlSpreadsheetCell *cell;
  int i, lifeCounter;

  if(init(argc, argv) != 0)
  {
    return -1;
  }  
  thread->create(mailboxReadThread,NULL);
  lifeCounter = 0;
  while(1)                 // forever run the daemon
  {
    cell = namelist->getFirstCell();
    for(i=0; i<num_cycles; i++)
    {
      if(cell == NULL) break;
      strcpy(var,cell->text());
      // thread->lock();   // done in modbusCycle
      readModbus(i);
      // thread->unlock(); // done in modbusCycle
      cell = cell->getNextCell();
    }
    provider->setLifeCounter(lifeCounter++);
    if(lifeCounter >= 256*256) lifeCounter = 0;
    rlsleep(cycletime);
  }
  return 0;
}
Example #3
0
static void *centerMain(void *arg)
{
  int cnt;

  processlist = NULL; // processlist = empty
  cnt = 99999;        // cnt = expired
  do_reload(0);       // reload speadsheat
  while(1)
  {
    if(toCenter.poll() == rlFifo::DATA_AVAILABLE)
    {
      toCenter.read(interpreter.line,rl_PRINTF_LENGTH-1);
      if     (interpreter.isCommand("sigterm(")) do_sigterm();
      else if(interpreter.isCommand("sigkill(")) do_sigkill();
      else if(interpreter.isCommand("reload("))  do_reload(1);
      else if(interpreter.isCommand("remove("))  do_remove();
      else if(interpreter.isCommand("save("))    do_save();
      if(processes_have_been_modified)           do_save();
    }
    else if(cnt++ >= WATCHDOG_CYCLE_TIME)
    {
      cnt = 0;
      watchdog();
      if(processes_have_been_modified)           do_save();
    }
    else
    {
      rlsleep(1000); // 1 second
    }
    if(arg == NULL) return NULL; // just to fool the compiler
  }
}
Example #4
0
int rlCommandlineInterface::start(const char *how, const char *command)
{
    if(sock != NULL) delete sock;
    sock = NULL;
    if(spawn != NULL) delete spawn;
    spawn = NULL;
    tty = NULL;

    if(strcmp(how,"pipe") == 0)
    {
        if(command == NULL) return -1;
        spawn = new rlSpawn();
        int ret = spawn->spawn(command);
        if(ret < 0)
        {
            delete spawn;
            spawn = NULL;
            return -1;
        }
        return ret;
    }
    else if(strcmp(how,"stdio") == 0)
    {
        return 1;
    }
    else
    {
        rlString rlhow(how);
        char *cptr, *host;
        host = rlhow.text();
        cptr = strchr(host,':');
        if(cptr == NULL) return -1;
        *cptr = '\0';
        cptr++;
        int port = atoi(cptr);
        if(strcmp(host,"server.localhost") == 0)
        {
            sock = new rlSocket(host,port,0);
        }
        else
        {
            if(strcmp(host,"localhost") == 0 && command != NULL)
            {
                rlString cmd(command);
#ifdef RLUNIX
                cmd += " &";
#endif
                rlsystem(cmd.text());
            }
            sock = new rlSocket(host,port,1);
        }
        for(int itry=0; itry<10; itry++)
        {
            sock->connect();
            if(sock->isConnected()) return sock->s;
            rlsleep(10);
        }
        return -1;
    }
}
Example #5
0
void *profibus(void *arg)
{
#ifdef _RL_HILSCHER_CIF_H_
  THREAD_PARAM *p = (THREAD_PARAM *) arg;
  cif.debug = 1;
  if(cif.open() == DRV_NO_ERROR)
  {
    cif.debug = 0;
    while(p->running)
    {
      rlsleep(50);
      pbus.lock();
      cif.devExchangeIO(0,4,sendData,
                        0,4,receiveData,
                        1000);
      pbus.unlock();
    }
  }
  else 
  {
    printf("failed to cif.open()\n");
    printf("Please run me as root or\n");
    printf("make /dev/cif readable by normal user\n");
  }
#else
  printf("WARNING: you will have to install the hilscher driver and link to it. Then you can remove the ifdef _WIN32\n");
#endif  
  return arg;
}
Example #6
0
void *watchdogthread(void *arg)
{
  int cnt1 = -1;

  while(1)
  {
    rlsleep(60000);
    if(cnt1 == watchcnt1) break;
    cnt1 = watchcnt1;
  }
  rlsleep(100);
#ifdef unix
  rlexec(av0);
#endif
  exit(0); // pcontrol may start me again if rlexec fails
  return arg;
}
Example #7
0
static void *control(void *arg)
{
  THREAD_PARAM *p = (THREAD_PARAM *) arg;
  rlController *c = (rlController *) p->user;
  while(c->running == 1)
  {
    if(c->sleepLocally) rlsleep(c->dt);
    c->measurement = c->getMeasurement();
    c->lock(); // lock mutex because user might set another controller type
    c->ydk_1 = c->ydk;
    c->y1k_1 = c->y1k;
    c->yk_2  = c->yk_1;
    c->yk_1  = c->yk;
    c->ek_2  = c->ek_1;
    c->ek_1  = c->ek;
    c->ek    = c->reference - c->measurement;
    switch(c->type)
    {
      case rlController::P:
        c->yk = c->d0*c->ek;
        break;
      case rlController::I:
      case rlController::D_T1:
      case rlController::PI:
      case rlController::PD_T1:
        c->yk = c->d0*c->ek + c->d1*c->ek_1 + c->c1*c->yk_1;
        break;
      case rlController::PID_T1:
        c->yk = c->d0*c->ek + c->d1*c->ek_1 + c->d2*c->ek_2 + c->c1*c->yk_1 + c->c2*c->yk_2;
        break;
      case rlController::PI_SUM:
        c->yk = c->Kp*c->ek + c->y1k;
        c->y1k = c->y1k_1 + c->d1*(c->ek+c->ek_1);
        break;
      case rlController::PD_T1_SUM:
        c->yk = c->Kp*c->ek + c->ydk;
        c->ydk = c->cD*c->ydk_1 + c->dD*(c->ek-c->ek_1);
        break;
      case rlController::PID_T1_SUM:
        c->yk = c->Kp*c->ek + c->y1k + c->ydk;
        c->y1k = c->y1k_1 + c->d1*(c->ek+c->ek_1);
        c->ydk = c->cD*c->ydk_1 + c->dD*(c->ek-c->ek_1);
        break;
      default:
        break;
    }
    c->unlock();
    c->writeOutput(c->yk);
  }
  return arg;
} 
Example #8
0
int rlState::runSteps(int _cycletime)
{
  cycletime = _cycletime;
  lastState = NULL;;
  stepCounter = 0;
  
  while(nextStep != NULL)
  {
    (*nextStep)(this);
    rlsleep(cycletime);
    stepCounter++;
    if(stepCounter > MAX_STEP) stepCounter = 1;
  }

  return 0;
}
Example #9
0
void *watchdog_thread(void *arg)
{
  int cnt1 = -1;

  printf("watchdog thread starting\n");
  while(1)
  {
    rlsleep(10*sleep);
    if(cnt1 == watchcnt1) break;
    cnt1 = watchcnt1;
  }
  printf("startme again # %s\n",startme);
#ifdef unix
  rlexec(startme);
#endif
  exit(0); // pcontrol may start me again if rlexec fails
  return arg;
}
Example #10
0
// read cycle on modbus
int modbusCycle(int offset, int slave, int function, int start_adr, int num_register)
{
  unsigned char data[256+1];
  int ret;

  watchcnt1++;
  if(watchcnt1 > 10000) watchcnt1 = 0;
  rlsleep(MODBUS_IDLETIME);
  thread.lock();
  ret = modbus.request(slave, function, start_adr, num_register);
  if(ret >= 0) ret = modbus.response( &slave, &function, data);
  if(ret < 0) sock.disconnect();
  thread.unlock();
  if(ret > 0) shm.write(offset,data,ret);
  else
  {
    readErrorCount++;
    if(readErrorCount >= 256*128) readErrorCount = 0;
    shm.write(modbusdaemon_READ_ERROR_COUNT_BASE,&readErrorCount,2);
  }
  printf("cycle ret=%d slave=%d function=%d data[0]=%d\n",ret,slave,function,data[0]);
  return ret;
}
Example #11
0
static void *rlAcceptThread(void *arg)
{
  int port,s;
  rlThread worker;
  WORKER_DATA worker_data;
  rlEventLogServerThreads *thread;
  rlSocket *socket;
  THREAD_PARAM *p = (THREAD_PARAM *) arg;

  thread = (rlEventLogServerThreads *) p->user;
  port = thread->getPort();
  socket = new rlSocket("localhost",port,0);
  while(1)
  {
    s = socket->connect();
    if(s == -1) break;
    worker_data.thread = thread;
    worker_data.socket = s;
    worker.create(workerThread,&worker_data);
    rlsleep(100);
  }
  delete socket;
  return NULL;
}
Example #12
0
static int modbusCycle(int slave, int function, int start_adr, int num_register, unsigned char *data)
{
  int ret;

  if(slave < 0 || slave >= 256) return -1;
  if(poll_slave_counter[slave] > 0)
  {
    if(debug) printf("modbusCycle not polling slave%d: poll_slave_counter[%d]=%d\n", slave, slave, poll_slave_counter[slave]);
    poll_slave_counter[slave] -= 1;
    if(poll_slave_counter[slave] != 0) 
    {
      int cnt = provider->readErrorCount() + 1;
      if(cnt >= 256*256) cnt = 0;
      provider->setReadErrorCount(cnt);
      return -1;
    }  
  }

  if(debug) printf("modbusRequest: var=%s : slave=%d function=%d start_adr=%d num_register=%d\n", 
                                   var,     slave,   function,   start_adr,   num_register);
  if(use_socket != 1) rlsleep(modbus_idletime); // on tty we have to sleep
  thread->lock();
  ret = modbus->request(slave, function, start_adr, num_register);
  if(ret >= 0) ret = modbus->response( &slave, &function, data);
  thread->unlock();
  if(ret < 0)
  {
    int cnt = provider->readErrorCount() + 1;
    if(cnt >= 256*256) cnt = 0;
    provider->setReadErrorCount(cnt);
    poll_slave_counter[slave] = n_poll_slave;
  }
  if(debug) printf("modbusResponse: ret=%d slave=%d function=%d data=%02x %02x %02x %02x\n",
                                    ret,   slave,   function,   data[0], data[1], data[2], data[3]);
  return ret;
}
Example #13
0
static void *mailboxReadThread(void *arg)
{
  char buf[1024],data[4],*itemname,*itemvalue,*cptr;
  int  ret,val,slave,function,adr,buflen,doit;

  if(debug) printf("mailboxReadThread: starting\n");
  mbx->clear(); // clear old messages
  while(mbx->read(buf,sizeof(buf)) > 0)
  {
    itemname = itemvalue = &buf[0];  // parse buf begin
    cptr = strrchr(buf,',');
    if(cptr != NULL)
    {
      *cptr = '\0';
      cptr++;
      itemvalue = cptr;
      cptr = strchr(itemvalue,'\n');
      if(cptr != NULL) *cptr = 0;
    }                                // parse buf end
    if(debug) printf("mailboxReadThread: Write itemname=%s itemvalue=%s\n",itemname,itemvalue);
    doit = 0;
    if(strncmp(buf,"coil(",5) == 0)
    {
      sscanf(itemname,"coil(%d,%d)",&slave,&adr);
      function     = rlModbus::ForceSingleCoil;
      data[0] = adr/256; data[1] = adr & 0x0ff;
      sscanf(itemvalue,"%d",&val);
      data[2] = 0; data[3] = 0;
      if(val != 0) data[2] = 0x0ff;
      buflen = 4;
      doit = 1;
    }  
    else if(strncmp(buf,"register(",8) == 0)
    {
      sscanf(itemname,"register(%d,%d)",&slave,&adr);
      function     = rlModbus::PresetSingleRegister;
      data[0] = adr/256; data[1] = adr & 0x0ff;
      sscanf(itemvalue,"%d",&val);
      data[2] = val/256; data[3] = val & 0x0ff;
      buflen = 4;
      doit = 1;
    }
    else
    {
      printf("USER_ERROR: unknown %s entered\n", buf);
      printf("Possible values:\n");
      printf("coil(slave,adr)\n");
      printf("register(slave,adr)\n");
    }

    if(doit)
    {
      thread->lock();
      if(use_socket != 1) rlsleep(modbus_idletime); // on tty we have to sleep
      if(debug) printf("modbus_write: slave=%d function=%d data[0]=%d\n",
                                      slave,   function,   data[0]);
      ret = modbus->write( slave, function, (const unsigned char *) data, buflen);
      ret = modbus->response( &slave, &function, (unsigned char *) buf);
      if(use_socket != 1) rlsleep(modbus_idletime); // on tty we have to sleep
      thread->unlock();
      if(ret < 0)
      {
        int cnt = provider->writeErrorCount() + 1;
        if(cnt >= 256*256) cnt = 0;
        provider->setWriteErrorCount(cnt);
      }
      rlsleep(10); // sleep in order that reading can work in parallel even if we are sending a lot of data
    }  
  }
  return arg;
}
Example #14
0
int run(const char *url, int maxItemNameLength)
{
  long shmsize_needed = ((maxItemNameLength+1)+(max_name_length+1))*num_items + sizeof(SHM_HEADER);
  FILE *fin;
  char buf[1024], *cptr;
  void *shmadr;
  SHM_HEADER *shmheader;
  int  i;
  SoapCtx *ctx, *ctx2;
  xmlNodePtr xmlcur,xmlitem;
  herror_t err;

  if(url == NULL) return 1;

  // print shm parameters
  printf("maxItemNameLength=%d max_name_length=%d shmsize=%ld shmsize_needed=%ld num_items=%d shm=%s\n",
          maxItemNameLength,   max_name_length,   shmsize,    shmsize_needed,    num_items,   shm);
  if(shmsize_needed > shmsize)
  {
    printf("shmsize too small -> increase it\n");
    return 1;
  }
  if(maxItemNameLength <= 0 || max_name_length <= 0 || shmsize <= 0 || shmsize_needed <= 0)
  {
    printf("some values are negative or 0\n");
    return 1;
  }
  if(maxItemNameLength >= (int) (sizeof(buf) - 100) || max_name_length >= (int) (sizeof(buf) - 100))
  {
    printf("name is bigger than buf length = %d\n", (int) sizeof(buf));
    return 1;
  }

  // init shared memory
  rlSharedMemory rlshm = rlSharedMemory(shm, (unsigned long) shmsize);
  if(rlshm.status != rlSharedMemory::OK)
  {
    printf("shared memory status is not OK\n");
    return 1;
  }
  shmadr = rlshm.getUserAdr();
  if(shmadr == NULL)
  {
    printf("shmadr = NULL\n");
    return 1;
  }
  memset(shmadr,0,shmsize);

  // read itemlist to shared memory
  fin = fopen(itemlist,"r");
  if(fin == NULL)
  {
    printf("could not open itemlist %s\n",itemlist);
    return 1;
  }
  i = 0;
  while(fgets(buf,sizeof(buf)-1,fin) != NULL)
  {
    if(buf[0] > ' ' && buf[0] != '#')
    {
      cptr = strchr(buf,'\n');
      if(cptr != NULL) *cptr = '\0';
      cptr = (char *) shmadr;
      cptr += sizeof(SHM_HEADER) + (i*(maxItemNameLength+1 + max_name_length+1));
      strcpy(cptr,buf);
      i++;
    }
  }
  fclose(fin);

  // init header in shared memory
  shmheader = (SHM_HEADER *) shmadr;
  shmheader->maxItemNameLength = maxItemNameLength;
  shmheader->maxNameLength     = max_name_length;
  shmheader->numItems          = num_items;
  shmheader->readErrorCount    = 0;
  shmheader->writeErrorCount   = 0;
  strcpy(shmheader->ident,"opc");

  /* create a SoapCtx object */
  err = soap_ctx_new_with_method(URN, "Read", &ctx);
  if(err != H_OK)
  {
     log_error4("%s():%s [%d]", herror_func(err),
                herror_message(err), herror_code(err));
     herror_release(err);
     return 1;
  }

  /* create the Read ItemList */
  xmlitem = soap_env_add_item(ctx->env, "xsd:element", "ItemList", "");
  xmlcur = ctx->env->cur;
  ctx->env->cur = xmlitem;
  for(i=0; i<shmheader->numItems; i++)
  {
    cptr = (char *) shmadr;
    cptr += sizeof(SHM_HEADER) + (i*(maxItemNameLength+1 + max_name_length+1));
    sprintf(buf,"Items ItemName=\"%s\"",cptr);
    soap_env_add_item(ctx->env, "xsd:string", buf, NULL);
  }
  ctx->env->cur = xmlcur;

  // create reader thread and the watchdog
  rlThread reader,watchdog;
  reader.create(reader_thread,(void *) url);
  watchdog.create(watchdog_thread,NULL);

  // poll the OPC XML-DA server forever
  while(1)
  {
    /* invoke */
    err = soap_client_invoke(ctx, &ctx2, url, "");
    if(err == H_OK)
    {
      /* print the result */
      if(debug) soap_xml_doc_print(ctx2->env->root->doc);

      /* write the result to the shared memory */
      reader.lock();
      write_to_shared_memory(ctx2,shmadr);
      reader.unlock();

      /* free the objects */
      soap_ctx_free(ctx2);
    }      
    watchcnt1++;
    if(watchcnt1 > 256*256) watchcnt1 = 0;
    rlsleep(sleep);
  }

  return 0;
}
Example #15
0
int rlEIBnetIP::setValueUnsigned(const char *name, unsigned int val, int length, int addi1, int ctrl, int apci)
{
  if(name == NULL || mem == NULL || channelid == -1) return rlEIBnetIP::EIBERROR;
  unsigned int i,a1,a2,a3,daddr;
  int retry;
  const char *cptr;
  PDU pdu;
  EIB_TEL tel;
  EIB_TEL *memptr = (EIB_TEL *) mem;

  // interpret name
  cptr = strchr(name,'/');
  if(cptr == NULL)
  {
    ::printf("USER_ERROR: rlEIBnetIP::setValue() wrong name=%s val=%d\n", name, val);
    return rlEIBnetIP::EIBERROR;
  }
  sscanf(cptr,"/%d/%d/%d",&a1,&a2,&a3);
  daddr = ((a1*8)+a2)*256+a3;

  // fill EIBnet/IP PDU
  pdu.headersize   = EIB_HEADERSIZE;
  pdu.version      = EIB_VERSION;
  pdu.servicetype  = htons(TUNNELLING_REQUEST);
  if(length == -1)
    pdu.totalsize    = htons(EIB_HEADERSIZE+4+10+1);
  else
    pdu.totalsize    = htons(EIB_HEADERSIZE+4+10+length);
  pdu.data[0]      = 4;                    // structlength
  pdu.data[1]      = channelid;            // channelid
  pdu.data[2]      = send_sequencecounter; // sequencecounter
  pdu.data[3]      = E_NO_ERROR;           // typespecific
  tel.mc           = L_Data_Req; // L_Data_Req=0x11, L_Data_Con=0x2E L_Data_Ind=0x29

  tel.addi1        = 0x0;
  tel.ctrl1        = 0xbc;
  tel.ctrl2        = 0xe0;
  tel.saddr        = (unsigned short) htons((short) saddr);   //0x1);
  tel.daddr        = (unsigned short) htons((short) daddr);   //(0x100)
  tel.apci_length  = 0x1;
  tel.apci         = 0x0;

  if(addi1  != -1) tel.addi1 = (unsigned char) ((addi1 & 0x0ff));
  if(ctrl   != -1)
  {
    tel.ctrl1 = (unsigned char) ((ctrl & 0x0ff00)/256);
    tel.ctrl2 = (unsigned char) ((ctrl & 0x0ff));
  }
  if(length != -1) tel.apci_length = (unsigned char) length;
  if(apci   != -1) tel.apci = (unsigned char) apci;

  if(length == -1 || length == 1)
  {
    tel.val[0]       = (unsigned char) val; // 0x80; // 0x81
    tel.val[1]       = (unsigned char) 0x0;
    tel.val[2]       = (unsigned char) 0x0;
    tel.val[3]       = (unsigned char) 0x0;
  }
  else if(length == 2)
  {
    tel.val[0]       = (unsigned char) ((val & 0x0ff00)/256);
    tel.val[1]       = (unsigned char) (val & 0x0ff);
    tel.val[2]       = (unsigned char) 0x0;
    tel.val[3]       = (unsigned char) 0x0;
  }
  else if(length == 3)
  {
    tel.val[0]       = (unsigned char) ((val & 0x0ff000000)/(256*256));
    tel.val[1]       = (unsigned char)  (val & 0x0ff0000)/256;
    tel.val[2]       = (unsigned char)  (val & 0x0ff00);
    tel.val[3]       = (unsigned char)  (val & 0x0ff);
  }
  else if(length == 4)
  {
    tel.val[0]       = (unsigned char) ((val & 0x0ff000000)/(256*256*256));
    tel.val[1]       = (unsigned char) ((val & 0x0ff0000)/(256*256));
    tel.val[2]       = (unsigned char) ((val & 0x0ff00)/(256));
    tel.val[3]       = (unsigned char) (val & 0x0ff);
  }
  else
  {
    ::printf("rlEIBnetIP::setValue(0x%x) unknown length=%d\n",val,length);
    return rlEIBnetIP::EIBERROR;
  }
  memcpy(&pdu.data[4],&tel,sizeof(EIB_TEL));

  if(debug)
  {
    ::printf("rlEIBnetIP::setValue() mc          = 0x%x\n", tel.mc);
    ::printf("rlEIBnetIP::setValue() addi1       = 0x%x\n", tel.addi1);
    ::printf("rlEIBnetIP::setValue() ctrl1       = 0x%x\n", tel.ctrl1);
    ::printf("rlEIBnetIP::setValue() ctrl2       = 0x%x\n", tel.ctrl2);
    ::printf("rlEIBnetIP::setValue() saddr       = 0x%x\n", ntohs(tel.saddr));
    ::printf("rlEIBnetIP::setValue() daddr       = 0x%x\n", ntohs(tel.daddr));
    ::printf("rlEIBnetIP::setValue() apci_length = 0x%x\n", tel.apci_length);
    ::printf("rlEIBnetIP::setValue() apci        = 0x%x\n", tel.apci);
    ::printf("rlEIBnetIP::setValue() val[0]      = 0x%x\n", tel.val[0]);
    ::printf("rlEIBnetIP::setValue() val[1]      = 0x%x\n", tel.val[1]);
    ::printf("rlEIBnetIP::setValue() val[2]      = 0x%x\n", tel.val[2]);
    ::printf("rlEIBnetIP::setValue() val[3]      = 0x%x\n", tel.val[3]);
  }

  tunnel_ack = retry = 0;
  while(1)
  {
    // send value over EIBnet/IP
    rlUdpSocket::sendto(&pdu, ntohs(pdu.totalsize), server);
    rlsleep(10);
    if     (tunnel_ack == 1) // OK
    {
      send_sequencecounter = (send_sequencecounter+1) & 0x0ff;
      if(debug) ::printf("rlEIBnetIP::setValue(0x%x) ACK\n",val);
      break;
    }
    else if(tunnel_ack == -1) // failure
    {
      if(debug) ::printf("rlEIBnetIP::setValue(0x%x) NACK\n",val);
      retry++;
    }
    else
    {
      if(debug) ::printf("rlEIBnetIP::setValue(0x%x) timeout\n",val);
      retry++;
    }
    if(retry >= 2)
    {
      is_connected = 0 ;
      ::printf("rlEIBnetIP::setValue() connection lost\n");
      return rlEIBnetIP::EIBERROR;
    }
  }
  tunnel_ack = 0;

  tel.saddr = ntohs(tel.saddr); // convert network -> host byte order
  tel.daddr = ntohs(tel.daddr);

  if(provider != NULL) return 0;

  // remember value within mem
  for(i=0; i< (unsigned int) maxvalues; i++)
  {
    if(memptr[i].mc == 0)
    {
      if(debug) ::printf("rlEIBnetIP::setValue(0x%x) insert new value\n",val);
      thread.lock();
      memcpy(&memptr[i],&tel,sizeof(tel));
      thread.unlock();
      return 0;
    }
    //else if(memptr[i].saddr == tel.saddr && memptr[i].daddr == tel.daddr)
    else if(memptr[i].daddr == tel.daddr)
    {
      if(debug) ::printf("rlEIBnetIP::setValue(0x%x) update existing value\n",val);
      thread.lock();
      memcpy(&memptr[i],&tel,sizeof(tel));
      thread.unlock();
      return 0;
    }
  }
  ::printf("ERROR rlEIBnetIP::setValue() not enough signals specified max=%d\n",maxvalues);
  return rlEIBnetIP::EIBERROR;
}
Example #16
0
int rlEIBnetIP::setText(const char *name, const char *text)
{
  if(name == NULL || text == NULL) return rlEIBnetIP::EIBERROR; 
  char buf[16];
  int length = strlen(text);
  unsigned int a1,a2,a3,daddr;
  int i,retry;
  const char *cptr;
  PDU pdu;
  EIB_TEL tel;
  EIB_TEL *memptr = (EIB_TEL *) mem;

  if(length > 14) length = 14;
  memset(buf,0,sizeof(buf));
  for(i=0; i<length; i++) buf[i] = text[i];

  // interpret name
  cptr = strchr(name,'/');
  if(cptr == NULL)
  {
    ::printf("USER_ERROR: rlEIBnetIP::setText() wrong name=%s text=%s\n", name, text);
    return rlEIBnetIP::EIBERROR;
  }
  sscanf(cptr,"/%d/%d/%d",&a1,&a2,&a3);
  daddr = ((a1*8)+a2)*256+a3;

  // fill EIBnet/IP PDU
  pdu.headersize   = EIB_HEADERSIZE;
  pdu.version      = EIB_VERSION;
  pdu.servicetype  = htons(TUNNELLING_REQUEST);
  pdu.totalsize    = htons(EIB_HEADERSIZE+4+10+length);
  pdu.data[0]      = 4;                    // structlength
  pdu.data[1]      = channelid;            // channelid
  pdu.data[2]      = send_sequencecounter; // sequencecounter
  pdu.data[3]      = E_NO_ERROR;           // typespecific
  tel.mc           = L_Data_Req; // L_Data_Req=0x11, L_Data_Con=0x2E L_Data_Ind=0x29
  tel.addi1        = 0x0;
  tel.ctrl1        = 0xbc;
  tel.ctrl2        = 0xe0;
  tel.saddr        = (unsigned short) htons((short) saddr);   //0x1);
  tel.daddr        = (unsigned short) htons((short) daddr);   //(0x100)
  tel.apci_length  = 0x1;
  tel.apci         = 0x0;
  for(i=0; i<14; i++) tel.val[i] = buf[i];
  memcpy(&pdu.data[4],&tel,sizeof(EIB_TEL));

  tunnel_ack = retry = 0;
  while(1)
  {
    // send value over EIBnet/IP
    rlUdpSocket::sendto(&pdu, ntohs(pdu.totalsize), server);
    rlsleep(10);
    if     (tunnel_ack == 1) // OK
    {
      send_sequencecounter = (send_sequencecounter+1) & 0x0ff;
      if(debug) ::printf("rlEIBnetIP::setText(%s) ACK\n",text);
      break;
    }
    else if(tunnel_ack == -1) // failure
    {
      if(debug) ::printf("rlEIBnetIP::setText(%s) NACK\n",text);
      retry++;
    }
    else
    {
      if(debug) ::printf("rlEIBnetIP::setText(%s) timeout\n",text);
      retry++;
    }
    if(retry >= 2)
    {
      is_connected = 0 ;
      ::printf("rlEIBnetIP::setText() connection lost\n");
      return rlEIBnetIP::EIBERROR;
    }
  }
  tunnel_ack = 0;

  tel.saddr = ntohs(tel.saddr); // convert network -> host byte order
  tel.daddr = ntohs(tel.daddr);
  // remember value within mem
  for(i=0; i< maxvalues; i++)
  {
    if(memptr[i].mc == 0)
    {
      if(debug) ::printf("rlEIBnetIP::setText() insert new value\n");
      thread.lock();
      memcpy(&memptr[i],&tel,sizeof(tel));
      thread.unlock();
      return length;
    }
    //else if(memptr[i].saddr == tel.saddr && memptr[i].daddr == tel.daddr)
    else if(memptr[i].daddr == tel.daddr)
    {
      if(debug) ::printf("rlEIBnetIP::setText() update existing value\n");
      thread.lock();
      memcpy(&memptr[i],&tel,sizeof(tel));
      thread.unlock();
      return length;
    }
  }
  ::printf("ERROR rlEIBnetIP::setText() not enough signals specified max=%d\n",maxvalues);
  return rlEIBnetIP::EIBERROR;
}