public void run() {
      StringBuffer data = new StringBuffer();
      Print.logDebug("Client:InputThread started");

      while (true) {
        data.setLength(0);
        boolean timeout = false;
        try {
          if (this.readTimeout > 0L) {
            this.socket.setSoTimeout((int) this.readTimeout);
          }
          ClientSocketThread.socketReadLine(this.socket, -1, data);
        } catch (InterruptedIOException ee) { // SocketTimeoutException ee) {
          // error("Read interrupted (timeout) ...");
          if (getRunStatus() != THREAD_RUNNING) {
            break;
          }
          timeout = true;
          // continue;
        } catch (Throwable t) {
          Print.logError("Client:InputThread - " + t);
          t.printStackTrace();
          break;
        }
        if (!timeout || (data.length() > 0)) {
          ClientSocketThread.this.handleMessage(data.toString());
        }
      }

      synchronized (this.threadLock) {
        this.isRunning = false;
        Print.logDebug("Client:InputThread stopped");
        this.threadLock.notify();
      }
    }
 protected DCServerFactory.ResultCode sendEmail(
     String frEmail, String toEmail, String subj, String body) {
   if (StringTools.isBlank(frEmail)) {
     Print.logError("'From' Email address not specified");
     return DCServerFactory.ResultCode.TRANSMIT_FAIL;
   } else if (StringTools.isBlank(toEmail) || !CommandPacketHandler.validateAddress(toEmail)) {
     Print.logError("'To' SMS Email address invalid, or not specified");
     return DCServerFactory.ResultCode.TRANSMIT_FAIL;
   } else if (StringTools.isBlank(subj) && StringTools.isBlank(body)) {
     Print.logError("Command string not specified");
     return DCServerFactory.ResultCode.INVALID_ARG;
   } else {
     try {
       Print.logInfo("SMS email: to <" + toEmail + ">");
       Print.logDebug("  From   : " + frEmail);
       Print.logDebug("  To     : " + toEmail);
       Print.logDebug("  Subject: " + subj);
       Print.logDebug("  Message: " + body);
       SendMail.send(frEmail, toEmail, null, null, subj, body, null);
       return DCServerFactory.ResultCode.SUCCESS;
     } catch (Throwable t) { // NoClassDefFoundException, ClassNotFoundException
       // this will fail if JavaMail support for SendMail is not available.
       Print.logWarn("SendMail error: " + t);
       return DCServerFactory.ResultCode.TRANSMIT_FAIL;
     }
   }
 }
Example #3
0
 public final User getUser() {
   if (this.user == null) {
     String userID = this.getUserID();
     Print.logDebug("[Optimize] Retrieving User record: " + userID);
     try {
       this.user = User.getUser(this.getAccount(), userID);
       // 'this.asset' may still be null if the asset was not found
     } catch (DBException dbe) {
       // may be caused by "java.net.ConnectException: Connection refused: connect"
       Print.logError("User not found: " + this.getAccountID() + "/" + userID);
       this.user = null;
     }
   }
   return this.user;
 }
  /** ** Add SMS Gateway support provider */
  public static void AddSMSGateway(String name, SMSOutboundGateway smsGW) {

    /* validate name */
    if (StringTools.isBlank(name)) {
      Print.logWarn("SMS Gateway name is blank");
      return;
    } else if (smsGW == null) {
      Print.logWarn("SMS Gateway handler is null");
      return;
    }

    /* initialize map? */
    if (SmsGatewayHandlerMap == null) {
      SmsGatewayHandlerMap = new HashMap<String, SMSOutboundGateway>();
    }

    /* save handler */
    SmsGatewayHandlerMap.put(name.toLowerCase(), smsGW);
    Print.logDebug("Added SMS Gateway Handler: " + name);
  }
Example #5
0
 public static boolean InitJ1587DescriptionProvider() {
   if (!j1587DidInit) {
     j1587DidInit = true;
     try {
       j1587GetDescription =
           new MethodAction(
               PACKAGE_EXTRA_DBTOOLS_ + "J1587", "GetJ1587Description", Properties.class);
       j1587DescProvider =
           new DTOBDFault.J1587DescriptionProvider() {
             public Properties getJ1587Descriptions(long fault) {
               if (DTOBDFault.IsJ1708(fault)) {
                 int mid = DTOBDFault.DecodeSystem(fault); // MID
                 boolean isSid = DTOBDFault.IsJ1708_SID(fault);
                 int pidSid = DTOBDFault.DecodePidSid(fault); // PID|SID "128/[s]123/1"
                 int fmi = DTOBDFault.DecodeFMI(fault); // FMI
                 Properties p = new Properties();
                 p.setProperty("MID", String.valueOf(mid));
                 p.setProperty((isSid ? "SID" : "PID"), String.valueOf(pidSid));
                 p.setProperty("FMI", String.valueOf(fmi));
                 try {
                   return (Properties) j1587GetDescription.invoke(p);
                 } catch (Throwable th) {
                   return null;
                 }
               } else {
                 return null;
               }
             }
           };
       Print.logDebug("J1587 Description Provider installed ...");
     } catch (Throwable th) {
       // Print.logException("J1587 Description Provider NOT installed!", th);
     }
   }
   return (j1587DescProvider != null);
 }
 /** ** Called when the thread has stopped */
 protected void threadStopped() {
   Print.logDebug("Client:ControlThread stopped ...");
 }
  /** ** Initialize outbound SMS gateway handlers */
  public static void _startupInit() {
    Print.logDebug("SMSOutboundGateway initializing ...");
    final String SMSKey_ = SMSOutboundGateway.PROP_SmsGatewayHandler_;

    /* already initialized? */
    if (SmsGatewayHandlerMap != null) {
      return;
    }

    // -----------------------------------------------
    // The following shows several example of outbound SMS gateway support.
    // The only method that needs to be overridden and implemented is
    //   public DCServerFactory.ResultCode sendSMSCommand(Device device, String commandStr)
    // The "device" is the Device record instance to which the SMS message should be sent,
    // and "commandStr" is the SMS text (device command) which is to be sent to the device.
    // -----------------------------------------------

    /* standard "Body" command */
    // Property:
    //   [email protected]
    // Notes:
    //   This outbound SMS method sends the SMS text in an email message body to the device
    //   "smsEmailAddress".  If the device "smsEmailAddress" is blank, then the "To" email
    //   address is constructed from the device "simPhoneNumber" and the email address
    //   specified on the property "SmsGatewayHandler.emailBody.smsEmailAddress".
    SMSOutboundGateway.AddSMSGateway(
        "emailBody",
        new SMSOutboundGateway() {
          public DCServerFactory.ResultCode sendSMSCommand(Device device, String commandStr) {
            if (device == null) {
              return DCServerFactory.ResultCode.INVALID_DEVICE;
            }
            String frEmail = this.getFromEmailAddress(device);
            String toEmail = this.getSmsEmailAddress(device);
            if (StringTools.isBlank(toEmail)) {
              String smsEmail =
                  this.getStringProperty(device, SMSKey_ + "emailBody.smsEmailAddress", "");
              toEmail =
                  smsEmail.startsWith("@") ? (device.getSimPhoneNumber() + smsEmail) : smsEmail;
            }
            return this.sendEmail(frEmail, toEmail, "", commandStr);
          }
        });

    /* standard "Subject" command */
    // Property:
    //   SmsGatewayHandler.emailSubject.smsEmailAddress=
    // Notes:
    //   This outbound SMS method sends the SMS text in an email message subject to the device
    //   "smsEmailAddress".  If the device "smsEmailAddress" is blank, then the "To" email
    //   address is constructed from the device "simPhoneNumber" and the email address
    //   specified on the property "SmsGatewayHandler.emailSubject.smsEmailAddress".
    SMSOutboundGateway.AddSMSGateway(
        "emailSubject",
        new SMSOutboundGateway() {
          public DCServerFactory.ResultCode sendSMSCommand(Device device, String commandStr) {
            if (device == null) {
              return DCServerFactory.ResultCode.INVALID_DEVICE;
            }
            String frEmail = this.getFromEmailAddress(device);
            String toEmail = this.getSmsEmailAddress(device);
            if (StringTools.isBlank(toEmail)) {
              String smsEmail =
                  this.getStringProperty(device, SMSKey_ + "emailSubject.smsEmailAddress", "");
              toEmail =
                  smsEmail.startsWith("@") ? (device.getSimPhoneNumber() + smsEmail) : smsEmail;
            }
            return this.sendEmail(frEmail, toEmail, commandStr, "");
          }
        });

    /* HTTP SMS */
    // Property:
    //
    // SmsGatewayHandler.httpURL.url=http://localhost:12345/smsredirector/sendsms?flash=0&acctuser=user&tracking_Pwd=pass&source=5551212&destination=${mobile}&message=${message}
    //
    // SmsGatewayHandler.httpURL.url=http://localhost:12345/sendsms?user=user&pass=pass&source=5551212&dest=${mobile}&text=${message}
    // Notes:
    //   This outbound SMS method sends the SMS text in an HTTP "GET" request to the URL
    //   specified on the property "SmsGatewayHandler.httpURL.url".  The following replacement
    //   variables may be specified in the URL string:
    //      ${mobile}  - replaced with the Device "simPhoneNumber" field contents
    //      ${message} - replaced with the SMS text/command to be sent to the device.
    //   It is expected that the server handling the request understands how to parse and
    //   interpret the various fields in the URL.
    SMSOutboundGateway.AddSMSGateway(
        "httpURL",
        new SMSOutboundGateway() {
          public DCServerFactory.ResultCode sendSMSCommand(Device device, String commandStr) {
            if (device == null) {
              return DCServerFactory.ResultCode.INVALID_DEVICE;
            }
            String KeyURL = SMSKey_ + "httpURL.url";
            String mobile = URIArg.encodeArg(device.getSimPhoneNumber());
            String message = URIArg.encodeArg(commandStr);
            String httpURL = this.getStringProperty(device, KeyURL, "");
            if (StringTools.isBlank(httpURL)) {
              Print.logWarn("'" + KeyURL + "' not specified");
              return DCServerFactory.ResultCode.INVALID_SMS;
            }
            httpURL = StringTools.replace(httpURL, "${mobile}", mobile);
            httpURL = StringTools.replace(httpURL, "${message}", message);
            try {
              Print.logDebug("SMS Gateway URL: " + httpURL);
              byte response[] = HTMLTools.readPage_GET(httpURL, 10000);
              // TODO: check response?
              return DCServerFactory.ResultCode.SUCCESS;
            } catch (UnsupportedEncodingException uee) {
              Print.logError("URL Encoding: " + uee);
              return DCServerFactory.ResultCode.TRANSMIT_FAIL;
            } catch (NoRouteToHostException nrthe) {
              Print.logError("Unreachable Host: " + httpURL);
              return DCServerFactory.ResultCode.UNKNOWN_HOST;
            } catch (UnknownHostException uhe) {
              Print.logError("Unknown Host: " + httpURL);
              return DCServerFactory.ResultCode.UNKNOWN_HOST;
            } catch (FileNotFoundException fnfe) {
              Print.logError("Invalid URL (not found): " + httpURL);
              return DCServerFactory.ResultCode.INVALID_SMS;
            } catch (MalformedURLException mue) {
              Print.logError("Invalid URL (malformed): " + httpURL);
              return DCServerFactory.ResultCode.INVALID_SMS;
            } catch (Throwable th) {
              Print.logError("HTML SMS error: " + th);
              return DCServerFactory.ResultCode.TRANSMIT_FAIL;
            }
          }
        });
  }
Example #8
0
  public boolean insertEventData() {

    /* valid device? */
    if (this.device == null) {
      return false;
    }

    /* debug message */
    if (RTConfig.isDebugMode()) {
      Print.logDebug("Inserting EventData ...\n" + this.toString());
    }

    /* EventData key */
    String acctID = this.device.getAccountID();
    String devID = this.device.getDeviceID();
    long fixtime = this.getTimestamp();
    int statusCode = this.getStatusCode();
    EventData.Key evKey = new EventData.Key(acctID, devID, fixtime, statusCode);
    EventData evdb = evKey.getDBRecord();

    /* set EventData field values */
    if (USE_EVENTDATA_SETVALUE) {
      for (Object fldn : this.fieldValues.getPropertyKeys()) {
        if (fldn.equals(EventData.FLD_timestamp)) {
          continue; // already set above
        } else if (fldn.equals(EventData.FLD_statusCode)) {
          continue; // already set above
        }
        Object fldv = this.fieldValues.getProperty(fldn, null);
        if (fldv != null) {
          evdb.setValue((String) fldn, fldv); // attempts to use "setter" methods
        }
      }
    } else {
      if (this.hasLatitude()) {
        evdb.setLatitude(this.getLatitude());
      }
      if (this.hasLongitude()) {
        evdb.setLongitude(this.getLongitude());
      }
      if (this.hasGpsAge()) {
        evdb.setGpsAge(this.getGpsAge());
      }
      if (this.hasHDOP()) {
        evdb.setHDOP(this.getHDOP());
      }
      if (this.hasSatelliteCount()) {
        evdb.setSatelliteCount(this.getSatelliteCount());
      }
      if (this.hasSpeedKPH()) {
        evdb.setSpeedKPH(this.getSpeedKPH());
      }
      if (this.hasHeading()) {
        evdb.setHeading(this.getHeading());
      }
      if (this.hasAltitude()) {
        evdb.setAltitude(this.getAltitude());
      }
      if (this.hasInputMask()) {
        evdb.setInputMask(this.getInputMask());
      }
      if (this.hasBatteryLevel()) {
        evdb.setBatteryLevel(this.getBatteryLevel());
      }
      if (this.hasSignalStrength()) {
        evdb.setSignalStrength(this.getSignalStrength());
      }
      if (this.hasOdometerKM()) {
        evdb.setOdometerKM(this.getOdometerKM());
      }
      if (this.hasEngineHours()) {
        evdb.setEngineHours(this.getEngineHours());
      }
      if (this.hasPtoHours()) {
        evdb.setPtoHours(this.getPtoHours());
      }
      if (this.hasFuelTotal()) {
        evdb.setFuelTotal(this.getFuelTotal());
      }
      if (this.hasGeozoneID()) {
        evdb.setGeozoneID(this.getGeozoneID());
      }
    }

    /* other fields (if available) */
    if (this.otherValues != null) {
      for (String fldn : this.otherValues.keySet()) {
        if (fldn.equals(EventData.FLD_timestamp)) {
          continue;
        } else if (fldn.equals(EventData.FLD_statusCode)) {
          continue;
        }
        Object fldv = this.otherValues.get(fldn);
        if (fldv != null) {
          evdb.setValue(fldn, fldv); // attempts to use "setter" methods
        }
      }
    }

    /* insert event */
    // this will display an error if it was unable to store the event
    Print.logInfo(
        "Event     : [0x"
            + StringTools.toHexString(statusCode, 16)
            + "] "
            + StatusCodes.GetDescription(statusCode, null));
    this.device.insertEventData(
        evdb); // FLD_lastValidLatitude,FLD_lastValidLongitude,FLD_lastGPSTimestamp,FLD_lastOdometerKM
    this.eventTotalCount++;
    return true;
  }
  // http://code.google.com/apis/maps/documentation/geocoding/index.html
  public GeoPoint getGeocode(String address, String country) {

    /* URL */
    String url = this.getGeoPointGeocodeURL(address, country);
    Print.logDebug("Google GC URL: " + url);

    /* create XML document */
    Document xmlDoc = GetXMLDocument(url, this.getGeocodeTimeout());
    if (xmlDoc == null) {
      return null;
    }

    /* vars */
    String errCode = null;
    GeoPoint geoPoint = null;

    /* parse "xml" */
    Element kml = xmlDoc.getDocumentElement();
    if (kml.getTagName().equalsIgnoreCase(TAG_kml)) {
      NodeList ResponseList = XMLTools.getChildElements(kml, TAG_Response);
      for (int g = 0; (g < ResponseList.getLength()); g++) {
        Element response = (Element) ResponseList.item(g);
        NodeList responseNodes = response.getChildNodes();
        for (int n = 0; n < responseNodes.getLength(); n++) {
          Node responseNode = responseNodes.item(n);
          if (!(responseNode instanceof Element)) {
            continue;
          }
          Element responseElem = (Element) responseNode;
          String responseNodeName = responseElem.getNodeName();
          if (responseNodeName.equalsIgnoreCase(TAG_name)) {
            // <name>1600 Amphitheatre Parkway, Mountain View, CA</name>
          } else if (responseNodeName.equalsIgnoreCase(TAG_Status)) {
            // <Status> ... </Status>
            NodeList statusNodes = responseElem.getChildNodes();
            for (int st = 0; st < statusNodes.getLength(); st++) {
              Node statusNode = statusNodes.item(st);
              if (!(statusNode instanceof Element)) {
                continue;
              }
              Element statusElem = (Element) statusNode;
              String statusNodeName = statusElem.getNodeName();
              if (statusNodeName.equalsIgnoreCase(TAG_code)) {
                errCode = StringTools.trim(GoogleGeocodeV2.GetNodeText(statusElem)); // expect "200"
                break; // we only care about the 'code'
              }
            }
          } else if (responseNodeName.equalsIgnoreCase(TAG_Placemark)) {
            // <Placemark> ... </Placemark>
            String id = responseElem.getAttribute(ATTR_id);
            if ((id != null) && id.equals("p1")) {
              NodeList placemarkNodes = responseElem.getChildNodes();
              for (int pm = 0; (geoPoint == null) && (pm < placemarkNodes.getLength()); pm++) {
                Node placemarkNode = placemarkNodes.item(pm);
                if (!(placemarkNode instanceof Element)) {
                  continue;
                }
                Element placemarkElem = (Element) placemarkNode;
                String placemarkNodeName = placemarkElem.getNodeName();
                if (placemarkNodeName.equalsIgnoreCase(TAG_Point)) {
                  NodeList pointNodes = placemarkElem.getChildNodes();
                  for (int ptn = 0; (geoPoint == null) && (ptn < pointNodes.getLength()); ptn++) {
                    Node pointNode = pointNodes.item(ptn);
                    if (!(pointNode instanceof Element)) {
                      continue;
                    }
                    Element pointElem = (Element) pointNode;
                    String pointNodeName = pointElem.getNodeName();
                    if (pointNodeName.equalsIgnoreCase(TAG_coordinates)) {
                      String ll[] = StringTools.split(GoogleGeocodeV2.GetNodeText(pointElem), ',');
                      if (ll.length >= 2) {
                        double lon = StringTools.parseDouble(ll[0], 0.0); // longitude is first
                        double lat = StringTools.parseDouble(ll[1], 0.0);
                        if (GeoPoint.isValid(lat, lon)) {
                          geoPoint = new GeoPoint(lat, lon);
                          break; // we only care about the 'GeoPoint'
                        }
                      }
                    }
                  }
                }
              }
            } else {
              // Print.logInfo("Skipping Placemark ID = %s", id);
            }
          }
        }
      }
    }

    /* create address */
    if (geoPoint != null) {
      // GeoPoint found
      return geoPoint;
    }

    /* check for Google reverse-geocode limit exceeded */
    if ((errCode != null) && errCode.equals("620")) {
      Print.logError("!!!! Google Reverse-Geocode Limit Exceeded [Error 620] !!!!");
    }

    /* no reverse-geocode available */
    return null;
  }
  /* return reverse-geocode using nearest address */
  public ReverseGeocode getAddressReverseGeocode(GeoPoint gp, String localeStr, boolean cache) {

    /* check for failover mode */
    if (this.isReverseGeocodeFailoverMode()) {
      ReverseGeocodeProvider frgp = this.getFailoverReverseGeocodeProvider();
      return frgp.getReverseGeocode(gp, localeStr, cache);
    }

    /* URL */
    String url = this.getAddressReverseGeocodeURL(gp, localeStr);
    Print.logDebug("Google RG URL: " + url);
    // byte xmlBytes[] = HTMLTools.readPage(url);

    /* create XML document */
    Document xmlDoc = GetXMLDocument(url, this.getReverseGeocodeTimeout());
    if (xmlDoc == null) {
      return null;
    }

    /* vars */
    String errCode = null;
    String address = null;

    /* parse "xml" */
    Element kml = xmlDoc.getDocumentElement();
    if (kml.getTagName().equalsIgnoreCase(TAG_kml)) {
      NodeList ResponseList = XMLTools.getChildElements(kml, TAG_Response);
      for (int g = 0; (g < ResponseList.getLength()); g++) {
        Element response = (Element) ResponseList.item(g);
        NodeList responseNodes = response.getChildNodes();
        for (int n = 0; n < responseNodes.getLength(); n++) {
          Node responseNode = responseNodes.item(n);
          if (!(responseNode instanceof Element)) {
            continue;
          }
          Element responseElem = (Element) responseNode;
          String responseNodeName = responseElem.getNodeName();
          if (responseNodeName.equalsIgnoreCase(TAG_name)) {
            // <name>40.479581,-117.773438</name>
          } else if (responseNodeName.equalsIgnoreCase(TAG_Status)) {
            // <Status> ... </Status>
            NodeList statusNodes = responseElem.getChildNodes();
            for (int st = 0; st < statusNodes.getLength(); st++) {
              Node statusNode = statusNodes.item(st);
              if (!(statusNode instanceof Element)) {
                continue;
              }
              Element statusElem = (Element) statusNode;
              String statusNodeName = statusElem.getNodeName();
              if (statusNodeName.equalsIgnoreCase(TAG_code)) {
                errCode = StringTools.trim(GoogleGeocodeV2.GetNodeText(statusElem)); // expect "200"
                break; // we only care about the 'code'
              }
            }
          } else if (responseNodeName.equalsIgnoreCase(TAG_Placemark)) {
            // <Placemark> ... </Placemark>
            String id = responseElem.getAttribute(ATTR_id);
            if ((id != null) && id.equals("p1")) {
              NodeList placemarkNodes = responseElem.getChildNodes();
              for (int pm = 0; pm < placemarkNodes.getLength(); pm++) {
                Node placemarkNode = placemarkNodes.item(pm);
                if (!(placemarkNode instanceof Element)) {
                  continue;
                }
                Element placemarkElem = (Element) placemarkNode;
                String placemarkNodeName = placemarkElem.getNodeName();
                if (placemarkNodeName.equalsIgnoreCase(TAG_address)) {
                  address = GoogleGeocodeV2.GetNodeText(placemarkElem);
                  break; // we only care about the 'address'
                }
              }
            } else {
              // Print.logInfo("Skipping Placemark ID = %s", id);
            }
          }
        }
      }
    }

    /* create address */
    if (FAILOVER_DEBUG) {
      errCode = "620";
    } else if (!StringTools.isBlank(address)) {
      // address found
      ReverseGeocode rg = new ReverseGeocode();
      rg.setFullAddress(address);
      return rg;
    }

    /* check for Google reverse-geocode limit exceeded */
    if ((errCode != null) && errCode.equals("620")) {
      Print.logError("!!!! Google Reverse-Geocode Limit Exceeded [Error 620] !!!!");
      if (this.hasFailoverReverseGeocodeProvider()) {
        this.startReverseGeocodeFailoverMode();
        ReverseGeocodeProvider frgp = this.getFailoverReverseGeocodeProvider();
        Print.logWarn("Failing over to '" + frgp.getName() + "'");
        return frgp.getReverseGeocode(gp, localeStr, cache);
      }
    }

    /* no reverse-geocode available */
    return null;
  }