1 /* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package com.android.im.imps; 18 19 import android.util.Log; 20 21 import com.android.im.engine.ImErrorInfo; 22 import com.android.im.engine.ImException; 23 import com.android.im.engine.SmsService; 24 import com.android.im.engine.SystemService; 25 import com.android.im.engine.SmsService.SmsListener; 26 import com.android.im.engine.SmsService.SmsSendFailureCallback; 27 import com.android.internal.telephony.EncodeException; 28 import com.android.internal.telephony.GsmAlphabet; 29 30 public class SmsCirChannel extends CirChannel 31 implements SmsListener, SmsSendFailureCallback { 32 private String mAddr; 33 private int mPort; 34 35 private SmsService mSmsService; 36 SmsCirChannel(ImpsConnection connection)37 protected SmsCirChannel(ImpsConnection connection) { 38 super(connection); 39 ImpsConnectionConfig cfg = connection.getConfig(); 40 mAddr = cfg.getSmsCirAddr(); 41 mPort = cfg.getSmsCirPort(); 42 } 43 44 @Override connect()45 public void connect() throws ImException { 46 mSmsService = SystemService.getDefault().getSmsService(); 47 if (mAddr != null) { 48 mSmsService.addSmsListener(mAddr, mPort, this); 49 sendHelo(); 50 } else { 51 mSmsService.addSmsListener(SmsService.ANY_ADDRESS, mPort, this); 52 } 53 } 54 isShutdown()55 public boolean isShutdown() { 56 return false; 57 } 58 59 @Override shutdown()60 public void shutdown() { 61 mSmsService.removeSmsListener(this); 62 } 63 onIncomingSms(byte[] data)64 public void onIncomingSms(byte[] data) { 65 // It's safe to assume that each character is encoded into 7-bit since 66 // all characters in CIR are in gsm 7-bit alphabet. 67 int lengthSeptets = data.length * 8 / 7; 68 String s = GsmAlphabet.gsm7BitPackedToString(data, 0, 69 lengthSeptets, 0); 70 // CIR format: WVCI <version> <session cookie> 71 if (!s.startsWith("WVCI")) { 72 // not a valid CIR, ignore. 73 Log.w("SmsCir", "Received a non-CIR SMS, ignore!"); 74 return; 75 } 76 77 String sessionCookie = mConnection.getSession().getCookie(); 78 String[] fields = s.split(" "); 79 if (fields.length != 3 || !sessionCookie.equalsIgnoreCase(fields[2])) { 80 // Not a valid CIR, ignore 81 Log.w("SmsCir", "The CIR format is not correct or session cookie" + 82 " does not match"); 83 } 84 mConnection.sendPollingRequest(); 85 } 86 onFailure(int errorCode)87 public void onFailure(int errorCode) { 88 mConnection.shutdownOnError(new ImErrorInfo(ImpsErrorInfo.NETWORK_ERROR, 89 "Could not establish SMS CIR channel")); 90 } 91 sendHelo()92 private void sendHelo() { 93 String data = "HELO " + mConnection.getSession().getID(); 94 try { 95 byte[] bytes = GsmAlphabet.stringToGsm7BitPacked(data); 96 mSmsService.sendSms(mAddr, mPort, bytes, this); 97 } catch (EncodeException ignore) { 98 } 99 } 100 101 } 102