From 248f6c56e17a0896ddbdaa2c81fa436e1a4c5b9a Mon Sep 17 00:00:00 2001 From: SaikrishnaBairamoni Date: Wed, 12 Apr 2023 17:07:58 -0400 Subject: [PATCH 01/15] update docker-compose to point k900 images --- configuration/amd64/docker-compose.yml | 6 +++--- configuration/arm64/docker-compose.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configuration/amd64/docker-compose.yml b/configuration/amd64/docker-compose.yml index 995c28958..ffafacc38 100755 --- a/configuration/amd64/docker-compose.yml +++ b/configuration/amd64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php:7.4.0 + image: usdotfhwaops/php:k900 container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubamd:latest + image: usdotfhwaops/v2xhubamd:k900 container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice:7.4.0 + image: usdotfhwaops/port-drayage-webservice:k900 container_name: port_drayage_webservice network_mode: host secrets: diff --git a/configuration/arm64/docker-compose.yml b/configuration/arm64/docker-compose.yml index d77dc6055..38c3359c6 100644 --- a/configuration/arm64/docker-compose.yml +++ b/configuration/arm64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php_arm:7.4.0 + image: usdotfhwaops/php_arm:k900 container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubarm:latest + image: usdotfhwaops/v2xhubarm:k900 container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice_arm:7.4.0 + image: usdotfhwaops/port-drayage-webservice_arm:k900 container_name: port_drayage_webservice network_mode: host secrets: From e86a930facf8b65e2265780b3124ab1956788594 Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Mon, 17 Apr 2023 12:33:23 -0400 Subject: [PATCH 02/15] Active ERV status update (#520) # PR Details ## Description The ERV should be considered activated when all three of these, emergency response type, sirens are active, and lights are active. ## Related Issue https://github.com/usdot-fhwa-OPS/V2X-Hub/issues/517 ## Motivation and Context ERV use case ## How Has This Been Tested? NA ## Types of changes - [x] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- .../src/ERVCloudForwardingWorker.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp index 46dd4934e..0ecfbd1db 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp @@ -20,9 +20,9 @@ namespace ERVCloudForwardingPlugin return xml_str; } std::stringstream route_ss; - //Add vehicle current position to the BSMRequest route point + // Add vehicle current position to the BSMRequest route point route_ss << "" << bsmPtr->coreData.lat << "" - << "" << bsmPtr->coreData.Long << ""; + << "" << bsmPtr->coreData.Long << ""; // If there is carma related regional extension value that contains the ERV route points, construct the BSM request with the points. auto bsmCarmaRegion = bsmPtr->regional->list.array[0]->regExtValue.choice.BasicSafetyMessage_addGrpCarma; for (int i = 0; i < bsmCarmaRegion.routeDestinationPoints->list.count; i++) @@ -56,20 +56,12 @@ namespace ERVCloudForwardingPlugin else { // The ERV broadcast BSM that has the PartII content, and the specical vehicle extension within the PartII has the emergency response type. - if (bsm_ptr->partII->list.count > 0 && bsm_ptr->partII->list.array[0]->partII_Value.present == BSMpartIIExtension__partII_Value_PR_SpecialVehicleExtensions ) + if (bsm_ptr->partII->list.count > 0 && bsm_ptr->partII->list.array[0]->partII_Value.present == BSMpartIIExtension__partII_Value_PR_SpecialVehicleExtensions) { - if(bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->responseType && *bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->responseType == ResponseType_emergency) + if (bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->responseType && *bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->responseType == ResponseType_emergency && bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->lightsUse == LightbarInUse_inUse && bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->sirenUse == SirenInUse_inUse) { return true; } - if(bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->lightsUse == LightbarInUse_inUse) - { - return true; - } - if(bsm_ptr->partII->list.array[0]->partII_Value.choice.SpecialVehicleExtensions.vehicleAlerts->sirenUse == SirenInUse_inUse) - { - return true; - } } return false; } From 53a3a21101d672dc236909f3228c2bbb641d9158 Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Thu, 20 Apr 2023 00:24:43 -0400 Subject: [PATCH 03/15] Verification Testing: Add v2xhub port number to BSM request (#521) # PR Details ## Description Add v2xhub port number to BSM request The port number helps user to identify which RSU is sending the BSM request to carma-cloud ## Related Issue NA ## Motivation and Context Freight ERV ## How Has This Been Tested? Local integration testing ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- .../src/ERVCloudForwardingPlugin.cpp | 4 ++-- .../src/ERVCloudForwardingWorker.cpp | 4 ++-- .../src/ERVCloudForwardingWorker.h | 2 +- .../test/ERVCloudForwardingWorkerTest.cpp | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp index 0118e76a3..6c1dfb96c 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp @@ -24,7 +24,7 @@ namespace ERVCloudForwardingPlugin if (ERVCloudForwardingWorker::IsBSMFromERV(msg)) { // Construct the ERV BSM and forward it to the cloud. - auto xml_str = ERVCloudForwardingWorker::constructERVBSMRequest(msg); + auto xml_str = ERVCloudForwardingWorker::constructERVBSMRequest(msg, _webPort); PLOG(logINFO) << "Forward ERV BSM to cloud: " << xml_str << endl; CloudSendAsync(xml_str, _CLOUDURL, _CLOUDBSMREQ, _POSTMETHOD); uint64_t delayEnd = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); @@ -193,7 +193,7 @@ namespace ERVCloudForwardingPlugin if (strcmp(local_method.c_str(), "POST") == 0) { curl_easy_setopt(req, CURLOPT_POSTFIELDS, local_msg.c_str()); - curl_easy_setopt(req, CURLOPT_TIMEOUT_MS, 1000L); + curl_easy_setopt(req, CURLOPT_TIMEOUT_MS, 5000L); //Http request timeout in 5 seconds curl_easy_setopt(req, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); res = curl_easy_perform(req); if (res != CURLE_OK) diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp index 0ecfbd1db..fcf06de42 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.cpp @@ -2,7 +2,7 @@ namespace ERVCloudForwardingPlugin { - std::string ERVCloudForwardingWorker::constructERVBSMRequest(BsmMessage &msg) + std::string ERVCloudForwardingWorker::constructERVBSMRequest(BsmMessage &msg, uint16_t v2xhubPort) { char xml_str[20000]; std::string bsmHex = encodeBSMHex(msg); @@ -32,7 +32,7 @@ namespace ERVCloudForwardingPlugin route_ss << "" << latitude << "" << "" << longitude << ""; } - snprintf(xml_str, sizeof(xml_str), "%s%s", bsmHex.c_str(), route_ss.str().c_str()); + snprintf(xml_str, sizeof(xml_str), "%s%d%s", bsmHex.c_str(), v2xhubPort, route_ss.str().c_str()); return xml_str; } diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.h b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.h index b6c0fe546..0d1bcd5ce 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.h +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingWorker.h @@ -36,7 +36,7 @@ namespace ERVCloudForwardingPlugin * @param msg The BSM object * @return The BSM request in XML format */ - static std::string constructERVBSMRequest(BsmMessage &msg); + static std::string constructERVBSMRequest(BsmMessage &msg, uint16_t v2xhubPort); /** * @brief Check whether the BSM is sent from an ERV * @param msg The BSM object diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/test/ERVCloudForwardingWorkerTest.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/test/ERVCloudForwardingWorkerTest.cpp index ecd8e6c49..8e75f1860 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/test/ERVCloudForwardingWorkerTest.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/test/ERVCloudForwardingWorkerTest.cpp @@ -191,14 +191,15 @@ namespace unit_test TEST_F(ERVCloudForwardingWorkerTest, constructERVBSMRequest) { + uint16_t v2xhubPort = 11111; // BSM without partII - string bsmReq = ERVCloudForwardingPlugin::ERVCloudForwardingWorker::constructERVBSMRequest(*_bsmMessage); + string bsmReq = ERVCloudForwardingPlugin::ERVCloudForwardingWorker::constructERVBSMRequest(*_bsmMessage, v2xhubPort); ASSERT_EQ("", bsmReq); // ERV BSM with partII - bsmReq = ERVCloudForwardingPlugin::ERVCloudForwardingWorker::constructERVBSMRequest(*_bsmMessagePartII); + bsmReq = ERVCloudForwardingPlugin::ERVCloudForwardingWorker::constructERVBSMRequest(*_bsmMessagePartII, v2xhubPort); string expectedBSMHex = "00146e604043030280ffdbfba868b3584ec40824646400320032000c888fc834e37fff0aaa960fa0040d082408804278d693a431ad275c7c6b49d9e8d693b60e35a4f0dc6b49deef1ad27a6235a4f16b8d693e2b1ad279afc6b49f928d693d54e35a5007c6b49ee8f1ad2823235a4f93b8"; - string expectedBSMReq = "" + expectedBSMHex + "38954961-7714930312131210122312201233123012431240125312501263126012731270128312"; + string expectedBSMReq = "" + expectedBSMHex + ""+ std::to_string(v2xhubPort)+"38954961-7714930312131210122312201233123012431240125312501263126012731270128312"; ASSERT_EQ(expectedBSMReq, bsmReq); } From 9eb454a0d939b0a71cb37cbb85ee61c2461391d5 Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Thu, 20 Apr 2023 08:44:06 -0400 Subject: [PATCH 04/15] Analysis script for Emergency Response vehicle v2xhub log (#519) # PR Details ## Description Analysis script for Emergency Response vehicle v2xhub log. The script is to extract useful information from the v2xhub log. The information should answer below questions: ![image](https://user-images.githubusercontent.com/62157949/232543415-85571577-9694-4d8d-90de-6b3167cc3370.png) ## Related Issue https://github.com/usdot-fhwa-OPS/V2X-Hub/issues/515 ## Motivation and Context ERV use case ## How Has This Been Tested? NA ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [x] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- scripts/requirements.txt | 1 + scripts/v2xhub_log_analysis_erv.py | 103 ++++++++++++++++++ .../src/ERVCloudForwardingPlugin.cpp | 2 +- 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 scripts/requirements.txt create mode 100644 scripts/v2xhub_log_analysis_erv.py diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 000000000..a717bf139 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1 @@ +openpyxl \ No newline at end of file diff --git a/scripts/v2xhub_log_analysis_erv.py b/scripts/v2xhub_log_analysis_erv.py new file mode 100644 index 000000000..88b9550bb --- /dev/null +++ b/scripts/v2xhub_log_analysis_erv.py @@ -0,0 +1,103 @@ +import sys +import pandas as pd +import xml.etree.ElementTree as ET +import argparse + +''' +Get file names +''' + + +def get_filenames(): + inputfile = '' + outputfile = '' + parser = argparse.ArgumentParser(prog="V2xHub Analysis for ERV BSM") + parser.add_argument('--input', type=str, required=True) + parser.add_argument('--output', type=str, required=True) + args = parser.parse_args() + print(f'Received log file: {args.input}; Result will be saved into file: {args.output}.xlsx') + inputfile = args.input + outputfile = args.output + return (inputfile, outputfile) +''' +Read the input logs file and search the relevant logs. Process the logs and return a dictionary of the relevant information +''' + + +def process_input_log_file(inputfile, search_keyword): + file_stream = open(inputfile, 'r') + fields_dict = {} + fields_dict["Time (UTC)"] = [] + while True: + line = file_stream.readline() + # if line is empty, end of file is reached + if not line: + break + if len(line.strip()) == 0: + continue + if len(line.strip().split(' - ')) < 2: + continue + + txt = line.strip().split(' - ')[1] + # Look for the specific metric by keyword + if search_keyword.lower().strip() in txt.lower(): + metadata_list = [x for x in line.strip().split( + ' - ')[0].split("[") if x != ''] + time = ''.join(metadata_list).split(']')[0].replace('"','').replace('log','').replace('{','').replace('{}','').replace(':','',1).replace('}','') + fields_dict["Time (UTC)"].append(time) + metric_field_value = '' + metric_field_title = '' + txt_list = [x.strip() for x in txt.strip().split(":") if x.strip() != 'INFO' if x.strip() != 'DEBUG' if x.strip() != 'ERROR' ] + if "stdout" in txt_list[1]: + metric_field_title = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','') + metric_field_value = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','').replace('\\u003e','>').replace('\\u003c','<').replace('\\','"') + else: + metric_field_title = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','') + metric_field_value = txt_list[1].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','').replace('\\u003e','>').replace('\\u003c','<').replace('\\','"') + try: + xml = ET.fromstring(metric_field_value) + metric_field_value = xml.find("id").text + except: + pass + if metric_field_title not in fields_dict.keys(): + fields_dict[metric_field_title] = [] + fields_dict[metric_field_title].append(metric_field_value) + file_stream.close() + return fields_dict + + +''' +main entrypoint to read carmacloud.log file and search based on the metric keyworkds. +Once the relevant logs are found, it write the data into the specified excel output file. +''' + + +def main(): + inputfile, outputfile = get_filenames() + search_metric_keywords = { + 'FER-5-6': 'Incoming BSM is not from Emergency Response Vehicle (ERV)', + 'FER-9-10-11': 'Forward ERV BSM to cloud:', + 'FER-12-1': 'Received ERV BSM and forward ERV BSM to cloud delay (ms)', + 'FER-TBD-1': 'Received ERV BSM from cloud:', + 'FER-TBD-2': 'Received ERV BSM from cloud and broadcast ERV BSM delay(ms)' + } + global_fields_dict = {} + print(f'Processing log file [{inputfile}]...') + for metric_keyword_key in search_metric_keywords.keys(): + if len(inputfile) > 0 and len(outputfile) > 0: + fields_dict = process_input_log_file(inputfile=inputfile, + search_keyword=search_metric_keywords[metric_keyword_key]) + if len(fields_dict) > 0: + global_fields_dict[metric_keyword_key] = fields_dict + + # Write dictionary into excel file + if len(global_fields_dict) > 0: + with pd.ExcelWriter(outputfile+".xlsx") as writer: + for metric_keyword in global_fields_dict.keys(): + data_frame = pd.DataFrame(global_fields_dict[metric_keyword]) + data_frame.to_excel(writer, sheet_name=metric_keyword, index=False) + print(f'Generated sheet for metric: {metric_keyword}') + + +if __name__ == '__main__': + main() diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp index 6c1dfb96c..a850e5de7 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp @@ -33,7 +33,7 @@ namespace ERVCloudForwardingPlugin else { // If BSM is not from ERV, print debug log - PLOG(logDEBUG) << "Incoming BSM is not from Emergency Response Vehicle (ERV)." << endl; + PLOG(logDEBUG) << "Incoming BSM is not from Emergency Response Vehicle (ERV): " << msg << endl; } } From 27932000751bb786293eb5852aba796b4ad7b0da Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Mon, 24 Apr 2023 21:12:26 -0400 Subject: [PATCH 05/15] Verification testing metrics: Add logs for metrics analysis (#522) # PR Details ## Description Add logs to print when v2xhub receives BSM. Add logs to print when the v2xhub successfully forward BSM to carma-cloud. ## Related Issue https://github.com/usdot-fhwa-OPS/V2X-Hub/issues/515 ## Motivation and Context ERV ## How Has This Been Tested? NA ## Types of changes - [x] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- .../ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp index a850e5de7..71bdca3c9 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp @@ -19,6 +19,7 @@ namespace ERVCloudForwardingPlugin void ERVCloudForwardingPlugin::handleBSM(BsmMessage &msg, routeable_message &routableMsg) { + PLOG(logDEBUG) << "Receive BSM: " << msg << endl; uint64_t delayStart = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); // Check if the BSM is broadcast by an ERV (Emergency Response Vehicle) if (ERVCloudForwardingWorker::IsBSMFromERV(msg)) @@ -200,6 +201,8 @@ namespace ERVCloudForwardingPlugin { fprintf(stderr, "curl send failed: %s\n", curl_easy_strerror(res)); return EXIT_FAILURE; + }else{ + PLOG(logDEBUG) << "Successfully forward ERV BSM to cloud: " << local_msg << endl; } } curl_easy_cleanup(req); From d0cb9790c0f6cc8b12de47192d8efdf7c020448d Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Wed, 26 Apr 2023 12:10:00 -0400 Subject: [PATCH 06/15] Add more logs for analysis (#523) # PR Details ## Description Add more terminal logs to catch http request from v2xhub to cloud. The timestamp before the request and after successfully response from the cloud. ## Related Issue https://github.com/usdot-fhwa-OPS/V2X-Hub/issues/515 ## Motivation and Context ERV verification testing metrics ## How Has This Been Tested? NA ## Types of changes - [x] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- .../ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp index 71bdca3c9..8a1d44037 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp +++ b/src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp @@ -196,13 +196,14 @@ namespace ERVCloudForwardingPlugin curl_easy_setopt(req, CURLOPT_POSTFIELDS, local_msg.c_str()); curl_easy_setopt(req, CURLOPT_TIMEOUT_MS, 5000L); //Http request timeout in 5 seconds curl_easy_setopt(req, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + PLOG(logDEBUG) << "Forwarding message to cloud via curl: " << local_msg << endl; res = curl_easy_perform(req); if (res != CURLE_OK) { fprintf(stderr, "curl send failed: %s\n", curl_easy_strerror(res)); return EXIT_FAILURE; }else{ - PLOG(logDEBUG) << "Successfully forward ERV BSM to cloud: " << local_msg << endl; + PLOG(logDEBUG) << "Successfully forwarded message to cloud via curl: " << local_msg << endl; } } curl_easy_cleanup(req); From 9c58fd08776cf0ea7c7c2b064da2ec09be33f51b Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Thu, 4 May 2023 12:16:45 -0400 Subject: [PATCH 07/15] Remove ERV analysis script (#528) # PR Details ## Description The ERV analysis script is not part of the K900 release and should be removed from the release candidate branch. The script is already moved into a dedicated repos https://github.com/usdot-fhwa-stol/carma-analytics-fotda that has all the past analysis script for different use cases ## Related Issue NA ## Motivation and Context ## How Has This Been Tested? NA ## Types of changes - [x] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- scripts/requirements.txt | 1 - scripts/v2xhub_log_analysis_erv.py | 103 ----------------------------- 2 files changed, 104 deletions(-) delete mode 100644 scripts/requirements.txt delete mode 100644 scripts/v2xhub_log_analysis_erv.py diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index a717bf139..000000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -openpyxl \ No newline at end of file diff --git a/scripts/v2xhub_log_analysis_erv.py b/scripts/v2xhub_log_analysis_erv.py deleted file mode 100644 index 88b9550bb..000000000 --- a/scripts/v2xhub_log_analysis_erv.py +++ /dev/null @@ -1,103 +0,0 @@ -import sys -import pandas as pd -import xml.etree.ElementTree as ET -import argparse - -''' -Get file names -''' - - -def get_filenames(): - inputfile = '' - outputfile = '' - parser = argparse.ArgumentParser(prog="V2xHub Analysis for ERV BSM") - parser.add_argument('--input', type=str, required=True) - parser.add_argument('--output', type=str, required=True) - args = parser.parse_args() - print(f'Received log file: {args.input}; Result will be saved into file: {args.output}.xlsx') - inputfile = args.input - outputfile = args.output - return (inputfile, outputfile) -''' -Read the input logs file and search the relevant logs. Process the logs and return a dictionary of the relevant information -''' - - -def process_input_log_file(inputfile, search_keyword): - file_stream = open(inputfile, 'r') - fields_dict = {} - fields_dict["Time (UTC)"] = [] - while True: - line = file_stream.readline() - # if line is empty, end of file is reached - if not line: - break - if len(line.strip()) == 0: - continue - if len(line.strip().split(' - ')) < 2: - continue - - txt = line.strip().split(' - ')[1] - # Look for the specific metric by keyword - if search_keyword.lower().strip() in txt.lower(): - metadata_list = [x for x in line.strip().split( - ' - ')[0].split("[") if x != ''] - time = ''.join(metadata_list).split(']')[0].replace('"','').replace('log','').replace('{','').replace('{}','').replace(':','',1).replace('}','') - fields_dict["Time (UTC)"].append(time) - metric_field_value = '' - metric_field_title = '' - txt_list = [x.strip() for x in txt.strip().split(":") if x.strip() != 'INFO' if x.strip() != 'DEBUG' if x.strip() != 'ERROR' ] - if "stdout" in txt_list[1]: - metric_field_title = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','') - metric_field_value = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','').replace('\\u003e','>').replace('\\u003c','<').replace('\\','"') - else: - metric_field_title = txt_list[0].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','') - metric_field_value = txt_list[1].strip().replace("stream","").replace('\\n','').replace('"','').replace(',','').replace('\\u003e','>').replace('\\u003c','<').replace('\\','"') - try: - xml = ET.fromstring(metric_field_value) - metric_field_value = xml.find("id").text - except: - pass - if metric_field_title not in fields_dict.keys(): - fields_dict[metric_field_title] = [] - fields_dict[metric_field_title].append(metric_field_value) - file_stream.close() - return fields_dict - - -''' -main entrypoint to read carmacloud.log file and search based on the metric keyworkds. -Once the relevant logs are found, it write the data into the specified excel output file. -''' - - -def main(): - inputfile, outputfile = get_filenames() - search_metric_keywords = { - 'FER-5-6': 'Incoming BSM is not from Emergency Response Vehicle (ERV)', - 'FER-9-10-11': 'Forward ERV BSM to cloud:', - 'FER-12-1': 'Received ERV BSM and forward ERV BSM to cloud delay (ms)', - 'FER-TBD-1': 'Received ERV BSM from cloud:', - 'FER-TBD-2': 'Received ERV BSM from cloud and broadcast ERV BSM delay(ms)' - } - global_fields_dict = {} - print(f'Processing log file [{inputfile}]...') - for metric_keyword_key in search_metric_keywords.keys(): - if len(inputfile) > 0 and len(outputfile) > 0: - fields_dict = process_input_log_file(inputfile=inputfile, - search_keyword=search_metric_keywords[metric_keyword_key]) - if len(fields_dict) > 0: - global_fields_dict[metric_keyword_key] = fields_dict - - # Write dictionary into excel file - if len(global_fields_dict) > 0: - with pd.ExcelWriter(outputfile+".xlsx") as writer: - for metric_keyword in global_fields_dict.keys(): - data_frame = pd.DataFrame(global_fields_dict[metric_keyword]) - data_frame.to_excel(writer, sheet_name=metric_keyword, index=False) - print(f'Generated sheet for metric: {metric_keyword}') - - -if __name__ == '__main__': - main() From 1e65ccfda0816bf9fb46d5fd589a656239b1f1ae Mon Sep 17 00:00:00 2001 From: paulbourelly999 <77466294+paulbourelly999@users.noreply.github.com> Date: Fri, 5 May 2023 10:24:32 -0400 Subject: [PATCH 08/15] Fix for development image throwing exception unknown source stoul (#526) + Added /usr/lib and /usr/bin to deployed image + Adding log statement for handshake + Removing cpprest library dependency which is unused # PR Details ## Description ## Related Issue #525 ## Motivation and Context Fix CDASimAdapterPlugin functionality in development image ## How Has This Been Tested? Locally integration tested using steps in the related issue. ## Types of changes - [x] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x ] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- .dockerignore | 2 ++ Dockerfile | 2 ++ scripts/install_dependencies.sh | 1 - src/v2i-hub/CARMACloudPlugin/CMakeLists.txt | 2 +- src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp | 8 ++++++++ .../test/TestCARMASimulationConnection.cpp | 12 ++++++++++++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 4f9521841..b4fc88967 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,3 +14,5 @@ Dockerfile docker-compose.yml *.md +**/build + diff --git a/Dockerfile b/Dockerfile index 9bf05373d..0ba4b10e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,6 +42,8 @@ RUN ldconfig COPY --from=dependencies /usr/local/plugins/ /usr/local/plugins/ COPY --from=dependencies /usr/local/lib/ /usr/local/lib/ COPY --from=dependencies /usr/local/bin/ /usr/local/bin/ +COPY --from=dependencies /usr/lib/ /usr/lib/ +COPY --from=dependencies /usr/bin/ /usr/bin/ COPY --from=dependencies /usr/local/share/ /usr/local/share/ COPY --from=dependencies /var/www/plugins/ /var/www/plugins/ COPY --from=dependencies /var/log/tmx/ /var/log/tmx/ diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index efd5f5010..9ddc86c72 100755 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -13,7 +13,6 @@ DEPENDENCIES="build-essential \ cmake \ git \ libboost-all-dev \ - libcpprest-dev \ libcurl4-openssl-dev \ libev-dev \ libgps-dev \ diff --git a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt index 767f81dc7..84ca7becd 100644 --- a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt @@ -30,7 +30,7 @@ BuildTmxPlugin () TARGET_INCLUDE_DIRECTORIES ( ${PROJECT_NAME} PUBLIC ${XercesC_INCLUDE_DIRS} ${NETSNMP_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) -TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} PUBLIC tmxutils ${XercesC_LIBRARY} ${NETSNMP_LIBRARIES} ${QHttpEngine_LIBRARY} ${Boost_SYSTEM_LIBRARY} ZLIB::ZLIB curl cpprest Qt5Widgets Qt5Core Qt5Network ssl crypto qhttpengine v2xhubWebAPI) +TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} PUBLIC tmxutils ${XercesC_LIBRARY} ${NETSNMP_LIBRARIES} ${QHttpEngine_LIBRARY} ${Boost_SYSTEM_LIBRARY} ZLIB::ZLIB curl Qt5Widgets Qt5Core Qt5Network ssl crypto qhttpengine v2xhubWebAPI) link_directories(${CMAKE_PREFIX_PATH}/lib) \ No newline at end of file diff --git a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp index b43e8c441..7349bda38 100644 --- a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp @@ -193,12 +193,20 @@ namespace CDASimAdapter{ void CDASimConnection::forward_message( const std::string &msg, const std::shared_ptr _client ) const { if ( !msg.empty() && _client) { + PLOG(logDEBUG) << "Sending UDP msg " << msg << " to host " << _client->GetAddress() + << ":" << _client->GetPort() << "." << std::endl; int ret =_client->Send(msg); if ( ret < 0) { throw UdpClientRuntimeError(("Failed to send message " + msg + " to " + _client->GetAddress() + ":" + std::to_string(_client->GetPort()) + " with error code : " + std::to_string(errno)).c_str()); } } + else if ( msg.empty() ) { + PLOG(logWARNING) << "Unable to send empty message to " << _client->GetAddress() << ":" << _client->GetPort() << "." << std::endl; + } + else { + PLOG(logWARNING) << "Unable to send message from uninitialized client." << std::endl; + } } void CDASimConnection::forward_v2x_message_to_simulation(const std::string &msg) const { diff --git a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp index fa00203ce..442c83142 100644 --- a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp @@ -47,6 +47,18 @@ namespace CDASimAdapter { connection->forward_message(test_message, client); } + TEST_F( TestCARMASimulationConnection, forward_message_invalid ) { + std::shared_ptr client = std::make_shared(); + std::string test_message = ""; + // ASSERT that we never call Send message. + EXPECT_CALL( *client, Send(test_message) ).Times(0); + // sent empty message + connection->forward_message(test_message,client); + test_message = "message"; + client = nullptr; + connection->forward_message(test_message, client); + } + TEST_F( TestCARMASimulationConnection, consume_msg){ std::shared_ptr server = std::make_shared(); From a112b6a6af9400f416ba5cd46cc3d9ba880b73d2 Mon Sep 17 00:00:00 2001 From: Cody Garver Date: Fri, 5 May 2023 11:04:01 -0400 Subject: [PATCH 09/15] Bump version 7.4.0 to 7.5.0 --- src/v2i-hub/CARMACloudPlugin/CMakeLists.txt | 2 +- src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt | 2 +- src/v2i-hub/CDASimAdapter/CMakeLists.txt | 2 +- src/v2i-hub/CommandPlugin/CMakeLists.txt | 2 +- src/v2i-hub/CswPlugin/CMakeLists.txt | 2 +- src/v2i-hub/DmsPlugin/CMakeLists.txt | 2 +- src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt | 2 +- src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt | 2 +- src/v2i-hub/LocationPlugin/CMakeLists.txt | 2 +- src/v2i-hub/MapPlugin/CMakeLists.txt | 2 +- src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt | 2 +- src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt | 2 +- src/v2i-hub/ODEForwardPlugin/CMakeLists.txt | 2 +- src/v2i-hub/PedestrianPlugin/CMakeLists.txt | 2 +- src/v2i-hub/PortDrayagePlugin/CMakeLists.txt | 2 +- src/v2i-hub/PreemptionPlugin/CMakeLists.txt | 2 +- src/v2i-hub/RtcmPlugin/CMakeLists.txt | 2 +- src/v2i-hub/SpatPlugin/CMakeLists.txt | 2 +- src/v2i-hub/TimPlugin/CMakeLists.txt | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt index 767f81dc7..4d4653f15 100644 --- a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMACloudPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( CARMACloudPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CARMACloud") add_compile_options(-fPIC) diff --git a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt index c9a2a11ee..a0bc494fb 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMAStreetsPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( CARMAStreetsPlugin VERSION 7.5.0 LANGUAGES CXX ) BuildTmxPlugin ( ) diff --git a/src/v2i-hub/CDASimAdapter/CMakeLists.txt b/src/v2i-hub/CDASimAdapter/CMakeLists.txt index 5c098053a..e8e8cd794 100755 --- a/src/v2i-hub/CDASimAdapter/CMakeLists.txt +++ b/src/v2i-hub/CDASimAdapter/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CDASimAdapter VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( CDASimAdapter VERSION 7.5.0 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) FIND_PACKAGE( carma-clock ) diff --git a/src/v2i-hub/CommandPlugin/CMakeLists.txt b/src/v2i-hub/CommandPlugin/CMakeLists.txt index 27461b7e3..651e1af0a 100644 --- a/src/v2i-hub/CommandPlugin/CMakeLists.txt +++ b/src/v2i-hub/CommandPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CommandPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( CommandPlugin VERSION 7.5.0 LANGUAGES CXX ) FIND_PACKAGE (OpenSSL REQUIRED) diff --git a/src/v2i-hub/CswPlugin/CMakeLists.txt b/src/v2i-hub/CswPlugin/CMakeLists.txt index 607a1b32c..66d0d9545 100644 --- a/src/v2i-hub/CswPlugin/CMakeLists.txt +++ b/src/v2i-hub/CswPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CswPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( CswPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CSW") diff --git a/src/v2i-hub/DmsPlugin/CMakeLists.txt b/src/v2i-hub/DmsPlugin/CMakeLists.txt index ac2960b0e..4508c8084 100644 --- a/src/v2i-hub/DmsPlugin/CMakeLists.txt +++ b/src/v2i-hub/DmsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( DmsPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( DmsPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Dynamic Message Sign") diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt index aa1cca06c..56f71f571 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt +++ b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT(ERVCloudForwardingPlugin VERSION 7.4.0 LANGUAGES CXX) +PROJECT(ERVCloudForwardingPlugin VERSION 7.5.0 LANGUAGES CXX) SET(TMX_PLUGIN_NAME "ERVCloudForwarding") add_compile_options(-fPIC) diff --git a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt index 3b6ca7277..e3d2365a2 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ImmediateForwardPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( ImmediateForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Immediate Forward") diff --git a/src/v2i-hub/LocationPlugin/CMakeLists.txt b/src/v2i-hub/LocationPlugin/CMakeLists.txt index 4ec30bd65..eb929373b 100644 --- a/src/v2i-hub/LocationPlugin/CMakeLists.txt +++ b/src/v2i-hub/LocationPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -project( LocationPlugin VERSION 7.4.0 LANGUAGES CXX ) +project( LocationPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME Location) diff --git a/src/v2i-hub/MapPlugin/CMakeLists.txt b/src/v2i-hub/MapPlugin/CMakeLists.txt index 4059655d4..7cf372de0 100644 --- a/src/v2i-hub/MapPlugin/CMakeLists.txt +++ b/src/v2i-hub/MapPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MapPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( MapPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MAP") diff --git a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt index 7430eef0b..b63b6d6df 100644 --- a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageLoggerPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( MessageLoggerPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MessageLoggerPlugin") diff --git a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt index d57b4835e..f77e4c1a3 100644 --- a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageReceiverPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( MessageReceiverPlugin VERSION 7.5.0 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt index 065c7c432..815527534 100644 --- a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ODEForwardPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( ODEForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "ODEForwardPlugin") diff --git a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt index a369271a0..8b0ba693f 100755 --- a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt +++ b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PedestrianPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( PedestrianPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Pedestrian") add_compile_options(-fPIC) diff --git a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt index 3eb50acdc..eb069bfd7 100644 --- a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt +++ b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PortDrayagePlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( PortDrayagePlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "PortDrayage") set(CMAKE_AUTOMOC ON) diff --git a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt index 2acc89e2a..eed709d13 100644 --- a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt +++ b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PreemptionPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( PreemptionPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Preemption") diff --git a/src/v2i-hub/RtcmPlugin/CMakeLists.txt b/src/v2i-hub/RtcmPlugin/CMakeLists.txt index adf1ba654..f10a35a31 100644 --- a/src/v2i-hub/RtcmPlugin/CMakeLists.txt +++ b/src/v2i-hub/RtcmPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( RtcmPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( RtcmPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "RTCM") diff --git a/src/v2i-hub/SpatPlugin/CMakeLists.txt b/src/v2i-hub/SpatPlugin/CMakeLists.txt index 94b51f3d4..ec48c6f14 100644 --- a/src/v2i-hub/SpatPlugin/CMakeLists.txt +++ b/src/v2i-hub/SpatPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( SpatPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( SpatPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "SPAT") diff --git a/src/v2i-hub/TimPlugin/CMakeLists.txt b/src/v2i-hub/TimPlugin/CMakeLists.txt index 5eb9c7af6..79a3ac8ca 100644 --- a/src/v2i-hub/TimPlugin/CMakeLists.txt +++ b/src/v2i-hub/TimPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( TimPlugin VERSION 7.4.0 LANGUAGES CXX ) +PROJECT ( TimPlugin VERSION 7.5.0 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "TIM") add_compile_options(-fPIC) From 0ebfac5bedc0a5f00b4ec72c194158d075cda342 Mon Sep 17 00:00:00 2001 From: Saikrishna Bairamoni <84093461+SaikrishnaBairamoni@users.noreply.github.com> Date: Mon, 8 May 2023 14:54:10 -0400 Subject: [PATCH 10/15] Update Release_notes.md with 7.5.0 version --- docs/Release_notes.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/Release_notes.md b/docs/Release_notes.md index c03fe51c1..3ab4842c9 100644 --- a/docs/Release_notes.md +++ b/docs/Release_notes.md @@ -1,5 +1,31 @@ V2X-Hub Release Notes --------------------------------- + +Version 7.5.0, released May 5th, 2023 +-------------------------------------------------------- + +**Summary:** +V2X Hub release 7.5.0 is comprised of the following new features: a new ERVCloudForwardingPlugin to enable BSMs from active Emergency Response Vehicles (ERVs) to be forwarded to CARMA Cloud in support of message forwarding to V2X Hub instances along an ERV’s future route when deployed along with other CARMA tools to demonstrate move-over law when an ERV is approaching a CDA vehicle from behind; new features to support CARMA Simulation integration such as simulation clock functionality; and a newly developed CARMA Simulation adaptor shell and handshake functionality to allow multiple V2X Hub instances to connect with a single CARMA Simulation platform. Along with the above enhancements, several enhancements and bug fixes are included in this release. + +**Freight Emergency Response Functionalities** + +Enhancements in this release related to Freight Emergency Response: + +- PR 460: The creation of a new ERVCloudForwardingPlugin that enables V2X Hub to register a connected RSU, along with its location information, with CARMA Cloud. Additionally, this plugin is responsible for sending received BSMs from active Emergency Response Vehicles (ERVs) to CARMA Cloud in support of message forwarding to V2X Hub instances located along the ERV’s future route. + +**Other** + +Enhancements in this release: + +- Issue 262: Updated CARMA Streets plugin to receive and decode Mobility Path messages into JSON through Kafka. +- PR 486: Updated the V2X Hub docker images to Ubuntu 22 (Jammy) which has LTS support through April 2027. This will also support new libraries created using the Carma-builds project. +- PR 487: Added some changes to allow for Docker to be installed on different Linux distros for arm64. + +Fixes in this release: + +- Issue 484: Fixed PedestrianPlugin does not update when any configuration changes are made with in Plugin, either when plugin is off or on. +- PR 494: Sets some error message in the Command Plugin for file upload operations to ERROR instead of DEBUG so they can be seen on the command line by default. + Version 7.4.0, released Feb 10th, 2023 -------------------------------------------------------- From f7d694f383c2ca289ea03beb938e74edde52251a Mon Sep 17 00:00:00 2001 From: Saikrishna Bairamoni <84093461+SaikrishnaBairamoni@users.noreply.github.com> Date: Mon, 8 May 2023 15:01:48 -0400 Subject: [PATCH 11/15] update docker compose to point latest from release images --- configuration/amd64/docker-compose.yml | 6 +++--- configuration/arm64/docker-compose.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configuration/amd64/docker-compose.yml b/configuration/amd64/docker-compose.yml index ffafacc38..6b5188297 100755 --- a/configuration/amd64/docker-compose.yml +++ b/configuration/amd64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php:k900 + image: usdotfhwaops/php:latest container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubamd:k900 + image: usdotfhwaops/v2xhubamd:latest container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice:k900 + image: usdotfhwaops/port-drayage-webservice:latest container_name: port_drayage_webservice network_mode: host secrets: diff --git a/configuration/arm64/docker-compose.yml b/configuration/arm64/docker-compose.yml index 38c3359c6..a32c31fab 100644 --- a/configuration/arm64/docker-compose.yml +++ b/configuration/arm64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php_arm:k900 + image: usdotfhwaops/php_arm:latest container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubarm:k900 + image: usdotfhwaops/v2xhubarm:latest container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice_arm:k900 + image: usdotfhwaops/port-drayage-webservice_arm:latest container_name: port_drayage_webservice network_mode: host secrets: From 842aa5b2689a54f69cb0face169f4b357d6fbdf1 Mon Sep 17 00:00:00 2001 From: dan-du-car <62157949+dan-du-car@users.noreply.github.com> Date: Wed, 24 May 2023 13:41:22 -0400 Subject: [PATCH 12/15] V2XHub / CARMA Streets to process and broadcast SSM (#533) # PR Details ## Description For the POC TIM/TSP use case, priority-eligible vehicles will broadcast J2375 Signal Request Message (SRM) to the MMITSS Roadside Processor (MRP), which in turn will send J2375 Signal Status Message (SSM) in acknowledgement. Since MRP is being integrated with CARMA Streets, CARMA Streets / V2XHub needs to #1) consume the json SSM (used by the MMITSS MRP internally, see [here](https://github.com/mmitss/mmitss-az/blob/master/src/mrp/priority-request-server/Readme.md) and [here](https://github.com/mmitss/mmitss-az/blob/master/src/mrp/priority-request-server/SSM.json)) sent on the CARMA Streets Kafka broker, #2) encode it according to the J2375 [ASN.1 ](https://leidoscorpus.sharepoint.us/:f:/s/STR/EpU-cLOWhUtGvsddHUSf8I4Bf7-Ot8oMIY4yf2m7x2-Uag?e=0Rvpug)schema, and #3) broadcast J2375 SSMs through RSU. For #1) the V2XHub carma-streets-plugin needs to pull the json SSM from CARMA Steets Kafa broker. For #3) the V2XHub immediate-forward-plugin configuration needs to to be updated. ## Related Issue https://github.com/usdot-fhwa-OPS/V2X-Hub/issues/534 ## Motivation and Context TM/TSP ## How Has This Been Tested? Unit test ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [x] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [x] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt | 2 +- src/v2i-hub/CARMAStreetsPlugin/manifest.json | 10 ++ .../src/CARMAStreetsPlugin.cpp | 89 +++++++++- .../src/CARMAStreetsPlugin.h | 23 ++- .../src/JsonToJ2735SSMConverter.cpp | 156 ++++++++++++++++++ .../src/JsonToJ2735SSMConverter.h | 49 ++++++ .../test/test_JsonToJ2735SSMConverter.cpp | 102 ++++++++++++ .../ImmediateForwardPlugin/manifest.json | 2 +- 8 files changed, 428 insertions(+), 5 deletions(-) create mode 100644 src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.cpp create mode 100644 src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.h create mode 100644 src/v2i-hub/CARMAStreetsPlugin/test/test_JsonToJ2735SSMConverter.cpp diff --git a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt index f904ecac6..f98aebcae 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt @@ -9,7 +9,7 @@ TARGET_LINK_LIBRARIES (${PROJECT_NAME} tmxutils rdkafka++ jsoncpp) ############# enable_testing() include_directories(${PROJECT_SOURCE_DIR}/src) -add_library(${PROJECT_NAME}_lib src/J2735MapToJsonConverter.cpp src/JsonToJ2735SpatConverter.cpp src/J2735ToSRMJsonConverter.cpp) +add_library(${PROJECT_NAME}_lib src/J2735MapToJsonConverter.cpp src/JsonToJ2735SSMConverter.cpp src/JsonToJ2735SpatConverter.cpp src/J2735ToSRMJsonConverter.cpp) target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${TMXAPI_LIBRARIES} ${ASN_J2735_LIBRARIES} ${MYSQL_LIBRARIES} diff --git a/src/v2i-hub/CARMAStreetsPlugin/manifest.json b/src/v2i-hub/CARMAStreetsPlugin/manifest.json index c4fb269cd..790ef1af9 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/manifest.json +++ b/src/v2i-hub/CARMAStreetsPlugin/manifest.json @@ -102,6 +102,16 @@ "default": "modified_spat", "description": "Apache Kafka topic plugin will transmit message to." }, + { + "key": "SsmTopic", + "default": "v2xhub_ssm_sub", + "description": "Apache Kafka topic plugin will transmit message to." + }, + { + "key": "SsmConsumerGroupId", + "default": "v2xhub_ssm", + "description": "Apache Kafka consumer group ID for spat consumer." + }, { "key": "SpatConsumerGroupId", "default": "v2xhub_spat", diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp index 2e2fdf499..08bc96d8a 100755 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp @@ -46,7 +46,9 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { GetConfigValue("SchedulingPlanTopic", _subscribeToSchedulingPlanTopic); GetConfigValue("SchedulingPlanConsumerGroupId", _subscribeToSchedulingPlanConsumerGroupId); GetConfigValue("SpatTopic", _subscribeToSpatTopic); + GetConfigValue("SsmTopic", _subscribeToSsmTopic); GetConfigValue("SpatConsumerGroupId", _subscribeToSpatConsumerGroupId); + GetConfigValue("SsmConsumerGroupId", _subscribeToSSMConsumerGroupId); GetConfigValue("BsmTopic", _transmitBSMTopic); GetConfigValue("MobilityOperationTopic", _transmitMobilityOperationTopic); GetConfigValue("MobilityPathTopic", _transmitMobilityPathTopic); @@ -68,6 +70,8 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { kafka_conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); kafka_conf_sp_consumer = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); kafka_conf_spat_consumer = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + kafka_conf_ssm_consumer = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); + PLOG(logDEBUG) <<"Attempting to connect to " << kafkaConnectString; if ((kafka_conf->set("bootstrap.servers", kafkaConnectString, error_string) != RdKafka::Conf::CONF_OK)) { @@ -87,7 +91,10 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { if (kafka_conf_sp_consumer->set("bootstrap.servers", kafkaConnectString, error_string) != RdKafka::Conf::CONF_OK || (kafka_conf_sp_consumer->set("group.id", _subscribeToSchedulingPlanConsumerGroupId, error_string) != RdKafka::Conf::CONF_OK) || (kafka_conf_spat_consumer->set("bootstrap.servers", kafkaConnectString, error_string) != RdKafka::Conf::CONF_OK) - || (kafka_conf_spat_consumer->set("group.id", _subscribeToSpatConsumerGroupId, error_string) != RdKafka::Conf::CONF_OK)) { + || (kafka_conf_spat_consumer->set("group.id", _subscribeToSpatConsumerGroupId, error_string) != RdKafka::Conf::CONF_OK) + || (kafka_conf_ssm_consumer->set("bootstrap.servers", kafkaConnectString, error_string) != RdKafka::Conf::CONF_OK) + || (kafka_conf_ssm_consumer->set("group.id", _subscribeToSSMConsumerGroupId, error_string) != RdKafka::Conf::CONF_OK) + ) { PLOG(logERROR) <<"Setting kafka config group.id options failed with error:" << error_string << "\n" <<"Exiting with exit code 1"; exit(1); } else { @@ -95,20 +102,24 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { } kafka_conf_sp_consumer->set("enable.partition.eof", "true", error_string); kafka_conf_spat_consumer->set("enable.partition.eof", "true", error_string); + kafka_conf_ssm_consumer->set("enable.partition.eof", "true", error_string); _scheduing_plan_kafka_consumer = RdKafka::KafkaConsumer::create(kafka_conf_sp_consumer, error_string); _spat_kafka_consumer = RdKafka::KafkaConsumer::create(kafka_conf_spat_consumer, error_string); + _ssm_kafka_consumer = RdKafka::KafkaConsumer::create(kafka_conf_ssm_consumer, error_string); - if ( !_scheduing_plan_kafka_consumer || !_spat_kafka_consumer) { + if ( !_scheduing_plan_kafka_consumer || !_spat_kafka_consumer || !_ssm_kafka_consumer) { PLOG(logERROR) << "Failed to create Kafka consumers: " << error_string << std::endl; exit(1); } PLOG(logDEBUG) << "Created consumer " << _scheduing_plan_kafka_consumer->name() << std::endl; PLOG(logDEBUG) << "Created consumer " << _spat_kafka_consumer->name() << std::endl; + PLOG(logDEBUG) << "Created consumer " << _ssm_kafka_consumer->name() << std::endl; //create kafka topics RdKafka::Conf *tconf_spat = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); RdKafka::Conf *tconf_sp = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); + RdKafka::Conf *tconf_ssm = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); if(!tconf_spat && !tconf_sp) { PLOG(logERROR) << "RDKafka create topic conf failed "; @@ -129,11 +140,20 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { return ; } + _ssm_topic = RdKafka::Topic::create(_ssm_kafka_consumer,_subscribeToSsmTopic,tconf_ssm,error_string); + if(!_ssm_topic) + { + PLOG(logERROR) << "RDKafka create SSM topic failed:" << error_string; + return ; + } + delete tconf_sp; delete tconf_spat; + delete tconf_ssm; boost::thread thread_schpl(&CARMAStreetsPlugin::SubscribeSchedulingPlanKafkaTopic, this); boost::thread thread_spat(&CARMAStreetsPlugin::SubscribeSpatKafkaTopic, this); + boost::thread thread_ssm(&CARMAStreetsPlugin::SubscribeSSMKafkaTopic, this); } void CARMAStreetsPlugin::OnConfigChanged(const char *key, const char *value) { @@ -659,6 +679,71 @@ void CARMAStreetsPlugin::SubscribeSpatKafkaTopic(){ } } +void CARMAStreetsPlugin::SubscribeSSMKafkaTopic(){ + + if(_subscribeToSsmTopic.length() > 0) + { + PLOG(logDEBUG) << "SubscribeSSMKafkaTopics:" <<_subscribeToSsmTopic << std::endl; + std::vector topics; + topics.emplace_back(_subscribeToSsmTopic); + + RdKafka::ErrorCode err = _ssm_kafka_consumer->subscribe(topics); + if (err) + { + PLOG(logERROR) << "Failed to subscribe to " << topics.size() << " topics: " << RdKafka::err2str(err) << std::endl; + return; + } + //Initialize Json to J2735 SSM convertor + JsonToJ2735SSMConverter ssm_convertor; + while (true) + { + auto msg = _ssm_kafka_consumer->consume( 500 ); + if( msg->err() == RdKafka::ERR_NO_ERROR ) + { + auto payload_str = static_cast( msg->payload() ); + if(msg->len() > 0) + { + PLOG(logDEBUG) << "consumed message payload: " << payload_str <(Key_SSMMessageSkipped, ++_ssmMessageSkipped); + continue; + } + //Convert the SSM JSON string into J2735 SSM message and encode it. + auto ssm_ptr = std::make_shared(); + ssm_convertor.toJ2735SSM(ssmDoc, ssm_ptr); + tmx::messages::SsmEncodedMessage ssmEncodedMsg; + try + { + ssm_convertor.encodeSSM(ssm_ptr, ssmEncodedMsg); + } + catch (TmxException &ex) + { + // Skip messages that fail to encode. + PLOG(logERROR) << "Failed to encoded SSM message : \n" << payload_str << std::endl << "Exception encountered: " + << ex.what() << std::endl; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssm_ptr.get()); + SetStatus(Key_SSMMessageSkipped, ++_ssmMessageSkipped); + continue; + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssm_ptr.get()); + PLOG(logDEBUG) << "ssmEncodedMsg: " << ssmEncodedMsg; + + //Broadcast the encoded SSM message + ssmEncodedMsg.set_flags(IvpMsgFlags_RouteDSRC); + ssmEncodedMsg.addDsrcMetadata(0x8002); + BroadcastMessage(static_cast(ssmEncodedMsg)); + } + } + delete msg; + } + } + +} bool CARMAStreetsPlugin::getEncodedtsm3( tsm3EncodedMessage *tsm3EncodedMsg, Json::Value metadata, Json::Value payload_json ) { try diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h index a9111e945..566aaf35c 100755 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h @@ -17,6 +17,7 @@ #include "J2735MapToJsonConverter.h" #include "JsonToJ2735SpatConverter.h" #include "J2735ToSRMJsonConverter.h" +#include "JsonToJ2735SSMConverter.h" @@ -62,6 +63,10 @@ class CARMAStreetsPlugin: public PluginClient { * @brief Subcribe to SPAT Kafka topic created by carma-streets */ void SubscribeSpatKafkaTopic(); + /** + * @brief Subcribe to SSM Kafka topic created by carma-streets + */ + void SubscribeSSMKafkaTopic(); bool getEncodedtsm3(tsm3EncodedMessage *tsm3EncodedMsg, Json::Value metadata, Json::Value payload_json); /** @@ -79,7 +84,9 @@ class CARMAStreetsPlugin: public PluginClient { std::string _subscribeToSchedulingPlanTopic; std::string _subscribeToSchedulingPlanConsumerGroupId; std::string _subscribeToSpatTopic; + std::string _subscribeToSsmTopic; std::string _subscribeToSpatConsumerGroupId; + std::string _subscribeToSSMConsumerGroupId; std::string _transmitMobilityPathTopic; std::string _transmitBSMTopic; std::string _transmitMAPTopic; @@ -89,11 +96,14 @@ class CARMAStreetsPlugin: public PluginClient { RdKafka::Conf *kafka_conf; RdKafka::Conf *kafka_conf_spat_consumer; RdKafka::Conf *kafka_conf_sp_consumer; + RdKafka::Conf *kafka_conf_ssm_consumer; RdKafka::Producer *kafka_producer; RdKafka::KafkaConsumer *_scheduing_plan_kafka_consumer; RdKafka::KafkaConsumer *_spat_kafka_consumer; + RdKafka::KafkaConsumer *_ssm_kafka_consumer; RdKafka::Topic *_scheduing_plan_topic; RdKafka::Topic *_spat_topic; + RdKafka::Topic *_ssm_topic; std::vector _strategies; tmx::messages::tsm3Message *_tsm3Message{NULL}; std::mutex data_lock; @@ -130,6 +140,7 @@ class CARMAStreetsPlugin: public PluginClient { /** * @brief Status label for Mobility Operation messages skipped due to errors. */ + const char* Key_MobilityOperationMessageSkipped = "Mobility Operation messages skipped due to errors."; /** @@ -156,7 +167,17 @@ class CARMAStreetsPlugin: public PluginClient { * @brief Count for BSM messages skipped due to errors. */ uint _bsmMessageSkipped = 0; - + + /** + * @brief Status label for SSM messages skipped due to errors. + */ + const char* Key_SSMMessageSkipped = "SSM messages skipped due to errors."; + + /** + * @brief Count for SSM messages skipped due to errors. + */ + uint _ssmMessageSkipped = 0; + /** * @brief Intersection Id for intersection */ diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.cpp b/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.cpp new file mode 100644 index 000000000..10e59d87d --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.cpp @@ -0,0 +1,156 @@ +#include "JsonToJ2735SSMConverter.h" + +namespace CARMAStreetsPlugin +{ + + bool JsonToJ2735SSMConverter::parseJsonString(const string &consumedMsg, Json::Value &ssmDoc) const + { + const auto jsonLen = static_cast(consumedMsg.length()); + Json::CharReaderBuilder builder; + JSONCPP_STRING err; + const std::unique_ptr reader(builder.newCharReader()); + bool parseResult = reader->parse(consumedMsg.c_str(), consumedMsg.c_str() + jsonLen, &ssmDoc, &err); + if (!parseResult) + { + PLOG(logERROR) << "Parse error: " << err << endl; + } + return parseResult; + } + + void JsonToJ2735SSMConverter::toJ2735SSM(const Json::Value &ssmDoc, std::shared_ptr ssmPtr) const + { + try + { + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssmPtr.get()); + if (!ssmDoc.isMember("SignalStatus")) + { + PLOG(logERROR) << "No SignalStatus present in JSON." << std::endl; + return; + } + + // populate SignalStatusMessage::second + if (ssmDoc["SignalStatus"].isMember("msOfMinute") && ssmDoc["SignalStatus"]["msOfMinute"].isNumeric()) + { + ssmPtr->second = ssmDoc["SignalStatus"]["msOfMinute"].asInt64(); + } + + // populate SignalStatusMessage::timstamp + if (ssmDoc["SignalStatus"].isMember("minuteOfYear") && ssmDoc["SignalStatus"]["minuteOfYear"].isNumeric()) + { + MinuteOfTheYear_t *timeStamp = (MinuteOfTheYear_t *)calloc(1, sizeof(MinuteOfTheYear_t)); + *timeStamp = ssmDoc["SignalStatus"]["minuteOfYear"].asInt64(); + ssmPtr->timeStamp = timeStamp; + } + + SignalStatusList_t *statusPtr = (SignalStatusList_t *)calloc(1, sizeof(SignalStatusList_t)); + SignalStatus *signalStatus = (SignalStatus *)calloc(1, sizeof(SignalStatus)); + + // populate SignalStatusMessage::status::id + if (ssmDoc["SignalStatus"].isMember("intersectionID") && ssmDoc["SignalStatus"]["intersectionID"].isNumeric()) + { + signalStatus->id.id = ssmDoc["SignalStatus"]["intersectionID"].asInt64(); + } + + // populate SignalStatusMessage::status::sequenceNumber + if (ssmDoc["SignalStatus"].isMember("sequenceNumber") && ssmDoc["SignalStatus"]["sequenceNumber"].isNumeric()) + { + signalStatus->sequenceNumber = ssmDoc["SignalStatus"]["sequenceNumber"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus + if (ssmDoc["SignalStatus"].isMember("requestorInfo") && ssmDoc["SignalStatus"]["requestorInfo"].isArray()) + { + Json::Value requesterJsonArr = ssmDoc["SignalStatus"]["requestorInfo"]; + for (auto itr = requesterJsonArr.begin(); itr != requesterJsonArr.end(); itr++) + { + SignalStatusPackage *signalStatusPackage = (SignalStatusPackage *)calloc(1, sizeof(SignalStatusPackage)); + populateSigStatusPackage(signalStatusPackage, itr); + asn_sequence_add(&signalStatus->sigStatus.list.array, signalStatusPackage); + } // Populate signal status package + } + + asn_sequence_add(&statusPtr->list.array, signalStatus); + ssmPtr->status = *statusPtr; + } + catch(exception &ex) + { + PLOG(logERROR) << "Cannot read JSON file." << std::endl; + } + } + + void JsonToJ2735SSMConverter::populateSigStatusPackage(SignalStatusPackage *signalStatusPackage, Json::Value::iterator itr) const + { + signalStatusPackage->requester = (SignalRequesterInfo *)calloc(1, sizeof(SignalRequesterInfo)); + + // populate SignalStatusMessage::status::sigStatus::requester::request + if (itr->isMember("requestID") && (*itr)["requestID"].isNumeric()) + { + signalStatusPackage->requester->request = (*itr)["requestID"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::requester::id + if (itr->isMember("vehicleID") && (*itr)["vehicleID"].isNumeric()) + { + signalStatusPackage->requester->id.choice.stationID = (*itr)["vehicleID"].asInt64(); + signalStatusPackage->requester->id.present = VehicleID_PR_stationID; + } + + // populate SignalStatusMessage::status::sigStatus::requester::sequenceNumber + if (itr->isMember("msgCount") && (*itr)["msgCount"].isNumeric()) + { + signalStatusPackage->requester->sequenceNumber = (*itr)["msgCount"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::requester::role + if (itr->isMember("basicVehicleRole") && (*itr)["basicVehicleRole"].isNumeric()) + { + signalStatusPackage->requester->role = (BasicVehicleRole_t *)calloc(1, sizeof(BasicVehicleRole_t)); + *signalStatusPackage->requester->role = (*itr)["basicVehicleRole"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::inboundOn + if (itr->isMember("inBoundLaneID") && (*itr)["inBoundLaneID"].isNumeric()) + { + signalStatusPackage->inboundOn.present = IntersectionAccessPoint_PR_lane; + signalStatusPackage->inboundOn.choice.lane = (*itr)["inBoundLaneID"].asInt64(); + } + else if (itr->isMember("inBoundApproachID") && (*itr)["inBoundApproachID"].isNumeric()) + { + signalStatusPackage->inboundOn.present = IntersectionAccessPoint_PR_approach; + signalStatusPackage->inboundOn.choice.approach = (*itr)["inBoundApproachID"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::status + if (itr->isMember("priorityRequestStatus") && (*itr)["priorityRequestStatus"].isNumeric()) + { + signalStatusPackage->status = (*itr)["priorityRequestStatus"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::duration + if (itr->isMember("ETA_Duration") && (*itr)["ETA_Duration"].isNumeric()) + { + signalStatusPackage->duration = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *signalStatusPackage->duration = (*itr)["ETA_Duration"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::minute + if (itr->isMember("ETA_Minute") && (*itr)["ETA_Minute"].isNumeric()) + { + signalStatusPackage->minute = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *signalStatusPackage->minute = (*itr)["ETA_Minute"].asInt64(); + } + + // populate SignalStatusMessage::status::sigStatus::second + if (itr->isMember("ETA_Second") && (*itr)["ETA_Second"].isNumeric()) + { + signalStatusPackage->minute = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *signalStatusPackage->minute = (*itr)["ETA_Second"].asInt64(); + } + } + void JsonToJ2735SSMConverter::encodeSSM(const std::shared_ptr &ssmPtr, tmx::messages::SsmEncodedMessage &encodedSSM) const + { + tmx::messages::MessageFrameMessage frame(ssmPtr); + encodedSSM.set_data(tmx::messages::TmxJ2735EncodedMessage::encode_j2735_message>(frame)); + free(frame.get_j2735_data().get()); + } +} diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.h b/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.h new file mode 100644 index 000000000..64d90c816 --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/src/JsonToJ2735SSMConverter.h @@ -0,0 +1,49 @@ +#ifndef JSONTOJ2735SSMCONVERTER_H_ +#define JSONTOJ2735SSMCONVERTER_H_ +#include "jsoncpp/json/json.h" +#include +#include +#include + +using namespace std; +using namespace tmx::utils; +namespace CARMAStreetsPlugin +{ + class JsonToJ2735SSMConverter + { + public: + // Constructor to initialize object + JsonToJ2735SSMConverter() = default; + /*** + * @brief Parse Json string into Json object + * @param jsonstring that is consumed from a kafka topic + * @param JsonObject that is populated by the input json string + * @return boolean. True if parse successfully, false if parse with errors + */ + bool parseJsonString(const string &consumed_msg, Json::Value &ssmDoc) const; + /*** + * @brief Read SSM Json document and populate J2735 SSM message + * @param ssmDoc Json object that contains the SSM information in Json format + * @param ssmPtr a pointer to J2735 message object. This object will be populated with the values in the Json object + */ + void toJ2735SSM(const Json::Value &ssmDoc, std::shared_ptr ssmPtr) const; + /*** + * @brief Encode J2735 SSM + * @param Pointer to J2735 SSM object + * @param Encoded J2735 SSM + */ + void encodeSSM(const std::shared_ptr &ssmPtr, tmx::messages::SsmEncodedMessage &encodedSSM) const; + + /*** + * @brief Populate J2735 SignalStatusPackage object with Json Value + * @param Pointer J2735 SignalStatusPackage object + * @param Json::Value SignalstatusPackage Json string iterator + */ + void populateSigStatusPackage(SignalStatusPackage *signalStatusPackage, Json::Value::iterator itr) const; + + ~JsonToJ2735SSMConverter() = default; + }; + +} + +#endif \ No newline at end of file diff --git a/src/v2i-hub/CARMAStreetsPlugin/test/test_JsonToJ2735SSMConverter.cpp b/src/v2i-hub/CARMAStreetsPlugin/test/test_JsonToJ2735SSMConverter.cpp new file mode 100644 index 000000000..2bd9fb405 --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/test/test_JsonToJ2735SSMConverter.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include "jsoncpp/json/json.h" +#include "JsonToJ2735SSMConverter.h" +using namespace std; + +namespace CARMAStreetsPlugin +{ + class test_JsonToJ2735SSMConverter : public ::testing::Test + { + }; + + TEST_F(test_JsonToJ2735SSMConverter, parseJsonString) + { + JsonToJ2735SSMConverter converter; + // Json string refer to: https://github.com/mmitss/mmitss-az/blob/master/src/mrp/priority-request-server/SSM.json + string valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1003,\"minuteOfYear\":345239,\"msOfMinute\":54000,\"regionalID\":0,\"requestorInfo\":[{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":20.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":8,\"msgCount\":2,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":601},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":605},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":9,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":0,\"requestID\":5,\"vehicleID\":610}],\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + Json::Value root; + bool result = converter.parseJsonString(valid_json_str, root); + ASSERT_TRUE(result); + string invalid_json = "invalid"; + result = converter.parseJsonString(invalid_json, root); + ASSERT_FALSE(result); + } + + TEST_F(test_JsonToJ2735SSMConverter, toJ2735SSM) + { + JsonToJ2735SSMConverter converter; + // Json string refer to: https://github.com/mmitss/mmitss-az/blob/master/src/mrp/priority-request-server/SSM.json + // Json has three requestors + string valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1003,\"minuteOfYear\":345239,\"msOfMinute\":54000,\"regionalID\":0,\"requestorInfo\":[{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":20.001000000000005,\"basicVehicleRole\":16,\"inBoundApproachID\":8,\"msgCount\":2,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":601},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":605},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":9,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":0,\"requestID\":5,\"vehicleID\":610}],\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + Json::Value root; + bool result = converter.parseJsonString(valid_json_str, root); + ASSERT_TRUE(result); + auto ssmPtr = std::make_shared(); + converter.toJ2735SSM(root, ssmPtr); + ASSERT_EQ(1, ssmPtr->status.list.count); + ASSERT_EQ(1003, ssmPtr->status.list.array[0]->id.id); + ASSERT_EQ(54000, ssmPtr->second); + ASSERT_EQ(345239, *ssmPtr->timeStamp); + ASSERT_EQ(3, ssmPtr->status.list.array[0]->sigStatus.list.count); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssmPtr.get()); + } + + TEST_F(test_JsonToJ2735SSMConverter, toJ2735SSM_2) + { + JsonToJ2735SSMConverter converter; + // Json has one requestor + string valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1004,\"minuteOfYear\":345240,\"msOfMinute\":54001,\"regionalID\":0,\"requestorInfo\":[{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":20.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":8,\"msgCount\":2,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":601}],\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + Json::Value root; + bool result = converter.parseJsonString(valid_json_str, root); + ASSERT_TRUE(result); + auto ssmPtr = std::make_shared(); + converter.toJ2735SSM(root, ssmPtr); + ASSERT_EQ(1, ssmPtr->status.list.count); + ASSERT_EQ(1004, ssmPtr->status.list.array[0]->id.id); + ASSERT_EQ(54001, ssmPtr->second); + ASSERT_EQ(345240, *ssmPtr->timeStamp); + ASSERT_EQ(1, ssmPtr->status.list.array[0]->sigStatus.list.count); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssmPtr.get()); + } + + TEST_F(test_JsonToJ2735SSMConverter, toJ2735SSM_3) + { + JsonToJ2735SSMConverter converter; + // Json has NO requestor + string valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1004,\"minuteOfYear\":345240,\"msOfMinute\":54001,\"regionalID\":0,\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + Json::Value root; + bool result = converter.parseJsonString(valid_json_str, root); + ASSERT_TRUE(result); + auto ssmPtr = std::make_shared(); + converter.toJ2735SSM(root, ssmPtr); + ASSERT_EQ(0, ssmPtr->status.list.array[0]->sigStatus.list.count); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssmPtr.get()); + } + + TEST_F(test_JsonToJ2735SSMConverter, encodeSSM) + { + JsonToJ2735SSMConverter converter; + // Json has one requestor + string valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1004,\"minuteOfYear\":345240,\"msOfMinute\":54001,\"regionalID\":0,\"requestorInfo\":[{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":20.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":8,\"msgCount\":2,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":601}],\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + Json::Value root; + converter.parseJsonString(valid_json_str, root); + auto ssmPtr = std::make_shared(); + converter.toJ2735SSM(root, ssmPtr); + tmx::messages::SsmEncodedMessage encodedSSM; + converter.encodeSSM(ssmPtr, encodedSSM); + string expected_payload_hex = "001e18454498d2f1001007d8054a000004b20a090010000280fa08"; + ASSERT_EQ(expected_payload_hex, encodedSSM.get_payload_str()); + + // Json has three requestors + valid_json_str = "{\"MessageType\":\"SSM\",\"SignalStatus\":{\"intersectionID\":1003,\"minuteOfYear\":345239,\"msOfMinute\":54000,\"regionalID\":0,\"requestorInfo\":[{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":20.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":8,\"msgCount\":2,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":601},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":16,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":4,\"requestID\":5,\"vehicleID\":605},{\"ETA_Duration\":2000,\"ETA_Minute\":1,\"ETA_Second\":22.001000000000005,\"basicVehicleRole\":9,\"inBoundLaneID\":12,\"msgCount\":6,\"priorityRequestStatus\":0,\"requestID\":5,\"vehicleID\":610}],\"sequenceNumber\":4,\"updateCount\":4},\"noOfRequest\":3}"; + converter.parseJsonString(valid_json_str, root); + converter.toJ2735SSM(root, ssmPtr); + converter.encodeSSM(ssmPtr, encodedSSM); + expected_payload_hex = "001e35454497d2f0001007d6254a000004b20a090010000280fa08a940000097414320030000581f4115280000131028624060000b03e800"; + ASSERT_EQ(expected_payload_hex, encodedSSM.get_payload_str()); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SignalStatusMessage, ssmPtr.get()); + } +} \ No newline at end of file diff --git a/src/v2i-hub/ImmediateForwardPlugin/manifest.json b/src/v2i-hub/ImmediateForwardPlugin/manifest.json index 5b142b2b1..43e6603c4 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/manifest.json +++ b/src/v2i-hub/ImmediateForwardPlugin/manifest.json @@ -14,7 +14,7 @@ }, { "key": "Messages_Destination_1", - "default": "{ \"Messages\": [ { \"TmxType\": \"SPAT-P\", \"SendType\": \"SPAT\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"MAP-P\", \"SendType\": \"MAP\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"PSM\", \"SendType\": \"PSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" } ,{ \"TmxType\": \"TMSG07\", \"SendType\": \"TMSG07\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG03-P\", \"SendType\": \"TMSG03-P\", \"PSID\": \"0xBFEE\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG05-P\", \"SendType\": \"TMSG05-P\", \"PSID\": \"0x8003\", \"Channel\": \"183\" }] }", + "default": "{ \"Messages\": [ { \"TmxType\": \"SPAT-P\", \"SendType\": \"SPAT\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"MAP-P\", \"SendType\": \"MAP\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"PSM\", \"SendType\": \"PSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" } ,{ \"TmxType\": \"TMSG07\", \"SendType\": \"TMSG07\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG03-P\", \"SendType\": \"TMSG03-P\", \"PSID\": \"0xBFEE\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG05-P\", \"SendType\": \"TMSG05-P\", \"PSID\": \"0x8003\", \"Channel\": \"183\" }, { \"TmxType\": \"SSM\", \"SendType\": \"SSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },] }", "description": "JSON data defining the message types, PSIDs, and channel number for messages forwarded to the V2X radio at destination 1." }, { From 4528b26194e76de39bade494e85cea8d6c47cf1b Mon Sep 17 00:00:00 2001 From: Will Martin Date: Fri, 16 Jun 2023 09:33:40 -0400 Subject: [PATCH 13/15] modified: src/v2i-hub/ImmediateForwardPlugin/manifest.json (#541) # PR Details ## Description Removing unexpected comma in manifest.json ## Related Issue ## Motivation and Context ## How Has This Been Tested? ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- src/v2i-hub/ImmediateForwardPlugin/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2i-hub/ImmediateForwardPlugin/manifest.json b/src/v2i-hub/ImmediateForwardPlugin/manifest.json index 43e6603c4..b26756a76 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/manifest.json +++ b/src/v2i-hub/ImmediateForwardPlugin/manifest.json @@ -14,7 +14,7 @@ }, { "key": "Messages_Destination_1", - "default": "{ \"Messages\": [ { \"TmxType\": \"SPAT-P\", \"SendType\": \"SPAT\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"MAP-P\", \"SendType\": \"MAP\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"PSM\", \"SendType\": \"PSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" } ,{ \"TmxType\": \"TMSG07\", \"SendType\": \"TMSG07\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG03-P\", \"SendType\": \"TMSG03-P\", \"PSID\": \"0xBFEE\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG05-P\", \"SendType\": \"TMSG05-P\", \"PSID\": \"0x8003\", \"Channel\": \"183\" }, { \"TmxType\": \"SSM\", \"SendType\": \"SSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },] }", + "default": "{ \"Messages\": [ { \"TmxType\": \"SPAT-P\", \"SendType\": \"SPAT\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"MAP-P\", \"SendType\": \"MAP\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }, { \"TmxType\": \"PSM\", \"SendType\": \"PSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" } ,{ \"TmxType\": \"TMSG07\", \"SendType\": \"TMSG07\", \"PSID\": \"0x8002\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG03-P\", \"SendType\": \"TMSG03-P\", \"PSID\": \"0xBFEE\", \"Channel\": \"183\" },{ \"TmxType\": \"TMSG05-P\", \"SendType\": \"TMSG05-P\", \"PSID\": \"0x8003\", \"Channel\": \"183\" }, { \"TmxType\": \"SSM\", \"SendType\": \"SSM\", \"PSID\": \"0x8002\", \"Channel\": \"183\" }] }", "description": "JSON data defining the message types, PSIDs, and channel number for messages forwarded to the V2X radio at destination 1." }, { From 37eeb9ba7f043548f9743c1e961c61adee0bbfc6 Mon Sep 17 00:00:00 2001 From: Will Martin Date: Wed, 5 Jul 2023 11:23:14 -0400 Subject: [PATCH 14/15] Routable metadata (#545) # PR Details ## Description Adds PSID metadata to BSMs and SRMs that are sent to the Message Receiver plugin. If "RouteMessage" is enabled, the messages will be available for the Immediate Forward plugin to use. Additional changes were made to build process to speed up process. ## Related Issue ## Motivation and Context ## How Has This Been Tested? Sent BSMs and SRMs to Message Receiver plugin. Messages were transmitted by Immediate Forward plugin when "RouteMessage" was enabled and not routed when disabled. Previously, messages were skipped or not routed, respectively. ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [X] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [X] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- ext/build.sh | 15 +++--- scripts/install_dependencies.sh | 3 ++ src/build.sh | 5 +- src/tmx/TmxApi/tmx/IvpMessage.h | 4 +- src/tmx/TmxApi/tmx/TmxApiMessages.h | 51 ++++++++++++++++++- .../src/ImmediateForwardPlugin.cpp | 2 +- .../MessageReceiverPlugin/manifest.json | 4 +- .../src/MessageReceiverPlugin.cpp | 9 ++-- 8 files changed, 76 insertions(+), 17 deletions(-) diff --git a/ext/build.sh b/ext/build.sh index 74a9d578c..03d2ec4fb 100755 --- a/ext/build.sh +++ b/ext/build.sh @@ -3,6 +3,9 @@ # exit on errors set -e +# Find number of cores available +numCPU=$(nproc) + # An OPENAPI based Qt webservice is needed by the plugins for http requests processing. A custom generated code using OPENAPI framework is located in GitHub. pushd /tmp QHTTPENGINE_VERSION=1.0.1 @@ -10,7 +13,7 @@ wget -O qhttpengine-${QHTTPENGINE_VERSION}.tar.gz https://github.com/nitroshare/ tar xvf qhttpengine-${QHTTPENGINE_VERSION}.tar.gz cd qhttpengine-${QHTTPENGINE_VERSION}/ cmake . -make +make -j${numCPU} make install popd @@ -20,7 +23,7 @@ wget -O date-${DATELIB_VERSION}.tar.gz https://github.com/HowardHinnant/date/arc tar xvf date-${DATELIB_VERSION}.tar.gz cd date-${DATELIB_VERSION}/ cmake . -make +make -j${numCPU} make install popd @@ -29,19 +32,19 @@ ldconfig # Server for the Qt webservice pushd server cmake . -make +make -j${numCPU} make install popd pushd ccserver cmake . -make +make -j${numCPU} make install popd pushd pdclient cmake . -make +make -j${numCPU} make install popd @@ -50,6 +53,6 @@ pushd /tmp git clone https://github.com/ckgt/NemaTode.git cd NemaTode cmake . -make +make -j${numCPU} make install popd \ No newline at end of file diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index 9ddc86c72..2fa104c86 100755 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -41,9 +41,12 @@ LIBRARY_DEPENDENCIES=" \ # install all things needed for deployment, always done apt-get install -y $DEPENDENCIES ${LIBRARY_DEPENDENCIES} +numCPU=$(nproc) + # install gtest cd /usr/src/googletest/ mkdir -p build/ cd build cmake .. +make -j${numCPU} make install diff --git a/src/build.sh b/src/build.sh index 48fa43381..9bb3d4c4f 100755 --- a/src/build.sh +++ b/src/build.sh @@ -18,6 +18,8 @@ set -e # script executes all tmx and v2i build and coverage steps so that they can be singularly # wrapped by the sonarcloud build-wrapper +numCPU=$(nproc) + RELEASE_BUILD=0 if [ "$1" = "release" ]; then RELEASE_BUILD=1 @@ -36,7 +38,7 @@ fi pushd tmx cmake -Bbuild -DCMAKE_PREFIX_PATH=\"/usr/local/share/tmx\;\/opt/carma/cmake\;\" -DCMAKE_CXX_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_C_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" . pushd build -make +make -j${numCPU} make install popd popd @@ -44,6 +46,7 @@ popd pushd v2i-hub cmake -Bbuild -DCMAKE_PREFIX_PATH=\"/usr/local/share/tmx\;\/opt/carma/cmake\;\" -DqserverPedestrian_DIR=/usr/local/share/qserverPedestrian/cmake -Dv2xhubWebAPI_DIR=/usr/local/share/v2xhubWebAPI/cmake/ -DCMAKE_CXX_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_C_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" . pushd build +make -j${numCPU} make install popd popd diff --git a/src/tmx/TmxApi/tmx/IvpMessage.h b/src/tmx/TmxApi/tmx/IvpMessage.h index 7bd74b3ac..698f66cf0 100644 --- a/src/tmx/TmxApi/tmx/IvpMessage.h +++ b/src/tmx/TmxApi/tmx/IvpMessage.h @@ -20,8 +20,8 @@ typedef unsigned int IvpMsgFlags; #define IvpMsgFlags_RouteDSRC 0x01 typedef struct IvpDsrcMetadata { - int channel; int psid; + int channel; } IvpDsrcMetadata; typedef struct IvpMessage { @@ -64,7 +64,7 @@ typedef enum { */ IvpMessage *ivpMsg_create(const char *type, const char *subtype, const char *encoding, IvpMsgFlags flags, cJSON *payload); -IvpMessage *ivpMsg_addDsrcMetadata(IvpMessage *msg, int channel, int psid); +IvpMessage *ivpMsg_addDsrcMetadata(IvpMessage *msg, int psid, int channel); /*! * Creates a new IvpMessage from a json string. diff --git a/src/tmx/TmxApi/tmx/TmxApiMessages.h b/src/tmx/TmxApi/tmx/TmxApiMessages.h index b4327e50f..b680329ff 100644 --- a/src/tmx/TmxApi/tmx/TmxApiMessages.h +++ b/src/tmx/TmxApi/tmx/TmxApiMessages.h @@ -177,7 +177,56 @@ static CONSTEXPR const char *STATUS_STARTED_STRING = "Started, waiting for conne static CONSTEXPR const char *STATUS_RUNNING_STRING = "Running"; static CONSTEXPR const char *STATUS_STALE_STRING = "Connection going stale"; static CONSTEXPR const char *STATUS_STOPPED_STRING = "Stopped / Disconnected"; - + +enum msgPSID +{ + None_PSID = 0x00, + mapData_PSID = 0x8002, + signalPhaseAndTimingMessage_PSID = 0x8002, + basicSafetyMessage_PSID = 0x20, + commonSafetyRequest_PSID = 0x20, + emergencyVehicleAlert_PSID = 0x8005, + intersectionCollision_PSID = 0x8002, + nmeaCorrections_PSID = 0x8000, + probeDataManagement_PSID = 0x8004, + probeVehicleData_PSID = 0x8004, + roadSideAlert_PSID = 0x8003, + rtcmCorrections_PSID = 0x8000, + signalRequestMessage_PSID = 0xE0000016, + signalStatusMessage_PSID = 0x8002, + travelerInformation_PSID = 0x8003, + personalSafetyMessage_PSID = 0x27, + testMessage00_PSID = 0xBFEE, + testMessage01_PSID = 0xBFEE, + testMessage02_PSID = 0xBFEE, + testMessage03_PSID = 0xBFEE, + testMessage04_PSID = 0x8003, + testMessage05_PSID = 0x8003 +}; + +static CONSTEXPR const char *MSGPSID_NONE_PSID_STRING = "None"; +static CONSTEXPR const char *MSGPSID_MAPDATA_PSID_STRING = "0x8002"; +static CONSTEXPR const char *MSGPSID_SIGNALPHASEANDTIMINGMESSAGE_PSID_STRING = "0x8002"; +static CONSTEXPR const char *MSGPSID_BASICSAFETYMESSAGE_PSID_STRING = "0x20"; +static CONSTEXPR const char *MSGPSID_COMMONSAFETYREQUEST_PSID_STRING = "0x20"; +static CONSTEXPR const char *MSGPSID_EMERGENCYVEHICLEALERT_PSID_STRING = "0x8005"; +static CONSTEXPR const char *MSGPSID_INTERSECTIONCOLLISION_PSID_STRING = "0x8002"; +static CONSTEXPR const char *MSGPSID_NMEACORRECTIONS_PSID_STRING = "0x8000"; +static CONSTEXPR const char *MSGPSID_PROBEDATAMANAGEMENT_PSID_STRING = "0x8004"; +static CONSTEXPR const char *MSGPSID_PROBEVEHICLEDATA_PSID_STRING = "0x8004"; +static CONSTEXPR const char *MSGPSID_ROADSIDEALERT_PSID_STRING = "0x8003"; +static CONSTEXPR const char *MSGPSID_RTCMCORRECTIONS_PSID_STRING = "0x8000"; +static CONSTEXPR const char *MSGPSID_SIGNALREQUESTMESSAGE_PSID_STRING = "0xE0000016"; +static CONSTEXPR const char *MSGPSID_SIGNALSTATUSMESSAGE_PSID_STRING = "0x8002"; +static CONSTEXPR const char *MSGPSID_TRAVELERINFORMATION_PSID_STRING = "0x8003"; +static CONSTEXPR const char *MSGPSID_PERSONALSAFETYMESSAGE_PSID_STRING = "0x27"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE00_PSID_STRING = "0xBFEE"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE01_PSID_STRING = "0xBFEE"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE02_PSID_STRING = "0xBFEE"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE03_PSID_STRING = "0xBFEE"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE04_PSID_STRING = "0x8003"; +static CONSTEXPR const char *MSGPSID_TESTMESSAGE05_PSID_STRING = "0x8003"; + } /* End namespace api */ } /* End namespace messages */ diff --git a/src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.cpp b/src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.cpp index 7e957c80c..e907ce667 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.cpp +++ b/src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.cpp @@ -428,7 +428,7 @@ void ImmediateForwardPlugin::SendMessageToRadio(IvpMessage *msg) if (!foundMessageType) { SetStatus(Key_SkippedNoMessageRoute, ++_skippedNoMessageRoute); - PLOG(logWARNING)<<" WARNINNG TMX Subtype not found in configuration. Message Ignored: " << + PLOG(logWARNING)<<" WARNING TMX Subtype not found in configuration. Message Ignored: " << "Type: " << msg->type << ", Subtype: " << msg->subtype; return; } diff --git a/src/v2i-hub/MessageReceiverPlugin/manifest.json b/src/v2i-hub/MessageReceiverPlugin/manifest.json index 0ca9ed689..7be05050d 100644 --- a/src/v2i-hub/MessageReceiverPlugin/manifest.json +++ b/src/v2i-hub/MessageReceiverPlugin/manifest.json @@ -29,9 +29,9 @@ "description":"Port for the incoming message network connection." }, { - "key":"RouteDSRC", + "key":"RouteJ2735", "default":"false", - "description":"Set the flag to route a received J2735 message." + "description":"Set the flag to route/broadcast a received J2735 message to TMX Core." }, { "key":"EnableSimulatedBSM", diff --git a/src/v2i-hub/MessageReceiverPlugin/src/MessageReceiverPlugin.cpp b/src/v2i-hub/MessageReceiverPlugin/src/MessageReceiverPlugin.cpp index dee2bfa7e..0da347c74 100644 --- a/src/v2i-hub/MessageReceiverPlugin/src/MessageReceiverPlugin.cpp +++ b/src/v2i-hub/MessageReceiverPlugin/src/MessageReceiverPlugin.cpp @@ -166,7 +166,7 @@ void MessageReceiverPlugin::OnMessageReceived(routeable_message &msg) BsmEncodedMessage encodedBsm; SrmEncodedMessage encodedSrm; - + int msgPSID = api::msgPSID::None_PSID; if (msg.get_type() == "Unknown" && msg.get_subtype() == "Unknown") { @@ -263,6 +263,7 @@ void MessageReceiverPlugin::OnMessageReceived(routeable_message &msg) } sendMsg = encode(encodedBsm, bsm); + msgPSID = api::msgPSID::basicSafetyMessage_PSID; if (!simBSM) return; } break; @@ -280,7 +281,7 @@ void MessageReceiverPlugin::OnMessageReceived(routeable_message &msg) ntohl(*((uint32_t*)&(bytes.data()[24]))), ntohl(*((uint32_t*)&(bytes.data()[28])))); sendMsg = encode(encodedSrm, srm); - + msgPSID = api::msgPSID::signalRequestMessage_PSID; } break; default: @@ -330,6 +331,7 @@ void MessageReceiverPlugin::OnMessageReceived(routeable_message &msg) if (routeDsrc) { sendMsg->set_flags(IvpMsgFlags_RouteDSRC); + sendMsg->addDsrcMetadata(msgPSID); } else { @@ -345,7 +347,7 @@ void MessageReceiverPlugin::UpdateConfigSettings() lock_guard lock(syncLock); // Atomic flags - GetConfigValue("RouteDSRC", routeDsrc); + GetConfigValue("RouteJ2735", routeDsrc); GetConfigValue("EnableSimulatedBSM", simBSM); GetConfigValue("EnableSimulatedSRM", simSRM); GetConfigValue("EnableSimulatedLocation", simLoc); @@ -465,7 +467,6 @@ int MessageReceiverPlugin::Main() SetStatus(Key_SkippedSignVerifyError, ++_skippedSignVerifyErrorResponse); PLOG(logERROR) << "Error parsing Messages: " << ex.what(); continue; -; } PLOG(logDEBUG1) << "SCMS Contain response = " << result << std::endl; cJSON *root = cJSON_Parse(result.c_str()); From b708d325f68cbda0888333fd464746f515abf163 Mon Sep 17 00:00:00 2001 From: Andy <109987630+gainesaw@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:13:38 -0400 Subject: [PATCH 15/15] updated initialization script for amd64 and arm64. (#546) # PR Details ## Description script now installs necessary dependencies, creates secret files, prompts user to input mysql passwords, and create v2xhub user ## Related Issue open JIRA task to update initialization script for amd64 and arm64 ## Motivation and Context requested by project leads, automates v2xhub setup/initialization ## How Has This Been Tested? code has been used to setup v2xhub from scratch ## Types of changes - [ ] Defect fix (non-breaking change that fixes an issue) - [ x] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that cause existing functionality to change) ## Checklist: - [ ] I have added any new packages to the sonar-scanner.properties file - [x ] My change requires a change to the documentation. - ###potential change to documentation as running this script automates setup. user only needs to clone the repo, run the script, and input passwords when prompted, then navigate to https://127.0.0.1:19760 to accept security certs then v2xhub is ready to use. - [ ] I have updated the documentation accordingly. - [x ] I have read the **CONTRIBUTING** document. [V2XHUB Contributing Guide](https://github.com/usdot-fhwa-OPS/V2X-Hub/blob/develop/Contributing.md) - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. --- configuration/amd64/initialization.sh | 37 +++++++++++++++++++++++++-- configuration/arm64/initialization.sh | 36 ++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/configuration/amd64/initialization.sh b/configuration/amd64/initialization.sh index 9a9f68e18..03660e9d5 100755 --- a/configuration/amd64/initialization.sh +++ b/configuration/amd64/initialization.sh @@ -1,12 +1,45 @@ #!/bin/bash + +# update and upgrade commands to update linux OS +sudo apt update -y && sudo apt upgrade -y + +#installing necessary and useful apps +sudo apt-get install chromium-browser -y #Chrome required for CARMA platform/V2X Hub UI(?) +sudo apt install curl -y #Curl for downloading files over internet + +#install docker +curl -L https://raw.githubusercontent.com/usdot-fhwa-stol/carma-platform/develop/engineering_tools/install-docker.sh | bash + +#make passwords for mysql +mkdir secrets && cd secrets + +#creates password files where user inputs password +read -p "enter password for the mysql_root_password: " sql_root_pass +echo "$sql_root_pass" > sql_root_pass.txt + +read -p "enter password for mysql_password: " sql_pass +echo "$sql_pass" > sql_pass.txt + +#remove endline characters from password files +tr -d '\n' mysql_root_password.txt && tr -d '\n' mysql_password.txt +rm sql_root_pass.txt && rm sql_pass.txt + +#AMD64 initialzation +cd .. sudo apt-get -y remove docker docker-engine docker.io containerd runc -sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" -sudo apt-get update sudo apt-get -y install docker-ce docker-ce-cli containerd.io sudo apt -y install python3-pip sudo pip3 install docker-compose sudo docker-compose pull +sudo apt update -y && sudo apt upgrade -y sudo docker-compose up -d + +#create v2xhub user +cd mysql +./add_v2xhub_user.bash + +chromium-browser "https://127.0.0.1" > /dev/null 2>&1 & +chromium-browser "https://127.0.0.1:19760" > /dev/null 2>&1 & diff --git a/configuration/arm64/initialization.sh b/configuration/arm64/initialization.sh index f8a4dc088..2430a1641 100755 --- a/configuration/arm64/initialization.sh +++ b/configuration/arm64/initialization.sh @@ -1,13 +1,45 @@ #!/bin/bash +# update and upgrade commands to update linux OS +sudo apt update -y && sudo apt upgrade -y + +#installing necessary and useful apps +sudo apt-get install chromium-browser -y #Chrome required for CARMA platform/V2X Hub UI(?) +sudo apt install curl -y #Curl for downloading files over internet + +#install docker +curl -L https://raw.githubusercontent.com/usdot-fhwa-stol/carma-platform/develop/engineering_tools/install-docker.sh | bash + +#make passwords for mysql +mkdir secrets && cd secrets + +#creates password files where user inputs password +read -p "enter password for the mysql_root_password: " sql_root_pass +echo "$sql_root_pass" > sql_root_pass.txt + +read -p "enter password for mysql_password: " sql_pass +echo "$sql_pass" > sql_pass.txt + +#remove endline characters from password files +tr -d '\n' mysql_root_password.txt && tr -d '\n' mysql_password.txt +rm sql_root_pass.txt && rm sql_pass.txt + +#ARM initialization +cd .. sudo apt-get -y remove docker docker-engine docker.io containerd runc -sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common OS=$(lsb_release -i | awk 'FS=":" {print $3;}' | awk '{print tolower($0)}') arch=$(dpkg --print-architecture) curl -fsSL https://download.docker.com/linux/$OS/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=$arch] https://download.docker.com/linux/$OS $(lsb_release -cs) stable" -sudo apt-get update sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin sudo apt -y install python3-pip sudo pip3 install docker-compose +sudo apt update -y && sudo apt upgrade -y sudo docker-compose up -d + +#create v2xhub user +cd mysql +./add_v2xhub_user.bash + +chromium-browser "https://127.0.0.1" > /dev/null 2>&1 & +chromium-browser "https://127.0.0.1:19760" > /dev/null 2>&1 &