int CGXCommunication::ReadDataBlock(CGXByteBuffer& data, CGXReplyData& reply) { //If ther is no data to send. if (data.GetSize() == 0) { return DLMS_ERROR_CODE_OK; } int ret; CGXByteBuffer bb; //Send data. if ((ret = ReadDLMSPacket(data, reply)) != DLMS_ERROR_CODE_OK) { return ret; } while (reply.IsMoreData()) { bb.Clear(); if ((ret = m_Parser->ReceiverReady(reply.GetMoreData(), bb)) != 0) { return ret; } if ((ret = ReadDLMSPacket(bb, reply)) != DLMS_ERROR_CODE_OK) { return ret; } } return DLMS_ERROR_CODE_OK; }
int CGXDLMSProfileGeneric::GetColumns(CGXByteBuffer& data) { int cnt = m_CaptureObjects.size(); data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count GXHelpers::SetObjectCount(cnt, data); std::string ln; int ret; CGXDLMSVariant tmp, ai, di; for (std::vector<std::pair<CGXDLMSObject*, CGXDLMSCaptureObject*> >::iterator it = m_CaptureObjects.begin(); it != m_CaptureObjects.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(4); //Count tmp = it->first->GetObjectType(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, tmp)) != 0) //ClassID { return ret; } (*it).first->GetLogicalName(ln); tmp = ln; ai = (*it).second->GetAttributeIndex(); di = (*it).second->GetDataIndex(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp)) != 0 || //LN (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_INT8, ai)) != 0 || //Attribute Index (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, di)) != 0) //Data Index { return ret; } } return DLMS_ERROR_CODE_OK; }
int CGXCommunication::ReadDataBlock(std::vector<CGXByteBuffer>& data, CGXReplyData& reply) { //If ther is no data to send. if (data.size() == 0) { return DLMS_ERROR_CODE_OK; } int ret; CGXByteBuffer bb; //Send data. for (std::vector<CGXByteBuffer>::iterator it = data.begin(); it != data.end(); ++it) { //Send data. if ((ret = ReadDLMSPacket(*it, reply)) != DLMS_ERROR_CODE_OK) { return ret; } while (reply.IsMoreData()) { bb.Clear(); if ((ret = m_Parser->ReceiverReady(reply.GetMoreData(), bb)) != 0) { return ret; } if ((ret = ReadDLMSPacket(bb, reply)) != DLMS_ERROR_CODE_OK) { return ret; } } } return DLMS_ERROR_CODE_OK; }
// Returns value of given attribute. int CGXDLMSImageTransfer::GetValue(int index, int selector, CGXDLMSVariant& parameters, CGXDLMSVariant& value) { if (index == 1) { return GetLogicalName(this, value); } if (index == 2) { value = GetImageBlockSize(); return ERROR_CODES_OK; } if (index == 3) { value = m_ImageTransferredBlocksStatus; return ERROR_CODES_OK; } if (index == 4) { value = m_ImageFirstNotTransferredBlockNumber; return ERROR_CODES_OK; } if (index == 5) { value = m_ImageTransferEnabled; return ERROR_CODES_OK; } if (index == 6) { value = m_ImageTransferStatus; return ERROR_CODES_OK; } if (index == 7) { CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(m_ImageActivateInfo.size()); //Count int ret; CGXDLMSVariant size, id, signature; for (std::vector<CGXDLMSImageActivateInfo>::iterator it = m_ImageActivateInfo.begin(); it != m_ImageActivateInfo.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3);//Item count. size = it->GetSize(); id = it->GetIdentification(); signature = (*it).GetSignature(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT32, size)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, id)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, signature)) != 0) { return ret; } } value = data; } return ERROR_CODES_INVALID_PARAMETER; }
/* * Returns value of given attribute. */ int CGXDLMSProfileGeneric::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArgs& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { CGXByteBuffer tmp; tmp.Set(e.GetValue().byteArr, e.GetValue().size); int ret = GetProfileGenericData(e.GetSelector(), e.GetParameters(), tmp); e.SetValue(tmp); return ret; } if (e.GetIndex() == 3) { CGXByteBuffer data; int ret = GetColumns(data); e.SetValue(data); return ret; } if (e.GetIndex() == 4) { e.SetValue(GetCapturePeriod()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 5) { e.SetValue(GetSortMethod()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 5) { return DLMS_ERROR_CODE_INVALID_PARAMETER; } if (e.GetIndex() == 7) { e.SetValue(GetEntriesInUse()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 8) { e.SetValue(GetProfileEntries()); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
CGXDLMSVariant::CGXDLMSVariant(CGXByteBuffer& value) { vt = DLMS_DATA_TYPE_OCTET_STRING; size = value.GetSize(); if (size != 0) { byteArr = (unsigned char*) malloc(size); memcpy(byteArr, value.GetData(), size); } else { byteArr = NULL; } }
// Returns value of given attribute. int CGXDLMSSpecialDaysTable::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { e.SetByteArray(true); CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count GXHelpers::SetObjectCount((unsigned long)m_Entries.size(), data); int ret; CGXDLMSVariant index, date, id; for (std::vector<CGXDLMSSpecialDay*>::iterator it = m_Entries.begin(); it != m_Entries.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); //Count index = (*it)->GetIndex(); date = (*it)->GetDate(); id = (*it)->GetDayId(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, index)) != DLMS_ERROR_CODE_OK || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, date)) != DLMS_ERROR_CODE_OK || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, id)) != DLMS_ERROR_CODE_OK) { return ret; } } e.SetValue(data); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
/** * Find start index and row count using start and end date time. * * @param start * Start time. * @param end * End time * @param index * Start index. * @param count * Item count. */ void GetProfileGenericDataByRange(CGXDLMSValueEventArg* e) { int len, month = 0, day = 0, year = 0, hour = 0, minute = 0, second = 0, value = 0; CGXDLMSVariant start, end; CGXByteBuffer bb; bb.Set(e->GetParameters().Arr[1].byteArr, e->GetParameters().Arr[1].size); CGXDLMSClient::ChangeType(bb, DLMS_DATA_TYPE_DATETIME, start); bb.Clear(); bb.Set(e->GetParameters().Arr[2].byteArr, e->GetParameters().Arr[2].size); CGXDLMSClient::ChangeType(bb, DLMS_DATA_TYPE_DATETIME, end); #if defined(_WIN32) || defined(_WIN64)//Windows FILE* f; _tfopen_s(&f, DATAFILE, _T("r")); #else FILE* f = fopen(DATAFILE, "r"); #endif if (f != NULL) { #if defined(_WIN32) || defined(_WIN64)//Windows while ((len = fscanf_s(f, "%d/%d/%d %d:%d:%d;%d", &month, &day, &year, &hour, &minute, &second, &value)) != -1) #else while ((len = fscanf(f, "%d/%d/%d %d:%d:%d;%d", &month, &day, &year, &hour, &minute, &second, &value)) != -1) #endif { CGXDateTime tm(2000 + year, month, day, hour, minute, second, 0, 0x8000); if (tm.CompareTo(end.dateTime) > 0) { // If all data is read. break; } if (tm.CompareTo(start.dateTime) < 0) { // If we have not find first item. e->SetRowBeginIndex(e->GetRowBeginIndex() + 1); } e->SetRowEndIndex(e->GetRowEndIndex() + 1); } fclose(f); } }
/** * Add new object to the byte buffer. * * @param value * Value to add. */ int CGXDLMSVariant::GetBytes(CGXByteBuffer& value) { if (vt == DLMS_DATA_TYPE_OCTET_STRING) { value.AddRange(byteArr, size); } else if (vt == DLMS_DATA_TYPE_UINT8) { value.SetUInt8(cVal); } else if (vt == DLMS_DATA_TYPE_UINT16) { value.SetUInt16(uiVal); } else if (vt == DLMS_DATA_TYPE_UINT32) { value.SetUInt32(ulVal); } else if (vt == DLMS_DATA_TYPE_UINT64) { value.SetUInt64(ullVal); } else if (vt == DLMS_DATA_TYPE_STRING) { value.AddString(strVal.c_str()); } else { //Invalid object type. return ERROR_CODES_INVALID_PARAMETER; } return 0; }
// Read DLMS Data frame from the device. int CGXCommunication::ReadDLMSPacket(CGXByteBuffer& data, CGXReplyData& reply) { int ret, pos; CGXByteBuffer bb; std::string tmp; if (data.GetSize() == 0) { return DLMS_ERROR_CODE_OK; } Now(tmp); tmp = "TX: " + tmp; tmp += "\t" + data.ToHexString(); if (m_Trace > GX_TRACE_LEVEL_INFO) { printf("%s\r\n", tmp.c_str()); } GXHelpers::Write("trace.txt", tmp + "\r\n"); int len = data.GetSize(); //Send data. for (pos = 0; pos != data.GetSize(); ++pos) { pc.putc(data.GetData()[pos]); } // Loop until whole DLMS packet is received. tmp = ""; do { if (Read(0x7E, bb) != 0) { return DLMS_ERROR_CODE_SEND_FAILED; } if (tmp.size() == 0) { Now(tmp); tmp = "RX: " + tmp + "\t"; } else { tmp += " "; } tmp += bb.ToHexString(); } while ((ret = m_Parser->GetData(bb, reply)) == DLMS_ERROR_CODE_FALSE); tmp += "\r\n"; if (m_Trace > GX_TRACE_LEVEL_INFO) { printf("%s", tmp.c_str()); } GXHelpers::Write("trace.txt", tmp); if (ret == DLMS_ERROR_CODE_REJECTED) { ret = ReadDLMSPacket(data, reply); } return ret; }
int CGXCommunication::Read(unsigned char eop, CGXByteBuffer& reply) { bool bFound = false; int pos, lastReadIndex = 0; do { reply.SetUInt8(pc.getc()); if (reply.GetSize() > 5) { //Some optical strobes can return extra bytes. for (pos = reply.GetSize() - 1; pos != lastReadIndex; --pos) { if (reply.GetData()[pos] == eop) { bFound = true; break; } } lastReadIndex = pos; } } while (!bFound); return DLMS_ERROR_CODE_OK; }
DLMS_SOURCE_DIAGNOSTIC CGXDLMSBase::ValidateAuthentication( DLMS_AUTHENTICATION authentication, CGXByteBuffer& password) { if (authentication == DLMS_AUTHENTICATION_NONE) { //Uncomment this if authentication is always required. //return DLMS_SOURCE_DIAGNOSTIC_AUTHENTICATION_MECHANISM_NAME_REQUIRED; } if (authentication == DLMS_AUTHENTICATION_LOW) { CGXByteBuffer expected; std::string name = "0.0.40.0.0.255"; if (GetUseLogicalNameReferencing()) { CGXDLMSAssociationLogicalName* ln = (CGXDLMSAssociationLogicalName*)GetItems().FindByLN( DLMS_OBJECT_TYPE_ASSOCIATION_LOGICAL_NAME, name); expected = ln->GetSecret(); } else { CGXDLMSAssociationShortName* sn = (CGXDLMSAssociationShortName*)GetItems().FindByLN( DLMS_OBJECT_TYPE_ASSOCIATION_SHORT_NAME, name); expected = sn->GetSecret(); } if (expected.Compare(password.GetData(), password.GetSize())) { return DLMS_SOURCE_DIAGNOSTIC_NONE; } return DLMS_SOURCE_DIAGNOSTIC_AUTHENTICATION_FAILURE; } // Other authentication levels are check on phase two. return DLMS_SOURCE_DIAGNOSTIC_NONE; }
int CGXDLMSProfileGeneric::GetData(std::vector< std::vector<CGXDLMSVariant> >& table, CGXByteBuffer& data) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); GXHelpers::SetObjectCount(table.size(), data); std::vector<DLMS_DATA_TYPE> types; DLMS_DATA_TYPE type; int ret; for (std::vector<std::pair<CGXDLMSObject*, CGXDLMSCaptureObject*> >::iterator it = m_CaptureObjects.begin(); it != m_CaptureObjects.end(); ++it) { if ((ret = (*it).first->GetDataType((*it).second->GetAttributeIndex(), type)) != 0) { return ret; } types.push_back(type); } for (std::vector< std::vector<CGXDLMSVariant> >::iterator row = table.begin(); row != table.end(); ++row) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); GXHelpers::SetObjectCount((*row).size(), data); int pos = -1; for (std::vector<CGXDLMSVariant>::iterator value = (*row).begin(); value != (*row).end(); ++value) { DLMS_DATA_TYPE tp = types[++pos]; if (tp == DLMS_DATA_TYPE_NONE) { tp = value->vt; types[pos] = tp; } if ((ret = GXHelpers::SetData(data, tp, *value)) != 0) { return ret; } } } return DLMS_ERROR_CODE_OK; }
int CGXSecure::GenerateChallenge(DLMS_AUTHENTICATION authentication, CGXByteBuffer& challenge) { // Random challenge is 8 to 64 bytes. // Texas Instruments accepts only 16 byte long challenge. // For this reason challenge size is 16 bytes at the moment. int len = 16; //int len = rand() % 58 + 8; unsigned char val; for (int pos = 0; pos != len; ++pos) { val = rand(); challenge.SetUInt8(val); } return 0; }
// Returns value of given attribute. int CGXDLMSAutoAnswer::GetValue(int index, int selector, CGXDLMSVariant& parameters, CGXDLMSVariant& value) { if (index == 1) { return GetLogicalName(this, value); } if (index == 2) { value = GetMode(); return ERROR_CODES_OK; } if (index == 3) { int ret; int cnt = m_ListeningWindow.size(); CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant f, s; for (std::vector<std::pair<CGXDateTime, CGXDateTime> >::iterator it = m_ListeningWindow.begin(); it != m_ListeningWindow.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); //Count f = it->first; s = it->second; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, f)) != 0 || //start_time (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, s)) != 0) //end_time { return ret; } } value = data; return ERROR_CODES_OK; } if (index == 4) { value = GetStatus(); return ERROR_CODES_OK; } if (index == 5) { value = GetNumberOfCalls(); return ERROR_CODES_OK; } if (index == 6) { CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); GXHelpers::SetObjectCount(2, data); CGXDLMSVariant in = m_NumberOfRingsInListeningWindow; CGXDLMSVariant out = m_NumberOfRingsOutListeningWindow; int ret; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, in)) != ERROR_CODES_OK || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, out)) != ERROR_CODES_OK) { return ret; } value = data; return ERROR_CODES_OK; } return ERROR_CODES_INVALID_PARAMETER; }
// Returns value of given attribute. int CGXDLMSLimiter::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } else if (e.GetIndex() == 2) { int ret; CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); std::string ln; m_MonitoredValue->GetLogicalName(ln); CGXDLMSVariant type = m_MonitoredValue->GetObjectType(); CGXDLMSVariant tmp = ln; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_INT16, type)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp)) != 0) { return ret; } //TODO: GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, m_Monitorede.GetValue().GetSelectedAttributeIndex()); e.SetValue(data); } else if (e.GetIndex() == 3) { e.SetValue(m_ThresholdActive); return DLMS_ERROR_CODE_OK; } else if (e.GetIndex() == 4) { e.SetValue(m_ThresholdNormal); } else if (e.GetIndex() == 5) { e.SetValue(m_ThresholdEmergency); } else if (e.GetIndex() == 6) { e.SetValue(m_MinOverThresholdDuration); } else if (e.GetIndex() == 7) { e.SetValue(m_MinUnderThresholdDuration); } else if (e.GetIndex() == 8) { int ret; CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); CGXDLMSVariant id = m_EmergencyProfile.GetID(); CGXDLMSVariant time = m_EmergencyProfile.GetActivationTime(); CGXDLMSVariant duration = m_EmergencyProfile.GetDuration(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, id)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_DATETIME, time)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT32, duration)) != 0) { return ret; } e.SetValue(data); } else if (e.GetIndex() == 9) { int ret; CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(m_EmergencyProfileGroupIDs.size()); CGXDLMSVariant tmp; for(std::vector<int>::iterator it = m_EmergencyProfileGroupIDs.begin(); it != m_EmergencyProfileGroupIDs.end(); ++it) { tmp = *it; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, tmp)) != 0) { return ret; } } e.SetValue(data); } else if (e.GetIndex() == 10) { e.SetValue(m_EmergencyProfileActive); } else if (e.GetIndex() == 11) { CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); int ret; CGXDLMSVariant ln = m_ActionOverThreshold.GetLogicalName(); CGXDLMSVariant selector = m_ActionOverThreshold.GetScriptSelector(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, ln)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, selector)) != 0) { return ret; } data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); ln = m_ActionUnderThreshold.GetLogicalName(); selector = m_ActionUnderThreshold.GetScriptSelector(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, ln)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, selector)) != 0) { return ret; } e.SetValue(data); } else { return DLMS_ERROR_CODE_INVALID_PARAMETER; } return DLMS_ERROR_CODE_OK; }
/* * Returns value of given attribute. */ int CGXDLMSProfileGeneric::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { CGXByteBuffer tmp; tmp.Set(e.GetValue().byteArr, e.GetValue().size); int ret = GetProfileGenericData(e.GetSelector(), e.GetParameters(), tmp); e.SetValue(tmp); return ret; } if (e.GetIndex() == 3) { CGXByteBuffer data; int ret = GetColumns(data); e.SetValue(data); return ret; } if (e.GetIndex() == 4) { e.SetValue(GetCapturePeriod()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 5) { e.SetValue(GetSortMethod()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 6) { char empty[6] = {0}; CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(4); if (m_SortObject == NULL) { //ClassID data.SetUInt8(DLMS_DATA_TYPE_UINT16); data.SetUInt16(0); //LN data.SetUInt8(DLMS_DATA_TYPE_OCTET_STRING); data.SetUInt8(6); data.Set(empty, 6); //Selected Attribute Index data.SetUInt8(DLMS_DATA_TYPE_INT8); data.SetUInt8(0); //Selected Data Index data.SetUInt8(DLMS_DATA_TYPE_UINT16); data.SetUInt16(0); } else { int ret; CGXDLMSVariant ln; //ClassID data.SetUInt8(DLMS_DATA_TYPE_UINT16); data.SetUInt16(m_SortObject->GetObjectType()); //LN data.SetUInt8(DLMS_DATA_TYPE_OCTET_STRING); data.SetUInt8(6); if ((ret = GetLogicalName(m_SortObject, ln)) != 0) { return ret; } data.Set(&ln.byteArr, 6); //Selected Attribute Index data.SetUInt8(DLMS_DATA_TYPE_INT8); data.SetUInt8(m_SortObjectAttributeIndex); //Selected Data Index data.SetUInt8(DLMS_DATA_TYPE_UINT16); data.SetUInt16(m_SortObjectDataIndex); } e.SetValue(data); } if (e.GetIndex() == 7) { e.SetValue(GetEntriesInUse()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 8) { e.SetValue(GetProfileEntries()); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
// Returns value of given attribute. int CGXDLMSActivityCalendar::GetValue(int index, int selector, CGXDLMSVariant& parameters, CGXDLMSVariant& value) { CGXByteBuffer data; if (index == 1) { return GetLogicalName(this, value); } if (index == 2) { value.Add(&m_CalendarNameActive[0], m_CalendarNameActive.size()); return ERROR_CODES_OK; } if (index == 3) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_SeasonProfileActive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant tmp; for (std::vector<CGXDLMSSeasonProfile>::iterator it = m_SeasonProfileActive.begin(); it != m_SeasonProfileActive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); tmp = it->GetName(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp = it->GetStart(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp.Clear(); tmp.Add((*it).GetWeekName()); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); } value = data; return ERROR_CODES_OK; } if (index == 4) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_WeekProfileTableActive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant tmp; for (std::vector<CGXDLMSWeekProfile>::iterator it = m_WeekProfileTableActive.begin(); it != m_WeekProfileTableActive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(8); tmp = it->GetName(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp = it->GetMonday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetTuesday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetWednesday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetThursday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetFriday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetSaturday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetSunday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); } value = data; return ERROR_CODES_OK; } if (index == 5) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_DayProfileTableActive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); for (std::vector<CGXDLMSDayProfile>::iterator it = m_DayProfileTableActive.begin(); it != m_DayProfileTableActive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); CGXDLMSVariant tmp = it->GetDayId(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count std::vector<CGXDLMSDayProfileAction>& schedules = (*it).GetDaySchedules(); GXHelpers::SetObjectCount(schedules.size(), data); CGXDLMSVariant time, ln, selector; for (std::vector<CGXDLMSDayProfileAction>::iterator action = schedules.begin(); action != schedules.end(); ++action) { time = action->GetStartTime(); ln = action->GetScriptLogicalName(); selector = action->GetScriptSelector(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, time); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, ln); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, selector); } } value = data; return ERROR_CODES_OK; } if (index == 6) { value.Add(m_CalendarNamePassive); return ERROR_CODES_OK; } // if (index == 7) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_SeasonProfilePassive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant tmp; for (std::vector<CGXDLMSSeasonProfile>::iterator it = m_SeasonProfilePassive.begin(); it != m_SeasonProfilePassive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); tmp = it->GetName(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp = it->GetStart(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp = it->GetWeekName(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); } value = data; return ERROR_CODES_OK; } if (index == 8) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_WeekProfileTablePassive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant tmp; for (std::vector<CGXDLMSWeekProfile>::iterator it = m_WeekProfileTablePassive.begin(); it != m_WeekProfileTablePassive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(8); tmp = it->GetName(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, tmp); tmp = it->GetMonday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetTuesday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetWednesday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetThursday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetFriday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetSaturday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); tmp = it->GetSunday(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, tmp); } value = data; return ERROR_CODES_OK; } if (index == 9) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int cnt = m_DayProfileTablePassive.size(); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant id, time, ln, selector; for (std::vector<CGXDLMSDayProfile>::iterator it = m_DayProfileTablePassive.begin(); it != m_DayProfileTablePassive.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); id = it->GetDayId(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, id); data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count GXHelpers::SetObjectCount((*it).GetDaySchedules().size(), data); for (std::vector<CGXDLMSDayProfileAction>::iterator action = (*it).GetDaySchedules().begin(); action != (*it).GetDaySchedules().end(); ++action) { time = action->GetStartTime(); ln = action->GetScriptLogicalName(); selector = action->GetScriptSelector(); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, time); GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, ln); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT16, selector); } } value = data; return ERROR_CODES_OK; } if (index == 10) { value = GetTime(); return ERROR_CODES_OK; } return ERROR_CODES_INVALID_PARAMETER; }
// Returns value of given attribute. int CGXDLMSPppSetup::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { CGXByteBuffer data; if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { e.SetValue(m_PHYReference); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 3) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(m_LCPOptions.size()); CGXDLMSVariant type, len; for(std::vector<CGXDLMSPppSetupLcpOption>::iterator it = m_LCPOptions.begin(); it != m_LCPOptions.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); type = it->GetType(); len = it->GetLength(); CGXDLMSVariant tmp = it->GetData(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, type); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, len); GXHelpers::SetData(data, it->GetData().vt, tmp); } e.SetValue(data); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 4) { data.SetUInt8(DLMS_DATA_TYPE_ARRAY); data.SetUInt8(m_IPCPOptions.size()); CGXDLMSVariant type, len; for(std::vector<CGXDLMSPppSetupIPCPOption>::iterator it = m_IPCPOptions.begin(); it != m_IPCPOptions.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(3); type = it->GetType(); len = it->GetLength(); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, type); GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, len); GXHelpers::SetData(data, it->GetData().vt, it->m_Data); } e.SetValue(data); return DLMS_ERROR_CODE_OK; } else if (e.GetIndex() == 5) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); //Add username. data.SetUInt8(DLMS_DATA_TYPE_OCTET_STRING); data.SetUInt8(m_UserName.GetSize()); data.Set(&m_UserName, 0, -1); //Add password. data.SetUInt8(DLMS_DATA_TYPE_OCTET_STRING); data.SetUInt8(m_Password.GetSize()); data.Set(&m_Password, 0, -1); e.SetValue(data); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
// Returns value of given attribute. int CGXDLMSAutoAnswer::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { e.SetValue(GetMode()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 3) { e.SetByteArray(true); int ret; unsigned long cnt = (unsigned long)m_ListeningWindow.size(); CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); //Add count GXHelpers::SetObjectCount(cnt, data); CGXDLMSVariant f, s; for (std::vector<std::pair<CGXDateTime, CGXDateTime> >::iterator it = m_ListeningWindow.begin(); it != m_ListeningWindow.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); //Count f = it->first; s = it->second; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, f)) != 0 || //start_time (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, s)) != 0) //end_time { return ret; } } e.SetValue(data); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 4) { e.SetValue(GetStatus()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 5) { e.SetValue(GetNumberOfCalls()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 6) { e.SetByteArray(true); CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); GXHelpers::SetObjectCount(2, data); CGXDLMSVariant in = m_NumberOfRingsInListeningWindow; CGXDLMSVariant out = m_NumberOfRingsOutListeningWindow; int ret; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, in)) != DLMS_ERROR_CODE_OK || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, out)) != DLMS_ERROR_CODE_OK) { return ret; } e.SetValue(data); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
// Returns value of given attribute. int CGXDLMSGPRSSetup::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { e.SetValue(m_APN); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 3) { e.SetValue(m_PINCode); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 4) { CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(5); int ret; CGXDLMSVariant precedence = m_DefaultQualityOfService.GetPrecedence(); CGXDLMSVariant delay = m_DefaultQualityOfService.GetDelay(); CGXDLMSVariant reliability = m_DefaultQualityOfService.GetReliability(); CGXDLMSVariant peak = m_DefaultQualityOfService.GetPeakThroughput(); CGXDLMSVariant mean = m_DefaultQualityOfService.GetMeanThroughput(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, precedence)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, delay)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, reliability)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, peak)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, mean)) != 0) { return ret; } data.SetUInt8(5); precedence = m_RequestedQualityOfService.GetPrecedence(); delay = m_RequestedQualityOfService.GetDelay(); reliability = m_RequestedQualityOfService.GetReliability(); peak = m_RequestedQualityOfService.GetPeakThroughput(); mean = m_RequestedQualityOfService.GetMeanThroughput(); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, precedence)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, delay)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, reliability)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, peak)) != 0 || (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_UINT8, mean)) != 0) { return ret; } e.SetValue(data); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }
void ListenerThread(void* pVoid) { CGXByteBuffer reply; CGXDLMSBase* server = (CGXDLMSBase*)pVoid; sockaddr_in add = { 0 }; int ret; char tmp[10]; CGXByteBuffer bb; bb.Capacity(2048); #if defined(_WIN32) || defined(_WIN64)//If Windows int len; int AddrLen = sizeof(add); SOCKET socket; #else //If Linux socklen_t len; socklen_t AddrLen = sizeof(add); int socket; #endif struct sockaddr_in client; memset(&client, 0, sizeof(client)); //Get buffer data basic_string<char> senderInfo; while (server->IsConnected()) { len = sizeof(client); senderInfo.clear(); socket = accept(server->GetSocket(), (struct sockaddr*)&client, &len); server->Reset(); if (server->IsConnected()) { server->Reset(); if ((ret = getpeername(socket, (sockaddr*)&add, &AddrLen)) == -1) { closesocket(socket); #if defined(_WIN32) || defined(_WIN64)//If Windows socket = INVALID_SOCKET; #else //If Linux socket = -1; #endif continue; //Notify error. } senderInfo = inet_ntoa(add.sin_addr); senderInfo.append(":"); #if _MSC_VER > 1000 _ltoa_s(add.sin_port, tmp, 10, 10); #else sprintf(tmp, "%d", add.sin_port); #endif senderInfo.append(tmp); while (server->IsConnected()) { //If client is left wait for next client. if ((ret = recv(socket, (char*) bb.GetData() + bb.GetSize(), bb.Capacity() - bb.GetSize(), 0)) == -1) { //Notify error. server->Reset(); #if defined(_WIN32) || defined(_WIN64)//If Windows closesocket(socket); socket = INVALID_SOCKET; #else //If Linux close(socket); socket = -1; #endif break; } //If client is closed the connection. if (ret == 0) { server->Reset(); #if defined(_WIN32) || defined(_WIN64)//If Windows closesocket(socket); socket = INVALID_SOCKET; #else //If Linux close(socket); socket = -1; #endif break; } bb.SetSize(bb.GetSize() + ret); if (server->m_Trace == GX_TRACE_LEVEL_VERBOSE) { printf("RX:\t%s\r\n", bb.ToHexString().c_str()); } if (server->HandleRequest(bb, reply) != 0) { #if defined(_WIN32) || defined(_WIN64)//If Windows closesocket(socket); socket = INVALID_SOCKET; #else //If Linux close(socket); socket = -1; #endif } bb.SetSize(0); if (reply.GetSize() != 0) { if (server->m_Trace == GX_TRACE_LEVEL_VERBOSE) { printf("TX:\t%s\r\n", reply.ToHexString().c_str()); } if (send(socket, (const char*)reply.GetData(), reply.GetSize() - reply.GetPosition(), 0) == -1) { //If error has occured server->Reset(); #if defined(_WIN32) || defined(_WIN64)//If Windows closesocket(socket); socket = INVALID_SOCKET; #else //If Linux close(socket); socket = -1; #endif } reply.Clear(); } } server->Reset(); } } }
/** * Chipher text. * * @param auth * Authentication level. * @param data * Text to chipher. * @param secret * Secret. * @return Chiphered text. */ int CGXSecure::Secure( CGXDLMSSettings& settings, CGXCipher* cipher, unsigned long ic, CGXByteBuffer& data, CGXByteBuffer& secret, CGXByteBuffer& reply) { int ret = 0, pos; reply.Clear(); if (settings.GetAuthentication() == DLMS_AUTHENTICATION_HIGH) { CGXByteBuffer s; int len = data.GetSize(); if (len % 16 != 0) { len += (16 - (data.GetSize() % 16)); } if (secret.GetSize() > data.GetSize()) { len = secret.GetSize(); if (len % 16 != 0) { len += (16 - (secret.GetSize() % 16)); } } s.Set(&secret); s.Zero(s.GetSize(), len - s.GetSize()); reply.Set(&data); reply.Zero(reply.GetSize(), len - reply.GetSize()); for (pos = 0; pos < len / 16; ++pos) { CGXCipher::Aes1Encrypt(reply, pos * 16, s); } return 0; } // Get server Challenge. CGXByteBuffer challenge; // Get shared secret if (settings.GetAuthentication() != DLMS_AUTHENTICATION_HIGH_GMAC) { challenge.Set(&data); challenge.Set(&secret); } if (settings.GetAuthentication() == DLMS_AUTHENTICATION_HIGH_MD5) { return CGXDLMSMD5::Encrypt(challenge, reply); } else if (settings.GetAuthentication() == DLMS_AUTHENTICATION_HIGH_SHA1) { return CGXDLMSSha1::Encrypt(challenge, reply); } else if (settings.GetAuthentication() == DLMS_AUTHENTICATION_HIGH_SHA256) { return CGXDLMSSha256::Encrypt(challenge, reply); } else if (settings.GetAuthentication() == DLMS_AUTHENTICATION_HIGH_GMAC) { CGXByteBuffer tmp; CGXByteBuffer& key = settings.GetCipher()->GetBlockCipherKey(); ret = cipher->Encrypt(DLMS_SECURITY_AUTHENTICATION, DLMS_COUNT_TYPE_TAG, ic, 0, secret, key, data, tmp); if (ret == 0) { reply.SetUInt8(DLMS_SECURITY_AUTHENTICATION); reply.SetUInt32(ic); reply.Set(&tmp); } } return ret; }
// Returns value of given attribute. int CGXDLMSAutoConnect::GetValue(CGXDLMSSettings& settings, CGXDLMSValueEventArg& e) { if (e.GetIndex() == 1) { int ret; CGXDLMSVariant tmp; if ((ret = GetLogicalName(this, tmp)) != 0) { return ret; } e.SetValue(tmp); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 2) { e.SetValue((unsigned char) GetMode()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 3) { e.SetValue(GetRepetitions()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 4) { e.SetValue(GetRepetitionDelay()); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 5) { int cnt = m_CallingWindow.size(); CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int ret; //Add count GXHelpers::SetObjectCount(cnt, data); if (cnt != 0) { CGXDLMSVariant s, e; for (std::vector<std::pair< CGXDateTime, CGXDateTime> >::iterator it = m_CallingWindow.begin(); it != m_CallingWindow.end(); ++it) { data.SetUInt8(DLMS_DATA_TYPE_STRUCTURE); data.SetUInt8(2); //Count s = it->first; e = it->second; if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, s)) != 0 || //start_time (ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, e)) != 0) //end_time { return ret; } } } e.SetValue(data); return DLMS_ERROR_CODE_OK; } if (e.GetIndex() == 6) { CGXByteBuffer data; data.SetUInt8(DLMS_DATA_TYPE_ARRAY); int ret; int cnt = m_Destinations.size(); //Add count GXHelpers::SetObjectCount(cnt, data); for (std::vector< std::string >::iterator it = m_Destinations.begin(); it != m_Destinations.end(); ++it) { CGXDLMSVariant value; e.GetValue().Add(&(*it)[0], it->size()); if ((ret = GXHelpers::SetData(data, DLMS_DATA_TYPE_OCTET_STRING, value)) != 0) //destination { return ret; } } e.SetValue(data); return DLMS_ERROR_CODE_OK; } return DLMS_ERROR_CODE_INVALID_PARAMETER; }