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; } } }
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); }
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; } } }); }
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; }