/** Copies the values of the objects to capture into the buffer by reading capture objects. */ void CGXDLMSProfileGeneric::Capture() { //TODO: vector<CGXDLMSVariant> values; for (std::vector<std::pair<CGXDLMSObject*, CGXDLMSCaptureObject*> >::iterator it = m_CaptureObjects.begin(); it != m_CaptureObjects.end(); ++it) { OBJECT_TYPE type = (*it).first->GetObjectType(); string ln; (*it).first->GetLogicalName(ln); CGXDLMSObject* pObj = NULL; if(GetParent() != NULL) { pObj = GetParent()->FindByLN(type, ln); } if(pObj == NULL) { pObj = CGXDLMSObjectFactory::CreateObject(type); pObj->SetLogicalName(ln); } CGXDLMSVariant null; CGXDLMSVariant value; pObj->GetValue((*it).second->GetAttributeIndex(), 0, null, value); values.push_back(value); } if(GetProfileEntries() == m_Buffer.size()) { m_Buffer.erase(m_Buffer.begin()); } m_Buffer.push_back(values); m_EntriesInUse = m_Buffer.size(); }
int CGXDLMSAssociationShortName::SetValue(int index, CGXDLMSVariant& value) { if (index == 1) { if (value.vt != DLMS_DATA_TYPE_OCTET_STRING || value.GetSize() != 6) { return ERROR_CODES_INVALID_PARAMETER; } memcpy(m_LN, &value.byteArr[0], 6); return ERROR_CODES_OK; } else if (index == 2) { m_ObjectList.clear(); if (value.vt == DLMS_DATA_TYPE_ARRAY) { for(vector<CGXDLMSVariant>::iterator item = value.Arr.begin(); item != value.Arr.end(); ++item) { int sn = item->Arr[0].ToInteger(); CGXDLMSObject* pObj = GetParent()->FindBySN(sn); if (pObj == NULL) { OBJECT_TYPE type = (OBJECT_TYPE) item->Arr[1].ToInteger(); int version = item->Arr[2].ToInteger(); string ln; CGXOBISTemplate::GetLogicalName(&(*item).Arr[3].byteArr[0], ln); pObj = CGXDLMSObjectFactory::CreateObject(type); pObj->SetLogicalName(ln); pObj->SetShortName(sn); pObj->SetVersion(version); } m_ObjectList.push_back(pObj); } } } else if (index == 3) { if (value.vt == DLMS_DATA_TYPE_NONE) { for(vector<CGXDLMSObject*>::iterator it = m_ObjectList.begin(); it != m_ObjectList.end(); ++it) { for(int pos = 1; pos != (*it)->GetAttributeCount(); ++pos) { (*it)->SetAccess(pos, ACCESSMODE_NONE); } } } else { UpdateAccessRights(value); } } return ERROR_CODES_INVALID_PARAMETER; }
void CGXDLMSAssociationShortName::UpdateAccessRights(CGXDLMSVariant& buff) { for(vector<CGXDLMSVariant>::iterator access = buff.Arr.begin(); access != buff.Arr.end(); ++access) //for (Object access : buff) { int sn = access->Arr[0].ToInteger(); CGXDLMSObject* pObj = m_ObjectList.FindBySN(sn); if (pObj != NULL) { for(vector<CGXDLMSVariant>::iterator attributeAccess = access->Arr[1].Arr.begin(); access != access->Arr[1].Arr.end(); ++access) { int id = attributeAccess->Arr[0].ToInteger(); int tmp = attributeAccess->Arr[1].ToInteger(); pObj->SetAccess(id, (ACCESSMODE) tmp); } for(vector<CGXDLMSVariant>::iterator methodAccess = access->Arr[2].Arr.begin(); access != access->Arr[2].Arr.end(); ++access) { int id = methodAccess->Arr[0].ToInteger(); int tmp = methodAccess->Arr[1].ToInteger(); pObj->SetMethodAccess(id, (METHOD_ACCESSMODE) tmp); } } } }
int CGXDLMSAssociationLogicalName::SetValue(int index, CGXDLMSVariant& value) { if (index == 1) { if (value.vt != DLMS_DATA_TYPE_OCTET_STRING || value.GetSize() != 6) { return ERROR_CODES_INVALID_PARAMETER; } memcpy(m_LN, &value.byteArr[0], 6); } else if (index == 2) { m_ObjectList.clear(); if (value.vt != DLMS_DATA_TYPE_NONE) { for (std::vector<CGXDLMSVariant >::iterator it = value.Arr.begin(); it != value.Arr.end(); ++it) { OBJECT_TYPE type = (OBJECT_TYPE) (*it).Arr[0].ToInteger(); int version = (*it).Arr[1].ToInteger(); string ln; CGXOBISTemplate::GetLogicalName(&(*it).Arr[2].byteArr[0], ln); CGXDLMSObject* pObj = GetParent()->FindByLN(type, ln); if (pObj == NULL) { pObj = CGXDLMSObjectFactory::CreateObject(type); pObj->SetLogicalName(ln); pObj->SetVersion(version); } UpdateAccessRights(pObj, (*it).Arr[3]); m_ObjectList.push_back(pObj); } } } else if (index == 3) { m_AssociatedPartnersId = value; } else if (index == 4) { m_ApplicationContextName = value; } else if (index == 5) { m_XDLMSContextInfo = value; } else if (index == 6) { m_AuthenticationMechanismMame = value; } else if (index == 7) { m_Secret = value; } else if (index == 8) { m_AssociationStatus = (GX_ASSOCIATION_STATUS) value.ToInteger(); } else if (index == 9) { m_SecuritySetupReference = value.ToString(); } else { return ERROR_CODES_INVALID_PARAMETER; } return ERROR_CODES_OK; }
/* * Set value of given attribute. */ int CGXDLMSProfileGeneric::SetValue(int index, CGXDLMSVariant& value) { int ret; if (index == 1) { if (value.vt != DLMS_DATA_TYPE_OCTET_STRING || value.GetSize() != 6) { return ERROR_CODES_INVALID_PARAMETER; } memcpy(m_LN, &value.byteArr[0], 6); } else if (index == 2) { if (m_CaptureObjects.size() == 0) { //Read capture objects first. return ERROR_CODES_INVALID_PARAMETER; } m_Buffer.clear(); if (value.vt != DLMS_DATA_TYPE_NONE) { vector<DLMS_DATA_TYPE> types; DLMS_DATA_TYPE type; for (std::vector<std::pair<CGXDLMSObject*, CGXDLMSCaptureObject*> >::iterator it = m_CaptureObjects.begin(); it != m_CaptureObjects.end(); ++it) { if ((ret = (*it).first->GetUIDataType((*it).second->GetAttributeIndex(), type)) != 0) { return ret; } types.push_back(type); } for (std::vector<CGXDLMSVariant >::iterator row = value.Arr.begin(); row != value.Arr.end(); ++row) { if ((*row).Arr.size() != m_CaptureObjects.size()) { //Number of columns do not match. return ERROR_CODES_INVALID_PARAMETER; } for(unsigned int a = 0; a < (*row).Arr.size(); ++a) { CGXDLMSVariant data = (*row).Arr[a]; DLMS_DATA_TYPE type = types[a]; if (type != DLMS_DATA_TYPE_NONE && data.vt == DLMS_DATA_TYPE_OCTET_STRING) { unsigned char* pBuff = &data.byteArr[0]; int size = data.byteArr.size(); if ((ret = CGXOBISTemplate::GetData(pBuff, size, type, (*row).Arr[a])) != 0) { return ret; } } std::pair<CGXDLMSObject*, CGXDLMSCaptureObject*> item = m_CaptureObjects[a]; if (item.first->GetObjectType() == OBJECT_TYPE_REGISTER && item.second->GetAttributeIndex() == 2) { double scaler = ((CGXDLMSRegister*) item.first)->GetScaler(); if (scaler != 1) { row[a] = data.ToDouble() * scaler; } } } m_Buffer.push_back(row->Arr); } } m_EntriesInUse = m_Buffer.size(); } else if (index == 3) { m_CaptureObjects.clear(); m_Buffer.clear(); m_EntriesInUse = 0; if (value.vt == DLMS_DATA_TYPE_ARRAY) { for (std::vector<CGXDLMSVariant >::iterator it = value.Arr.begin(); it != value.Arr.end(); ++it) { if ((*it).Arr.size() != 4) { //Invalid structure format. return ERROR_CODES_INVALID_PARAMETER; } OBJECT_TYPE type = (OBJECT_TYPE) (*it).Arr[0].ToInteger(); string ln; CGXOBISTemplate::GetLogicalName(&(*it).Arr[1].byteArr[0], ln); CGXDLMSObject* pObj = NULL; if (GetParent() != NULL) { pObj = GetParent()->FindByLN(type, ln); } if(pObj == NULL) { pObj = CGXDLMSObjectFactory::CreateObject(type); pObj->SetLogicalName(ln); } AddCaptureObject(pObj, (*it).Arr[2].ToInteger(), (*it).Arr[3].ToInteger()); } } } else if (index == 4) { m_CapturePeriod = value.ToInteger(); } else if (index == 5) { m_SortMethod = (GX_SORT_METHOD) value.ToInteger(); } else if (index == 6) { if (value.vt == DLMS_DATA_TYPE_NONE) { m_SortObject = NULL; } else { if (value.Arr.size() != 4) { //Invalid structure format. return ERROR_CODES_INVALID_PARAMETER; } OBJECT_TYPE type = (OBJECT_TYPE) value.Arr[0].ToInteger(); string ln; CGXOBISTemplate::GetLogicalName(&value.Arr[1].byteArr[0], ln); int attributeIndex = value.Arr[2].ToInteger(); int dataIndex = value.Arr[3].ToInteger(); m_SortObject = NULL; if (GetParent() != NULL) { m_SortObject = GetParent()->FindByLN(type, ln); } if(m_SortObject == NULL) { m_SortObject = CGXDLMSObjectFactory::CreateObject(type); m_SortObject->SetLogicalName(ln); } m_SortObjectAttributeIndex = attributeIndex; m_SortObjectDataIndex = dataIndex; } } else if (index == 7) { m_EntriesInUse = value.ToInteger(); } else if (index == 8) { m_ProfileEntries = value.ToInteger(); } else { return ERROR_CODES_INVALID_PARAMETER; } return ERROR_CODES_OK; }
void CGXDLMSBase::PreRead(std::vector<CGXDLMSValueEventArg*>& args) { CGXDLMSVariant value; CGXDLMSObject* pObj; int ret, index; DLMS_OBJECT_TYPE type; std::string ln; for (std::vector<CGXDLMSValueEventArg*>::iterator it = args.begin(); it != args.end(); ++it) { //Let framework handle Logical Name read. if ((*it)->GetIndex() == 1) { continue; } //Get attribute index. index = (*it)->GetIndex(); pObj = (*it)->GetTarget(); //Get target type. type = pObj->GetObjectType(); if (type == DLMS_OBJECT_TYPE_PROFILE_GENERIC) { CGXDLMSProfileGeneric* p = (CGXDLMSProfileGeneric*)pObj; // If buffer is read and we want to save memory. if (index == 7) { // If client wants to know EntriesInUse. p->SetEntriesInUse(GetProfileGenericDataCount()); } else if (index == 2) { // Read rows from file. // If reading first time. if ((*it)->GetRowEndIndex() == 0) { if ((*it)->GetSelector() == 0) { (*it)->SetRowEndIndex(GetProfileGenericDataCount()); } else if ((*it)->GetSelector() == 1) { // Read by entry. GetProfileGenericDataByRange((*it)); } else if ((*it)->GetSelector() == 2) { // Read by range. unsigned int begin = (*it)->GetParameters().Arr[0].ulVal; (*it)->SetRowBeginIndex(begin); (*it)->SetRowEndIndex(begin + (*it)->GetParameters().Arr[1].ulVal); // If client wants to read more data what we have. int cnt = GetProfileGenericDataCount(); if ((*it)->GetRowEndIndex() - (*it)->GetRowBeginIndex() > cnt - (*it)->GetRowBeginIndex()) { (*it)->SetRowEndIndex(cnt - (*it)->GetRowBeginIndex()); if ((*it)->GetRowEndIndex() < 0) { (*it)->SetRowEndIndex(0); } } } } long count = (*it)->GetRowEndIndex() - (*it)->GetRowBeginIndex(); // Read only rows that can fit to one PDU. if ((*it)->GetRowEndIndex() - (*it)->GetRowBeginIndex() > (*it)->GetRowToPdu()) { count = (*it)->GetRowToPdu(); } GetProfileGenericDataByEntry(p, (*it)->GetRowBeginIndex(), count); } continue; } //Framework will handle Association objects automatically. if (type == DLMS_OBJECT_TYPE_ASSOCIATION_LOGICAL_NAME || type == DLMS_OBJECT_TYPE_ASSOCIATION_SHORT_NAME || //Framework will handle profile generic automatically. type == DLMS_OBJECT_TYPE_PROFILE_GENERIC) { continue; } DLMS_DATA_TYPE ui, dt; (*it)->GetTarget()->GetUIDataType(index, ui); (*it)->GetTarget()->GetDataType(index, dt); //Update date and time of clock object. if (type == DLMS_OBJECT_TYPE_CLOCK && index == 2) { CGXDateTime tm = CGXDateTime::Now(); ((CGXDLMSClock*)pObj)->SetTime(tm); continue; } else if (type == DLMS_OBJECT_TYPE_REGISTER_MONITOR) { CGXDLMSRegisterMonitor* pRm = (CGXDLMSRegisterMonitor*)pObj; if (index == 2) { //Initialize random seed. srand((unsigned int)time(NULL)); pRm->GetThresholds().clear(); pRm->GetThresholds().push_back(rand() % 100 + 1); continue; } } else { CGXDLMSVariant null; CGXDLMSValueEventArg e(pObj, index); ret = ((IGXDLMSBase*)pObj)->GetValue(m_Settings, e); if (ret != DLMS_ERROR_CODE_OK) { //TODO: Show error. continue; } //If data is not assigned and value type is unknown return number. DLMS_DATA_TYPE tp = e.GetValue().vt; if (tp == DLMS_DATA_TYPE_INT8 || tp == DLMS_DATA_TYPE_INT16 || tp == DLMS_DATA_TYPE_INT32 || tp == DLMS_DATA_TYPE_INT64 || tp == DLMS_DATA_TYPE_UINT8 || tp == DLMS_DATA_TYPE_UINT16 || tp == DLMS_DATA_TYPE_UINT32 || tp == DLMS_DATA_TYPE_UINT64) { //Initialize random seed. srand((unsigned int)time(NULL)); value = rand() % 100 + 1; value.vt = tp; e.SetValue(value); } } } }