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; }
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; }
/** * 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); } }
/** * 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; }
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(); } } }