📄 realtag.c
字号:
if (ent.attr.taName) tFlag ^= loTt_VISIBLE;
else if (!se->driver.ldAskItemID || (tFlag & loTF_EMPTY))
{ rv = EINVAL; goto Exit; }
else tFlag &= ~loTt_VISIBLE;
#if defined(OPC_QUALITY_BAD) /* OPC DA pre 3.0 */ && 0
ent.prim.tsQuality = OPC_QUALITY_BAD;
#else
ent.prim.tsQuality = OPC_QUALITY_WAITING_FOR_INITIAL_DATA;
#endif
ent.prim.tsError = S_FALSE/*E_FAILED*/;
ent.active = 0;
#define loTF_ALL (/*OPC_READABLE | OPC_WRITEABLE | */ \
loTF_NOCOMP | loTF_NOCONV | loTF_CANONAME | loTF_EMPTY | \
loTF_CONVERT | loTF_CHECKITEM | loTF_NOBROWSE)
ent.attr.taFlags |= tFlag & loTF_ALL |
se->driver.ldFlags & (loDF_NOCONV | loDF_NOCOMP | loDF_CANONAME);
ent.attr.taRights |= tRight & loOPC_RIGHTS/*(OPC_READABLE | OPC_WRITEABLE)*/;
ent.attr.taRt = rt;
if (!se->driver.ldConvertTags) ent.attr.taFlags &= ~loTF_CONVERT;
if (!se->driver.ldAskItemID) ent.attr.taFlags &= ~loTF_CHECKITEM;
ent_hash = loSTRHASH(se, ent.attr.taName);
{
unsigned ii;
loTagEntry *te;
lw_rw_wrlock(&se->lkMgmt);
if (!ent.attr.taDetail/*tBase*/)
{
loTagEntry *te = &se->tags[tBase];
if (tBase > se->lastused/*tag_count*/ ||
tBase && !loTE_USED(te) ||
!te->attr.taDetail)
{
rv = ENOENT; goto Unlock;
}
ent.attr.taDetail = te->attr.taDetail;
ent.attr.taRangecent = te->attr.taRangecent;
ent.attr.taFlags |= te->attr.taFlags & loTF_EMPTY;
if (S_OK != VariantCopy(&ent.primValue, &ent.attr.taValue))
{ rv = EFAULT; goto Unlock; }
}
if (!ent.attr.taRangecent) ent.attr.taFlags |= loTt_ZERORANGE;
if (ent.attr.taName && (ii = lo_find_tag(se, ent.attr.taName)))
{
#if 1
if (ti) *ti = ii;
#endif
rv = EEXIST; goto Unlock;
}
for(ii = se->firstfree; ii < se->tag_count; ii++)
if (!loTE_USED(&se->tags[ii]))
{
te = &se->tags[ii]; goto Found;
}
rv = EMLINK/*ENOMEM*/; goto Unlock;
Found:
lw_mutex_lock(&se->update_pipe.lk);
if (S_OK != VariantCopy(&se->secondary[ii].tvValue, &ent.attr.taValue))
rv = EFAULT;
else
{
se->secondary[ii].tvTi = 0;
if (ii > se->lastused) se->lastused = ii;
if (ent.attr.taName &&
ii > se->lastnamed) se->lastnamed = ii;
se->firstfree = ii/* + 1*/;
/* we don't know will we use it or not so lets firstfree be one step behind */
*te = ent;
te->attr.taTi = ii;
se->name_hash[ii] = ent_hash;
ent.attr.taTi = ii;
rv = 0;
}
lw_mutex_unlock(&se->update_pipe.lk);
#if 0
if (rv) goto Unlock;
*te = ent;
te->attr.taTi = ii;
ent.attr.taTi = ii;
#endif
Unlock:
lw_rw_unlock(&se->lkMgmt);
}
Exit:
//UL_DEBUG((LOGID, "loAddTag(%s)...Exiting", loWnul(ent.attr.taName)));
if (rv)
{
UL_INFO((LOGID, "%!e loAddTag(%s%ls) failed", rv,
sName? sName: "", sName && !wName? L"": loWnul(ent.attr.taName)));
loTagEntry_clear(&ent, 1);
}
else
{
if (ti) *ti = ent.attr.taTi;
UL_NOTICE((LOGID, "loAddTag(%ls vt=%x fl=%x ha=%X) = %u",
loWnul(ent.attr.taName), taVTYPE(&ent.attr),
ent.attr.taFlags, ent_hash, ent.attr.taTi));
}
return rv;
}
/**************************************************************************/
static int intAddRealTag_a(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const char *sName,
const loWchar *wName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
double range_min,
double range_max)
{
int rv = 0;
SAFEARRAY *sa;
SAFEARRAYBOUND sbound[1];
sbound[0].lLbound = 0;
sbound[0].cElements = 2;
if (ti) *ti = 0;
if (sa = SafeArrayCreate(VT_R8, 1, sbound))
{
HRESULT hr;
VARIANT eui;
long ix0 = 0, ix1 = 1;
VARIANTINIT(&eui);
V_ARRAY(&eui) = sa;
V_VT(&eui) = VT_ARRAY|VT_R8;
/* UL_DEBUG((LOGID, "loAddRealTag->Build EU-ANALOGEU = %#x (%p/%p)",
V_VT(&eui), &eui, sa));
*/
if (S_OK != (hr = SafeArrayPutElement(sa, &ix0, &range_min)) ||
S_OK != (hr = SafeArrayPutElement(sa, &ix1, &range_max)))
{
UL_INFO((LOGID, "loAddRealTag_a::SafeArrayPutElement() = %s", loStrError(hr)));
rv = EFAULT;
}
else rv = intAddRealTag(se, ti, rt, sName, wName, tFlag, tRight, tValue, OPC_ANALOG, &eui, 0);
VariantClear(&eui);
}
else
{
rv = ENOMEM;
UL_INFO((LOGID, "loAddRealTag_a::SafeArrayCreate() failed"));
}
return rv;
}
/**************************************************************************/
int loAddRealTag(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const char *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
/*OPCEUTYPE*/int tEUtype,
VARIANT *tEUinfo) /* optional, if tdEUtype is 0*/
{
// UL_DEBUG((LOGID, "loAddTag(%s)...", loSnul(tName)));
return intAddRealTag(se, ti, rt, tName, 0, tFlag, tRight, tValue, tEUtype, tEUinfo, 0);
}
int loAddRealTag_a(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const char *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
double range_min,
double range_max) /* optional, if tdEUtype is 0*/
{
// UL_DEBUG((LOGID, "loAddTag_a(%s)...", loSnul(tName)));
return intAddRealTag_a(se, ti, rt, tName, 0, tFlag, tRight, tValue, range_min, range_max);
}
int loAddRealTag_b(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const char *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
loTagId tBase)
{
// UL_DEBUG((LOGID, "loAddTag_b(%s)...", loSnul(tName)));
return intAddRealTag(se, ti, rt, tName, 0, tFlag, tRight, 0, 0, 0, tBase);
}
int loAddRealTagW(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const loWchar *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
/*OPCEUTYPE*/int tEUtype,
VARIANT *tEUinfo) /* optional, if tdEUtype is 0*/
{
// UL_DEBUG((LOGID, "loAddTagU(%ls)...", loWnul(tName)));
return intAddRealTag(se, ti, rt, 0, tName, tFlag, tRight, tValue, tEUtype, tEUinfo, 0);
}
int loAddRealTag_aW(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const loWchar *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
double range_min,
double range_max) /* optional, if tdEUtype is 0*/
{
// UL_DEBUG((LOGID, "loAddTag_aU(%ls)...", loWnul(tName)));
return intAddRealTag_a(se, ti, rt, 0, tName, tFlag, tRight, tValue, range_min, range_max);
}
int loAddRealTag_bW(loService *se, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const loWchar *tName,
int tFlag,
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
loTagId tBase)
{
// UL_DEBUG((LOGID, "loAddTagU(%ls)...", loWnul(tName)));
return intAddRealTag(se, ti, rt, 0, tName, tFlag, tRight, 0, 0, 0, tBase);
}
/**************************************************************************/
/* end of realtag.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -