Index: Configuration.cpp
===================================================================
--- Configuration.cpp	(revision 6359)
+++ Configuration.cpp	(working copy)
@@ -526,6 +526,7 @@
   bool id_after_73_;
   bool tx_QSY_allowed_;
   bool spot_to_psk_reporter_;
+  bool spot_to_snus_reporter_;
   bool monitor_off_at_startup_;
   bool monitor_last_used_;
   bool log_as_RTTY_;
@@ -607,6 +608,7 @@
 bool Configuration::id_after_73 () const {return m_->id_after_73_;}
 bool Configuration::tx_QSY_allowed () const {return m_->tx_QSY_allowed_;}
 bool Configuration::spot_to_psk_reporter () const {return m_->spot_to_psk_reporter_;}
+bool Configuration::spot_to_snus_reporter () const {return m_->spot_to_snus_reporter_;}
 bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
 bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
 bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
@@ -1055,6 +1057,7 @@
   ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
   ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
   ui_->psk_reporter_check_box->setChecked (spot_to_psk_reporter_);
+  ui_->snus_reporter_check_box->setChecked (spot_to_snus_reporter_);
   ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
   ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
   ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
@@ -1243,6 +1246,7 @@
   monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
   monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
   spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
+  spot_to_snus_reporter_ = settings_->value ("SNUSReporter", false).toBool ();
   id_after_73_ = settings_->value ("After73", false).toBool ();
   tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
 
@@ -1362,6 +1366,7 @@
   settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
   settings_->setValue ("MonitorLastUsed", monitor_last_used_);
   settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
+  settings_->setValue ("SNUSReporter", spot_to_snus_reporter_);
   settings_->setValue ("After73", id_after_73_);
   settings_->setValue ("TxQSYAllowed", tx_QSY_allowed_);
   settings_->setValue ("Macros", macros_.stringList ());
@@ -1762,6 +1767,7 @@
   my_callsign_ = ui_->callsign_line_edit->text ();
   my_grid_ = ui_->grid_line_edit->text ();
   spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
+  spot_to_snus_reporter_ = ui_->snus_reporter_check_box->isChecked ();
   id_interval_ = ui_->CW_id_interval_spin_box->value ();
   ntrials_ = ui_->sbNtrials->value ();
   aggressive_ = ui_->sbAggressive->value ();
Index: Configuration.hpp
===================================================================
--- Configuration.hpp	(revision 6359)
+++ Configuration.hpp	(working copy)
@@ -97,6 +97,7 @@
   bool id_after_73 () const;
   bool tx_QSY_allowed () const;
   bool spot_to_psk_reporter () const;
+  bool spot_to_snus_reporter () const;
   bool monitor_off_at_startup () const;
   bool monitor_last_used () const;
   bool log_as_RTTY () const;
Index: Configuration.ui
===================================================================
--- Configuration.ui	(revision 6359)
+++ Configuration.ui	(working copy)
@@ -2,6 +2,14 @@
 <ui version="4.0">
  <class>configuration_dialog</class>
  <widget class="QDialog" name="configuration_dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>545</width>
+    <height>614</height>
+   </rect>
+  </property>
   <property name="windowTitle">
    <string>Settings</string>
   </property>
@@ -1582,11 +1590,14 @@
        </item>
        <item>
         <widget class="QGroupBox" name="network_group_box">
+         <property name="enabled">
+          <bool>true</bool>
+         </property>
          <property name="title">
           <string>Network Services</string>
          </property>
-         <layout class="QGridLayout" name="gridLayout_17">
-          <item row="0" column="0">
+         <layout class="QVBoxLayout" name="verticalLayout_13">
+          <item>
            <widget class="QCheckBox" name="psk_reporter_check_box">
             <property name="toolTip">
              <string>The program can send your station details and all
@@ -1599,6 +1610,16 @@
             </property>
            </widget>
           </item>
+          <item>
+           <widget class="QCheckBox" name="snus_reporter_check_box">
+            <property name="toolTip">
+             <string>Please check so that any received balloon data will be reported to http://picospace.net</string>
+            </property>
+            <property name="text">
+             <string>Enable &amp;SNUS Reporter Spotting</string>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
        </item>
@@ -1698,22 +1719,22 @@
             </item>
            </layout>
           </item>
+          <item row="1" column="0" colspan="2">
+           <spacer name="verticalSpacer_4">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
          </layout>
         </widget>
        </item>
-       <item>
-        <spacer name="verticalSpacer_4">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="frequencies_tab">
@@ -2349,7 +2370,6 @@
   </layout>
  </widget>
  <tabstops>
-  <tabstop>configuration_tabs</tabstop>
   <tabstop>callsign_line_edit</tabstop>
   <tabstop>grid_line_edit</tabstop>
   <tabstop>type_2_msg_gen_combo_box</tabstop>
@@ -2412,6 +2432,7 @@
   <tabstop>report_in_comments_check_box</tabstop>
   <tabstop>clear_DX_check_box</tabstop>
   <tabstop>psk_reporter_check_box</tabstop>
+  <tabstop>snus_reporter_check_box</tabstop>
   <tabstop>udp_server_line_edit</tabstop>
   <tabstop>udp_server_port_spin_box</tabstop>
   <tabstop>accept_udp_requests_check_box</tabstop>
@@ -2427,6 +2448,18 @@
   <tabstop>pbTxMsg</tabstop>
   <tabstop>pbNewDXCC</tabstop>
   <tabstop>pbNewCall</tabstop>
+  <tabstop>offset_Rx_freq_check_box</tabstop>
+  <tabstop>sbNtrials</tabstop>
+  <tabstop>cbSync1Bit</tabstop>
+  <tabstop>cbTwoPass</tabstop>
+  <tabstop>cbMyDx</tabstop>
+  <tabstop>cbCQMyN</tabstop>
+  <tabstop>cbNDxG</tabstop>
+  <tabstop>cbNN</tabstop>
+  <tabstop>cbEMEonly</tabstop>
+  <tabstop>sbAggressive</tabstop>
+  <tabstop>sbDegrade</tabstop>
+  <tabstop>configuration_tabs</tabstop>
  </tabstops>
  <resources/>
  <connections>
@@ -2496,10 +2529,10 @@
   </connection>
  </connections>
  <buttongroups>
+  <buttongroup name="TX_audio_source_button_group"/>
+  <buttongroup name="split_mode_button_group"/>
   <buttongroup name="CAT_stop_bits_button_group"/>
   <buttongroup name="PTT_method_button_group"/>
-  <buttongroup name="split_mode_button_group"/>
-  <buttongroup name="TX_audio_source_button_group"/>
   <buttongroup name="CAT_data_bits_button_group"/>
   <buttongroup name="CAT_handshake_button_group"/>
   <buttongroup name="TX_mode_button_group"/>
Index: mainwindow.cpp
===================================================================
--- mainwindow.cpp	(revision 6359)
+++ mainwindow.cpp	(working copy)
@@ -18,6 +18,9 @@
 #include <QVector>
 #include <QCursor>
 #include <QToolTip>
+#include <QHash>
+#include <QNetworkRequest>
+#include <QNetworkAccessManager>
 
 #include "revision_utils.hpp"
 #include "qt_helpers.hpp"
@@ -184,7 +187,8 @@
                    m_config.udp_server_name (), m_config.udp_server_port (),
                    this}},
   psk_Reporter {new PSK_Reporter {m_messageClient, this}},
-  m_manual {network_manager}
+  m_manual {network_manager},
+  m_network_manager (network_manager)
 {
   ui->setupUi(this);
 
@@ -682,6 +686,9 @@
   m_dialFreqRxWSPR=0;
   wsprNet = new WSPRNet(network_manager, this);
   connect( wsprNet, SIGNAL(uploadStatus(QString)), this, SLOT(uploadResponse(QString)));
+  balloonData = new QHash<QString,QString>();
+  connect(network_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_requestCompleted(QNetworkReply *)));
+  
   if(m_bFastMode) {
     int ntr[]={5,10,15,30};
     m_TRperiod=ntr[m_TRindex-11];
@@ -1900,6 +1907,24 @@
           psk_Reporter->addRemoteStation(deCall,grid,QString::number(frequency),msgmode,
                   QString::number(snr),QString::number(QDateTime::currentDateTime().toTime_t()));
       }
+      // send telemetry to HAB server if required
+      // will send the RX station callsign, grid, frequency and JT9/65 string
+      QString deCall;
+      QString grid;
+      decodedtext.deCallAndGrid(/*out*/deCall,grid);
+      if (m_config.spot_to_snus_reporter () and gridChanged(deCall,grid) and stdMsg and !m_diskData){
+        QUrl serviceUrl = QUrl("http://vps.comms.net.au/snus.php");
+        QByteArray postData;
+        Frequency frequency = m_dialFreq + decodedtext.frequencyOffset();
+        QUrlQuery q;
+        q.addQueryItem("callsign",  m_config.my_callsign());
+        q.addQueryItem("grid",  m_config.my_grid());
+        q.addQueryItem("frequency", QString::number(frequency));
+        q.addQueryItem("data", QString(decodedtext.string()).replace(QString("+"), QString("%2B")));
+        q.addQueryItem("version", version());
+        postData = q.query(QUrl::FullyEncoded).toUtf8();
+        m_network_manager->post(QNetworkRequest(serviceUrl), postData);
+      }
     }
 
   }
@@ -1908,6 +1933,27 @@
   ui->DecodeButton->setChecked (false);
 }
 
+void MainWindow::on_requestCompleted(QNetworkReply *reply) {
+    QByteArray data = reply->readAll();
+    // delete request object instance on return to the event loop otherwise it is leaked
+    reply->deleteLater ();
+}
+
+bool MainWindow::gridChanged(QString deCall, QString grid)
+{
+	if (!gridOK(grid)) return false;
+	if (balloonData->contains(deCall)) {
+		// Any change from first grid report will report all subsequent decodes
+		if (balloonData->value(deCall) != grid) {
+			return true;
+		}
+	}
+	else {
+		balloonData->insert(deCall,grid);
+	}
+	return false;
+}
+
 void MainWindow::jt9_error (QProcess::ProcessError e)
 {
   if(!m_killAll) {
Index: mainwindow.h
===================================================================
--- mainwindow.h	(revision 6359)
+++ mainwindow.h	(working copy)
@@ -17,6 +17,7 @@
 #include <QAbstractSocket>
 #include <QHostAddress>
 #include <QPointer>
+#include <QNetworkReply>
 
 #include "AudioDevice.hpp"
 #include "commons.h"
@@ -250,6 +251,7 @@
   void on_actionJTMSK_triggered();
   void on_sbCQRxFreq_valueChanged(int n);
   void on_cbCQRx_toggled(bool b);
+  void on_requestCompleted(QNetworkReply *reply);
 
 private:
   Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
@@ -523,6 +525,8 @@
   MessageClient * m_messageClient;
   PSK_Reporter *psk_Reporter;
   DisplayManual m_manual;
+  QNetworkAccessManager *m_network_manager;
+  QHash<QString, QString> *balloonData;
 
   //---------------------------------------------------- private functions
   void readSettings();
@@ -559,6 +563,7 @@
   QString WSPR_hhmm(int n);
   void fast_config(bool b);
   void CQRxFreq();
+  bool gridChanged(QString deCall, QString grid);
 };
 
 extern void getfile(QString fname, int ntrperiod);
