mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-18 08:20:08 -07:00
More API features
This commit is contained in:
parent
7b276a21e3
commit
e243ad615f
163
application/.settings/org.eclipse.cdt.core.prefs
Normal file
163
application/.settings/org.eclipse.cdt.core.prefs
Normal file
@ -0,0 +1,163 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=18
|
||||
org.eclipse.cdt.core.formatter.alignment_for_assignment=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
|
||||
org.eclipse.cdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=34
|
||||
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain=18
|
||||
org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_member_access=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=18
|
||||
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment=1
|
||||
org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column=true
|
||||
org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true
|
||||
org.eclipse.cdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
|
||||
org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces=0
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=true
|
||||
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=true
|
||||
org.eclipse.cdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=true
|
||||
org.eclipse.cdt.core.formatter.indentation.size=4
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.lineSplit=80
|
||||
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.cdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.cdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
3
application/.settings/org.eclipse.cdt.ui.prefs
Normal file
3
application/.settings/org.eclipse.cdt.ui.prefs
Normal file
@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_GNU Variant
|
||||
formatter_settings_version=1
|
@ -225,9 +225,17 @@ void CommandProcessor::setLength(uint8_t len)
|
||||
sendEmptyReply(true);
|
||||
}
|
||||
|
||||
void CommandProcessor::setVesselData(const char *data)
|
||||
void CommandProcessor::setVesselData(const char *s)
|
||||
{
|
||||
sendEmptyReply(true);
|
||||
StationData data;
|
||||
EEPROM::instance().readStationData(data);
|
||||
int items = sscanf(s, "%lu,%s,%s,%cu,%cu", &data.mmsi, data.name, data.callsign, &data.beam, &data.len);
|
||||
if ( items < 5 )
|
||||
sendEmptyReply(false);
|
||||
else {
|
||||
EEPROM::instance().writeStationData(data);
|
||||
sendEmptyReply(true);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandProcessor::setMode(const char *mode)
|
||||
@ -259,6 +267,20 @@ void CommandProcessor::setMode(const char *mode)
|
||||
Event *e = EventPool::instance().newEvent(RESET_EVENT);
|
||||
EventQueue::instance().push(e);
|
||||
}
|
||||
else if ( strcmp(mode, "rx") == 0 ) {
|
||||
StationData data;
|
||||
EEPROM::instance().readStationData(data);
|
||||
data.flags |= STATION_RX_ONLY;
|
||||
EEPROM::instance().writeStationData(data);
|
||||
sendEmptyReply(true);
|
||||
}
|
||||
else if ( strcmp(mode, "trx") == 0 ) {
|
||||
StationData data;
|
||||
EEPROM::instance().readStationData(data);
|
||||
data.flags &= ~(STATION_RX_ONLY);
|
||||
EEPROM::instance().writeStationData(data);
|
||||
sendEmptyReply(true);
|
||||
}
|
||||
else
|
||||
sendError("Unrecognized mode");
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "printf2.h"
|
||||
#include <stm32f30x_i2c.h>
|
||||
#include "Utils.hpp"
|
||||
#include <cstring>
|
||||
|
||||
#define EEPROM_STATION_ADDR 0x00 // A StationData structure starts here
|
||||
#define EEPROM_REGION_CNT_ADDR 0x24 // Number of active special regions goes here (single byte)
|
||||
@ -76,6 +77,7 @@ void EEPROM::init()
|
||||
I2C_Init(I2C1, &i2c);
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
|
||||
readStationData(mData);
|
||||
}
|
||||
|
||||
uint8_t EEPROM::readByte(uint8_t addr)
|
||||
@ -133,6 +135,8 @@ void EEPROM::writeByte(uint8_t address, uint8_t byte)
|
||||
|
||||
void EEPROM::writeStationData(const StationData &data)
|
||||
{
|
||||
memcpy(&mData, &data, sizeof data);
|
||||
|
||||
uint8_t addr = EEPROM_STATION_ADDR;
|
||||
const uint8_t *p = (uint8_t*)&data;
|
||||
for ( size_t i = 0; i < sizeof data; ++i )
|
||||
@ -141,12 +145,15 @@ void EEPROM::writeStationData(const StationData &data)
|
||||
|
||||
void EEPROM::readStationData(StationData &data)
|
||||
{
|
||||
memcpy(&data, &mData, sizeof mData);
|
||||
/*
|
||||
uint8_t addr = EEPROM_STATION_ADDR;
|
||||
uint8_t *p = (uint8_t*)&data;
|
||||
for ( size_t i = 0; i < sizeof data; ++i ) {
|
||||
uint8_t byte = readByte(addr++);
|
||||
*p++ = byte;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
|
||||
private:
|
||||
EEPROM();
|
||||
StationData mData;
|
||||
};
|
||||
|
||||
#endif /* EEPROM_HPP_ */
|
||||
|
@ -238,26 +238,27 @@ void GPS::processLine(const char* buff)
|
||||
}
|
||||
}
|
||||
|
||||
void GPS::parseSentence(const char *buff)
|
||||
void
|
||||
GPS::parseSentence(const char *buff)
|
||||
{
|
||||
//printf2(buff);
|
||||
//if ( strstr(buff, "RMC") != buff+3 )
|
||||
// return;
|
||||
// return;
|
||||
|
||||
NMEASentence sentence(buff);
|
||||
if ( sentence.code().find("RMC") == 2 ) {
|
||||
NMEASentence sentence (buff);
|
||||
if (sentence.code ().find ("RMC") == 2) {
|
||||
#ifdef ENABLE_TERMINAL
|
||||
#ifdef OUTPUT_GPS_NMEA
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
DataTerminal::instance().write("NMEA", buff);
|
||||
DataTerminal::instance ().write ("NMEA", buff);
|
||||
#else
|
||||
DataTerminal::instance().write(buff);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This is the time that corresponds to the previous PPS
|
||||
const vector<string> &fields = sentence.fields();
|
||||
// This is the time that corresponds to the previous PPS
|
||||
const vector<string> &fields = sentence.fields ();
|
||||
|
||||
/*
|
||||
* Sometimes the GPS indicates errors with sentences like
|
||||
@ -266,43 +267,38 @@ void GPS::parseSentence(const char *buff)
|
||||
*
|
||||
* TODO: Should we consider the GPS non-functioning at this point and thus prevent transmission until it recovers?
|
||||
*/
|
||||
if ( fields.size() < 10 )
|
||||
if (fields.size () < 10)
|
||||
return;
|
||||
|
||||
// GPS updates arrive even with no time or fix information
|
||||
if ( fields[1].length() < 6 || fields[9].length() < 6 )
|
||||
if (fields[1].length () < 6 || fields[9].length () < 6)
|
||||
return;
|
||||
|
||||
//printf2(buff);
|
||||
//LEDManager::instance().blink();
|
||||
|
||||
if ( mUTC == 0 ) {
|
||||
const string ×tr = fields[1].substr(0, 6);
|
||||
const string &datestr = fields[9].substr(0, 6);
|
||||
mTime.tm_hour = Utils::toInt(timestr.substr(0, 2));
|
||||
mTime.tm_min = Utils::toInt(timestr.substr(2, 2));
|
||||
mTime.tm_sec = Utils::toInt(timestr.substr(4, 2));
|
||||
mTime.tm_mday = Utils::toInt(datestr.substr(0, 2));
|
||||
mTime.tm_mon = Utils::toInt(datestr.substr(2, 2)) - 1; // Month is 0-based
|
||||
mTime.tm_year = 100 + Utils::toInt(datestr.substr(4, 2)); // Year is 1900-based
|
||||
mUTC = mktime(&mTime);
|
||||
//printf2("UTC=%d\r\n", mUTC);
|
||||
}
|
||||
const string ×tr = fields[1].substr (0, 6);
|
||||
const string &datestr = fields[9].substr (0, 6);
|
||||
mTime.tm_hour = Utils::toInt (timestr.substr (0, 2));
|
||||
mTime.tm_min = Utils::toInt (timestr.substr (2, 2));
|
||||
mTime.tm_sec = Utils::toInt (timestr.substr (4, 2));
|
||||
mTime.tm_mday = Utils::toInt (datestr.substr (0, 2));
|
||||
mTime.tm_mon = Utils::toInt (datestr.substr (2, 2)) - 1; // Month is 0-based
|
||||
mTime.tm_year = 100 + Utils::toInt (datestr.substr (4, 2)); // Year is 1900-based
|
||||
mUTC = mktime (&mTime);
|
||||
|
||||
// Do we have a fix?
|
||||
if ( mUTC && sentence.fields()[3].length() > 0 && sentence.fields()[5].length() > 0 ) {
|
||||
mLat = Utils::latitudeFromNMEA(sentence.fields()[3], sentence.fields()[4]);
|
||||
mLng = Utils::longitudeFromNMEA(sentence.fields()[5], sentence.fields()[6]);
|
||||
mSpeed = Utils::toDouble(sentence.fields()[7]);
|
||||
mCOG = Utils::toDouble(sentence.fields()[8]);
|
||||
Event *event = EventPool::instance().newEvent(GPS_FIX_EVENT);
|
||||
if ( event ) {
|
||||
if (mUTC && sentence.fields ()[3].length () > 0 && sentence.fields ()[5].length () > 0) {
|
||||
mLat = Utils::latitudeFromNMEA (sentence.fields ()[3], sentence.fields ()[4]);
|
||||
mLng = Utils::longitudeFromNMEA (sentence.fields ()[5], sentence.fields ()[6]);
|
||||
mSpeed = Utils::toDouble (sentence.fields ()[7]);
|
||||
mCOG = Utils::toDouble (sentence.fields ()[8]);
|
||||
Event *event = EventPool::instance ().newEvent (GPS_FIX_EVENT);
|
||||
if (event) {
|
||||
event->gpsFix.utc = mUTC;
|
||||
event->gpsFix.lat = mLat;
|
||||
event->gpsFix.lng = mLng;
|
||||
event->gpsFix.speed = mSpeed;
|
||||
event->gpsFix.cog = mCOG;
|
||||
EventQueue::instance().push(event);
|
||||
EventQueue::instance ().push (event);
|
||||
}
|
||||
//printf2("Lat: %f, Lng: %f\r\n", mLat, mLng);
|
||||
}
|
||||
|
@ -247,34 +247,5 @@ uint32_t RXPacket::mmsi() const
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RXPacketPool
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
RXPacketPool &RXPacketPool::instance()
|
||||
{
|
||||
static RXPacketPool __instance;
|
||||
return __instance;
|
||||
}
|
||||
|
||||
void RXPacketPool::init()
|
||||
{
|
||||
mPool = new ObjectPool<RXPacket>(40);
|
||||
}
|
||||
|
||||
RXPacket *RXPacketPool::newRXPacket()
|
||||
{
|
||||
return mPool->get();
|
||||
}
|
||||
|
||||
void RXPacketPool::deleteRXPacket(RXPacket *p)
|
||||
{
|
||||
ASSERT(p);
|
||||
mPool->put(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define RXPACKET_HPP_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "ObjectPool.hpp"
|
||||
#include "_assert.h"
|
||||
#include "globals.h"
|
||||
#include "AISChannels.h"
|
||||
|
||||
@ -70,21 +70,4 @@ private:
|
||||
uint8_t mRSSI;
|
||||
};
|
||||
|
||||
#if 0
|
||||
class RXPacketPool
|
||||
{
|
||||
public:
|
||||
static RXPacketPool &instance();
|
||||
|
||||
void init();
|
||||
|
||||
RXPacket *newRXPacket();
|
||||
void deleteRXPacket(RXPacket*);
|
||||
|
||||
private:
|
||||
ObjectPool<RXPacket> *mPool;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* RXPACKET_HPP_ */
|
||||
|
@ -13,11 +13,14 @@
|
||||
#include <time.h>
|
||||
#include "AISChannels.h"
|
||||
|
||||
// Station flags
|
||||
#define STATION_RX_ONLY 0x01
|
||||
#define STATION_PRIVACY_MODE 0x02
|
||||
|
||||
struct StationData {
|
||||
uint32_t mmsi; // Vessel MMSI (should be 30 bit)
|
||||
char name[21]; // Vessel name (all caps)
|
||||
char callsign[8]; // Radio station call sign assigned with MMSI
|
||||
char callsign[8]; // Radio station call sign assigned with MMSI (if applicable)
|
||||
uint8_t len; // Length in meters (default: 0)
|
||||
uint8_t beam; // Beam in meters (default: 0)
|
||||
uint8_t flags; // Reserved - 0 for now
|
||||
|
@ -25,13 +25,10 @@ TXScheduler::TXScheduler ()
|
||||
mPositionReportChannel = CH_87;
|
||||
mStaticDataChannel = CH_87;
|
||||
mUTC = 0;
|
||||
mAvgSpeed = 0.0;
|
||||
mTesting = false;
|
||||
|
||||
EEPROM::instance().readStationData(mStationData);
|
||||
printf2("Read station data from EEPROM:\r\n");
|
||||
printf2("MMSI: %d\r\n", mStationData.mmsi);
|
||||
printf2("CS: %s\r\n", mStationData.callsign);
|
||||
printf2("Name: %s\r\n", mStationData.name);
|
||||
mLast18Time = 0;
|
||||
mLast24Time = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -55,18 +52,24 @@ void TXScheduler::processEvent(const Event &e)
|
||||
if ( mTesting )
|
||||
return;
|
||||
|
||||
//GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (event);
|
||||
|
||||
//printf2("UTC: %d\r\n", mUTC);
|
||||
|
||||
// We do not schedule transmissions if the ChannelManager is not sure what channels are in use yet
|
||||
if ( !ChannelManager::instance().channelsDetermined() )
|
||||
return;
|
||||
|
||||
// TODO: This is UGLY. Stop using modulus and start counting from previous timestamps
|
||||
// A class B transponder only transmits when its internal GPS is working, so we tie these to GPS updates.
|
||||
if ( !RadioManager::instance().initialized() || mUTC == 0 )
|
||||
return;
|
||||
|
||||
// A class B only transmits when its internal GPS is working, so we tie these to GPS updates.
|
||||
if ( RadioManager::instance().initialized() && mUTC && (mUTC % DEFAULT_TX_INTERVAL) == 0) {
|
||||
StationData stationData;
|
||||
EEPROM::instance().readStationData(stationData);
|
||||
if ( stationData.flags & STATION_RX_ONLY )
|
||||
return;
|
||||
|
||||
// Using a moving average to determine transmission rate
|
||||
double alpha = 0.2;
|
||||
mAvgSpeed = mAvgSpeed * (1.0 - alpha) + e.gpsFix.speed * alpha;
|
||||
|
||||
if ( mUTC - mLast18Time > positionReportTimeInterval() ) {
|
||||
TXPacket *p1 = TXPacketPool::instance().newTXPacket(mPositionReportChannel, mUTC);
|
||||
if ( !p1 ) {
|
||||
printf2("Unable to allocate TX packet for message 18, will try again later\r\n");
|
||||
@ -80,22 +83,23 @@ void TXScheduler::processEvent(const Event &e)
|
||||
msg.cog = e.gpsFix.cog;
|
||||
msg.utc = e.gpsFix.utc;
|
||||
|
||||
msg.encode (mStationData, *p1);
|
||||
msg.encode (stationData, *p1);
|
||||
RadioManager::instance ().scheduleTransmission (p1);
|
||||
|
||||
// Our next position report should be on the other channel
|
||||
mPositionReportChannel = RadioManager::instance().alternateChannel(mPositionReportChannel);
|
||||
mLast18Time = mUTC;
|
||||
}
|
||||
|
||||
|
||||
if ( RadioManager::instance().initialized() && mUTC && (mUTC % MSG_24_TX_INTERVAL) == 0 ) {
|
||||
if ( mUTC - mLast24Time > MSG_24_TX_INTERVAL ) {
|
||||
TXPacket *p2 = TXPacketPool::instance().newTXPacket(mStaticDataChannel, mUTC+2);
|
||||
if ( !p2 ) {
|
||||
printf2("Unable to allocate TX packet for 24A\r\n");
|
||||
break;
|
||||
}
|
||||
AISMessage24A msg2;
|
||||
msg2.encode(mStationData, *p2);
|
||||
msg2.encode(stationData, *p2);
|
||||
RadioManager::instance().scheduleTransmission(p2);
|
||||
|
||||
TXPacket *p3 = TXPacketPool::instance().newTXPacket(mStaticDataChannel, mUTC+7);
|
||||
@ -105,18 +109,18 @@ void TXScheduler::processEvent(const Event &e)
|
||||
}
|
||||
|
||||
AISMessage24B msg3;
|
||||
msg3.encode(mStationData, *p3);
|
||||
msg3.encode(stationData, *p3);
|
||||
RadioManager::instance().scheduleTransmission(p3);
|
||||
|
||||
// Our next static data report should be on the other channel
|
||||
mStaticDataChannel = RadioManager::instance().alternateChannel(mStaticDataChannel);
|
||||
mLast24Time = mUTC;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CLOCK_EVENT: {
|
||||
// This is reliable and independent of GPS update frequency which could change to something other than 1Hz
|
||||
//ClockEvent *c = static_cast<ClockEvent*>(event);
|
||||
mUTC = e.clock.utc;
|
||||
if ( RadioManager::instance().initialized() && mTesting && mUTC % 1 == 0 ) {
|
||||
scheduleTestPacket();
|
||||
@ -130,6 +134,15 @@ void TXScheduler::processEvent(const Event &e)
|
||||
|
||||
}
|
||||
|
||||
time_t TXScheduler::positionReportTimeInterval()
|
||||
{
|
||||
// As a class B "CS" transponder, we transmit every 3 minutes if speed is < 2 knots, otherwise 30 seconds.
|
||||
if ( mAvgSpeed < 2.0 )
|
||||
return 180;
|
||||
|
||||
return DEFAULT_TX_INTERVAL;
|
||||
}
|
||||
|
||||
void TXScheduler::scheduleTestPacket()
|
||||
{
|
||||
VHFChannel channel = CH_84;
|
||||
|
@ -26,12 +26,15 @@ public:
|
||||
void startTXTesting();
|
||||
private:
|
||||
void scheduleTestPacket();
|
||||
time_t positionReportTimeInterval();
|
||||
private:
|
||||
VHFChannel mPositionReportChannel;
|
||||
VHFChannel mStaticDataChannel;
|
||||
time_t mUTC;
|
||||
time_t mLast18Time;
|
||||
time_t mLast24Time;
|
||||
double mAvgSpeed;
|
||||
bool mTesting;
|
||||
StationData mStationData;
|
||||
};
|
||||
|
||||
#endif /* TXSCHEDULER_HPP_ */
|
||||
|
@ -64,11 +64,11 @@
|
||||
// Define this to set BT=0.4 for GMSK (as per ITU spec for AIS). Default is 0.5
|
||||
#define USE_BT_04
|
||||
|
||||
// Default interval for message 18 (position report)
|
||||
// Default interval for message 18 (position report) is 30 seconds when under way
|
||||
#define DEFAULT_TX_INTERVAL 30
|
||||
|
||||
// Default interval for message 24 A&B (static data report)
|
||||
#define MSG_24_TX_INTERVAL 180
|
||||
// Default interval for message 24 A&B (static data report) is 6 minutes
|
||||
#define MSG_24_TX_INTERVAL 360
|
||||
|
||||
// The spec calls for Class B transmitters to listen for the first 20 bits of each frame before transmitting.
|
||||
// It takes the Si4463 a few bits' time to switch from RX to TX, so I arbitrarily picked the 12th bit.
|
||||
|
Loading…
x
Reference in New Issue
Block a user