/* start UDP listener */ private ServerSocketThread _startUDP(int port) throws Throwable { ServerSocketThread sst = null; /* create server socket */ try { sst = new ServerSocketThread(ServerSocketThread.createDatagramSocket(port)); } catch (Throwable t) { // trap any server exception Print.logException("ServerSocket error", t); throw t; } /* initialize */ sst.setTextPackets(Constants.ASCII_PACKETS); sst.setBackspaceChar(null); // no backspaces allowed sst.setLineTerminatorChar(Constants.ASCII_LINE_TERMINATOR); sst.setIgnoreChar(Constants.ASCII_IGNORE_CHARS); sst.setMaximumPacketLength(Constants.MAX_PACKET_LENGTH); sst.setMinimumPacketLength(Constants.MIN_PACKET_LENGTH); sst.setIdleTimeout(TrackServer.udpTimeout_idle); sst.setPacketTimeout(TrackServer.udpTimeout_packet); sst.setSessionTimeout(TrackServer.udpTimeout_session); sst.setTerminateOnTimeout(Constants.TERMINATE_ON_TIMEOUT); sst.setClientPacketHandlerClass(TrackClientPacketHandler.class); /* start thread */ Print.logInfo( "Starting UDP listener thread on port " + port + " [timeout=" + sst.getSessionTimeout() + "ms] ..."); sst.start(); this.udpThread.add(sst); return sst; }
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; } } }
protected String getStringProperty(Device device, String key, String dft) { DCServerConfig dcs = (device != null) ? DCServerFactory.getServerConfig(device.getDeviceCode()) : null; String prop = null; if (dcs != null) { prop = dcs.getStringProperty(key, dft); Print.logInfo("DCServerConfig property '" + key + "' ==> " + prop); if (StringTools.isBlank(prop) && RTConfig.hasProperty(key)) { Print.logInfo("(RTConfig property '" + key + "' ==> " + RTConfig.getString(key, "") + ")"); } } else { prop = RTConfig.getString(key, dft); Print.logInfo("RTConfig property '" + key + "' ==> " + prop); } return prop; }
protected boolean _setDevice(Device device, String ipAddress, int clientPort) { /* valid device? */ if (device == null) { return false; } /* validate ID address */ DataTransport dataXPort = device.getDataTransport(); if ((ipAddress != null) && !dataXPort.isValidIPAddress(ipAddress)) { Print.logError( "Invalid IPAddr: " + device.getAccountID() + "/" + device.getDeviceID() + " Found=" + ipAddress + " Expect=" + dataXPort.getIpAddressValid()); return false; } /* update device */ this.device = device; this.dataXPort = dataXPort; this.dataXPort.setIpAddressCurrent(ipAddress); // FLD_ipAddressCurrent this.dataXPort.setRemotePortCurrent(clientPort); // FLD_remotePortCurrent this.dataXPort.setDeviceCode(this.getDeviceCode()); // FLD_deviceCode this.device.setLastTotalConnectTime(DateTime.getCurrentTimeSec()); // FLD_lastTotalConnectTime /* ok */ return true; }
/* private constructor */ private TrackServer(int tcpPorts[], int udpPorts[], int commandPort) throws Throwable { int listeners = 0; // Start TCP listeners if (!ListTools.isEmpty(tcpPorts)) { for (int i = 0; i < tcpPorts.length; i++) { int port = tcpPorts[i]; if (ServerSocketThread.isValidPort(port)) { try { this._startTCP(port); listeners++; } catch (java.net.BindException be) { Print.logError("TCP: Error binding to port: %d", port); } } else { throw new Exception("TCP: Invalid port number: " + port); } } } // Start UDP listeners if (!ListTools.isEmpty(udpPorts)) { for (int i = 0; i < udpPorts.length; i++) { int port = udpPorts[i]; if (ServerSocketThread.isValidPort(port)) { try { ServerSocketThread sst = this._startUDP(port); if (this.udpSocket == null) { this.udpSocket = sst.getDatagramSocket(); } listeners++; } catch (java.net.BindException be) { Print.logError("UDP: Error binding to port: %d", port); } } else { throw new Exception("UDP: Invalid port number: " + port); } } } /* do we have any active listeners? */ if (listeners <= 0) { Print.logWarn("No active device communication listeners!"); } }
protected Device loadDevice(String acctID, String devID) { if (StringTools.isBlank(acctID)) { return this.loadDevice(devID); // load ad ModemID } else { try { Account account = Account.getAccount(acctID); if (account == null) { Print.logError("Account-ID not found: " + acctID); return null; } else { Device dev = Transport.loadDeviceByTransportID(account, devID); return dev; } } catch (DBException dbe) { Print.logError("Error getting Device: " + acctID + "/" + devID + " [" + dbe + "]"); return null; } } }
/** ** 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); }
/* start TCP listener */ private void _startTCP(int port) throws Throwable { ServerSocketThread sst = null; /* create server socket */ try { sst = new ServerSocketThread(port); } catch (Throwable t) { // trap any server exception Print.logException("ServerSocket error", t); throw t; } /* initialize */ sst.setTextPackets(Constants.ASCII_PACKETS); sst.setBackspaceChar(null); // no backspaces allowed sst.setLineTerminatorChar(Constants.ASCII_LINE_TERMINATOR); sst.setIgnoreChar(Constants.ASCII_IGNORE_CHARS); sst.setMaximumPacketLength(Constants.MAX_PACKET_LENGTH); sst.setMinimumPacketLength(Constants.MIN_PACKET_LENGTH); sst.setIdleTimeout(TrackServer.tcpTimeout_idle); // time between packets sst.setPacketTimeout( TrackServer.tcpTimeout_packet); // time from start of packet to packet completion sst.setSessionTimeout(TrackServer.tcpTimeout_session); // time for entire session sst.setTerminateOnTimeout(Constants.TERMINATE_ON_TIMEOUT); sst.setClientPacketHandlerClass(TrackClientPacketHandler.class); sst.setLingerTimeoutSec(Constants.LINGER_ON_CLOSE_SEC); /* start thread */ Print.logInfo( "Starting TCP listener thread on port " + port + " [timeout=" + sst.getSessionTimeout() + "ms] ..."); sst.start(); this.tcpThread.add(sst); }
public boolean updateDevice() { if (this.device != null) { /* save device changes */ try { // TODO: check "this.device" vs "this.dataXPort" this.device.updateChangedEventFields(); return true; } catch (DBException dbe) { Print.logException( "Unable to update Device: " + this.getAccountID() + "/" + this.getDeviceID(), dbe); } finally { // } } return false; }
/** ** 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; }
public static void main(String args[]) { DBConfig.cmdLineInit(args, true); // main String acctID = RTConfig.getString(ARG_ACCOUNT, ""); String roleID = RTConfig.getString(ARG_ROLE, ""); String aclID = RTConfig.getString(ARG_ACL, ""); /* account-id specified? */ if ((acctID == null) || acctID.equals("")) { Print.logError("Account-ID not specified."); usage(); } /* get account */ Account acct = null; try { acct = Account.getAccount(acctID); // may return DBException if (acct == null) { Print.logError("Account-ID does not exist: " + acctID); usage(); } } catch (DBException dbe) { Print.logException("Error loading Account: " + acctID, dbe); // dbe.printException(); System.exit(99); } /* role-id specified? */ if ((roleID == null) || roleID.equals("")) { Print.logError("Role-ID not specified."); usage(); } /* get role */ Role role = null; try { role = Role.getRole(acct, roleID); // may return DBException if (role == null) { Print.logError("Role-ID does not exist: " + acctID + "/" + roleID); usage(); } } catch (DBException dbe) { Print.logException("Error loading Role: " + acctID + "/" + roleID, dbe); // dbe.printException(); System.exit(99); } /* RoleAcl exists? */ boolean aclExists = false; if ((aclID != null) && !aclID.equals("")) { try { aclExists = RoleAcl.exists(acctID, roleID, aclID); } catch (DBException dbe) { Print.logError( "Error determining if RoleAcl exists: " + acctID + "/" + roleID + "/" + aclID); System.exit(99); } } /* option count */ int opts = 0; /* list */ if (RTConfig.getBoolean(ARG_LIST, false)) { opts++; try { String aclList[] = role.getAclsForRole(); for (int i = 0; i < aclList.length; i++) { AccessLevel level = RoleAcl.getAccessLevel(role, aclList[i], AccessLevel.NONE); Print.sysPrintln(" " + aclList[i] + " ==> " + level); } } catch (DBException dbe) { Print.logError("Error getting Acl list: " + dbe); System.exit(99); } System.exit(0); } /* delete */ if (RTConfig.getBoolean(ARG_DELETE, false) && !acctID.equals("") && !roleID.equals("")) { opts++; if (!aclExists) { Print.logWarn("RoleAcl does not exist: " + acctID + "/" + roleID + "/" + aclID); Print.logWarn("Continuing with delete process ..."); } try { RoleAcl.Key aclKey = new RoleAcl.Key(acctID, roleID, aclID); aclKey.delete(true); // also delete dependencies Print.logInfo("RoleAcl deleted: " + acctID + "/" + roleID + "/" + aclID); } catch (DBException dbe) { Print.logError("Error deleting RoleAcl: " + acctID + "/" + roleID + "/" + aclID); dbe.printException(); System.exit(99); } System.exit(0); } /* create */ if (RTConfig.getBoolean(ARG_CREATE, false)) { opts++; if (aclExists) { Print.logWarn("RoleAcl already exists: " + acctID + "/" + roleID + "/" + aclID); } else { try { RoleAcl.createNewRoleAcl(role, aclID); Print.logInfo("Created RoleAcl: " + acctID + "/" + roleID + "/" + aclID); aclExists = true; } catch (DBException dbe) { Print.logError("Error creating RoleAcl: " + acctID + "/" + roleID + "/" + aclID); dbe.printException(); System.exit(99); } } } /* set */ if (RTConfig.hasProperty(ARG_SET)) { opts++; AccessLevel aclLevel = EnumTools.getValueOf(AccessLevel.class, RTConfig.getInt(ARG_SET, -1)); try { RoleAcl.setAccessLevel(role, aclID, aclLevel); Print.logInfo( "Set RoleAcl '" + acctID + "/" + roleID + "/" + aclID + "' to level " + aclLevel); } catch (DBException dbe) { Print.logError("Error setting RoleAcl: " + acctID + "/" + roleID + "/" + aclID); dbe.printException(); System.exit(99); } System.exit(0); } /* edit */ if (RTConfig.getBoolean(ARG_EDIT, false)) { opts++; if (!aclExists) { Print.logError("RoleAcl does not exist: " + acctID + "/" + roleID + "/" + aclID); } else { try { RoleAcl roleAcl = RoleAcl.getRoleAcl(role, aclID, false); // may throw DBException DBEdit editor = new DBEdit(roleAcl); editor.edit(); // may throw IOException } catch (IOException ioe) { if (ioe instanceof EOFException) { Print.logError("End of input"); } else { Print.logError("IO Error"); } } catch (DBException dbe) { Print.logError("Error editing RoleAcl: " + acctID + "/" + roleID + "/" + aclID); dbe.printException(); } } System.exit(0); } /* no options specified */ if (opts == 0) { Print.logWarn("Missing options ..."); usage(); } }
private static void usage() { Print.logInfo("Usage:"); Print.logInfo(" java ... " + RoleAcl.class.getName() + " {options}"); Print.logInfo("Common Options:"); Print.logInfo(" -account=<id> Acount ID which owns Role"); Print.logInfo(" -role=<id> Role ID which owns RoleAcl"); Print.logInfo(" -list List Acls for Role"); Print.logInfo(" -acl=<id> Role ID to create/edit"); Print.logInfo(" -set=<val> RoleAcl value (create if necessary)"); Print.logInfo(" -create Create a new RoleAcl"); Print.logInfo(" -edit Edit an existing (or newly created) RoleAcl"); Print.logInfo(" -delete Delete specified RoleAcl"); System.exit(1); }