diff --git a/src/AISMessages.cpp b/src/AISMessages.cpp index 3b4f387..113eb9c 100644 --- a/src/AISMessages.cpp +++ b/src/AISMessages.cpp @@ -19,15 +19,30 @@ AISMessage::AISMessage () { - mmsi = STATION_MMSI; - repeatIndicator = 0; - messageType = 0; + mMMSI = 0; + mRI = 0; + mType = 0; } AISMessage::~AISMessage () { } +uint8_t AISMessage::type() const +{ + return mType; +} + +uint8_t AISMessage::repeatIndicator() const +{ + return mRI; +} + +uint32_t AISMessage::mmsi() const +{ + return mMMSI; +} + bool AISMessage::decode(RXPacket &) { // The base class method should never be called @@ -37,10 +52,9 @@ bool AISMessage::decode(RXPacket &) return false; } -void AISMessage::encode(TXPacket &) +void AISMessage::encode(const StationData &station, TXPacket &) { - // The base class method should never be called - ASSERT(false); + mMMSI = station.mmsi; } void AISMessage::addBits(uint8_t *bitVector, uint16_t &size, uint32_t value, uint8_t numBits) @@ -199,9 +213,9 @@ AISMessage123::AISMessage123() bool AISMessage123::decode(RXPacket &packet) { - messageType = packet.messageType(); - repeatIndicator = packet.repeatIndicator(); - mmsi = packet.mmsi(); + mType = packet.messageType(); + mRI = packet.repeatIndicator(); + mMMSI = packet.mmsi(); sog = packet.bits(50, 10) / 10.0f; longitude = Utils::coordinateFromUINT32(packet.bits(61, 28), 28); latitude = Utils::coordinateFromUINT32(packet.bits(89, 27), 27); @@ -216,23 +230,25 @@ bool AISMessage123::decode(RXPacket &packet) AISMessage18::AISMessage18() { - messageType = 18; + mType = 18; } -void AISMessage18::encode(TXPacket &packet) +void AISMessage18::encode(const StationData &station, TXPacket &packet) { + AISMessage::encode(station, packet); + // TODO: Perhaps this shouldn't live on the stack? uint8_t payload[MAX_AIS_TX_PACKET_SIZE]; uint16_t size = 0; uint32_t value; - value = messageType; + value = mType; addBits(payload, size, value, 6); // Message type - value = repeatIndicator; + value = mRI; addBits(payload, size, value, 2); // Repeat Indicator - value = mmsi; + value = mMMSI; addBits(payload, size, value, 30); // MMSI value = 0; @@ -298,9 +314,9 @@ void AISMessage18::encode(TXPacket &packet) bool AISMessage18::decode(RXPacket &packet) { - messageType = packet.messageType(); - repeatIndicator = packet.repeatIndicator(); - mmsi = packet.mmsi(); + mType = packet.messageType(); + mRI = packet.repeatIndicator(); + mMMSI = packet.mmsi(); sog = packet.bits(46, 10) / 10.0f; longitude = Utils::coordinateFromUINT32(packet.bits(57, 28), 28); @@ -315,28 +331,29 @@ bool AISMessage18::decode(RXPacket &packet) /////////////////////////////////////////////////////////////////////////////// AISMessage24A::AISMessage24A() { - messageType = 24; - name = STATION_NAME; + mType = 24; } -void AISMessage24A::encode(TXPacket &packet) +void AISMessage24A::encode(const StationData &station, TXPacket &packet) { + AISMessage::encode(station, packet); + uint8_t payload[MAX_AIS_TX_PACKET_SIZE]; uint16_t size = 0; uint32_t value; - value = messageType; + value = mType; addBits(payload, size, value, 6); // Message type - value = repeatIndicator; + value = mRI; addBits(payload, size, value, 2); // Repeat Indicator - value = mmsi; + value = mMMSI; addBits(payload, size, value, 30); // MMSI value = 0; addBits(payload, size, value, 2); // Part number (0 for 24A) - addString(payload, size, name, 20); // Station name + addString(payload, size, station.name, 20); // Station name finalize(payload, size, packet); } @@ -348,24 +365,24 @@ void AISMessage24A::encode(TXPacket &packet) /////////////////////////////////////////////////////////////////////////////// AISMessage24B::AISMessage24B() { - messageType = 24; - vendorId = ""; - callSign = ""; + mType = 24; } -void AISMessage24B::encode(TXPacket &packet) +void AISMessage24B::encode(const StationData &station, TXPacket &packet) { + AISMessage::encode(station, packet); + uint8_t payload[MAX_AIS_TX_PACKET_SIZE]; uint16_t size = 0; uint32_t value; - value = messageType; + value = mType; addBits(payload, size, value, 6); // Message type - value = repeatIndicator; + value = mRI; addBits(payload, size, value, 2); // Repeat Indicator - value = mmsi; + value = mMMSI; addBits(payload, size, value, 30); // MMSI value = 1; @@ -374,8 +391,8 @@ void AISMessage24B::encode(TXPacket &packet) value = 0; addBits(payload, size, value, 8); // Type of ship unknown - addString(payload, size, vendorId, 7); - addString(payload, size, callSign, 7); + addString(payload, size, "", 7); + addString(payload, size, station.callsign, 7); value = 0; addBits(payload, size, value, 30); // No dimension information diff --git a/src/AISMessages.hpp b/src/AISMessages.hpp index 1498315..5baba52 100644 --- a/src/AISMessages.hpp +++ b/src/AISMessages.hpp @@ -12,7 +12,8 @@ #include "RXPacket.hpp" #include #include -#include "globals.h" +#include "StationData.h" + using namespace std; @@ -29,12 +30,18 @@ public: virtual ~AISMessage (); virtual bool decode(RXPacket &packet); - virtual void encode(TXPacket &packet); + virtual void encode(const StationData &station, TXPacket &packet); - uint8_t messageType; - uint8_t repeatIndicator; - uint32_t mmsi; + uint8_t type() const; + uint8_t repeatIndicator() const; + uint32_t mmsi() const; protected: + // Every AIS message has these attributes at a minimum + uint8_t mType; + uint8_t mRI; + uint32_t mMMSI; +protected: + void appendCRC(uint8_t *buff, uint16_t &size); void addBits(uint8_t *buff, uint16_t &size, uint32_t value, uint8_t numBits); void putBits(uint8_t *buff, uint32_t value, uint8_t numBits); @@ -73,16 +80,16 @@ public: AISMessage18(); bool decode(RXPacket &packet); - void encode(TXPacket &packet); + void encode(const StationData &data, TXPacket &packet); }; class AISMessage24A : public AISMessage { public: - string name; + //string name; AISMessage24A(); - void encode(TXPacket &packet); + void encode(const StationData &data, TXPacket &packet); }; class AISMessage24B : public AISMessage @@ -90,10 +97,10 @@ class AISMessage24B : public AISMessage public: AISMessage24B(); - string vendorId; - string callSign; + //string vendorId; + //string callSign; - void encode(TXPacket &packet); + void encode(const StationData &data, TXPacket &packet); }; diff --git a/src/DataTerminal.cpp b/src/DataTerminal.cpp index 5f32108..fe1ace4 100644 --- a/src/DataTerminal.cpp +++ b/src/DataTerminal.cpp @@ -147,13 +147,14 @@ void DataTerminal::showScreen(MenuScreen screen) _write(buff); sprintf(buff, "Software revision: %s\r\n", REVISION); _write(buff); +#if 0 sprintf(buff, "MMSI: %d\r\n", STATION_MMSI); _write(buff); sprintf(buff, "Name: %s\r\n", STATION_NAME); _write(buff); sprintf(buff, "Call sign: %s\r\n", STATION_CALLSIGN); _write(buff); - +#endif _write("\r\n"); _write("****************************** AIS Transponder Menu ******************************\r\n\r\n"); _write("\t\033[1mP\033[0m\tProgram MMSI, station name and call sign \r\n"); diff --git a/src/EEPROM.cpp b/src/EEPROM.cpp index 3647a8d..19b8b98 100644 --- a/src/EEPROM.cpp +++ b/src/EEPROM.cpp @@ -10,6 +10,11 @@ #include #include "Utils.hpp" +#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) +#define EEPROM_REGION_ADDR 0x25 // Special region data array starts here + + /* * The Microchip EEPROM doesn't really expect to share the I2C bus with any other EEPROM. * So the four high bits of the address are 1010 (same for most EEPROMs) and the lower 3 don't matter. diff --git a/src/EEPROM.hpp b/src/EEPROM.hpp index 34ab400..8ffd513 100644 --- a/src/EEPROM.hpp +++ b/src/EEPROM.hpp @@ -8,48 +8,9 @@ #ifndef EEPROM_HPP_ #define EEPROM_HPP_ -#include -#include -#include "AISChannels.h" +#include "StationData.h" -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 - uint8_t len; // Length in meters (default: 0) - uint8_t beam; // Beam in meters (default: 0) - uint8_t flags; // Reserved - 0 for now -}; - -/* -static struct StationData __default_station_data = { - 987654321UL, - "TEST STATION 01", - "0N0000", - 0, - 0, - 0 -}; -*/ - - -typedef struct { - float swLat; - float swLng; - float neLat; - float neLng; - VHFChannel channA; - VHFChannel channB; - time_t expiration; -} SpecialRegion; - -#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) -#define EEPROM_REGION_ADDR 0x25 // Special region data array starts here - -//static SpecialRegion* __special_regions = new SpecialRegion[3]; - class EEPROM { public: diff --git a/src/RXPacketProcessor.cpp b/src/RXPacketProcessor.cpp index 65f45e7..5bea99a 100644 --- a/src/RXPacketProcessor.cpp +++ b/src/RXPacketProcessor.cpp @@ -84,7 +84,7 @@ void RXPacketProcessor::processEvent(Event *e) "RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n", pe->mPacket->rssi (), AIS_CHANNELS[pe->mPacket->channel ()].designation, - msg.messageType, msg.mmsi, msg.sog, + msg.type(), msg.mmsi(), msg.sog, msg.latitude, msg.longitude, miles); } @@ -97,11 +97,10 @@ void RXPacketProcessor::processEvent(Event *e) mLat, mLng, msg.latitude, msg.longitude); double miles = distance / METERS_PER_NAUTICAL_MILE; - printf2 ( - "RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n", + printf2 ("RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n", pe->mPacket->rssi (), AIS_CHANNELS[pe->mPacket->channel ()].designation, - msg.messageType, msg.mmsi, msg.sog, + msg.type(), msg.mmsi(), msg.sog, msg.latitude, msg.longitude, miles); } diff --git a/src/StationData.h b/src/StationData.h new file mode 100644 index 0000000..4570695 --- /dev/null +++ b/src/StationData.h @@ -0,0 +1,39 @@ +/* + * StationData.h + * + * Created on: May 30, 2016 + * Author: peter + */ + +#ifndef STATIONDATA_H_ +#define STATIONDATA_H_ + + +#include +#include +#include "AISChannels.h" + + +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 + uint8_t len; // Length in meters (default: 0) + uint8_t beam; // Beam in meters (default: 0) + uint8_t flags; // Reserved - 0 for now +}; + + +typedef struct { + float swLat; + float swLng; + float neLat; + float neLng; + VHFChannel channA; + VHFChannel channB; + time_t expiration; +} SpecialRegion; + + + +#endif /* STATIONDATA_H_ */ diff --git a/src/TXScheduler.cpp b/src/TXScheduler.cpp index e635c10..ffee22c 100644 --- a/src/TXScheduler.cpp +++ b/src/TXScheduler.cpp @@ -12,7 +12,6 @@ #include #include #include -//#include #include #include "RadioManager.hpp" #include "ChannelManager.hpp" @@ -85,7 +84,7 @@ void TXScheduler::processEvent(Event *event) msg.cog = gfe->mCOG; msg.utc = gfe->mUTC; - msg.encode (*p1); + msg.encode (mStationData, *p1); RadioManager::instance ().scheduleTransmission (p1); // Our next position report should be on the other channel @@ -100,7 +99,7 @@ void TXScheduler::processEvent(Event *event) break; } AISMessage24A msg2; - msg2.encode(*p2); + msg2.encode(mStationData, *p2); RadioManager::instance().scheduleTransmission(p2); TXPacket *p3 = TXPacketPool::instance().newTXPacket(mStaticDataChannel, mUTC+7); @@ -110,7 +109,7 @@ void TXScheduler::processEvent(Event *event) } AISMessage24B msg3; - msg3.encode(*p3); + msg3.encode(mStationData, *p3); RadioManager::instance().scheduleTransmission(p3); // Our next static data report should be on the other channel diff --git a/src/globals.h b/src/globals.h index 4d5a71b..793c762 100644 --- a/src/globals.h +++ b/src/globals.h @@ -92,9 +92,9 @@ * an open-source fashion, so they are (as usual) at least a decade behind the technology curve. */ -#define STATION_MMSI 987654321 -#define STATION_NAME "TEST STATION 01" -#define STATION_CALLSIGN "N0NNNN" +//#define STATION_MMSI 987654321 +//#define STATION_NAME "TEST STATION 01" +//#define STATION_CALLSIGN "N0NNNN" #endif /* GLOBALS_H_ */