@Override protected void onHandleIntent(Intent intent) { Log.d(TAG, "Started DataSmsReceivedService"); ThreeHeadedMonkeyApplication application = (ThreeHeadedMonkeyApplication) getApplication(); Bundle bundle = intent.getExtras(); if (bundle == null) return; Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus == null || pdus.length == 0) return; for (int i = 0; i < pdus.length; i++) { try { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]); // Log.d(TAG, "Received PDU: " + new String(Hex.encodeHex((byte[]) // pdus[i]))); byte[] data = smsMessage.getUserData(); String message = new String(data, "UTF-8"); String sender = smsMessage.getOriginatingAddress(); Log.d(TAG, "Received data-sms from " + sender + ": " + message); List<PhoneNumberInfo> infos = application.phoneNumberSettings.findEntriesForNumber(sender); if (infos.isEmpty()) { Log.d(TAG, "Datasms sender not authorized to send commands"); continue; } Intent command_intent = new Intent(this, CommandExecutorService.class); command_intent.putExtra(CommandExecutorService.INTENT_COMMAND_STRING_PARAM, message); command_intent.putExtra( CommandExecutorService.INTENT_OUTGOING_COMMUNICATION_TYPE_PARAM, OutgoingCommandCommunicationFactory.OUTGOING_COMMUNICATION_TYPE_DATASMS); command_intent.putExtra( CommandExecutorService.INTENT_OUTGOING_COMMUNICATION_SENDER_ADDRESS_PARAM, sender); startService(command_intent); } catch (Exception ex) { Log.e(TAG, "Exception while parsing data sms", ex); } } }
/** * Creates and returns a Message object from the provided PDU if possible * * @param pdu the message PDU (protocol data unit - header and payload) as a byte array * @return a BinaryMessage or TextMessage object depending on the type of the message provided * @throws InvalidMessageException if the message was definitely not relevant to Sapelli * @throws Exception for any other errors that occur while trying to parse the message */ private Message<?, ?> messageFromPDU(byte[] pdu, boolean binary) throws InvalidMessageException, Exception { // Get Android SMS msg representation for pdu: SmsMessage androidMsg = SmsMessage.createFromPdu(pdu); if (androidMsg == null) throw new Exception("Android could not parse the SMS message from its PDU."); // Debug: // Log.d(TAG,"MESSAGE BODY: " + androidMsg.getMessageBody()); // Get sender phone number (we assume that if the number doesn't start with '+' the correct // country is given by the current network (rather than the SIM)): PhoneNumber senderPhoneNumber = SMSCorrespondent.toPhoneNumber( androidMsg.getOriginatingAddress(), DeviceControl.getNetworkCountryISOCode(this)); // Get an SMSCorrespondent corresponding to this phone number: SMSCorrespondent sender = transmissionController.getSendingCorrespondentFor(senderPhoneNumber, binary); // Return Sapelli Message: if (binary) return new BinaryMessage(sender, androidMsg.getUserData()); else return new TextMessage(sender, androidMsg.getMessageBody()); }
/** {@inheritDoc} */ protected int dispatchMessage(SmsMessageBase smsb) { // If sms is null, means there was a parsing error. if (smsb == null) { return Intents.RESULT_SMS_GENERIC_ERROR; } SmsMessage sms = (SmsMessage) smsb; boolean handled = false; if (sms.isTypeZero()) { // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be // Displayed/Stored/Notified. They should only be acknowledged. Log.d(TAG, "Received short message type 0, Don't display or store it. Send Ack"); return Intents.RESULT_SMS_HANDLED; } // Special case the message waiting indicator messages if (sms.isMWISetMessage()) { mGsmPhone.updateMessageWaitingIndicator(true); handled = sms.isMwiDontStore(); if (Config.LOGD) { Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled); } } else if (sms.isMWIClearMessage()) { mGsmPhone.updateMessageWaitingIndicator(false); handled = sms.isMwiDontStore(); if (Config.LOGD) { Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled); } } if (handled) { return Intents.RESULT_SMS_HANDLED; } if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { // It's a storable message and there's no storage available. Bail. // (See TS 23.038 for a description of class 0 messages.) return Intents.RESULT_SMS_OUT_OF_MEMORY; } SmsHeader smsHeader = sms.getUserDataHeader(); // See if message is partial or port addressed. if ((smsHeader == null) || (smsHeader.concatRef == null)) { // Message is not partial (not part of concatenated sequence). byte[][] pdus = new byte[1][]; pdus[0] = sms.getPdu(); if (smsHeader != null && smsHeader.portAddrs != null) { if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) { return mWapPush.dispatchWapPdu(sms.getUserData()); } else { // The message was sent to a port, so concoct a URI for it. dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort); } } else { // Normal short and non-port-addressed message, dispatch it. dispatchPdus(pdus); } return Activity.RESULT_OK; } else { // Process the message part. return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs); } }