CService.java
上传用户:shunchung
上传日期:2013-04-07
资源大小:438k
文件大小:26k
源码类别:

手机短信编程

开发平台:

Java

  1. // jSMSEngine API.
  2. // An open-source API package for sending and receiving SMS via a GSM device.
  3. // Copyright (C) 2002-2006, Thanasis Delenikas, Athens/GREECE
  4. // Web Site: http://www.jsmsengine.org
  5. //
  6. // jSMSEngine is a package which can be used in order to add SMS processing
  7. // capabilities in an application. jSMSEngine is written in Java. It allows you
  8. // to communicate with a compatible mobile phone or GSM Modem, and
  9. // send / receive SMS messages.
  10. //
  11. // jSMSEngine is distributed under the LGPL license.
  12. //
  13. // This library is free software; you can redistribute it and/or
  14. // modify it under the terms of the GNU Lesser General Public
  15. // License as published by the Free Software Foundation; either
  16. // version 2.1 of the License, or (at your option) any later version.
  17. // This library is distributed in the hope that it will be useful,
  18. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20. // Lesser General Public License for more details.
  21. // You should have received a copy of the GNU Lesser General Public
  22. // License along with this library; if not, write to the Free Software
  23. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24. //
  25. package org.jsmsengine;
  26. import java.io.*;
  27. import java.util.*;
  28. import java.util.logging.*;
  29. import java.text.*;
  30. /**
  31. This class provides all the functionality of jSMSEngine API to the developer.
  32. <br><br>
  33. The class CService provides all the interface routines to jSMSEngine. It
  34. is responsible for initialization of the communication with the GSM device,
  35. reading and sending messages, setting the phonebook.
  36. <br><br>
  37. The sequence of actions that need to be done are:
  38. <ul>
  39. <li>Call connect() to connect with the GSM device.</li>
  40. <li>Call sendMessage(), or readMessages() to send or receive messages
  41. from the device. Call deleteMessage() to delete a message from
  42. the device's memory.</li>
  43. <li>Call refreshDeviceInfo() to get updated GSM device specific information.</li>
  44. <li>Call disconnect() to disconnect from the GSM device.</li>
  45. </ul>
  46. <br>
  47. */
  48. public class CService
  49. {
  50. /**
  51. Internal Software Name.
  52. */
  53. public static final String _name = "jSMSEngine API";
  54. /**
  55. Version.
  56. */
  57. public static final String _version = "2.0.4";
  58. /**
  59. Release Date.
  60. */
  61. public static final String _reldate = "Jan 18, 2006";
  62. /**
  63. Logging facilities.
  64. */
  65. private static Logger log = Logger.getLogger("org.jsmsengine");
  66. /**
  67. Preferred Message Storage constants.
  68. */
  69. public static final int SMS_STORAGE_SIM = 1;
  70. /**
  71. Preferred Message Storage constants.
  72. */
  73. public static final int SMS_STORAGE_MEM = 2;
  74. /**
  75. Receive modes: Synchronous and Ascynchronous.
  76. */
  77. public static final int RECEIVE_MODE_SYNC = 1;
  78. /**
  79. Receive modes: Synchronous and Ascynchronous.
  80. */
  81. public static final int RECEIVE_MODE_ASYNC = 2;
  82. /**
  83. Default value for information that is not reported by the GSM device. 
  84. */
  85. public static final String VALUE_NOT_REPORTED = "* N/A *";
  86. /**
  87. Maximum number of retries when a message failes to be sent (various CMS errors)
  88. */
  89. public static final int CMS_ERRORS_MAX_RETRIES = 5;
  90. public static final int CMS_ERRORS_DELAY = 5000;
  91. public static final int MAX_SMS_LEN_7BIT = 160;
  92. public static final int MAX_SMS_LEN_8BIT = 140;
  93. public static final int MAX_SMS_LEN_UNICODE = 70;
  94. /**
  95. The SMSC number (if specifically given).
  96. */
  97. private String smscNumber;
  98. /**
  99. The PIN number.
  100. */
  101. private String simPin;
  102. /**
  103. Receive Mode: Synchronous or Asynchronous.
  104. */
  105. private int receiveMode;
  106. /**
  107. AT Commands' Handler.
  108. */
  109. private CATHandler atHandler;
  110. private CSerialDriver serialDriver;
  111. private boolean connected;
  112. private CPhoneBook phoneBook;
  113. private CDeviceInfo deviceInfo;
  114. private CReceiveThread receiveThread;
  115. private CSmsMessageListener messageHandler;
  116. /**
  117. Default constructor of the class.
  118. @param port the serial port where the GSM device is connected (e.g. "com1"). 
  119. @param baud the connection speed (i.e. 9600, 19200 etc).
  120. @param gsmDeviceManufacturer The manufacturer of your device, i.e. Nokia, Siemens, etc.
  121. @param gsmDeviceModel The model of your device, i.e. 6310i, C55, V600 etc.
  122. <br><br>
  123. Notes:
  124. <ul>
  125. <li>The manufacturer / model combination is used for accessing the correct AT handler for
  126. your device. If there is no specific handler developed, jSMSEngine will fall back and
  127. use the generic AT handler. This may or may not work, depending on the
  128. peculiarities of your device. If you wish to create a custom handler, please look
  129. at the specific section of the documentation pages.</li>
  130. <li>Use one of the standard values for baud. Most GSM phones work well
  131. at 9600 or 19200. Most dedicated GSM modems may work well up to
  132. 115200. The connection speed is not that important to the speed
  133. at which jSMSEngine processes messages.</li>
  134. </ul>
  135. */
  136. public CService(String port, int baud, String gsmDeviceManufacturer, String gsmDeviceModel)
  137. {
  138. smscNumber = null;
  139. simPin = null;
  140. connected = false;
  141. serialDriver = new CSerialDriver(port, baud, log);
  142. phoneBook = new CPhoneBook();
  143. deviceInfo = new CDeviceInfo();
  144. if ((System.getProperty("jsmsengine.debug") != null) && (System.getProperty("jsmsengine.debug").equalsIgnoreCase("true")))
  145. {
  146. log.setLevel(Level.FINEST);
  147. log.log(Level.INFO, "jSMSEngine:" + _name + " / " + _version + " / " + _reldate);
  148. log.log(Level.INFO, " JRE Version: " + System.getProperty("java.version"));
  149. log.log(Level.INFO, " JRE Impl Version: " + System.getProperty("java.vm.version"));
  150. log.log(Level.INFO, " Class Path: " + System.getProperty("java.class.path"));
  151. log.log(Level.INFO, " Library Path: " + System.getProperty("java.library.path"));
  152. log.log(Level.INFO, " O/S: " + System.getProperty("os.name") + " / " + System.getProperty("os.arch") + " / " + System.getProperty("os.version"));
  153. }
  154. else log.setLevel(Level.SEVERE);
  155. // Which AT Handler should I use???
  156. if (gsmDeviceManufacturer.equalsIgnoreCase("Nokia"))
  157. {
  158. atHandler = new CATHandler_Nokia(serialDriver, log);
  159. log.log(Level.INFO, "jSMSEngine: Using Nokia(Generic) AT handler.");
  160. }
  161. else if (gsmDeviceManufacturer.equalsIgnoreCase("Wavecom"))
  162. {
  163. atHandler = new CATHandler_Wavecom(serialDriver, log);
  164. log.log(Level.INFO, "jSMSEngine: Using Wavecom(Generic) AT handler.");
  165. }
  166. else if (gsmDeviceManufacturer.equalsIgnoreCase("Siemens"))
  167. {
  168. atHandler = new CATHandler_Siemens(serialDriver, log);
  169. log.log(Level.INFO, "jSMSEngine: Using Siemens AT(Generic) handler.");
  170. }
  171. else if (gsmDeviceManufacturer.equalsIgnoreCase("SonyEricsson"))
  172. {
  173. atHandler = new CATHandler_SonyEricsson(serialDriver, log);
  174. log.log(Level.INFO, "jSMSEngine: Using SonyEricsson(Generic) AT handler.");
  175. }
  176. else
  177. {
  178. atHandler = new CATHandler(serialDriver, log);
  179. log.log(Level.INFO, "jSMSEngine: Using generic AT handler.");
  180. }
  181. receiveMode = RECEIVE_MODE_SYNC;
  182. receiveThread = null;
  183. }
  184. /**
  185. Returns TRUE if the API is connected to the GSM device.
  186. @return  TRUE if the API is connected to the GSM device.
  187. */
  188. public boolean getConnected() { return connected; }
  189. /**
  190. Returns a CDeviceInfo object that holds information about the GSM
  191. device in use.
  192. @return  a CDeviceInfo object.
  193. @see CDeviceInfo
  194. */
  195. public CDeviceInfo getDeviceInfo() { return deviceInfo; }
  196. /**
  197. Sets the Short Message Service Center (SMSC) number. Please use international format.
  198. If you don't want to set the SMSC and use the one defined in your GSM device, use an
  199. empty string parameter. Another way to do the same, is to pass a null parameter. Some
  200. phones may prefer one way or the other - please test your phone.
  201. @param smscNumber the SMSC number.
  202. */
  203. public void setSmscNumber(String smscNumber) { this.smscNumber = smscNumber; }
  204. /**
  205. Returns the Short Message Service Center (SMSC) number you have previously
  206. defined with setSmscNumber().
  207. @return  the SMSC number.
  208. */
  209. public String getSmscNumber() { return smscNumber; }
  210. /**
  211. Sets the SIM pin number. This is used if and when the GSM device asks for it. If you set it to
  212. null, then the API does not give any PIN to the device (in order to avoid locking it up), and
  213. returns ERR_SIM_PIN_ERROR.
  214. @param simPin the SIM pin number.
  215. */
  216. public void setSimPin(String simPin) { this.simPin = simPin; }
  217. public void setMessageHandler(CSmsMessageListener messageHandler) { this.messageHandler = messageHandler; }
  218. /**
  219. Returns the SIM pin number.
  220. @return  the SIM pin number.
  221. */
  222. public String getSimPin() { return simPin; }
  223. /**
  224. Sets the reception mode.
  225. There are two reception modes, the synchronous and the asynchronous.
  226. In synchronous mode, you should call readMessages() function on demand,
  227. where you want to check for new messages. In asynchronous mode, the engine
  228. automatically calls the received() method (which you <strong>should</strong>
  229. override) for every received message.
  230. <br>By default, the reception mode is the synchronous one.
  231. @param receiveMode the reception mode (one of values RECEIVE_MODE_ASYNC, RECEIVE_MODE_SYNC).
  232. @see CService#getReceiveMode()
  233. */
  234. public void setReceiveMode(int receiveMode) { this.receiveMode = receiveMode; }
  235. /**
  236. Returns the reception mode.
  237. @return the reception mode (one of values RECEIVE_MODE_ASYNC, RECEIVE_MODE_SYNC).
  238. @see CService#setReceiveMode(int)
  239. */
  240. public int getReceiveMode() { return receiveMode; }
  241. /**
  242. Loads the phonebook. The phonebook is an XML file containing associations of name
  243. and phone numbers.
  244. <br><br>
  245. <strong>The phonebook is optional.</strong> 
  246. @param phoneBookFile The XML full-path name which keeps the phonebook.
  247. @see CPhoneBook
  248. @see CService#sendMessage(COutgoingMessage)
  249. @see CService#sendMessage(LinkedList)
  250. */
  251. public void setPhoneBook(String phoneBookFile) throws Exception
  252. {
  253. phoneBook.load(phoneBookFile);
  254. }
  255. protected CSmsMessageListener getMessageHandler() { return messageHandler; }
  256. /**
  257. Connects to the GSM device. Opens the serial port, and sends the appropriate
  258. AT commands to initialize the operation mode of the GSM device. Retrieves
  259. information about the GSM device.
  260. Notes:
  261. <br>
  262. <ul>
  263. <li>The GSM device specific information (read by the call to refreshDeviceInfo()
  264. function is called once from this method. Since some information changes
  265. with time (such as battery or signal level), its your responsibility to
  266. call refreshDeviceInfo() periodically in order to have the latest information.
  267. Otherwise, you will get the information snapshot taken at the time
  268. of the initial connection.
  269. </li>
  270. </ul>
  271. @throws  AlreadyConnectedException
  272. @throws NoPinException
  273. @throws InvalidPinException
  274. @throws NoPduSupportException
  275. @throws CannotDisableIndicationsException
  276. @see CDeviceInfo
  277. @see CService#refreshDeviceInfo()
  278. @see CService#disconnect()
  279. */
  280. public void connect() throws Exception
  281. {
  282. if (getConnected()) throw new AlreadyConnectedException();
  283. else
  284. try
  285. {
  286. serialDriver.open();
  287. atHandler.reset();
  288. atHandler.sync();
  289. if (atHandler.isAlive())
  290. {
  291. if (atHandler.waitingForPin())
  292. {
  293. if (getSimPin() == null) throw new NoPinException();
  294. else if (!atHandler.enterPin(getSimPin())) throw new InvalidPinException();
  295. }
  296. atHandler.echoOff();
  297. atHandler.init();
  298. atHandler.setVerboseErrors();
  299. if (!atHandler.setPduMode()) throw new NoPduSupportException();
  300. if (!atHandler.disableIndications()) throw new CannotDisableIndicationsException();
  301. connected = true;
  302. refreshDeviceInfo();
  303. receiveThread = new CReceiveThread();
  304. receiveThread.start();
  305. }
  306. else throw new NotConnectedException("GSM device is not responding.");
  307. }
  308. catch (AlreadyConnectedException e)
  309. {
  310. throw e;
  311. }
  312. catch (Exception e)
  313. {
  314. disconnect();
  315. throw e;
  316. }
  317. }
  318. /**
  319. Disconnects to the GSM device. Closes the serial port. 
  320. @see CService#connect()
  321. */
  322. public void disconnect()
  323. {
  324. if (receiveThread != null)
  325. {
  326. receiveThread.killMe();
  327. while (!receiveThread.killed()) try { Thread.sleep(1000); } catch (Exception e) {}
  328. receiveThread = null;
  329. }
  330. try { serialDriver.close(); } catch (Exception e) {}
  331. connected = false;
  332. }
  333. /**
  334. Reads SMS from the GSM device's memory. You should call this method when
  335. you want to read messages from the device. In the MessageList object you
  336. pass, the method will add objects of type CIncomingMessage, as many of them
  337. as the messages pending to be read. The class defines which types of messages
  338. should be read.
  339. <br><br>
  340. <strong>Notes:</strong>
  341. <ul>
  342. <li>The method <strong>does not delete</strong> the messages it reads
  343. from the GSM device. It's your responsibility to delete them, if you
  344. don't want them. Otherwise, on the next call of this function you
  345. will read the same messages.</li>
  346. </ul>
  347. @param messageList a LinkedList object which will be loaded with the messages.
  348. @param messageClass one of the CLASS_* values defined in CIncomingMessage class which
  349. define what type of messages are to be read.
  350. @throws NotConnectedException
  351. @see CIncomingMessage
  352. @see CService#deleteMessage(CIncomingMessage)
  353. @see CService#deleteMessage(int)
  354. */
  355. public void readMessages(LinkedList messageList, int messageClass) throws Exception
  356. {
  357. int i, j, memIndex;
  358. String response, line, sms, temp, originator, text, pdu;
  359. String day, month, year, hour, min, sec;
  360. BufferedReader reader;
  361. Date sentDate;
  362. Calendar cal = Calendar.getInstance();
  363. if (getConnected())
  364. {
  365. atHandler.switchToCmdMode();
  366. response = atHandler.listMessages(messageClass);
  367. reader = new BufferedReader(new StringReader(response));
  368. line = reader.readLine().trim();
  369. while ((line != null) && (line.length() > 0) && (!line.equalsIgnoreCase("OK")))
  370. {
  371. i = line.indexOf(':');
  372. j = line.indexOf(',');
  373. memIndex = Integer.parseInt(line.substring(i + 1, j).trim());
  374. pdu = reader.readLine();
  375. if (isIncomingMessage(pdu))
  376. {
  377. messageList.add(new CIncomingMessage(pdu, memIndex));
  378. deviceInfo.getStatistics().incTotalIn();
  379. }
  380. else if (isStatusReportMessage(pdu))
  381. {
  382. messageList.add(new CStatusReportMessage(pdu, memIndex));
  383. deviceInfo.getStatistics().incTotalIn();
  384. }
  385. line = reader.readLine().trim();
  386. }
  387. reader.close();
  388. }
  389. else throw new NotConnectedException();
  390. }
  391. /**
  392. Send an SMS message from the GSM device. Once connected, you can create a
  393. COutgoingMessage object with the message you want to send, and pass it
  394. to this function.
  395. <br><br>
  396. <strong>Notes:</strong>
  397. <ul>
  398. <li>If you have set a phonebook, you can create the COutgoingMessage
  399. object with a nickname, instead of the actual phone number.</li>
  400. </ul>
  401. @param message a COutgoingMessage containing the message you wish to send.
  402. @return  true if sending succeded.
  403. @see COutgoingMessage
  404. @see CPhoneBook
  405. @see CService#sendMessage(LinkedList)
  406. @see CService#setPhoneBook(String)
  407. */
  408. public boolean sendMessage(COutgoingMessage message) throws Exception
  409. {
  410. LinkedList messageList;
  411. COutgoingMessage msg;
  412. boolean result;
  413. messageList = new LinkedList();
  414. messageList.add(message);
  415. sendMessage(messageList);
  416. return (message.getDispatchDate() != null);
  417. }
  418. /**
  419. Send an series of SMS messages from the GSM device. This method is used
  420. when you want to send more than one message as a batch. If your GSM device
  421. support the feature of keeping the GSM link open during message dispatch,
  422. this method should work faster than calling the sendMessage(COutgoingMessage)
  423. method many times.
  424. <br>
  425. Just create a LinkedList object, add as many COutgoingMessage objects you wish
  426. and call the method.
  427. <br><br>
  428. <strong>Notes:</strong>
  429. <ul>
  430. <li>If you have set a phonebook, you can create the COutgoingMessage
  431. object with a nickname, instead of the actual phone number.</li>
  432. </ul>
  433. @param messageList a LinkedList filled with COutgoingMessage objects.
  434. @throws NotConnectedException
  435. @see COutgoingMessage
  436. @see CPhoneBook
  437. @see CService#sendMessage(COutgoingMessage)
  438. @see CService#setPhoneBook(String)
  439. */
  440. public void sendMessage(LinkedList messageList) throws Exception
  441. {
  442. LinkedList outList;
  443. COutgoingMessage message;
  444. int i, j;
  445. String pdu;
  446. if (getConnected())
  447. {
  448. if (phoneBook.isLoaded()) outList = phoneBook.expandPhoneBookEntries(messageList);
  449. else outList = messageList;
  450. atHandler.keepGsmLinkOpen();
  451. for (i = 0; i < outList.size(); i ++)
  452. {
  453. message = (COutgoingMessage) outList.get(i);
  454. pdu = message.getPDU(smscNumber);
  455. j = pdu.length();
  456. j /= 2;
  457. if (smscNumber == null) ;
  458. else if (smscNumber.length() == 0) j --;
  459. else
  460. {
  461. j -= ((smscNumber.length() - 1) / 2);
  462. j -= 2;
  463. }
  464. if (atHandler.sendMessage(j, pdu))
  465. {
  466. message.setDispatchDate(new Date());
  467. deviceInfo.getStatistics().incTotalOut();
  468. }
  469. else message.setDispatchDate(null);
  470. }
  471. }
  472. else throw new NotConnectedException();
  473. }
  474. /**
  475. Deletes an SMS message from the GSM device memory.
  476. <br><br>
  477. <strong>Notes:</strong>
  478. <ul>
  479. <li>A deleted message cannot be recovered.</li>
  480. <li>It is highly recommended to use the other form of the deleteMessage()
  481. method.</li>
  482. </ul>
  483. @param memIndex the memory index of the GSM device's memory from where
  484. the message (if there is any message there) should be deleted.
  485. @return  True if delete operation succeded.
  486. @throws NotConnectedException
  487. @see CService#deleteMessage(CIncomingMessage)
  488. */
  489. public boolean deleteMessage(int memIndex) throws Exception
  490. {
  491. String response;
  492. if (getConnected())
  493. {
  494. if (memIndex > 0) return atHandler.deleteMessage(memIndex);
  495. else return false;
  496. }
  497. else throw new NotConnectedException();
  498. }
  499. /**
  500. Deletes an SMS message from the GSM device memory.
  501. <br><br>
  502. <strong>Notes:</strong>
  503. <ul>
  504. <li>A deleted message cannot be recovered.</li>
  505. </ul>
  506. @param message a valid CIncomingMessage object, i.e. an object which is
  507. previously read with readMessages() from the GSM device.
  508. @return  True if delete operation succeded.
  509. @throws NotConnectedException
  510. @see CIncomingMessage
  511. @see CService#deleteMessage(int)
  512. */
  513. public boolean deleteMessage(CIncomingMessage message) throws Exception
  514. {
  515. return deleteMessage(message.getMemIndex());
  516. }
  517. /**
  518. Sets the preferred message storage of the GSM device to SIM memory.
  519. @return  true if the change of preferred message storage succeded.
  520. */
  521. public boolean setStorageSIM() throws Exception
  522. {
  523. return atHandler.setStorageSIM();
  524. }
  525. /**
  526. Sets the preferred message storage of the GSM device to build-in memory.
  527. @return  true if the change of preferred message storage succeded.
  528. */
  529. public boolean setStorageMEM() throws Exception
  530. {
  531. return atHandler.setStorageMEM();
  532. }
  533. /**
  534. Refreshes the GSM device specific information. This method is called once during
  535. connection. Its up to the developer to call it periodically in order to get the latest
  536. information.
  537. Note: Information about Manufacturer, Model, SerialNo, IMSI, S/W Version are
  538. refreshed only once, since they don't change during a session.
  539. @see CDeviceInfo
  540. @see CService#connect()
  541. @see CService#getDeviceInfo()
  542. */
  543. public void refreshDeviceInfo() throws Exception
  544. {
  545. if (getConnected())
  546. {
  547. if (deviceInfo.manufacturer.length() == 0) deviceInfo.manufacturer = getManufacturer();
  548. if (deviceInfo.model.length() == 0) deviceInfo.model = getModel();
  549. if (deviceInfo.serialNo.length() == 0) deviceInfo.serialNo = getSerialNo();
  550. if (deviceInfo.imsi.length() == 0) deviceInfo.imsi = getImsi();
  551. if (deviceInfo.swVersion.length() == 0) deviceInfo.swVersion = getSwVersion();
  552. deviceInfo.batteryLevel = getBatteryLevel();
  553. deviceInfo.signalLevel = getSignalLevel();
  554. }
  555. else throw new NotConnectedException();
  556. }
  557. private String getManufacturer() throws Exception
  558. {
  559. String response;
  560. StringTokenizer tokens;
  561. String whatToDiscard;
  562. response = atHandler.getManufacturer();
  563. if (response.indexOf("OK") > -1)
  564. {
  565. tokens = new StringTokenizer(response, "r");
  566. return tokens.nextToken();
  567. }
  568. else return VALUE_NOT_REPORTED;
  569. }
  570. private String getModel() throws Exception
  571. {
  572. String response;
  573. StringTokenizer tokens;
  574. String whatToDiscard;
  575. response = atHandler.getModel();
  576. if (response.indexOf("OK") > -1)
  577. {
  578. tokens = new StringTokenizer(response, "r");
  579. return tokens.nextToken();
  580. }
  581. else return VALUE_NOT_REPORTED;
  582. }
  583. private String getSerialNo() throws Exception
  584. {
  585. String response;
  586. StringTokenizer tokens;
  587. String whatToDiscard;
  588. response = atHandler.getSerialNo();
  589. if (response.indexOf("OK") > -1)
  590. {
  591. tokens = new StringTokenizer(response, "r");
  592. return tokens.nextToken();
  593. }
  594. else return VALUE_NOT_REPORTED;
  595. }
  596. private String getImsi() throws Exception
  597. {
  598. String response;
  599. StringTokenizer tokens;
  600. String whatToDiscard;
  601. response = atHandler.getImsi();
  602. if (response.indexOf("OK") > -1)
  603. {
  604. tokens = new StringTokenizer(response, "r");
  605. return tokens.nextToken();
  606. }
  607. else return VALUE_NOT_REPORTED;
  608. }
  609. private String getSwVersion() throws Exception
  610. {
  611. String response;
  612. StringTokenizer tokens;
  613. String whatToDiscard;
  614. response = atHandler.getSwVersion();
  615. if (response.indexOf("OK") > -1)
  616. {
  617. tokens = new StringTokenizer(response, "r");
  618. return tokens.nextToken();
  619. }
  620. else return VALUE_NOT_REPORTED;
  621. }
  622. private int getBatteryLevel() throws Exception
  623. {
  624. String response;
  625. StringTokenizer tokens;
  626. String whatToDiscard;
  627. response = atHandler.getBatteryLevel();
  628. if (response.indexOf("OK") > -1)
  629. {
  630. tokens = new StringTokenizer(response, "r:,");
  631. tokens.nextToken(); tokens.nextToken();
  632. return Integer.parseInt(tokens.nextToken());
  633. }
  634. else return 0;
  635. }
  636. private int getSignalLevel() throws Exception
  637. {
  638. String response;
  639. StringTokenizer tokens;
  640. String whatToDiscard;
  641. response = atHandler.getSignalLevel();
  642. if (response.indexOf("OK") > -1)
  643. {
  644. tokens = new StringTokenizer(response, "r:,");
  645. tokens.nextToken();
  646. return (Integer.parseInt(tokens.nextToken().trim()) * 100 / 31);
  647. }
  648. else return 0;
  649. }
  650. /**
  651. Checks if the message is SMS-DELIVER.
  652. @param pdu the message pdu
  653. @return true if the message is SMS-DELIVER
  654. */
  655. private boolean isIncomingMessage(String pdu)
  656. {
  657. int index, i;
  658. i = Integer.parseInt(pdu.substring(0, 2), 16);
  659. index = (i + 1) * 2;
  660. i = Integer.parseInt(pdu.substring(index, index + 2), 16);
  661. if ((i & 0x03) == 0) return true;
  662. else return false;
  663. }
  664. /**
  665. Checks if the message is SMS-STATUS-REPORT.
  666. @param pdu the message pdu
  667. @return true if the message is SMS-STATUS-REPORT
  668. */
  669. private boolean isStatusReportMessage(String pdu)
  670. {
  671. String str;
  672. int index, i;
  673. str = pdu.substring(0, 2);
  674. i = Integer.parseInt(str, 16);
  675. index = (i + 1) * 2;
  676. str = pdu.substring(index, index + 2);
  677. i = Integer.parseInt(str, 16);
  678. if ((i & 0x02) == 2) return true;
  679. else return false;
  680. }
  681. /**
  682. Virtual method, called upon receipt of a message (Asynchronous mode only!)
  683. <br><br>
  684. <strong>Notes:</strong>
  685. <ul>
  686. <li>If you plan to use jSMSEngine API in asynchronous mode, you should
  687. override this method, making it do your job upon message receipt.</li>
  688. </ul>
  689. @param message the received message.
  690. @return  return true if you wish the message to be deleted from the GSM device's memory.
  691. Otherwise false.
  692. @see CService#setReceiveMode(int)
  693. */
  694. public @Deprecated boolean received(CIncomingMessage message)
  695. {
  696. return false;
  697. }
  698. private class CReceiveThread extends Thread
  699. {
  700. private boolean stopFlag;
  701. private boolean stopped;
  702. public CReceiveThread()
  703. {
  704. stopFlag = false;
  705. stopped = false;
  706. }
  707. public void killMe() { stopFlag = true; }
  708. public boolean killed() { return stopped; }
  709. public void run()
  710. {
  711. LinkedList messageList;
  712. messageList = new LinkedList();
  713. while (!stopFlag)
  714. {
  715. try { sleep(5000); } catch (Exception e) {}
  716. if (stopFlag) break;
  717. if ((getConnected()) && (getReceiveMode() == RECEIVE_MODE_ASYNC))
  718. {
  719. messageList.clear();
  720. try
  721. {
  722. readMessages(messageList, CIncomingMessage.CLASS_ALL);
  723. for (int i = 0; i < messageList.size(); i ++)
  724. {
  725. CIncomingMessage message = (CIncomingMessage) messageList.get(i);
  726. if (getMessageHandler() == null)
  727. {
  728. if (received(message)) deleteMessage(message);
  729. }
  730. else
  731. {
  732. if (getMessageHandler() != null && getMessageHandler().received(CService.this, message)) deleteMessage(message);
  733. }
  734. }
  735. }
  736. catch (Exception e)
  737. {
  738. e.printStackTrace();
  739. }
  740. }
  741. }
  742. stopped = true;
  743. }
  744. }
  745. public static void main(String[] args)
  746. {
  747. System.out.println("jSMSEngine API.");
  748. System.out.println(" An open source Java API to process SMS messages from your ");
  749. System.out.println("  mobile phone or gsm modem.");
  750. System.out.println(" This software is distributed under the LGPL license.");
  751. System.out.println("");
  752. System.out.println("Copyright (C) 2002-2006, Thanasis Delenikas, Athens / GREECE.");
  753. System.out.println("Visit http://www.jsmsengine.org for latest information.");
  754. System.out.println("n");
  755. System.out.println(_name + " v" + _version + " { " + _reldate + " }");
  756. }
  757. }