Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbourelly999 committed Jul 3, 2024
1 parent b09b90a commit 54dfc3a
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 82 deletions.
51 changes: 35 additions & 16 deletions src/tmx/TmxUtils/src/SNMPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,28 +165,47 @@ namespace tmx::utils
PLOG(logINFO) << "Response request status: " << status << " (=" << (status == STAT_SUCCESS ? "SUCCESS" : "FAILED") << ")";

// Check GET response
if (status == STAT_SUCCESS && response && response->errstat == SNMP_ERR_NOERROR && request_type == request_type::GET)
if (status == STAT_SUCCESS && response && response->errstat == SNMP_ERR_NOERROR )
{
for (auto vars = response->variables; vars; vars = vars->next_variable)
{
// Get value of variable depending on ASN.1 type
// Variable could be a integer, string, bitstring, ojbid, counter : defined here https://github.com/net-snmp/net-snmp/blob/master/include/net-snmp/types.h
// get Integer value
if (vars->type == ASN_INTEGER && vars->val.integer)
{
val.type = snmp_response_obj::response_type::INTEGER;
val.val_int = *vars->val.integer;
}
else if (vars->type == ASN_OCTET_STR && vars->val.string)
if ( request_type == request_type::GET ) {
for (auto vars = response->variables; vars; vars = vars->next_variable)
{
size_t str_len = vars->val_len;
for (size_t i = 0; i < str_len; ++i)
// Get value of variable depending on ASN.1 type
// Variable could be a integer, string, bitstring, ojbid, counter : defined here https://github.com/net-snmp/net-snmp/blob/master/include/net-snmp/types.h
// get Integer value
if (vars->type == ASN_INTEGER && vars->val.integer)
{
val.val_string.push_back(vars->val.string[i]);
val.type = snmp_response_obj::response_type::INTEGER;
val.val_int = *vars->val.integer;
}
else if (vars->type == ASN_OCTET_STR && vars->val.string)
{
size_t str_len = vars->val_len;
for (size_t i = 0; i < str_len; ++i)
{
val.val_string.push_back(vars->val.string[i]);
}
val.type = snmp_response_obj::response_type::STRING;
}
val.type = snmp_response_obj::response_type::STRING;
}
}
else if( request_type == request_type::SET){

if(val.type == snmp_response_obj::response_type::INTEGER){
FILE_LOG(logDEBUG) << "Success in SET for OID: " << input_oid << " Value: " << val.val_int << std::endl;
}

else if(val.type == snmp_response_obj::response_type::STRING){
FILE_LOG(logDEBUG) << "Success in SET for OID: " << input_oid << " Value:" << std::endl;
for(auto data : val.val_string){
FILE_LOG(logDEBUG) << data ;
}
}
}
else {
log_error(status, request_type, response);
return false;
}
}
else
{
Expand Down
13 changes: 2 additions & 11 deletions src/v2i-hub/SpatPlugin/src/NTCIP1202.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ void Ntcip1202::setSignalGroupMappingList(string json)

void Ntcip1202::copyBytesIntoNtcip1202(char* buff, int numBytes)
{
std::lock_guard<std::mutex> lock(_spat_lock);

std::memcpy(&ntcip1202Data, buff, numBytes);

Expand Down Expand Up @@ -199,7 +198,7 @@ void Ntcip1202::printDebug()
}
}

bool Ntcip1202::ToJ2735r41SPAT(SPAT* spat, unsigned long msEpoch , const std::string &intersectionName, IntersectionID_t intersectionId)
void Ntcip1202::ToJ2735SPAT(SPAT* spat, unsigned long msEpoch , const std::string &intersectionName, IntersectionID_t intersectionId)
{
time_t epochSec = msEpoch/1000;
struct tm utctime;
Expand All @@ -213,8 +212,6 @@ bool Ntcip1202::ToJ2735r41SPAT(SPAT* spat, unsigned long msEpoch , const std::st
auto epochMs = msEpoch;
long msOfMin = 1000 * (epochSec % 60) + (epochMs % 1000);

std::lock_guard<std::mutex> lock(_spat_lock);

ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SPAT, spat);

#if SAEJ2735_SPEC < 63
Expand Down Expand Up @@ -303,9 +300,6 @@ bool Ntcip1202::ToJ2735r41SPAT(SPAT* spat, unsigned long msEpoch , const std::st

}
ASN_SEQUENCE_ADD(&(spat->intersections.list), intersection);


return true;
}

void Ntcip1202::populateVehicleSignalGroup(MovementState *movement, int phase, unsigned long msEpoch)
Expand All @@ -317,10 +311,7 @@ void Ntcip1202::populateVehicleSignalGroup(MovementState *movement, int phase, u

if(getPhaseRedStatus(phase))
{
PLOG(logDEBUG3) << "Phase " << phase <<
" Red " << getPhaseRedStatus(phase) <<
", isFlashing " << isFlashing <<
", forceFlashing " << forceFlashing ;
PLOG(logDEBUG3) << "Phase " << phase << " Red " << getPhaseRedStatus(phase) << ", isFlashing " << isFlashing << ", forceFlashing " << forceFlashing ;
if(isFlashing)
stateTimeSpeed->eventState = MovementPhaseState_stop_Then_Proceed;
else
Expand Down
3 changes: 1 addition & 2 deletions src/v2i-hub/SpatPlugin/src/NTCIP1202.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,14 @@ class Ntcip1202
bool isFlashingStatus();
bool isPhaseFlashing();

bool ToJ2735r41SPAT(SPAT* spat, unsigned long msEpoch , const std::string &intersectionName, IntersectionID_t intersectionId);
void ToJ2735SPAT(SPAT* spat, unsigned long msEpoch , const std::string &intersectionName, IntersectionID_t intersectionId);

void printDebug();
private:

Ntcip1202Ext ntcip1202Data;
std::map<uint8_t, int> _phaseToIndexMapping;

std::mutex _spat_lock;

list<SignalGroupMapping> signalGroupMappingList;

Expand Down
25 changes: 17 additions & 8 deletions src/v2i-hub/SpatPlugin/src/SignalControllerConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,31 @@

namespace SpatPlugin {

SignalControllerConnection::SignalControllerConnection(const std::string &localIp, unsigned int localPort, const std::string &signalGroupMapping, const std::string &scIp, unsigned int scSNMPPort, const std::string &intersectionName, unsigned int intersectionId) : spatPacketReceiver(std::make_unique<tmx::utils::UdpServer>(localIp, localPort)) ,scSNMPClient(std::make_unique<tmx::utils::snmp_client>(scIp, scSNMPPort ,"", "", "", "")), signalGroupMapping(signalGroupMapping), intersectionName(intersectionName), intersectionId(intersectionId) {
SignalControllerConnection::SignalControllerConnection(const std::string &localIp, unsigned int localPort, const std::string &signalGroupMapping, const std::string &scIp, unsigned int scSNMPPort, const std::string &intersectionName, unsigned int intersectionId) : spatPacketReceiver(std::make_unique<tmx::utils::UdpServer>(localIp, localPort)) ,scSNMPClient(std::make_unique<tmx::utils::snmp_client>(scIp, scSNMPPort ,"administrator", "", "", "")), signalGroupMapping(signalGroupMapping), intersectionName(intersectionName), intersectionId(intersectionId) {

};

tmx::messages::SpatEncodedMessage SignalControllerConnection::receiveSPAT(uint64_t timeMs , const SPAT_MODE &spatMode) {

bool SignalControllerConnection::initializeSignalControllerConnection() {
tmx::utils::snmp_response_obj resp;
resp.val_int = 2;
return scSNMPClient->process_snmp_request("1.3.6.1.4.1.1206.3.5.2.9.44.1.0", tmx::utils::request_type::SET, resp);
};
tmx::messages::SpatEncodedMessage SignalControllerConnection::receiveSPAT(uint64_t timeMs, const SPAT_MODE &spatMode)
{
if ( spatMode == SPAT_MODE::BINARY ) {
FILE_LOG(tmx::utils::logDEBUG) << "Receiving binary SPAT..." << std::endl;
char buf[1000];
auto numBytes = spatPacketReceiver->TimedReceive(buf, 1000, 3);
auto numBytes = spatPacketReceiver->TimedReceive(buf, 1000, 1000);
auto ntcip1202 = std::make_unique<Ntcip1202>();

if ( numBytes > 0 ) {
// TODO: Revist this implementation. See if we can make SPAT a shared pointer
// and skipe the SPAT to SpatMessage conversion.
ntcip1202->copyBytesIntoNtcip1202(buf, numBytes);
SPAT *_spat = (SPAT *) calloc(1, sizeof(SPAT));
ntcip1202->ToJ2735r41SPAT(_spat,timeMs, intersectionName, intersectionId);
if ( tmx::utils::FILELog::ReportingLevel() == tmx::utils::logDEBUG) {
xer_fprint(stdout, &asn_DEF_SPAT, _spat);
}
ntcip1202->ToJ2735SPAT(_spat,timeMs, intersectionName, intersectionId);
auto _spatMessage = std::make_unique<tmx::messages::SpatMessage>(_spat);
tmx::messages::MessageFrameMessage frame(_spatMessage->get_j2735_data());
tmx::messages::SpatEncodedMessage spatEncodedMsg;
Expand All @@ -31,6 +39,8 @@ namespace SpatPlugin {
}
}
else {
FILE_LOG(tmx::utils::logDEBUG) << "Receiving J2725 HEX SPAT ..." << std::endl;

tmx::messages::SpatEncodedMessage spatEncodedMsg;
tmx::byte_stream buf(4000);
int numBytes = spatPacketReceiver->TimedReceive((char *)buf.data(), buf.size(), 3);
Expand All @@ -42,7 +52,6 @@ namespace SpatPlugin {
else {
throw std::runtime_error("Something went wrong");
}
}
}
}

}
4 changes: 2 additions & 2 deletions src/v2i-hub/SpatPlugin/src/SignalControllerConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <SNMPClient.h>
#include <tmx/j2735_messages/SpatMessage.hpp>
#include "NTCIP1202.h"
#include <PluginLog.h>

namespace SpatPlugin {
enum class SPAT_MODE
Expand All @@ -23,11 +24,10 @@ namespace SpatPlugin {
std::string signalGroupMapping;
std::string intersectionName;
unsigned int intersectionId;
void initializeSignalControllerConnection();

public:
SignalControllerConnection(const std::string &localIp, unsigned int localPort, const std::string &signalGroupMapping, const std::string &scIp, unsigned int scSNMPPort, const std::string &intersectionName, unsigned int intersectionID);

bool initializeSignalControllerConnection();
tmx::messages::SpatEncodedMessage receiveSPAT(uint64_t timeMs , const SPAT_MODE &spat_mode = SPAT_MODE::BINARY);

};
Expand Down
23 changes: 18 additions & 5 deletions src/v2i-hub/SpatPlugin/src/SpatPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ using namespace tmx::utils;
namespace SpatPlugin {

SpatPlugin::SpatPlugin(string name) :PluginClientClockAware(name) {
spatReceiverThread = std::make_unique<tmx::utils::ThreadTimer>(std::chrono::milliseconds(5));

if ( PluginClientClockAware::isSimulationMode() ) {
SubscribeToMessages();
}
Expand Down Expand Up @@ -40,21 +42,32 @@ namespace SpatPlugin {
else {
scConnection = std::make_unique<SignalControllerConnection>(ip_address, port, signalGroupMappingJson, scIp, scSNMPPort, intersectionName, intersectionId);
}
spatReceiverThread->AddPeriodicTick([this]() {
this->processSpat();
auto connected = scConnection->initializeSignalControllerConnection();
if ( connected ) {
SetStatus(keyConnectionStatus, "IDLE");

spatReceiverThread->AddPeriodicTick([this]()
{
this->processSpat();
}, // end of lambda expression
std::chrono::milliseconds(5));
spatReceiverThread->Start();
}
else {

} // end of lambda expression
, std::chrono::milliseconds(5) );
spatReceiverThread->Start();
}
}
}

void SpatPlugin::processSpat() {
if (this->scConnection ) {
PLOG(tmx::utils::logDEBUG) << "Processing SPAT ... " << std::endl;
auto spatMessage = scConnection->receiveSPAT(PluginClientClockAware::getClock()->nowInMilliseconds());
spatMessage.set_flags(IvpMsgFlags_RouteDSRC);
spatMessage.addDsrcMetadata(0x8002);
BroadcastMessage(static_cast<routeable_message &>(spatMessage));
SetStatus(keyConnectionStatus, "CONNECTED");

}
}
void SpatPlugin::OnConfigChanged(const char *key, const char *value) {
Expand Down
3 changes: 3 additions & 0 deletions src/v2i-hub/SpatPlugin/src/SpatPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class SpatPlugin: public tmx::utils::PluginClientClockAware {

std::unique_ptr<SignalControllerConnection> scConnection;

const char* keyConnectionStatus = "Connection Status";


void processSpat();
};
} /* namespace SpatPlugin */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,8 @@ using namespace fwha_stol::lib::time;

TEST(NTCIP1202Test, copyBytesIntoNtcip1202)
{
DescriptiveName_t *update_to_intersection_name = (DescriptiveName_t *)calloc(1, sizeof(DescriptiveName_t));
char *my_string = (char*) "test intersection name";
stringstream ss;
update_to_intersection_name->buf = reinterpret_cast<uint8_t *>(my_string);
ss << update_to_intersection_name->buf;
ASSERT_EQ(ss.str(), "test intersection name");
uint64_t tsMsec = 1677775434400;

IntersectionReferenceID_t *update_to_intersection_id = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t));
update_to_intersection_id->id = 9012;

auto clock = std::make_shared<CarmaClock>();
clock->wait_for_initialization();
auto ntcip1202_p = std::make_shared<Ntcip1202>();
unsigned int raw_data[] = {4294967245, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 118, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4294967208, 0, 4294967208, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 118, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4294967208, 0, 4294967208, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294967295, 4294967261, 0, 0, 0, 34, 4294967295, 4294967295, 0, 0, 0, 0, 4294967295, 4294967295, 0, 0, 0, 0, 0, 0, 0, 0, 4294967168, 0, 8, 103, 1, 10, 4294967237, 0, 0};
int numBytes = sizeof(raw_data)/sizeof(unsigned int);
Expand All @@ -32,52 +22,39 @@ TEST(NTCIP1202Test, copyBytesIntoNtcip1202)
ntcip1202_p->copyBytesIntoNtcip1202(buf, numBytes);

SPAT *spat_ptr = (SPAT *)calloc(1, sizeof(SPAT));
ntcip1202_p->ToJ2735r41SPAT(spat_ptr,clock->nowInMilliseconds(), "test intersection name", update_to_intersection_id->id);
ntcip1202_p->ToJ2735SPAT(spat_ptr,tsMsec, "test intersection name", 9012);
xer_fprint(stdout, &asn_DEF_SPAT, spat_ptr);

ASSERT_EQ(3, spat_ptr->intersections.list.array[0]->states.list.array[0]->state_time_speed.list.array[0]->eventState);

free(spat_ptr);
}

TEST(NTCIP1202Test, ToJ2735r41SPAT)
TEST(NTCIP1202Test, ToJ2735SPAT)
{
auto clock = std::make_shared<CarmaClock>();
clock->wait_for_initialization();
uint64_t tsMsec = 1677775434400;

auto ntcip1202_p = std::make_shared<Ntcip1202>();
SPAT *spat_ptr = (SPAT *)calloc(1, sizeof(SPAT));

char *my_string = (char*)"test intersection name";
stringstream ss;

DescriptiveName_t *update_to_intersection_name = (DescriptiveName_t *)calloc(1, sizeof(DescriptiveName_t));
update_to_intersection_name->buf = reinterpret_cast<uint8_t *>(my_string);
ss << update_to_intersection_name->buf;
ASSERT_EQ(ss.str(), "test intersection name");

IntersectionReferenceID_t *update_to_intersection_id = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t));
update_to_intersection_id->id = 9012;


bool transform_status = ntcip1202_p->ToJ2735r41SPAT(spat_ptr, clock->nowInMilliseconds(), reinterpret_cast<char *>(update_to_intersection_name->buf), update_to_intersection_id->id);
ntcip1202_p->ToJ2735SPAT(spat_ptr, tsMsec, "test intersection name", 9012);
auto _spatMessage = std::make_shared<tmx::messages::SpatMessage>(spat_ptr);
auto spat = _spatMessage->get_j2735_data();
ASSERT_EQ(transform_status, true);
}

TEST(NTCIP1202Test, TestAdjustedTime)
{
auto clock = std::make_shared<CarmaClock>(true);
// 1677775434 = 2023-02-03 16:43:54
timeStampMilliseconds tsMsec = ((uint64_t)1677775434 * 1000) + 400;
// 1677775434400 = 2023-02-03 16:43:54.400
uint64_t tsMsec = 1677775434400;
auto baseTenthsOfSeconds = 43 * 600 + 54 * 10 + 4;
clock->update(tsMsec);
auto ntcip1202_p = std::make_shared<Ntcip1202>();
auto result = ntcip1202_p->getAdjustedTime(0, clock->nowInMilliseconds());
auto result = ntcip1202_p->getAdjustedTime(0, tsMsec);
EXPECT_EQ(baseTenthsOfSeconds, result);
result = ntcip1202_p->getAdjustedTime(46, clock->nowInMilliseconds());
result = ntcip1202_p->getAdjustedTime(46, tsMsec);
EXPECT_EQ(baseTenthsOfSeconds + 46, result);
// cross minute boundary
result = ntcip1202_p->getAdjustedTime(200, clock->nowInMilliseconds());
result = ntcip1202_p->getAdjustedTime(200, tsMsec);
EXPECT_EQ(baseTenthsOfSeconds + 200, result);
// cross hour boundary
result = ntcip1202_p->getAdjustedTime(10200, clock->nowInMilliseconds());
result = ntcip1202_p->getAdjustedTime(10200, tsMsec);
EXPECT_EQ((baseTenthsOfSeconds + 10200) % 36000, result);
}
Empty file.

0 comments on commit 54dfc3a

Please sign in to comment.