Index: trunk/FACT++/src/gcn.cc
===================================================================
--- trunk/FACT++/src/gcn.cc	(revision 19444)
+++ trunk/FACT++/src/gcn.cc	(revision 19452)
@@ -1,3 +1,4 @@
 #include <functional>
+#include <boost/algorithm/string/join.hpp>
 
 #include "Dim.h"
@@ -16,4 +17,5 @@
 
 #include "HeadersGCN.h"
+#include "HeadersToO.h"
 
 #include <QtXml/QDomDocument>
@@ -44,5 +46,5 @@
     Time fLastKeepAlive;
 
-    GCN::PaketType_t GetType(const QDomElement &what)
+    QString GetParamValue(const QDomElement &what, const string &name)
     {
         const QDomNodeList param = what.elementsByTagName("Param");
@@ -50,18 +52,25 @@
         {
             const QDomElement elem = param.at(i).toElement();
-            if (elem.attribute("name").toStdString()!="Packet_Type")
-                continue;
-
-            const uint16_t val = elem.attribute("value").toUInt();
-            const auto it = fTypes.find(val);
-            if (it!=fTypes.end())
-                return it->second;
-
-            Warn("Unknown paket type "+to_string(val)+".");
-        }
-
+            if (elem.attribute("name").toStdString()==name)
+                return elem.attribute("value");
+        }
+
+        return "";
+    }
+
+    GCN::PaketType_t GetType(const QDomElement &what)
+    {
+        const auto value = GetParamValue(what, "Packet_Type");
+        if (value.isEmpty())
+            return { -1, "", "" };
+
+        const uint16_t val = value.toUInt();
+        const auto it = fTypes.find(val);
+        if (it!=fTypes.end())
+            return it->second;
+
+        Warn("Unknown paket type "+to_string(val)+".");
         return { -1, "", "" };
     }
-
 
     int ProcessXml(const QDomElement &root)
@@ -117,4 +126,6 @@
                 return -1;
 
+            const GCN::PaketType_t ptype = GetType(what);
+
             const QDomElement date   = who.firstChildElement("Date");
             const QDomElement author = who.firstChildElement("Author");
@@ -135,11 +146,41 @@
             const QDomElement errad  = pos2d.firstChildElement("Error2Radius");
 
-            if (date.isNull()   || author.isNull() || sname.isNull() || //desc.isNull() ||
-                obsdat.isNull() || obsloc.isNull() || coord.isNull() || time.isNull() ||
-                pos2d.isNull()  || name1.isNull()  || name2.isNull() || val2.isNull() ||
-                c1.isNull()     || c2.isNull()     || errad.isNull())
+            const bool is_gw = ptype.type==150 || ptype.type==151 || ptype.type==153;
+
+            vector<string> missing;
+            if (date.isNull())
+                missing.emplace_back("Date");
+            if (author.isNull())
+                missing.emplace_back("Author");
+            if (sname.isNull() && !is_gw)
+                missing.emplace_back("shortName");
+            if (obsdat.isNull())
+                missing.emplace_back("ObsDataLocation");
+            if (obsloc.isNull())
+                missing.emplace_back("ObservationLocation");
+            if (coord.isNull())
+                missing.emplace_back("AstroCoords");
+            if (time.isNull())
+                missing.emplace_back("Time/TimeInstant/ISOTime");
+            if (pos2d.isNull() && !is_gw)
+                missing.emplace_back("Position2D");
+            if (name1.isNull() && !is_gw)
+                missing.emplace_back("Name1");
+            if (name1.isNull() && !is_gw)
+                missing.emplace_back("Name2");
+            if (val2.isNull() && !is_gw)
+                missing.emplace_back("Value2");
+            if (c1.isNull() && !is_gw)
+                missing.emplace_back("C1");
+            if (c2.isNull() && !is_gw)
+                missing.emplace_back("C2");
+            if (errad.isNull() && !is_gw)
+                missing.emplace_back("Error2Radius");
+
+            if (!missing.empty())
+            {
+                Warn("Missing elements: "+boost::algorithm::join(missing, ", "));
                 return -1;
-
-            const GCN::PaketType_t ptype = GetType(what);
+            }
 
             //  59/31: Konus LC / IPN raw         [observation]
@@ -195,7 +236,8 @@
             const string unit = pos2d.attribute("unit").toStdString();
 
-            const double ra  = c1.text().toDouble();
-            const double dec = c2.text().toDouble();
-            const double err = errad.text().toDouble();
+            const uint32_t trig  = GetParamValue(what, "TrigID").toUInt();
+            const double   ra    = c1.text().toDouble();
+            const double   dec   = c2.text().toDouble();
+            const double   err   = errad.text().toDouble();
 
             const string n1 = name1.text().toStdString();
@@ -212,6 +254,21 @@
             Out() << "  " << setw(5) << "ERR"  << "= " << err << unit << '\n';
 
-            if (n1=="RA" && n2=="Dec" && unit=="deg")
+            const bool has_coordinates = n1=="RA" && n2=="Dec" && unit=="deg";
+
+            if (has_coordinates)
             {
+                const ToO::DataGRB data =
+                {
+                    .type   = ptype.type,
+                    .trigid = trig,
+                    .ra     = ra,
+                    .dec    = dec,
+                    .err    = err,
+                };
+
+                Info("Sending ToO #"+to_string(trig)+" ["+role+"]");
+                Dim::SendCommandNB("TARGET_OF_OPPORTUNITY/SCHEDULE_GCN", data);
+
+/*
                 const double jd = Time().JD();
 
@@ -244,4 +301,5 @@
                     Out() << '\n';
                 }
+*/
             }
 
