예제 #1
0
string Hddtemp::getHDDTemp( )
{
    string val;
    char buf[20];

    ResAlloc res(m_res, true);
    //Check connect and start
    if(!SYS->transport().at().at(t_tr).at().outPresent(n_tr)) SYS->transport().at().at(t_tr).at().outAdd(n_tr);
    AutoHD<TTransportOut> tr = SYS->transport().at().at(t_tr).at().outAt(n_tr);

    MtxAlloc resN(tr.at().reqRes(), true);
    tr.at().setName(_("Parameter Hddtemp"));
    tr.at().setAddr("TCP:127.0.0.1:7634");
    tr.at().setTimings("5:0.01");

    if(tr.at().startStat()) tr.at().stop();
    tr.at().start();

    //Request
    int len;
    do {
	len = tr.at().messIO(NULL, 0, buf, sizeof(buf));
	val.append(buf,len);
    }while(len);

    tr.at().stop();

    return val;
}
예제 #2
0
void HddStat::makeActiveDA( TMdContr *aCntr )
{
    string ap_nm = "Statistic_";

    vector<string> list;
    dList(list,true);
    for(unsigned i_hd = 0; i_hd < list.size(); i_hd++)
    {
	vector<string> pLs;
	// Find propper parameter's object
	aCntr->list(pLs);

	unsigned i_p;
	for(i_p = 0; i_p < pLs.size(); i_p++)
	{
	    AutoHD<TMdPrm> p = aCntr->at(pLs[i_p]);
	    if(p.at().cfg("TYPE").getS() == id() && p.at().cfg("SUBT").getS() == list[i_hd])	break;
	}
	if(i_p < pLs.size()) continue;

	string hddprm = ap_nm+list[i_hd];
	while(aCntr->present(hddprm)) hddprm = TSYS::strLabEnum(hddprm);
	aCntr->add(hddprm, 0);
	AutoHD<TMdPrm> dprm = aCntr->at(hddprm);
	dprm.at().setName(_("HD statistic: ")+list[i_hd]);
	dprm.at().autoC(true);
	dprm.at().cfg("TYPE").setS(id());
	dprm.at().cfg("SUBT").setS(list[i_hd]);
	dprm.at().cfg("EN").setB(true);
	if(aCntr->enableStat()) dprm.at().enable();
    }
}
예제 #3
0
void Hddtemp::makeActiveDA( TMdContr *aCntr )
{
    string ap_nm = "Temperature_hd";

    vector<string> list;
    dList(list);
    try {
	for(unsigned i_hd = 0; i_hd < list.size(); i_hd++) {
	    vector<string> pLs;
	    // Find propper parameter's object
	    aCntr->list(pLs);

	    unsigned i_p;
	    for(i_p = 0; i_p < pLs.size(); i_p++)
	    {
		AutoHD<TMdPrm> p = aCntr->at(pLs[i_p]);
		if(p.at().cfg("TYPE").getS() == id() && p.at().cfg("SUBT").getS() == list[i_hd])	break;
	    }
	    if(i_p < pLs.size()) continue;

	    string hddprm = ap_nm+i2s(i_hd);
	    while(aCntr->present(hddprm)) hddprm = TSYS::strLabEnum(hddprm);
	    aCntr->add(hddprm,0);
	    AutoHD<TMdPrm> dprm = aCntr->at(hddprm);
	    dprm.at().setName(_("HD temperature: ")+i2s(i_hd));
	    dprm.at().autoC(true);
	    dprm.at().cfg("TYPE").setS(id());
	    dprm.at().cfg("SUBT").setS(list[i_hd]);
	    dprm.at().cfg("EN").setB(true);
	    if(aCntr->enableStat()) dprm.at().enable();
	}
    } catch(TError &err) { /*mess_err(err.cat.c_str(),"%s",err.mess.c_str());*/ }
}
예제 #4
0
파일: val.cpp 프로젝트: Strongc/openscada
bool ModVArchEl::setValsProc( TValBuf &buf, int64_t beg, int64_t end )
{
    if(needMeta && (needMeta=!readMeta())) return false;

    //Check border
    if(!buf.vOK(beg,end)) return false;
    beg = vmax(beg, buf.begin());
    end = vmin(end, buf.end());
    beg = (beg/period())*period();
    end = (end/period())*period();

    //Table struct init
    TConfig cfg((archive().valType()==TFld::Real) ? (&mod->vlRealEl()) :
		(archive().valType()==TFld::String) ? (&mod->vlStrEl()) : &mod->vlIntEl());

    AutoHD<TTable> tbl = SYS->db().at().open(archivator().addr()+"."+archTbl(), true);
    if(tbl.freeStat()) return false;

    //Write data to table
    for(int64_t ctm; beg <= end; beg++) {
	switch(archive().valType()) {
	    case TFld::Boolean:	cfg.cfg("VAL").setI(buf.getB(&beg,true));	break;
	    case TFld::Integer:	cfg.cfg("VAL").setI(buf.getI(&beg,true));	break;
	    case TFld::Real:	cfg.cfg("VAL").setR(buf.getR(&beg,true));	break;
	    case TFld::String:	cfg.cfg("VAL").setS(buf.getS(&beg,true));	break;
	    default: break;
	}
	ctm = (beg/period())*period();
	cfg.cfg("TM").setI(ctm/1000000);
	cfg.cfg("TMU").setI(ctm%1000000);
	tbl.at().fieldSet(cfg);
	//Archive time border update
	mBeg = mBeg ? vmin(mBeg,ctm) : ctm;
	mEnd = mEnd ? vmax(mEnd,ctm) : ctm;
    }

    //Archive size limit process
    if((mEnd-mBeg) > (int64_t)(archivator().maxSize()*3600e6)) {
	int64_t n_end = ((mEnd-(int64_t)(archivator().maxSize()*3600e6))/period())*period();
	for(int64_t t_c = vmax(mBeg,n_end-3600ll*period()); t_c < n_end; t_c += period()) {
	    cfg.cfg("TM").setI(t_c/1000000, true);
	    cfg.cfg("TMU").setI(t_c%1000000, true);
	    tbl.at().fieldDel(cfg);
	}
	mBeg = n_end;
    }
    tbl.free();
    SYS->db().at().close(archivator().addr()+"."+archTbl());

    //Update archive info
    cfg.setElem(&mod->archEl());
    cfg.cfgViewAll(false);
    cfg.cfg("TBL").setS(archTbl(), true);
    cfg.cfg("BEGIN").setS(ll2s(mBeg), true);
    cfg.cfg("END").setS(ll2s(mEnd), true);
    cfg.cfg("PRM1").setS(ll2s(mPer), true);

    return SYS->db().at().dataSet(archivator().addr()+"."+mod->mainTbl(),"",cfg,false,true);
}
예제 #5
0
파일: val.cpp 프로젝트: careychow/openscada
//!!! Inherited (virtual) start archivator functions.
void ModVArch::start()
{
    //> Connection to DB and enable status check
    string wdb = TBDS::realDBName(addr());
    AutoHD<TBD> db = SYS->db().at().nodeAt(wdb,0,'.');
    if( !db.at().enableStat( ) ) db.at().enable();

    //> Start getting data cycle
    TVArchivator::start();
}
예제 #6
0
파일: mess.cpp 프로젝트: Strongc/openscada
void ModMArch::start( )
{
    //Connection to DB and enable status check
    string wdb = TBDS::realDBName(addr());
    AutoHD<TBD> db = SYS->db().at().nodeAt(wdb, 0, '.');
    try { if(!db.at().enableStat()) db.at().enable(); }
    catch(TError err) { mess_warning(nodePath().c_str(), _("Enable target DB error: %s"), err.mess.c_str()); }

    TMArchivator::start();
}
예제 #7
0
파일: mess.cpp 프로젝트: alimon/oscada
bool ModMArch::put( vector<TMess::SRec> &mess, bool force )
{
    if(needMeta && (needMeta=!readMeta()))	return false;

    TMArchivator::put(mess, force);	//Allow redundancy

    if(!runSt) throw TError(nodePath().c_str(), _("The archive is not started!"));

    AutoHD<TTable> tbl = SYS->db().at().open(addr()+"."+archTbl(), true);
    if(tbl.freeStat()) return false;

    TConfig cfg(&reqEl);
    int64_t t_cnt = TSYS::curTime();
    for(unsigned i_m = 0; i_m < mess.size(); i_m++) {
	if(!chkMessOK(mess[i_m].categ,mess[i_m].level)) continue;

	//Put record to DB
	cfg.cfg("MIN").setI(mess[i_m].time/60);
	cfg.cfg("TM").setI(mess[i_m].time);
	cfg.cfg("TMU").setI(mess[i_m].utime);
	cfg.cfg("CATEG").setS(mess[i_m].categ);
	cfg.cfg("MESS").setS(mess[i_m].mess);
	cfg.cfg("LEV").setI(mess[i_m].level);
	tbl.at().fieldSet(cfg);
	//Archive time border update
	mBeg = mBeg ? vmin(mBeg,mess[i_m].time) : mess[i_m].time;
	mEnd = mEnd ? vmax(mEnd,mess[i_m].time) : mess[i_m].time;
    }

    //Archive size limit process
    if(maxSize() && (mEnd-mBeg) > (time_t)(maxSize()*86400)) {
	time_t nEnd = mEnd - (time_t)(maxSize()*86400);
	cfg.cfg("TM").setKeyUse(false);
	for(int tC = mBeg/60; tC < nEnd/60; tC++) {
	    cfg.cfg("MIN").setI(tC, true);
	    tbl.at().fieldDel(cfg);
	}
	mBeg = nEnd;
    }
    tbl.free();
    //SYS->db().at().close(addr()+"."+archTbl());	//!!! No close the table manually

    //Update archive info
    cfg.setElem(&mod->archEl());
    cfg.cfgViewAll(false);
    cfg.cfg("TBL").setS(archTbl(),true);
    cfg.cfg("BEGIN").setS(i2s(mBeg),true);
    cfg.cfg("END").setS(i2s(mEnd),true);
    bool rez = SYS->db().at().dataSet(addr()+"."+mod->mainTbl(),"",cfg,false,true);

    tmProc = TSYS::curTime() - t_cnt; tmProcMax = vmax(tmProcMax, tmProc);

    return rez;
}
예제 #8
0
파일: dbf_mod.cpp 프로젝트: alimon/oscada
void MBD::transCloseCheck( )
{
    if(enableStat()) {
	vector<string> t_list;
	list(t_list);
	for(unsigned i_l = 0; i_l < t_list.size(); i_l++) {
	    AutoHD<MTable> t = at(t_list[i_l]);
	    if(t.at().mModify && (SYS->sysTm()-t.at().mModify) > 10) t.at().save();
	}
    }
}
예제 #9
0
파일: mod_prt.cpp 프로젝트: alimon/oscada
void TProt::discoveryUrls( vector<string> &ls )
{
    ls.clear();
    //Get allowed enpoints list
    vector<string> epLs;
    epList(epLs);
    for(unsigned i_ep = 0; i_ep < epLs.size(); i_ep++) {
	AutoHD<OPCEndPoint> ep = epAt(epLs[i_ep]);
	if(!ep.at().enableStat()) continue;
	ls.push_back(ep.at().url());
	break;
    }
}
예제 #10
0
파일: mess.cpp 프로젝트: Strongc/openscada
bool ModMArch::put( vector<TMess::SRec> &mess )
{
    if(!run_st) throw TError(nodePath().c_str(), _("Archive is not started!"));

    AutoHD<TTable> tbl = SYS->db().at().open(addr()+"."+archTbl(), true);
    if(tbl.freeStat()) return false;

    TConfig cfg(&mod->messEl());
    int64_t t_cnt = TSYS::curTime();
    for(unsigned i_m = 0; i_m < mess.size(); i_m++) {
	if(!chkMessOK(mess[i_m].categ,mess[i_m].level)) continue;

	//Put record to DB
	cfg.cfg("TM").setI(mess[i_m].time);
	cfg.cfg("TMU").setI(mess[i_m].utime);
	cfg.cfg("CATEG").setS(mess[i_m].categ);
	cfg.cfg("MESS").setS(mess[i_m].mess);
	cfg.cfg("LEV").setI(mess[i_m].level);
	tbl.at().fieldSet(cfg);
	//Archive time border update
	mBeg = mBeg ? vmin(mBeg,mess[i_m].time) : mess[i_m].time;
	mEnd = mEnd ? vmax(mEnd,mess[i_m].time) : mess[i_m].time;
    }

    //Archive size limit process
    if((mEnd-mBeg) > (time_t)(maxSize()*3600)) {
	time_t n_end = mEnd-(time_t)(maxSize()*3600);
	for(time_t t_c = vmax(mBeg,n_end-3600); t_c < n_end; t_c++) {
	    cfg.cfg("TM").setI(t_c,true);
	    tbl.at().fieldDel(cfg);
	}
	mBeg = n_end;
    }
    tbl.free();
    SYS->db().at().close(addr()+"."+archTbl());

    //Update archive info
    cfg.setElem(&mod->archEl());
    cfg.cfgViewAll(false);
    cfg.cfg("TBL").setS(archTbl(),true);
    cfg.cfg("BEGIN").setS(i2s(mBeg),true);
    cfg.cfg("END").setS(i2s(mEnd),true);
    bool rez = SYS->db().at().dataSet(addr()+"."+mod->mainTbl(),"",cfg,false,true);

    tm_calc = 1e-3*(TSYS::curTime()-t_cnt);

    return rez;
}
예제 #11
0
void Contr::start_( )
{
    //Schedule process
    mPer = TSYS::strSepParse(cron(),1,' ').empty() ? vmax(0,1e9*s2r(cron())) : 0;

    if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("Start stage 1: set all blocks to process."));

    //Make process all bloks
    vector<string> lst;
    blkList(lst);
    for(unsigned i_l = 0; i_l < lst.size(); i_l++)
	if(blkAt(lst[i_l]).at().enable() && blkAt(lst[i_l]).at().toProcess())
	    try { blkAt(lst[i_l]).at().setProcess(true); }
	    catch(TError err) {
		mess_warning(err.cat.c_str(),"%s",err.mess.c_str());
		mess_warning(nodePath().c_str(),_("Process block '%s' error."),lst[i_l].c_str());
	    }

    if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("Start stage 2: sort blocks for need sequence."));

    //Sort blocks
    ResAlloc res(hdRes, true);
    string pvl;
    for(int iBe = 0, mvCnt = 0, iBlk = 0; iBe < (int)calcBlks.size(); ) {
	AutoHD<Block> cBlk = calcBlks[iBe];
	bool isMoved = false;
	for(int off = 0, curPos = iBe; (pvl=TSYS::strSepParse(cBlk.at().prior(),0,';',&off)).size(); ) {
	    for(iBlk = curPos+1; iBlk < (int)calcBlks.size(); iBlk++)
		if(pvl == calcBlks[iBlk].at().id()) {
		    if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("Reshuffle blocks '%s'(%d) <-> '%s'(%d)."),
			calcBlks[curPos].at().id().c_str(), curPos, calcBlks[iBlk].at().id().c_str(), iBlk);
		    calcBlks[curPos] = calcBlks[iBlk];
		    calcBlks[iBlk] = cBlk;
		    curPos = iBlk;
		    isMoved = true;
		    break;
		}
	}
	if(isMoved) mvCnt++;
	if(!isMoved || mvCnt >= (int)(calcBlks.size()/2)) { iBe++; mvCnt = 0; }
    }
    res.release();

    if(messLev() == TMess::Debug) mess_debug_(nodePath().c_str(), _("Start stage 3: task create: prcSt=%d."), prcSt);

    //Start the request and calc data task
    if(!prcSt) SYS->taskCreate(nodePath('.',true), mPrior, Contr::Task, this);
}
예제 #12
0
void Prm::vlGet( TVal &val )
{
    if(val.name() == "err") {
	if(!enableStat()) val.setS(_("1:Parameter is disabled."),0,true);
	else if(!owner().startStat()) val.setS(_("2:Controller is stopped."),0,true);
	else val.setS("0",0,true);
	return;
    }

    if(owner().redntUse()) return;

    try {
	//if( !enableStat() ) return;
	AutoHD<Block> blk = ((Contr &)owner()).blkAt(TSYS::strSepParse(val.fld().reserve(),0,'.'));
	int io_id = blk.at().ioId(TSYS::strSepParse(val.fld().reserve(),1,'.'));
	if( io_id < 0 )	disable();
	else val.set((enableStat()&&owner().startStat()) ? blk.at().get(io_id) : EVAL_STR, 0, true);
    }catch(TError err) { disable(); }
}
예제 #13
0
파일: mess.cpp 프로젝트: alimon/oscada
void ModMArch::start( )
{
    if(!runSt) {
	reqEl.fldClear();
	reqEl.fldAdd(new TFld("MIN",_("In minutes"),TFld::Integer,TCfg::Key,"15"));	//Mostly for fast reading next, by minutes
	reqEl.fldAdd(new TFld("TM",_("Time, seconds"),TFld::Integer,TCfg::Key|(tmAsStr()?TFld::DateTimeDec:0),"20"));
	reqEl.fldAdd(new TFld("TMU",_("Time, microseconds"),TFld::Integer,TCfg::Key,"6","0"));
	reqEl.fldAdd(new TFld("CATEG",_("Category"),TFld::String,TCfg::Key,"100"));
	reqEl.fldAdd(new TFld("MESS",_("Message"),TFld::String,TFld::NoFlag/*TCfg::Key*/,"100000"));
	reqEl.fldAdd(new TFld("LEV",_("Level"),TFld::Integer,TFld::NoFlag,"2"));
    }

    //Connection to DB and enable status check
    string wdb = TBDS::realDBName(addr());
    AutoHD<TBD> db = SYS->db().at().nodeAt(wdb, 0, '.');
    try { if(!db.at().enableStat()) db.at().enable(); }
    catch(TError &err) { mess_warning(nodePath().c_str(), _("Error enabling the target DB: %s"), err.mess.c_str()); }

    TMArchivator::start();
}
예제 #14
0
//*************************************************
//* Control request                               *
//*************************************************
void xmlCntrReq::calc( TValFunc *val )
{
    try {
	XMLNode req;
	AutoHD<XMLNodeObj> xnd = val->getO(1);
	if(xnd.freeStat()) { val->setS(0,_("1:Request is not object!")); return; }
	xnd.at().toXMLNode(req);
	string path = req.attr("path");
	if(val->getS(2).empty()) {
	    req.setAttr("user", val->user());
	    SYS->cntrCmd(&req);
	}
	else {
	    req.setAttr("path", "/"+val->getS(2)+path);
	    SYS->transport().at().cntrIfCmd(req, "xmlCntrReq");
	    req.setAttr("path", path);
	}
	xnd.at().fromXMLNode(req);
	val->setS(0, "0");
    }catch(TError err){ val->setS(0, TSYS::strMess(_("1:Request error: %s"),err.mess.c_str())); }
}
예제 #15
0
void Prm::vlSet( TVal &vo, const TVariant &vl, const TVariant &pvl )
{
    if(!enableStat() || !owner().startStat())	return;

    //Send to active reserve station
    if(owner().redntUse()) {
	if(vl == pvl) return;
	XMLNode req("set");
	req.setAttr("path",nodePath(0,true)+"/%2fserv%2fattr")->childAdd("el")->setAttr("id",vo.name())->setText(vl.getS());
	SYS->daq().at().rdStRequest(owner().workId(),req);
	return;
    }

    //Direct write
    try {
	AutoHD<Block> blk = ((Contr &)owner()).blkAt(TSYS::strSepParse(vo.fld().reserve(),0,'.'));
	int io_id = blk.at().ioId(TSYS::strSepParse(vo.fld().reserve(),1,'.'));
	if(io_id < 0) disable();
	else {
	    MtxAlloc sres(owner().calcRes, true);
	    blk.at().set(io_id, vl);
	}
    }catch(TError err) { disable(); }
}
예제 #16
0
파일: da_cpu.cpp 프로젝트: aleax/openscada
void CPU::makeActiveDA( TMdContr *aCntr )
{
    char buf[256];

    FILE *f = fopen("/proc/stat","r");
    if(f == NULL) return;

    //Check for allow CPU
    for(int n_cpu; fgets(buf,sizeof(buf),f) != NULL; )
	if(sscanf(buf,"cpu%d",&n_cpu)) {
	    string pId = "CPULoad";
	    string pNm = _("Full CPU Load");
	    string pSTp = "gen";
	    if(isdigit(buf[3])) {
		pId = "CPU"+i2s(n_cpu)+"Load";
		pNm = _("CPU Load: ")+i2s(n_cpu);
		pSTp = i2s(n_cpu);
	    }

	    vector<string> pLs;
	    // Find propper parameter's object
	    aCntr->list(pLs);
	    unsigned i_p;
	    for(i_p = 0; i_p < pLs.size(); i_p++) {
		AutoHD<TMdPrm> p = aCntr->at(pLs[i_p]);
		if(p.at().cfg("TYPE").getS() == id() && p.at().cfg("SUBT").getS() == pSTp)	break;
	    }
	    if(i_p < pLs.size()) continue;

	    while(aCntr->present(pId)) pId = TSYS::strLabEnum(pId);
	    aCntr->add(pId, 0);
	    AutoHD<TMdPrm> dprm = aCntr->at(pId);
	    dprm.at().setName(pNm);
	    dprm.at().autoC(true);
	    dprm.at().cfg("TYPE").setS(id());
	    dprm.at().cfg("SUBT").setS(pSTp);
	    dprm.at().cfg("EN").setB(true);
	    if(aCntr->enableStat()) dprm.at().enable();
	}
    fclose(f);
}
예제 #17
0
파일: module.cpp 프로젝트: aleax/openscada
void TTpContr::perSYSCall( unsigned int cnt )
{
    //Check for restart some conrollers need
    vector<string> cls, pls;
    list(cls);
    for(unsigned i_c = 0; i_c < cls.size(); i_c++) {
	AutoHD<TController> cntr = at(cls[i_c]);
	if(!cntr.at().startStat()) continue;
	cntr.at().list(pls);
	for(unsigned i_p = 0; i_p < pls.size(); i_p++) {
	    int errCode = cntr.at().at(pls[i_p]).at().vlAt("err").at().getI();
	    if(errCode == 21) {	//By MR/MC bus lost
		mess_warning(cntr.at().nodePath().c_str(), _("Re-enable by Reinit flag for MC/MR module."));
		cntr.at().disable();
		cntr.at().start();
		break;
	    }
	}
    }
}
예제 #18
0
void HddStat::makeActiveDA( TMdContr *a_cntr )
{
    string ap_nm = "Statistic_";

    vector<string> list;
    dList(list,true);
    for(unsigned i_hd = 0; i_hd < list.size(); i_hd++)
    {
        string hddprm = ap_nm+list[i_hd];
        if(!a_cntr->present(hddprm))
        {
            a_cntr->add(hddprm,0);
	    AutoHD<TMdPrm> dprm = a_cntr->at(hddprm);
	    dprm.at().setName(_("HD statistic: ")+list[i_hd]);
	    dprm.at().autoC(true);
            dprm.at().cfg("TYPE").setS(id());
    	    dprm.at().cfg("SUBT").setS(list[i_hd]);
            dprm.at().cfg("EN").setB(true);
            if(a_cntr->enableStat()) dprm.at().enable();
        }
    }
}
예제 #19
0
void TMdPrm::enable( )
{
    if(enableStat())	return;

    //Init to direction and the reverse flag load
    vector<string> ls;
    pEl.fldList(ls);
    for(unsigned iEl = 0; iEl < ls.size(); iEl++) {
	if(ls[iEl].compare(0,4,"gpio") != 0) continue;
	int pin = atoi(ls[iEl].c_str()+4);
	AutoHD<TVal> cVl = vlAt(ls[iEl]);
	switch(s2i(modPrm(TSYS::strMess("GPIOmode%d",pin)))) {
	    case 0:	//Disabled
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		break;
	    case 1:	//Input
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
		bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_OFF);
		break;
	    case 2:	//Input (pull up)
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
		bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_UP);
		break;
	    case 3:	//Input (pull down)
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
		bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_DOWN);
		break;
	    case 4:	//Output
		cVl.at().fld().setFlg(cVl.at().fld().flg()&(~TFld::NoWrite));
		bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
		break;
	}
	cVl.at().fld().setReserve(modPrm(TSYS::strMess("GPIOrev%d",pin)));
    }

    //Functions start
    fList(ls);
    for(unsigned iL = 0; iL < ls.size(); iL++)
	fAt(ls[iL]).at().setStart(true);

    TParamContr::enable();
}
예제 #20
0
파일: tuis.cpp 프로젝트: Strongc/openscada
string TUIS::docGet( const string &inm, string *tp, unsigned opt )
{
    unsigned i_tr = 0, i_t = 0;
    string rez, pathi, nm = TSYS::strParse(inm, 0, "|");
    vector<string> transl;

    //Find the offline document into filesystem
    int hd = -1;
    char types[][5] = {"pdf", "html", "odt"};
    transl.push_back(""); transl.push_back(Mess->lang2Code()); transl.push_back("en");

    for(int off = 0; hd == -1 && (pathi=TSYS::strParse(SYS->docDir(),0,";",&off)).size(); )
	for(i_tr = 0; i_tr < transl.size(); ++i_tr) {
	    for(i_t = 0; i_t < sizeof(types)/5; ++i_t)
		if((hd=open((pathi+"/"+transl[i_tr]+"/"+nm+"."+types[i_t]).c_str(),O_RDONLY)) != -1) break;
	    if(hd != -1) break;
	}
    if(hd != -1) {
	if(tp) *tp = types[i_t];
	if(opt == GetFilePath) rez = pathi+"/"+transl[i_tr]+"/"+nm+"."+types[i_t];
	else if(opt == GetExecCommand) rez = "xdg-open "+pathi+"/"+transl[i_tr]+"/"+nm+"."+types[i_t];
	else {
	    char buf[STR_BUF_LEN];
	    for(int len = 0; (len=read(hd,buf,sizeof(buf))) > 0; ) rez.append(buf,len);
	}
	close(hd);
    }

    //Find the online document into network
    if(rez.empty() && (nm=TSYS::strParse(inm,1,"|")).size()) {
	const char  *docHost = "wiki.oscada.org", *docURI = "/Doc",
		    *tTr = "Sockets", *nTr = "docCheck";
	transl.clear(); transl.push_back((Mess->lang2Code()=="ru")?"":Mess->lang2Code()); transl.push_back("en");

	try {
	    //Check connect and start
	    AutoHD<TTransportOut> tr;
	    if(!SYS->transport().at().at(tTr).at().outPresent(nTr)) {
		SYS->transport().at().at(tTr).at().outAdd(nTr);
		tr = SYS->transport().at().at(tTr).at().outAt(nTr);
		tr.at().setName(_("Doc check"));
	    }
	    else tr = SYS->transport().at().at(tTr).at().outAt(nTr);

	    XMLNode req("GET");
	    for(i_tr = 0; i_tr < transl.size(); ++i_tr) {
		req.setAttr("URI", (transl[i_tr].size()?"/HomePage"+transl[i_tr]:"/")+docURI+"/"+nm+"?tm="+i2s(SYS->sysTm()))->
		    setAttr("Host", string(docHost)+":80")->
		    setAttr("onlyHeader", (opt!=GetContent)?"1":"0");
		tr.at().messProtIO(req, "HTTP");
		if(s2i(req.attr("RezCod")) == 200) {
		    if(opt == GetFilePath) rez = string("http://")+docHost+TSYS::strParse(req.attr("URI"),0,"?");
		    else if(opt == GetExecCommand) rez = string("xdg-open ")+"http://"+docHost+TSYS::strParse(req.attr("URI"),0,"?");
		    else rez = req.text();
		    break;
		}
	    }
	} catch(TError) { }
    }

    return rez;
}
예제 #21
0
파일: sound.cpp 프로젝트: Strongc/openscada
int TMdContr::recordCallback( const void *iBuf, void *oBuf, unsigned long framesPerBuffer,
	const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData )
{
    TMdContr &cntr = *(TMdContr*)userData;
    cntr.prcSt = true;
    const char *bptr = (const char*)iBuf;

    if(cntr.redntUse()) { cntr.prcSt = false; return cntr.endrunReq; }

    //Set priority for call task
    if(cntr.firstCall) {
	int policy = SCHED_OTHER;
	struct sched_param prior;

	pthread_getschedparam(pthread_self(), &policy, &prior);
#if __GLIBC_PREREQ(2,4)
	if(cntr.prior() < 0)	policy = SCHED_BATCH;
#endif
	if(cntr.prior() > 0)	{ policy = SCHED_RR; prior.sched_priority = cntr.prior(); }
	if(pthread_setschedparam(pthread_self(), SCHED_FIFO, &prior) == EPERM)
	    setpriority(PRIO_PROCESS, syscall(SYS_gettid), -cntr.prior()/5);
	cntr.firstCall = false;
    }

    //Check for current time correction
    int64_t t_sz = (1000000ll*framesPerBuffer)/cntr.sRt;
    double err = ((timeInfo->inputBufferAdcTime-cntr.inAdcTimePrev)-1e-6*t_sz)/(1e-6*t_sz);

    //Pass short framesPerBuffer by incorrect
    cntr.framesPerBufferMax = vmax(cntr.framesPerBufferMax,framesPerBuffer);
    if(framesPerBuffer < cntr.framesPerBufferMax) {
	cntr.inAdcTimePrev = timeInfo->inputBufferAdcTime;
	return paContinue;
    }

    // Lost frames process
    if(cntr.inAdcTimePrev > 0 && err > 0.001) {
	cntr.wTm += (int64_t)((double)t_sz*err);
	mess_warning(cntr.nodePath().c_str(), _("CallBack: Lost frames correct: framesPerBuffer=%lu; sRt=%d; t_sz=%lld; err=%g; diff=%lld."),
	    framesPerBuffer, cntr.sRt, t_sz, err, (TSYS::curTime()-cntr.wTm));
	cntr.lostFrmsCntr++;
    }
    // Sound counter difference from time clock correction
    else if(cntr.inAdcTimeAdj < 0 || (timeInfo->inputBufferAdcTime-cntr.inAdcTimeAdj) >= 60) {
	int64_t dTm = TSYS::curTime()-cntr.wTm;
	if(cntr.inAdcTimeAdj > 0) cntr.sRt -= (dTm-cntr.tmAdj)*cntr.sRt/60000000;
	if(cntr.messLev() == TMess::Debug)
	    mess_debug_(cntr.nodePath().c_str(), _("CallBack: Sound counter difference fix: sRt=%d; dTm=%lld."), cntr.sRt, dTm);
	cntr.tmAdj = dTm;
	cntr.inAdcTimeAdj = timeInfo->inputBufferAdcTime;
    }
    cntr.inAdcTimePrev = timeInfo->inputBufferAdcTime;

    //Input buffer process
    ResAlloc res(cntr.nodeRes(),false);
    for(unsigned i_p = 0; i_p < cntr.pHd.size(); i_p++) {
	int  chn = cntr.pHd[i_p].at().iCnl();
	AutoHD<TVal> val = cntr.pHd[i_p].at().vlAt("val");
	AutoHD<TVArchive> arch = val.at().arch();
	bool archAllow = (!arch.freeStat() && arch.at().srcMode() == TVArchive::PassiveAttr);
	switch(cntr.mSmplType) {
	    case paFloat32:
		if(archAllow)
		    for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period())
			arch.at().setR(*(float*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t);
		if(SYS->sysTm() > cntr.cTm) {
		    val.at().setR(*(float*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true);
		    cntr.cTm = SYS->sysTm();
		}
		break;
	    case paInt32:
		if(archAllow)
		    for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period())
			arch.at().setI(*(int32_t*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t);
		if(SYS->sysTm() > cntr.cTm) {
		    val.at().setI(*(int32_t*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true);
		    cntr.cTm = SYS->sysTm();
		}
		break;
	    case paInt16:
		if(archAllow)
		    for(int64_t i_t = 0; i_t < t_sz; i_t += arch.at().period())
			arch.at().setI(*(int16_t*)(bptr+cntr.smplSize*((i_t*framesPerBuffer/t_sz)*cntr.numChan+chn)), cntr.wTm+i_t);
		if(SYS->sysTm() > cntr.cTm) {
		    val.at().setI(*(int16_t*)(bptr+cntr.smplSize*((framesPerBuffer-1)*cntr.numChan+chn)),cntr.wTm+(1000000ll*(framesPerBuffer-1))/cntr.sRt,true);
		    cntr.cTm = SYS->sysTm();
		}
		break;
	}
    }

    cntr.wTm += t_sz;

    cntr.acqSize += (float)(framesPerBuffer*cntr.smplSize*cntr.numChan)/1048576;

    cntr.prcSt = false;

    return cntr.endrunReq;
}
예제 #22
0
string TMdContr::modBusReq( string &pdu, bool MC, bool broadCast )
{
    char buf[1024];
    string mbap, rez, err;

    try
    {
	//> Transport creation for MC and MR busses and connect
	AutoHD<TTransportOut> tro = SYS->transport().at().nodeAt(MC?"Serial.out_SMH2Gi_MC":"Serial.out_SMH2Gi_MR", 0, '.', 0, true);
	if(tro.freeStat())
	{
	    SYS->transport().at().at("Serial").at().outAdd(MC?"SMH2Gi_MC":"SMH2Gi_MR");
	    tro = SYS->transport().at().nodeAt(MC?"Serial.out_SMH2Gi_MC":"Serial.out_SMH2Gi_MR", 0, '.', 0, true);
	    //>> Typical parameters set
	    tro.at().setDscr(TSYS::strMess(_("Segnetics SMH2Gi automatic created transport for '%s' bus"),MC?"MC":"MR"));
	    tro.at().setAddr(MC?(cfg("MC_DEV").getS()+":230400:8N1"):(cfg("MR_DEV").getS()+":230400:8N2"));
	}

	ResAlloc resN(tro.at().nodeRes(), true);

	//> Start stoped transport
	if(!tro.at().startStat()) tro.at().start();

	//> Prepare request
	mbap.reserve(pdu.size()+2);
	mbap += pdu;
	uint16_t crc = CRC16(mbap);
	mbap += (crc>>8);
	mbap += crc;

	//> Send request
	for(int i_tr = 0; i_tr < connTry; i_tr++)
	{
	    if(messLev() == TMess::Debug)
		mess_debug_(nodePath().c_str(), _("ModBUS REQ -> '%s': %s"), tro.at().id().c_str(), TSYS::strDecode(mbap,TSYS::Bin," ").c_str());
	    int resp_len = tro.at().messIO(mbap.data(), mbap.size(), (broadCast?NULL:buf), sizeof(buf), 0, true);
	    if(broadCast) { err = ""; break; }
	    rez.assign(buf, resp_len);
	    //> Wait tail
	    while(resp_len)
	    {
		try{ resp_len = tro.at().messIO(NULL, 0, buf, sizeof(buf), 0, true); } catch(TError err){ break; }
		rez.append(buf, resp_len);
	    }

	    if(rez.size() < 2) { err = _("13:Error respond: Too short."); continue; }
	    if(CRC16(rez.substr(0,rez.size()-2)) != (uint16_t)((rez[rez.size()-2]<<8)+(uint8_t)rez[rez.size()-1]))
	    { err = _("13:Error respond: CRC check error."); continue; }
	    if(messLev() == TMess::Debug)
		mess_debug_(nodePath().c_str(), _("ModBUS RESP -> '%s': %s"), tro.at().id().c_str(), TSYS::strDecode(rez,TSYS::Bin," ").c_str());
	    pdu = rez.substr(0, rez.size()-2);
	    err = "";
	    break;
	}
    }
    catch(TError ierr) { err = "10:"+ierr.mess; }

    if(messLev() >= TMess::Error && err.size()) mess_err(nodePath().c_str(), "%s", err.c_str());
    if(messLev() == TMess::Debug && err.size())
	mess_debug_(nodePath().c_str(), _("ModBUS ERR -> %s: %s"), TSYS::strDecode(mbap,TSYS::Bin," ").c_str(), err.c_str());

    return err;
}
예제 #23
0
void SUNXI::enable( TParamContr *ip )
{
    TMdPrm *p = (TMdPrm *)ip;

    if(sunxi_gpio_init() != 0)
	throw TError(p->nodePath().c_str(),_("Init SUNXI GPIO library error whether that is not SUNXI or there is not access."));

    MtxAlloc res(p->owner().dataRes(), true);
    if(use)	throw TError(p->nodePath().c_str(), _("SUNXI GPIO is already used."));
    use = true;

    //Init for loading the direction and reversion flag
    vector<string> ls;
    p->pEl.fldList(ls);
    for(unsigned iEl = 0; iEl < ls.size(); iEl++) {
	if(ls[iEl].compare(0,4,"gpio") != 0) continue;
	int pin = atoi(ls[iEl].c_str()+4);
	AutoHD<TVal> cVl = p->vlAt(ls[iEl]);
	switch(s2i(p->modPrm(TSYS::strMess("GPIOmode%d",pin)))) {
	    case 0:	//Disabled
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		break;
	    case 1:	//Input
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		sunxi_gpio_set_cfgpin(pin, SUNXI_GPIO_INPUT);
		sunxi_gpio_pullup(pin, SUNXI_PULL_NONE);
		break;
	    case 2:	//Input (pull up)
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		sunxi_gpio_set_cfgpin(pin, SUNXI_GPIO_INPUT);	//Or SUNXI_GPIO_PER
		sunxi_gpio_pullup(pin, SUNXI_PULL_UP);
		break;
	    case 3:	//Input (pull down)
		cVl.at().fld().setFlg(cVl.at().fld().flg()|TFld::NoWrite);
		sunxi_gpio_set_cfgpin(pin, SUNXI_GPIO_INPUT);	//Or SUNXI_GPIO_PER
		sunxi_gpio_pullup(pin, SUNXI_PULL_DOWN);
		break;
	    case 4:	//Output
		cVl.at().fld().setFlg(cVl.at().fld().flg()&(~TFld::NoWrite));
		sunxi_gpio_set_cfgpin(pin, SUNXI_GPIO_OUTPUT);
		break;
	}
	cVl.at().fld().setReserve(p->modPrm(TSYS::strMess("GPIOrev%d",pin)));
    }

    //Register the functions
    p->fReg(new GPIO_mode());
    p->fReg(new GPIO_get());
    p->fReg(new GPIO_put());
}
예제 #24
0
void *TMdContr::Task( void *icntr )
{
    vector<string>	als;
    string		nId;
    TMdContr &cntr = *(TMdContr *)icntr;

    cntr.endrun_req = false;
    cntr.prc_st = true;
    bool firstCall = true;

    XML_N req("opc.tcp"); req.setAttr("id", "Read")->setAttr("timestampsToReturn", TSYS::int2str(TS_NEITHER));

    try
    {
	for(unsigned int it_cnt = cntr.p_hd.size(); !cntr.endrun_req; it_cnt++)
	{
	    if(cntr.redntUse())	{ TSYS::sysSleep(1); continue; }
	    if(cntr.tmDelay > 0){ TSYS::sysSleep(1); cntr.tmDelay = vmax(0,cntr.tmDelay-1); continue; }

	    int64_t t_cnt = TSYS::curTime();
	    cntr.call_st = true;
	    unsigned int div = cntr.period() ? (unsigned int)(cntr.syncPer()/(1e-9*cntr.period())) : 0;

	    ResAlloc res(cntr.en_res, false);

	    if(!req.childSize() || cntr.mPCfgCh || (div && (it_cnt%div) < cntr.p_hd.size()))
	    {
		if(div && (it_cnt%div) < cntr.p_hd.size()) cntr.p_hd[it_cnt%div].at().attrPrc();

		//> Prepare nodes list
		req.childClear();
		req.childAdd("node")->setAttr("prmId", "OPC_UA_Server")->setAttr("prmAttr", "ServerStatus_State")->
		    setAttr("nodeId", "2259")->setAttr("attributeId", "13");
		for(unsigned i_p = 0; i_p < cntr.p_hd.size(); i_p++)
		{
		    if(firstCall) cntr.p_hd[i_p].at().attrPrc();
		    cntr.p_hd[i_p].at().vlList(als);
		    for(unsigned i_a = 0; i_a < als.size(); i_a++)
		    {
			nId = TSYS::strLine(cntr.p_hd[i_p].at().vlAt(als[i_a]).at().fld().reserve(), 0);
			if(nId.empty())	continue;
			req.childAdd("node")->setAttr("prmId", cntr.p_hd[i_p].at().id())->
			    setAttr("prmAttr", als[i_a])->setAttr("nodeId", nId)->setAttr("attributeId", "13");
		    }
		}
		cntr.mPCfgCh = false;
	    }
	    res.release();
	    cntr.reqService(req);

	    //> Place results
	    bool isErr = !req.attr("err").empty(), ndSt = 0;
	    AutoHD<TVal> vl;
	    res.request(false);
	    for(unsigned i_c = 0, i_p = 0; i_c < req.childSize() && i_p < cntr.p_hd.size(); i_c++)
	    {
		XML_N *cnX = req.childGet(i_c);
		if(cnX->attr("prmId") == "OPC_UA_Server" && cnX->attr("prmAttr") == "ServerStatus_State")
		{ cntr.servSt = strtoul(cnX->text().c_str(),NULL,10); continue; }
		while(cnX->attr("prmId") != cntr.p_hd[i_p].at().id()) i_p++;
		if(i_p >= cntr.p_hd.size()) break;
		if(cntr.p_hd[i_p].at().vlPresent(cnX->attr("prmAttr")))
		{
		    ndSt = strtol(cnX->attr("Status").c_str(),NULL,0);
		    vl = cntr.p_hd[i_p].at().vlAt(cnX->attr("prmAttr"));
		    vl.at().setS((isErr||ndSt)?EVAL_STR:cnX->text(),0,true);
		    vl.at().fld().setLen(ndSt);
		}
	    }
	    if(isErr)
	    {
		cntr.acq_err.setVal(req.attr("err"));
		mess_err(cntr.nodePath().c_str(), "%s", cntr.acq_err.getVal().c_str());
		cntr.tmDelay = cntr.syncPer();
		continue;
	    }
	    else if(cntr.tmDelay == -1) cntr.acq_err.setVal("");
	    res.release();

	    firstCall = false;
	    cntr.tm_gath = TSYS::curTime()-t_cnt;
	    cntr.call_st = false;

	    TSYS::taskSleep(cntr.period(), cntr.period() ? 0 : TSYS::cron(cntr.cron()));
	}
    }
    catch(TError err){ mess_err(err.cat.c_str(), err.mess.c_str()); }

    cntr.prc_st = false;

    return NULL;
}
예제 #25
0
void UpTime::makeActiveDA( TMdContr *aCntr )
{
    vector<string> pLs;
    aCntr->list(pLs);

    unsigned i_p;
    for(i_p = 0; i_p < pLs.size(); i_p++)
    {
	AutoHD<TMdPrm> p = aCntr->at(pLs[i_p]);
	if(p.at().cfg("TYPE").getS() == id() && p.at().cfg("SUBT").getS() == "sys") break;
    }
    if(i_p >= pLs.size())
    {
	string ap_nm = "UpTimeSystem";
	while(aCntr->present(ap_nm)) ap_nm = TSYS::strLabEnum(ap_nm);
	FILE *f = fopen("/proc/uptime","r");
	if(f != NULL)
	{
	    aCntr->add(ap_nm, 0);
	    AutoHD<TMdPrm> dprm = aCntr->at(ap_nm);
	    dprm.at().setName(_("System up time"));
	    dprm.at().autoC(true);
	    dprm.at().cfg("TYPE").setS(id());
	    dprm.at().cfg("SUBT").setS("sys");
	    dprm.at().cfg("EN").setB(true);
	    if(aCntr->enableStat()) dprm.at().enable();
	    fclose(f);
	}
    }

    for(i_p = 0; i_p < pLs.size(); i_p++)
    {
	AutoHD<TMdPrm> p = aCntr->at(pLs[i_p]);
	if(p.at().cfg("TYPE").getS() == id() && p.at().cfg("SUBT").getS() == "stat") break;
    }
    if(i_p >= pLs.size())
    {
	string ap_nm = "UpTimeStation";
	while(aCntr->present(ap_nm)) ap_nm = TSYS::strLabEnum(ap_nm);
	aCntr->add(ap_nm, 0);
	AutoHD<TMdPrm> dprm = aCntr->at(ap_nm);
	dprm.at().setName(_("Station up time"));
	dprm.at().autoC(true);
	dprm.at().cfg("TYPE").setS(id());
	dprm.at().cfg("SUBT").setS("stat");
	dprm.at().cfg("EN").setB(true);
	if(aCntr->enableStat()) dprm.at().enable();
    }
}
예제 #26
0
파일: mod_prt.cpp 프로젝트: alimon/oscada
bool TProt::inReq( string &request, const string &inPrtId, string *answ )
{
    ResAlloc res(enRes, false);
    bool rez = Server::inReq(request, inPrtId, answ);
    res.unlock();

#ifdef POOL_OF_TR
    //Pool for subscriptions process
    AutoHD<TProtIn> ip = at(inPrtId);
    if(ip.at().waitReqTm() && !ip.at().mSubscrIn && epPresent(ip.at().mEp)) {
	int64_t wTm = SYS->curTime();
	AutoHD<OPCEndPoint> ep = epAt(ip.at().mEp);
	bool tmToCall = (wTm-ip.at().mPrevTm)/1000 >= ip.at().waitReqTm();
	if(tmToCall || ep.at().forceSubscrQueue) {
	    if(tmToCall) ep.at().forceSubscrQueue = false;
	    if(!ep.at().forceSubscrQueue) ip.at().mSubscrCntr++;
	    ip.at().mPrevTm = wTm;
	    ip.at().mSubscrIn = true;
	    epAt(ip.at().mEp).at().subScrCycle(ip.at().mSubscrCntr, answ, inPrtId);
	    ip.at().mSubscrIn = false;
	}
    }
#endif

    return rez;
}
예제 #27
0
void TSocketIn::messPut( int sock, string &request, string &answer, string sender, AutoHD<TProtocolIn> &prot_in )
{
    AutoHD<TProtocol> proto;
    string n_pr = mod->modId()+"_"+id()+"_"+TSYS::int2str(sock);
    try
    {
	proto = SYS->protocol().at().modAt(protocol());
	if( prot_in.freeStat() )
	{
	    if( !proto.at().openStat(n_pr) ) proto.at().open( n_pr, workId() );
	    prot_in = proto.at().at( n_pr );
	}
	if( prot_in.at().mess(request,answer,sender) ) return;
	prot_in.free();
	if( proto.at().openStat(n_pr) ) proto.at().close(n_pr);
    }catch(TError err)
    {
	prot_in.free();
	if( !proto.freeStat() && proto.at().openStat(n_pr) ) proto.at().close( n_pr );

	mess_err(nodePath().c_str(),"%s",err.mess.c_str() );
	mess_err(nodePath().c_str(),_("Error request to protocol."));
    }
}
예제 #28
0
void *TSocketIn::ClTask( void *s_inf )
{
    SSockIn	&s = *(SSockIn *)s_inf;

    int		rez;
    char	err[255];
    char	buf[s.s->bufLen()*1024];
    string	req, answ;
    AutoHD<TProtocolIn> prot_in;
    SSL		*ssl;

    int cSock = s.s->clientReg(pthread_self());

    if(mess_lev() == TMess::Debug)
	mess_debug(s.s->nodePath().c_str(),_("Socket has been connected by '%s'!"),s.sender.c_str());

    if(BIO_do_handshake(s.bio) <= 0)
    {
	if(BIO_should_retry(s.bio))
	    while(BIO_should_retry(s.bio) && !s.s->endrun_cl)	{ BIO_do_handshake(s.bio); TSYS::sysSleep(STD_WAIT_DELAY*1e-3); }
	else
	{
	    if(ERR_peek_last_error())
	    {
		ERR_error_string_n(ERR_peek_last_error(),err,sizeof(err));
		mess_err(s.s->nodePath().c_str(),"BIO_should_retry: %s",err);
	    }
	    BIO_flush(s.bio);
	    delete (SSockIn*)s_inf;
	    return NULL;
	}
    }

    int sock_fd = BIO_get_fd(s.bio,NULL);
    BIO_get_ssl(s.bio,&ssl);

    //> Select mode
    struct  timeval tv;
    fd_set  rd_fd;
    int cnt = 0;		//> Requests counter
    int tm = time(NULL);	//> Last connection time

    do
    {
	if(!SSL_pending(ssl))
	{
	    tv.tv_sec  = 0; tv.tv_usec = STD_WAIT_DELAY*1000;
	    FD_ZERO(&rd_fd); FD_SET(sock_fd,&rd_fd);

	    int kz = select(sock_fd+1,&rd_fd,NULL,NULL,&tv);
	    if( kz == 0 || (kz == -1 && errno == EINTR) || kz < 0 || !FD_ISSET(sock_fd,&rd_fd) ) continue;
	}

	rez = BIO_read(s.bio,buf,sizeof(buf));
	if(rez <= 0)	break;		//Connection closed by client
	if(mess_lev() == TMess::Debug)
    	    mess_debug(s.s->nodePath().c_str(),_("The message is received with the size '%d'."),rez);
	req.assign(buf,rez);
	s.s->sock_res.resRequestW();
	s.s->trIn += rez;
	s.s->sock_res.resRelease();

	s.s->messPut(cSock,req,answ,s.sender,prot_in);
	if(answ.size())
	{
	    if(mess_lev() == TMess::Debug)
        	mess_debug(s.s->nodePath().c_str(),_("The message is replied with the size '%d'."),answ.size());
	    do { rez = BIO_write(s.bio,answ.data(),answ.size()); }
	    while(rez < 0 && SSL_get_error(ssl,rez) == SSL_ERROR_WANT_WRITE);
	    s.s->sock_res.resRequestW();
	    s.s->trOut += vmax(0, rez);
	    s.s->sock_res.resRelease();
	    answ = "";
	    cnt++;
	    tm = time(NULL);
	}
    }
    while(!s.s->endrun_cl &&
		(!s.s->keepAliveCon() || cnt < s.s->keepAliveCon()) &&
		(!s.s->keepAliveTm() || (time(NULL)-tm) < s.s->keepAliveTm()));

    BIO_flush(s.bio);
    close(sock_fd);
    //BIO_reset(s.bio);
    BIO_free(s.bio);

    //> Close protocol on broken connection
    if( !prot_in.freeStat() )
    {
	string n_pr = prot_in.at().name();
	prot_in.free();
	AutoHD<TProtocol> proto = SYS->protocol().at().modAt(s.s->protocol());
	if( proto.at().openStat(n_pr) ) proto.at().close(n_pr);
    }

    s.s->clientUnreg( pthread_self() );

    if(mess_lev() == TMess::Debug)
	mess_debug(s.s->nodePath().c_str(),_("Socket has been disconnected (%d)."),s.s->cl_id.size());

    delete (SSockIn*)s_inf;

    return NULL;
}
예제 #29
0
void Prm::enable( )
{
    if(enableStat())	return;
    string ioLs = cfg("IO").getS();

    //Check and delete no used fields
    /*for(int i_fld = 0; i_fld < (int)v_el.fldSize(); i_fld++)
    {
	if(v_el.fldAt(i_fld).reserve().empty()) continue;
	string fel;
	for(int io_off = 0; (fel=TSYS::strSepParse(ioLs,0,'\n',&io_off)).size(); )
	    if(TSYS::strSepParse(fel,0,':') == v_el.fldAt(i_fld).reserve()) break;
	if(fel.empty())
	{
	    try{ v_el.fldDel(i_fld); i_fld--; }
	    catch(TError err)
	    { mess_err(err.cat.c_str(),"%s",err.mess.c_str()); }
	}
    }*/

    //Init elements
    vector<string> pls;
    AutoHD<Block> blk;
    int io, if_off, id_off;
    string mio, ioaddr, ioblk, ioid, aid, anm;
    for(int io_off = 0; (mio=TSYS::strParse(ioLs,0,"\n",&io_off)).size(); ) {
	if(mio[0] == '#') continue;
	if_off = id_off = 0;
	ioaddr = TSYS::strParse(mio,0,":",&if_off);
	ioblk  = TSYS::strParse(ioaddr,0,".",&id_off);
	ioid   = ioaddr.substr(id_off);
	aid    = TSYS::strParse(mio,0,":",&if_off);
	anm    = TSYS::strParse(mio,0,":",&if_off);

	if(ioblk.empty() || ioid.empty()) continue;

	unsigned	flg = 0;
	TFld::Type	tp  = TFld::String;
	string		reserve;

	// Constant attributes
	if(ioblk[0] == '*') {
	    if(aid.empty()) continue;
	    if(anm.empty()) anm = aid;
	    if(ioblk.size() > 1)
		switch(ioblk[1]) {
		    case 's': case 'S':	tp = TFld::String;	break;
		    case 'i': case 'I':	tp = TFld::Integer;	break;
		    case 'r': case 'R':	tp = TFld::Real;	break;
		    case 'b': case 'B':	tp = TFld::Boolean;	break;
		}
	    flg = TFld::NoWrite;
	}
	// Links to block's io
	else {
	    if(aid.empty()) aid = ioblk+"_"+ioid;
	    if(!((Contr&)owner()).blkPresent(ioblk)) continue;
	    blk = ((Contr&)owner()).blkAt(ioblk);
	    if((io=blk.at().ioId(ioid)) < 0)	continue;
	    if(anm.empty()) anm = blk.at().func()->io(io)->name();
	    tp = TFld::type(blk.at().ioType(io));
	    flg = TVal::DirWrite|TVal::DirRead;
	    reserve = ioaddr;
	}

	// Attribute creation
	if(!v_el.fldPresent(aid) || v_el.fldAt(v_el.fldId(aid)).type() != tp || v_el.fldAt(v_el.fldId(aid)).flg() != flg)
	{
	    if(v_el.fldPresent(aid)) v_el.fldDel(v_el.fldId(aid));
	    v_el.fldAdd(new TFld(aid.c_str(),"",tp,flg));
	}
	int el_id = v_el.fldId(aid);
	v_el.fldAt(el_id).setDescr(anm);
	v_el.fldAt(el_id).setReserve(ioaddr);
	if(ioblk[0] == '*') vlAt(aid).at().setS(ioid,0,true);

	pls.push_back(aid);
    }

    //Check and delete no used attrs
    for(int i_fld = 0; i_fld < (int)v_el.fldSize(); i_fld++) {
	int i_p;
	for(i_p = 0; i_p < (int)pls.size(); i_p++)
	    if(pls[i_p] == v_el.fldAt(i_fld).name())	break;
	if(i_p < (int)pls.size()) continue;
	try{ v_el.fldDel(i_fld); i_fld--; }
	catch(TError err) { mess_err(err.cat.c_str(),"%s",err.mess.c_str()); }
    }

    TParamContr::enable();
}