; 핸들러로 지연시키지 않으면 안 뜬다...이상해...

Handler keyPadHandler = new Handler();
            keyPadHandler.postDelayed(new Runnable() {
                public void run() {
                    if(mRecipientsEditor!= null){
                    if(mRecipientsEditor.getVisibility()== View.VISIBLE){
                        InputMethodManager inputMethodManager =
                            (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);       
                     inputMethodManager.showSoftInput(mRecipientsEditor, 0);
                    }
                    }
                }
            }, 100);

'old > sms&mms' 카테고리의 다른 글

SMS solicite_eclair  (0) 2010.07.22
Internals of Telephony subsystem  (0) 2010.07.09
The Radio Interface Layer (RIL)  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Posted by jazzlife
,

SMS solicite_eclair

old/sms&mms 2010. 7. 22. 12:12
[ComposeMessageActivity.java]
confirmSendMessageIfNeeded()
sendMessage()

[WorkingMessage.java]
send()
sendSmsWorker(conv, msgText)

[SmsMessageSender.java]
sendMessage(threadId)

- frameworks
[SmsManager.java]
1.sendMultipartTextMessage(mDests[i], mServiceCenter, messages, sentIntents, deliveryIntents)
2.sendTextMessage()

[IccSmsInterfaceManager.java] - ISms.aidl (ISms_Stub.java)
권한승인 -  
PhoneBase.getContext().enforceCallingPermission("android.permission.SEND_SMS","Sending SMS message");
1.sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents)
2.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent)

[GsmSMSDispatcher.java] - extended SMSDispatcher
1.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,(ArrayList<PendingIntent>) sentIntents,
(ArrayList<PendingIntent>) deliveryIntents)
   SmsMessage.getSubmitPdu(scAddress, destinationAddress,parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader),encoding)
   sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent)

2.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent)
   SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddr, destAddr, text, (deliveryIntent != null))
   SMSDispatcher.sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent)


Posted by jazzlife
,

Internals of Telephony Subsystem

1.1. Part I, the key items

Assumption: We are in the top level of Android source code repository

  • Files
    frameworks\base\telephony  the core of the telephony subsystem implementation, GSM phone and so on
    packages\apps\Phone        Phone application implementation, UI related stuffs reside
    hardware\ril               Radio reference implementation

  • The big picture

  • The key interfaces and classes

    1. Phone interfaces
      Phone.java:Base abstraction of the phone

      frameworks\base\telephony\java\com\android\internal\telephony\Phone.java

      PhoneBase.java:An abstract class which extends Phone interface and implements the Event registration and notification

      frameworks\base\telephony\java\com\android\internal\telephony\PhoneBase.java

      GSMPhone.java:A concrete phone implementation

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\GSMPhone.java

      CommandsInterface.java:Radio operation abstraction

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\CommandsInterface.java

      BaseCommands.java:Radio event registration and notification

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\BaseCommands.java

      RIL.java: Radio interface library implementation, responsible for sending request to Radio layer and
      distribute the response from Radio layer to request sender
       

      frameworks\base\telephony\java\com\android\internal\telephony\RIL.java

      Native stub for RIL.java: communicates with RIL.java through local socket

      hardware\ril\libril\*

      Reference implementation of Radio library:communicates with Radio hardware through AT command

      hardware\ril\reference-ril\*

      Radio interface lib daemon runs as a stand alone process

      hardware\ril\rild\*

    2. RIL request and response
      1, Solicited and Unsolicited response
      Solicited response response to the upper layer request, this is a kind of passive response,
      for instance, response the request of Singal strength request
      Unsolicited response a response triggered by the underlying hardware, for instance, the state change
      Radio will trigger an RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED response to notify the upper layer

    3. Request sending and handling
      RIL_Sender thread
      gets the reqeust from mRequestsList and send it to Radio reference library through local socket
      RIL Receiver thread
      receives the response from Radio reference library and process it with processUnsolicited()/processSolicited()
      according to response type RESPONSE_UNSOLICITED/RESPONSE_SOLICITED
      processUnsolicited() is responsible for processing active event from Radio layer
      processSolicited() is responsible for processing passive response to upper layer request

    4. Message identity localization and Parcel
      The mechanism used here is localize the identity of message and put it into a Parcel, send it to the target,
      the target receives the Parcel, put the wanted stuffs into Parcel and return back it to the sender, it is
      the sender's responsibility to classify and handle the response corresponds to the specific request.

      We explain this trick by an example, User dialed a number
      *A user's dialing activity runs a long trip to get to the point dial() in RIL.java
      * RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
           send(rr);
           put the RIL_REQUEST_DIAL ID into Parcel embedded in rr and send it to the target, the target here is      reference-ril.c
      * refernece-ril.c receives the request and handle it with requestDial()
      * requestDial() completes it work and send response back by RIL_onRequestComplete()
      * The implementation of RIL_onRequestComplete() resides in ril.cpp
           p.writeInt32 (RESPONSE_SOLICITED);
           p.writeInt32 (pRI->token);
           put the response type to RESPONSE_SOLICITED, because the request is initiated by upper level, and it      is a passive response, put the RIL_REQUEST_DIAL into the Parcel (pRI->token == RIL_REQUEST_DIAL) for      upper layer to handle the response to the RIL_REQUEST_DIAL request.
      * thanks to the local socket, the control flow arrived at RIL.java again, this time it hits at
           RIL_Receiver(),for the reason of RIL_Receiver's listing on SOCKET_NAME_RIL socket
           the RIL_Receiver delegates the response to the processSolicited(), it was responsibility of
           processSolicited() to notify the registrarant according the content of the response.

'old > sms&mms' 카테고리의 다른 글

soft keyboard 출력 방법  (0) 2010.07.22
SMS solicite_eclair  (0) 2010.07.22
The Radio Interface Layer (RIL)  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Posted by jazzlife
,

The Radio Interface Layer (RIL)

Introduction

Android's Radio Interface Layer (RIL) provides an abstraction layer between Android telephony services (android.telephony) and radio hardware. The RIL is radio agnostic, and includes support for Global System for Mobile communication (GSM)-based radios.

The diagram below illustrates the RIL in the context of Android's Telephony system architecture.

Solid elements represent Android blocks and dashed elements represent partner-specific proprietary blocks.

The RIL consists of two primary components:

  • RIL Daemon: The RIL daemon initializes the Vendor RIL, processes all communication from Android telephony services, and dispatches calls to the Vendor RIL as solicited commands.
  • Vendor RIL: The radio-specific Vendor RIL of ril.h that processes all communication with radio hardware and dispatches calls to the RIL Daemon (rild) through unsolicited commands.

The RIL Shim Layer

Radio Interface Layer (RIL)

  • HAL interface between the Android TelephonyManager and the baseband modem
  • Voice, Data, SMS, SIM, SIMToolkit
  • Android includes a reference AT command based RIL

RIL API

  • Currently 75 requests (e.g. Dial) and 17 unsolicited responses (e.g. signal strength)
  • Android RIL inspired by GSM TS 27.007
  • Can implement as AT command based or proprietary protocol (e.g. RPCs via shared memory)

Enhancing the RIL

  • Carriers may require specific features (e.g. JCDMA, O2 Homezone)
  • Qualcomm working on adding CDMA and Multi-mode support

Certification

  • GCF
  • CDG

Tips

  • SIM and SIM Toolkit is complex, get an expert
  • RIL needs to provide neighboring cell id (non-standard). Used by Google Maps.
  • Data: suggest packet interface, no DHCP, no PPP.
  • Depending on modem interface, RIL may get complicated with lots of logic/state.
  • Android data is always-on, modem should support dormancy

Architecture overview

Linux手机打电话代码分析(Android) - clarkluo2004 - 天翼的博客

 
RIL
Initialization

Android initializes the telephony stack and the Vendor RIL at startup as described in the sequence below:

  1. RIL daemon reads rild.lib path and rild.libargs system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
  2. RIL daemon loads the Vendor RIL library and calls RIL_Init to initialize the RIL and obtain a reference to RIL functions
  3. RIL daemon calls RIL_register on the Android telephony stack, providing a reference to the Vendor RIL functions

See the RIL Daemon source code at /device/commands/rild/rild.c for details.

RIL Interaction

There are two forms of communication that the RIL handles:

  • Solicited commands: Solicited commands originated by RIL lib, such as DIAL and HANGUP.
  • Unsolicited responses: Unsolicited responses that originate from the baseband, such as CALL_STATE_CHANGED and NEW_SMS.

Solicited

The following snippet illustrates the interface for solicited commands:

void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);

There are over sixty solicited commands grouped by the following families:

  • SIM PIN, IO, and IMSI/IMEI (11)
  • Call status and handling (dial, answer, mute…) (16)
  • Network status query (4)
  • Network setting (barring, forwarding, selection…) (12)
  • SMS (3)
  • PDP connection (4)
  • Power and reset (2)
  • Supplementary Services (5)
  • Vendor defined and support (4)

The following diagram illustrates a solicited call in Android:

Unsolicited

The following snippet illustrates the interface for unsolicited commands:

void OnUnsolicitedResponse (int unsolResponse, void *data, size_t datalen);

There are over ten unsolicited commands grouped by the following families:

  • Network status changed (4)
  • New SMS notify (3)
  • New USSD notify (2)
  • Signal strength or time changed (2)

The following diagram illustrates an unsolicited call in Android:

Implementing the RIL

To implement a radio-specific RIL, create a shared library that implements a set of functions required by Android to process radio requests. The required functions are defined in the RIL header (/include/telephony/ril.h).

The Android radio interface is radio-agnostic and the Vendor RIL can use any protocol to communicate with the radio. Android provides a reference Vendor RIL, using the Hayes AT command set, that you can use as a quick start for telephony testing and a guide for commercial vendor RILs. The source code for the reference RIL is found at /commands/reference-ril/.

Compile your Vendor RIL as a shared library using the convention libril-<companyname>-<RIL version>.so, for example, libril-acme-124.so, where:

  • libril: all vendor RIL implementations start with 'libril'
  • <companyname>: a company-specific abbreviation
  • <RIL version>: RIL version number
  • so: file extension

RIL_Init

Your Vendor RIL must define a RIL_Init function that provides a handle to the functions which will process all radio requests. RIL_Init will be called by the Android RIL Daemon at boot time to initialize the RIL.

RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);

RIL_Init should return a RIL_RadioFunctions structure containing the handles to the radio functions:

type structure {
	int RIL_version;
	RIL_RequestFunc onRequest;
	RIL_RadioStateRequest onStateRequest;      
	RIL_Supports supports;
	RIL_Cancel onCancel;
	RIL_GetVersion getVersion;
} 
RIL_RadioFunctions;

RIL Functions

ril.h defines RIL states and variables, such as RIL_UNSOL_STK_CALL_SETUP, RIL_SIM_READY, RIL_SIM_NOT_READY, as well as the functions described in the tables below. Skim the header file (/device/include/telephony/ril.h) for details.

RIL Solicited Command Requests

The vendor RIL must provide the functions described in the table below to handle solicited commands. The RIL solicited command request types are defined in ril.h with the RIL_REQUEST_ prefix. Check the header file for details.

void (*RIL_RequestFunc)(int request, void *data, size_t datalen, RIL_Token t);

This is the RIL entry point for solicited commands and must be able to handle the various RIL solicited request types defined in ril.h with the RIL_REQUEST_ prefix.

  • request is one of RIL_REQUEST_*
  • data is pointer to data defined for that RIL_REQUEST_*
  • t should be used in subsequent call to RIL_onResponse
  • datalen is owned by caller, and should not be modified or freed by callee

Must be completed with a call to RIL_onRequestComplete(). RIL_onRequestComplete() may be called from any thread before or after this function returns. This will always be called from the same thread, so returning here implies that the radio is ready to process another command (whether or not the previous command has completed).|

RIL_RadioState (*RIL_RadioStateRequest)();

This function should return the current radio state synchronously.

int (*RIL_Supports)(int requestCode);

This function returns “1” if the specified RIL_REQUEST code is supported and 0 if it is not.

void (*RIL_Cancel)(RIL_Token t);

This function is used to indicate that a pending request should be canceled. This function is called from a separate thread–not the thread that calls RIL_RequestFunc.

On cancel, the callee should do its best to abandon the request and call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point.

Subsequent calls to RIL_onRequestComplete for this request with other results will be tolerated but ignored (that is, it is valid to ignore the cancellation request).

RIL_Cancel calls should return immediately and not wait for cancellation.

const char* (*RIL_GetVersion)(void);

Return a version string for your Vendor RIL

The vendor RIL uses the following callback methods to communicate back to the Android RIL daemon.

void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);

* t is parameter passed in on previous call to RIL_Notification routine.

  • If e != SUCCESS, then response can be null and is ignored
  • response is owned by caller, and should not be modified or freed by callee
  • RIL_onRequestComplete will return as soon as possible

void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime);

Call user-specified callback function on the same thread that RIL_RequestFunc is called. If relativeTime is specified, then it specifies a relative time value at which the callback is invoked. If relativeTime is NULL or points to a 0-filled structure, the callback will be invoked as soon as possible.

RIL Unsolicited Commands

The functions listed in the table below are call-back functions used by the Vendor RIL to invoke unsolicited commands on the Android platform. See ril.h for details.

void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);

* unsolResponse is one of RIL_UNSOL_RESPONSE_*

  • data is pointer to data defined for that RIL_UNSOL_RESPONSE_*
  • data is owned by caller, and should not be modified or freed by callee

The ril source code in userspace

Usefull links

'old > sms&mms' 카테고리의 다른 글

SMS solicite_eclair  (0) 2010.07.22
Internals of Telephony subsystem  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Android SMS call analysis  (0) 2010.07.06
Posted by jazzlife
,
RIL 이란 무엇인가?
 
개요.
 
안드로이드 RIL은 android.telephony 서비스들과 radio h/w간의 추상화된 계층을 제공한다.
RIL은 radio agnostic(존재하지만 정확하게 표현하기는 어려운 실체)이며, GSM 기반의 radio들에 대한 지원을 포함하고
있다.
 
아래의 그림은 안드로이드 전화통화 시스템 구조를 설명한다.
 
   
 
위의 그림에서 Radio Daemon과 Vender RIL은 파트너의 특수성을 가진 사적소유영역에 속하며, 나머지 블록은
안드로이드 영역에 속한다고 할 수 있다.
 
RIL은 두가지의 기본적인 컴포넌트로 구성된다.
 
RIL 데몬(Daemon) : 
 
RIL 데몬은 Vender RIL을 초기화하며, 안드로이드 telephony 서비스들로부터의 모든 통신을 프로세스하며,
solicited 명령어를 통해 Vender RIL로 콜을 넘긴다.
 
Vender RIL :
 
ril.h의 radio 특수성을 포함하는 Vender RIL은 radio h/w와의 모든 통신을 처리하며, unsolicited 명령어들을 통해서
RIL 데몬(rild)에 콜을 넘긴다.



 
RIL 초기화
 
안드로이드는 구동시점에 아래에 언급된 순서대로, telephony 스택과 Vender RIL 을 초기화한다.
 
1. RIL 데몬은 Vender RIL에 제공해야할 초기화 argument와 그것을 사용하기 위한 Vender RIL 라이브러리를
   결정하기 위한 rild.lib 경로와 rild.libargs 시스템 속성들을 읽어들인다.
 
2. RIL 데몬은 Vender RIL 라이브러리를 load(탑재)하며, RIL을 초기화하기 위해 RIL_Init을 호출하며,
    RIL 함수에 대한 참조를 얻는다.
 
3. RIL 데몬은 Vender RIL 함수들에 대한 하나의 참조를 제공하는 안드로이드 Telephony 스택상의  
    RIL_register를 호출한다.
 
RIL 상호작용
 
RIL 제어 관련 통신에는 두가지 형식이 존재한다.
 
Solicited commands : Solicited 명령어들은 전화걸기(DIAL) 과 HANGUP(전화끊기)와 같은 RIL 라이브러리에 의해
                                만들어 진다.
Unsolicited responses : Unsolicited responses는 CALL_STATE_CHNGED(전화 상태 변화)와 NEW_SMS(새 문자
                                   메시지)와 같은 baseband로 부터 만들어 진다.

 
Solicited
 
아래의 인용은 solicited 명령어들에 대한 인터페이스를 보여주고 있다.
 
void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);

 
그리고 아래와 같이 계열들로 묶여질 수 있는 60개 이상의 solicited 명령어들이 존재한다.
 
  • SIM PIN, IO, and IMSI/IMEI (11)
  • Call status and handling (dial, answer, mute…) (16)
  • Network status query (4)
  • Network setting (barring, forwarding, selection…) (12)
  • SMS (3)
  • PDP connection (4)
  • Power and reset (2)
  • Supplementary Services (5)
  • Vendor defined and support (4)
아래의 다이어그램은 안드로이드에서의 solicited call을 설명하고 있다.
 
 
 
Unsolicited
 
아래의 인용은 unsolicited 명령어들에 대한 인터페이스를 설명하고 있다.
 
void OnUnsolicitedResponse (int unsolResponse, void *data, size_t datalen);

 
그리고 아래와 같이 계열들로 묶여질 수 있는 10개 이상의 unsolicited 명령어들이 존재한다.
 
  • Network status changed (4)
  • New SMS notify (3)
  • New USSD notify (2)
  • Signal strength or time changed (2)
아래의 다이어그램은 안드로이드에서의 unsolicited call을 설명하고 있다.
 
 
 
RIL 구현하기
 
특정 radio RIL을 구현하기 위해서는, 라디오 요청을 처리하기 위해 안드로이드에서 요구되는 함수의 집합을 구현하는
공유 라이브러리를 만들어야 한다. 요구되는 함수들은 RIL header (/include/telephony/ril.h)에 정의된다.
 
안드로이드 radio 인터페이스는 radio-agnostic이며, Vender RIL은 radio를 통해 통신하기 위한 어떤 프로토콜도
사용할 수 있다. 안드로이드는 하나의 참조적 구현형태로써의 Vender RIL을 제공하고 있는데, 그것은 Hayes AT
command 집합을 사용하고 있으며, 여러분들은 telephony 테스트를 위한 쉬운 시작과 상업적 Vender RIL 들을 위한
가이드로써 사용할 수 있다. 참조적으로 구현된 RIL 소스 코드는 /commands/reference-ril/ 에서 볼 수 있다.
 
libril-<companyname>-<RIL version>.so 규약을 사용해서 공유 라이브러리 형태로 여러분의 Vender RIL을 컴파일
해라. 여기에 예로써, libril-acme-124.so가 있다.
  • libril: 모든 vender RIL 구현은 'libril' 로 시작
  • <companyname>: 특정 회사의 약어
  • <RIL version>: RIL 버전 숫자
  • so: 파일 확장자
RIL_Init
 
여러분의 Vender RIL은 모든 radio 요청들을 처리할 함수들에 대한 제어를 제공하는 RIL_Init 함수를 정의해야 한다.
RIL_Init은 RIL을 초기화하기 위해, 부트시점에서 안드로이드 RIL Daemon에 의해 호출된다.
 
RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);

 
RIL_Init은 radio 함수들에 대한 제어를 포함하는 RIL_RadioFuncions 구조체를 반환해야 한다.
 
type structure {
       int RIL_version;
       RIL_RequestFunc onRequest;
       RIL_RadioStateRequest onStateRequest;      
       RIL_Supports supports;
       RIL_Cancel onCancel;
       RIL_GetVersion getVersion;
}
RIL_RadioFunctions;

 
 
RIL 함수들
 
ril.h는 아래의 테이블에 설명된 함수들 같은, RIL_UNSOL_STK_CALL_SETUP, RIL_SIM_READY, RIL_SIM_NOT_READY 과
같은 RIL 상태들과 변수들을 정의한다. 더 상세하게는 헤더파일(/device/incldue/telephony/ril.h)을 살펴보길.
 
RIL Solicited 명령어 요청들.
 
Vender RIL은 solicited 명령어들을 처리하기 위해 아래의 테이블에 설명된 함수들을 제공해야 한다.
RIL solicited 명령어 요청 타입들은 RIL_REQUEST_ 라는 접두사를 가지고 ril.h에 정의된다.
상세하게는 헤더 파일을 체크하길.
 
함수명 설명
void (*RIL_RequestFunc) (int request, void *data, size_t datalen, RIL_Token t); 이것은 solicited 명령어들에 대한 시작 포인트이며, RIL_REQUST_ 접두사를 가지고 ril.h에 정의된 다양한 RIL solicited 요청 타입들을 제어할 수 있어야 한다.
  • request 는 RIL_REQUEST_* 중 하나임.
  • data 는 RIL_REQUST_* 위해 정의된 data에 대한 포인터임.
  • t 는 RIL_onResponse 에 수반되는 호출에서 사용되어야 함.
  • datalen 은 caller 소유이며, callee에 의해 수정되거나 free 되어서는 안됨.
RIL_onRequestComplete()에 대한 호출을 통해 완료되어야 함.
RIL_onRequestComplete()는 임의의 쓰레드로부터 이 함수의 반환 이전 또는 이후에 호출될 수 있다. 이것은 항상 동일한 쓰레드로부터 호출될 것이며, 그러므로 여기에서 반환이라함은 radio가 다른 명령을 수행할 준비하 되어있음을 의미한다.(이전 명령이 완료여부와 상관없이)
RIL_RadioState (*RIL_RadioStateRequest)(); 이 함수는 현재의 radio 상태를 동기적으로 반환해야 한다.
int (*RIL_Supports)(int requestCode); 이 함수는 명시된 RIL_REQUEST 코드가 지원된다면 "1"을 아니라면 "0"을 반환한다.
void (*RIL_Cancel)(RIL_Token t); 이 함수는 멈춰져 있는 요청을 취소시키기 위해 사용된다.
이 함수는 다른 쓰레드, 즉 RIL_RequestFunc 을 호출한 쓰레드가 아닌 쓰레드에 의해 호출된다.
 
취소시, callee는 요청을 포기하기 위해 최선을 다해야하며, 잠시후 RIL_Errno CALCELLED 를 가지고 RIL_onRequestComplete를 호출한다.
 
다른 결과들을 가진 이 요청들에 대한 RIL_onRequestComplete에 대한 수반되는 호출들은 묵인되지만, 무시된다.(그것은 취소 요청을 무시하기 위해 유효한 것이다)
 
RIL_Cancel 호출들은 즉시 반환되어야 하며, 취소를 기다려서는 안된다.
const char * (*RIL_GetVersion) (void); 여러분의 Vender RIL에 대한 버젼 문자열을 반환한다.
 
Vender RIL은 안드로이드 RIL 데몬에 역으로 통신하기 위해 다음과 같은 callback 메쏘드를 사용한다.
 
함수명 설명
void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
  • t 는 이전 호출에서 RIL_Notification 루틴에 전달된 파라메터이다.
  • 만약 e != SUCCESS 라면, response 는 null 이 될것이며, 무시된다.
  • RIL_onRequestComplete 는 가능한 빨리 return 할 것이다.
void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime); RIL_RequestFunc 이 호출된 동일한 쓰레드에서 사용자 정의의 callback 함수를 호출한다. 만약 relativeTime 이 명시되었다면, 그것은 callback이 발생해야하는 상대적인 시각을 명시한다. 만약 relativeTime 이 NULL 이거나 0 으로 채워진 구조체에 대한 포인터라면, callback은 최대한 빨리 발생한다.

 
RIL Unsolicited 명령어들
 
아래의 테이블에 열거된 함수들은 안드로이드 플랫폼에서 unsolicited 명령어들을 발생시키기 위해 Vendor RIL에 의해
사용되는 call-back 함수들이다. 자세하게는 ril.h 를 보길.
 
함수명 설명
void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);
  • unsolResponse 는 RIL_UNSOL_RESPONSE_* 중 하나임.
  • data 는 RIL_UNSOL_RESPONSE_* 를 위해 정의된 data에 대한 포인터임.
  • data 는 caller 소유이며, callee 에 의해 수정되거나 free 되어서는 안됨.

이건 뭐 간단히 말해서 안드로이드 소프트웨어(Telephony service)와 하드웨어(Radio) 사이에 존재하는 놈(추상레이어)으로  인터페이스 역할을 한다.
  • Ex) SMS Sending/Receiving, Incomming/Outgoing call, Data, Network and so on.
  • 두가지 Command로 나눈다.

       1. Solicited : User가 요청한 command (SMS Sending, Outgoing call 등)

          - 101 개 정도 commands : (Ril_commands.h 에 정의)

       2. Unsolicited : User의 의도와 상관없이 network나 h/w에서 받는 command (SMS Retriving, Incomming call 등)

          - 31개 정도 (Ril_unsol_commands.h에 정의)

     

    getIMSI() : ril.java - {RIL_REQUEST_GET_IMSI, dispatchVoid, responseString}

    - dispatchVoid() : ril.cpp

    -- s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI); //Vendor ril

    -- RIL_onRequestComplete : ril.cpp

    ---- responseFunction() : responseString()

    ---- sendResponse(p)

    - processResponse : ril.java

    processSolicited : ril.java

     

    Posted by jazzlife
    ,
     Complete End to End Call Flow of Short Message Service(SMS)

    [ad#co-1]

     We will use above picture as refference.

    For example,  Subscriber A(MS A) want to send Short message to subscriber B(MS B)

    1.  Then subscriber A will type the message on the phone and select subscriber B as the destination address.
    2.  After subsriber A, hit send button, MS terminal will request channel assignment to the BTS and BSC and then forward the MS A Information to MSC A
    3.  MSC A will check MS A(subscriber A) data from VLR, if the telecommunication operator has many SMSC, it will identified which SMSC this MS A belong to.
    4.  After that MS A will transfer the short message to MSC A, at this point on MS A phone will display “sending…” notification
    5.  MSC A routes the message to the interworking MSC(IW MSC), beside use IW MSC usually it can use STP
    6.  IW MSC will route the short message to the SMSC.
    7.  SMSC Send a notification report to IW MSC and then to MSC A, MSC B and come to subscriber. At this point MS A phone will display “Message Sent” but not yet delivered to MS B
    8.  All Above step called MO(Message Originating), we will come on MT(Message Terminating) on the next step
    9.  SMSC Transfer the short message to the Gateway MSC(GW MSC)
    10.  The GW MSC ask information from the HLR for routing the short message
    11.  GW MSC will forward the message to MSC B, and MSC B will check MS B data from VLR
    12.  MSC B Transfer the short message to MS B through BSC and BTS
    13.  MSC B Send delivery report to GW MSC, and GW MSC will forward to HLR and SMSC. At this point MS B receive the message and can read it.
    14.  Delivery report will send by SMSC to MS A after MS B receive the message.

    Quite log story  :) . but this simple thing need so many interworking between quite alot of telecommunication network element.

    'old > sms&mms' 카테고리의 다른 글

    The Radio Interface Layer (RIL)  (0) 2010.07.09
    Android's Radio Interface Layer(RIL)  (0) 2010.07.08
    Android SMS call analysis  (0) 2010.07.06
    기본 안드로이드 서비스 구조  (0) 2010.05.12
    SMS framework 소스 참고  (0) 2010.05.10
    Posted by jazzlife
    ,
     

    Android SMS call analysis




    < android SDK1.5 cupcake emulator >


    solicited Message

    emulator HOME의 Messaging 아이콘 클릭
    ConversationList.java
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ConversationList.java
    onCreate();
        View, Listener 초기화 작업    
    onResume();
        DraftCache.getInstance().addOnDraftChangedListener(this);
        getContentResolver().delete(Threads.OBSOLETE_THREADS_URI, null, null);
        DraftCache.getInstance().refresh();
        startAsyncQuery();
        ContactInfoCache.getInstance().invalidateCache();


    New message 클릭
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ConversationList.java
    @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            if (LOCAL_LOGV) {
                Log.v(TAG, "onListItemClick: position=" + position + ", id=" + id);
            }

            if (position == 0) {
                createNewMessage();
            } else if (v instanceof ConversationHeaderView) {
                ConversationHeaderView headerView = (ConversationHeaderView) v;
                ConversationHeader ch = headerView.getConversationHeader();

                // TODO: The 'from' view of the ConversationHeader was
                // repurposed to be the cached display value, rather than
                // the old raw value, which openThread() wanted.  But it
                // turns out openThread() doesn't need it:
                // ComposeMessageActivity will load it.  That's not ideal,
                // though, as it's an SQLite query.  So fix this later to
                // save some latency on starting ComposeMessageActivity.
                String somethingDelimitedAddresses = null;
                openThread(ch.getThreadId(), somethingDelimitedAddresses);
            }
        }



            
    createNewMesage()
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ConversationList.java
    private void createNewMessage() {
            Intent intent = new Intent(this, ComposeMessageActivity.class);
            startActivity(intent);
        }


    ComposeMessageActivity.java
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ComposeMessageActivity.java
    onCreate() {
        initResourceRefs(); // Initialize members for UI elements.
        initActivityState(savedInstanceState, getIntent()); // Read parameters or previously saved              
                                                                                 state of this activity.
        mRecipientList = RecipientList.from(mExternalAddress, this); // Parse the recipient list.
        initMessageList(); // Set up the message history ListAdapter
        markAsRead(mThreadId); // Mark the current thread as read.
        updateSendButtonState();
        // 이 밖에도 MMS 모드 체크, 전송 실패한 메시지 정보를 pop-up 등등의 초기화 작업을 함.
    }

    onStart() {
        updateWindowTitle();
        initFocus();
        registerReceiver(mHttpProgressReceiver, mHttpProgressFilter); // Register a  
                                                      // BroadcastReceiver to listen on HTTP I/O process.  
        startMsgListQuery();                                                      
        startQueryForContactInfo();
        updateSendFailedNotification();
    }

    onResume() {
        startPresencePollingRequest(); // enqueueMessage(Message msg, long when) 에서
                                                  // MessageQueue를 확인한다. 주기적 반복
    }

        
        
    Send 버튼 클릭
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ComposeMessageActivity.java
    /*
    onCreate() {
    ...  
        initResourceRefs() {
        ...
            mSendButton = (Button) findViewById(R.id.send_button);
            mSendButton.setOnClickListener(this);
        }
        updateSendButtonState() {
        ...  
            mSendButton.setEnabled(enable);
            mSendButton.setFocusable(enable);
        }
    }
    */

    public void onClick(View v) {
        if ((v == mSendButton) && isPreparedForSending()) {  
            // if문의 두번째 메소드는 hasRecipient() && (hasAttachment() || hasText()) 를 확인한다.
            // 즉, 메시지(받는사람, 내용, 첨부)를 작성했는지를 확인
            confirmSendMessageIfNeeded();
        }
    }    

       
    confirmSendMessageIfNeeded()
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ComposeMessageActivity.java
    //받는사람이 유효한지 확인한 후, 메시지 전송

    private void confirmSendMessageIfNeeded() {
        if (mRecipientList.hasInvalidRecipient()) {
            if (mRecipientList.hasValidRecipient()) {
                String title = getResourcesString(R.string.has_invalid_recipient,
                        mRecipientList.getInvalidRecipientString());
                new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle(title)
                    .setMessage(R.string.invalid_recipient_message)
                    .setPositiveButton(R.string.try_to_send,
                            new SendIgnoreInvalidRecipientListener())
                    .setNegativeButton(R.string.no, new CancelSendingListener())
                    .show();
            } else {
                new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle(R.string.cannot_send_message)
                    .setMessage(R.string.cannot_send_message_reason)
                    .setPositiveButton(R.string.yes, new CancelSendingListener())
                    .show();
            }
        } else {
            sendMessage();
        }
    }


    sendMessage()
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ComposeMessageActivity.java
    private void sendMessage() {
            // Need this for both SMS and MMS.
            final String[] dests = mRecipientList.getToNumbers();
            
            // removeSubjectIfEmpty will convert a message that is solely an MMS
            // message because it has an empty subject back into an SMS message.
            // It doesn't notify the user of the conversion.
            removeSubjectIfEmpty();
            if (requiresMms()) {
                // Make local copies of the bits we need for sending a message,
                // because we will be doing it off of the main thread, which will
                // immediately continue on to resetting some of this state.
                final Uri mmsUri = mMessageUri;
                final PduPersister persister = mPersister;
                final SlideshowModel slideshow = mSlideshow;
                final SendReq sendReq = new SendReq();
                fillMessageHeaders(sendReq);
                
                // Make sure the text in slide 0 is no longer holding onto a reference to the text
                // in the message text box.
                slideshow.prepareForSend();

                // Do the dirty work of sending the message off of the main UI thread.
                new Thread(new Runnable() {
                    public void run() {
                        sendMmsWorker(dests, mmsUri, persister, slideshow, sendReq);
                    }
                }).start();
            } else {
                // Same rules apply as above.
                final String msgText = mMsgText.toString();
                new Thread(new Runnable() {
                    public void run() {
                        sendSmsWorker(dests, msgText);
                    }
                }).start();
            }
            
            if (mExitOnSent) {
                // If we are supposed to exit after a message is sent,
                // clear out the text and URIs to inhibit saving of any
                // drafts and call finish().
                mMsgText = "";
                mMessageUri = null;
                finish();
            } else {
                // Otherwise, reset the UI to be ready for the next message.
                resetMessage();
            }
    }


    sendSmsWorker()
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Ui/ComposeMessageActivity.java
    private void sendSmsWorker(String[] dests, String msgText) {
            // Make sure we are still using the correct thread ID for our
            // recipient set.
            long threadId = getOrCreateThreadId(dests);

            MessageSender sender = new SmsMessageSender(this, dests, msgText, threadId);
            try {
                sender.sendMessage(threadId);
                setThreadId(threadId);
                startMsgListQuery();
            } catch (Exception e) {
                Log.e(TAG, "Failed to send SMS message, threadId=" + threadId, e);
            }
        }


    --- APPLICATION FRAMEWORK ↓ -------------------------------------------------------------

    sender.sendMessage(threadId)
    /open_src/Packages/Apps/Mms/Src/Com/Android/Mms/Transaction/SmsMessageSender.java
    /*
    위의 sender 인스턴스 생성시 SmsMessageSender(..) 생성자 실행
    public SmsMessageSender(Context context, String[] dests, String msgText,
                long threadId) {
            mContext = context;
            mMessageText = msgText;
            mNumberOfDests = dests.length;
            mDests = new String[mNumberOfDests];
            System.arraycopy(dests, 0, mDests, 0, mNumberOfDests);
            mTimestamp = System.currentTimeMillis();
            mThreadId = threadId > 0 ? threadId
                                                : Threads.getOrCreateThreadId(context,
                                                       new HashSet<String>(Arrays.asList(dests)));
            mServiceCenter = getOutgoingServiceCenter(mThreadId);
    }  
    */

    public boolean sendMessage(long token) throws MmsException {
            if ((mMessageText == null) || (mNumberOfDests == 0)) {
                // Don't try to send an empty message.
                throw new MmsException("Null message body or dest.");
            }

            SmsManager smsManager = SmsManager.getDefault(); //Get the default instance
                                                                                     // of the SmsManager

            for (int i = 0; i < mNumberOfDests; i++) {
                ArrayList<String> messages = smsManager.divideMessage(mMessageText);                      
                                                                          // Divide a text message into several
                                                                          // messages, none bigger than
                                                                          // the maximum SMS message size.      
                                                                          // SmsManager.java
                int messageCount = messages.size();
                ArrayList<PendingIntent> deliveryIntents =
                        new ArrayList<PendingIntent>(messageCount);
                ArrayList<PendingIntent> sentIntents =
                        new ArrayList<PendingIntent>(messageCount);
                SharedPreferences prefs =                         
                        PreferenceManager.getDefaultSharedPreferences(mContext);
                boolean requestDeliveryReport = prefs.getBoolean(
                        MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,
                        DEFAULT_DELIVERY_REPORT_MODE);
                Uri uri = null;
                try {
                    uri = Sms.Outbox.addMessage(mContext.getContentResolver(), mDests[i],
                                mMessageText, null, mTimestamp, requestDeliveryReport, mThreadId);
                } catch (SQLiteException e) {
                    SqliteWrapper.checkSQLiteException(mContext, e);
                }

                for (int j = 0; j < messageCount; j++) {
                    if (requestDeliveryReport) {
                        // TODO: Fix: It should not be necessary to
                        // specify the class in this intent.  Doing that
                        // unnecessarily limits customizability.
                        deliveryIntents.add(PendingIntent.getBroadcast(
                                mContext, 0,
                                new Intent(
                                        MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
                                        uri,
                                        mContext,
                                        MessageStatusReceiver.class),
                                0));
                    }
                    sentIntents.add(PendingIntent.getBroadcast(
                            mContext, 0,
                            new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
                                    uri,
                                    mContext,
                                    SmsReceiver.class),
                            0));
                }
                smsManager.sendMultipartTextMessage(
                        mDests[i], mServiceCenter, messages, sentIntents,
                        deliveryIntents);
            }
            return false;
    }


    smsManager.sendMultipartTextmessage(...)
    /open_src/Frameworks/Base/Telephony/Gsm/SmsManager.java
    /**
      * Send a multi-part text based SMS.  The callee should have already
      * divided the message into correctly sized parts by calling
      * <code>divideMessage</code>.
      */

    public void sendMultipartTextMessage(
                String destinationAddress, String scAddress, ArrayList<String> parts,
                ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
            if (TextUtils.isEmpty(destinationAddress)) {
                throw new IllegalArgumentException("Invalid destinationAddress");
            }
            if (parts == null || parts.size() < 1) {
                throw new IllegalArgumentException("Invalid message body");
            }
            
            // divided된 메시지 parts에 따라 전송 방법이 2 가지로 나뉜다.
            if (parts.size() > 1) {
                try {
                    ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
                    if (simISms != null) {
                        simISms.sendMultipartText(destinationAddress, scAddress, parts,
                                sentIntents, deliveryIntents);
                    }
                } catch (RemoteException ex) {
                    // ignore it
                }
            } else {
                PendingIntent sentIntent = null;
                PendingIntent deliveryIntent = null;
                if (sentIntents != null && sentIntents.size() > 0) {
                    sentIntent = sentIntents.get(0);
                }
                if (deliveryIntents != null && deliveryIntents.size() > 0) {
                    deliveryIntent = deliveryIntents.get(0);
                }
                sendTextMessage(destinationAddress, scAddress, parts.get(0),
                        sentIntent, deliveryIntent);
            }
        }


    simISms.sendMultipartText(...)  
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/
    SimSmsInterfaceManager.java
    /**
     * Send a multi-part text based SMS
     */
       
    private GSMPhone mPhone;

    public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
                List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
            Context context = mPhone.getContext();

            context.enforceCallingPermission(
                    "android.permission.SEND_SMS",
                    "Sending SMS message");
            if (DBG) log("sendMultipartText");
            mPhone.mSMS.sendMultipartText(destinationAddress, scAddress,     
                    (ArrayList<String>) parts,
                    (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>)         
                    deliveryIntents);
    }


    mphone.mSMS.sendMultipartText(...)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/
    SMSDispatcher.java
    /**
     * Send a multi-part text based SMS
     */

    void sendMultipartText(String destinationAddress, String scAddress, ArrayList<String> parts,
                ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {

            PendingIntent sentIntent = null;
            
            int ss = mPhone.getServiceState().getState(); //Get current servcie state of phone
            
            if (ss == ServiceState.STATE_IN_SERVICE) {
                // Only check SMS sending limit while in service
                if (sentIntents != null && sentIntents.size() > 0) {
                    sentIntent = sentIntents.get(0);
                }
                String appName = getAppNameByIntent(sentIntent);
                if ( !mCounter.check(appName, parts.size())) {
                    HashMap<String, Object> map = new HashMap<String, Object>();
                    map.put("destination", destinationAddress);
                    map.put("scaddress", scAddress);
                    map.put("parts", parts);
                    map.put("sentIntents", sentIntents);
                    map.put("deliveryIntents", deliveryIntents);
                    
                    SmsTracker multipartParameter = new SmsTracker(map, null, null);

                    sendMessage(obtainMessage(EVENT_POST_ALERT, multipartParameter));
                    return;
                }
            }
            
            sendMultipartTextWithPermit(destinationAddress,
                    scAddress, parts, sentIntents, deliveryIntents);
    }


    sendMultipartTextWithPermit(...)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/
    SMSDispatcher.java
    /**
     * Send a multi-part text based SMS which already passed SMS control check.
     *
     * It is the working function for sendMultipartText().
     */

    private void sendMultipartTextWithPermit(String destinationAddress,
                String scAddress, ArrayList<String> parts,
                ArrayList<PendingIntent> sentIntents,
                ArrayList<PendingIntent> deliveryIntents) {
            
            PendingIntent sentIntent = null;
            PendingIntent deliveryIntent = null;
            
            // check if in service
            int ss = mPhone.getServiceState().getState();
            if (ss != ServiceState.STATE_IN_SERVICE) {
                for (int i = 0, count = parts.size(); i < count; i++) {
                    if (sentIntents != null && sentIntents.size() > i) {
                        sentIntent = sentIntents.get(i);
                    }
                    SmsTracker tracker = new SmsTracker(null, sentIntent, null);
                    handleNotInService(ss, tracker);
                }
                return;
            }

            int ref = ++sConcatenatedRef & 0xff;

            for (int i = 0, count = parts.size(); i < count; i++) {
                // build SmsHeader
                byte[] data = new byte[3];
                data[0] = (byte) ref;   // reference #, unique per message
                data[1] = (byte) count; // total part count
                data[2] = (byte) (i + 1);  // 1-based sequence
                SmsHeader header = new SmsHeader();
                header.add(new SmsHeader.Element(
                    SmsHeader.CONCATENATED_8_BIT_REFERENCE, data));
     
                if (sentIntents != null && sentIntents.size() > i) {
                    sentIntent = sentIntents.get(i);
                }
                if (deliveryIntents != null && deliveryIntents.size() > i) {
                    deliveryIntent = deliveryIntents.get(i);
                }
                

                /**
                 * Get an SMS-SUBMIT PDU for a destination address and a message
                 */
                                                                          
                SmsMessage.SubmitPdu pdus = // ↓ Encoding
                            SmsMessage.getSubmitPdu(scAddress, destinationAddress,
                                parts.get(i), deliveryIntent != null, header.toByteArray());

                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put("smsc", pdus.encodedScAddress);
                map.put("pdu", pdus.encodedMessage);

                SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent);
                
                sendSms(tracker);
            }        
    }

        
    sendSms(tracker)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/
    SMSDispatcher.java
    /**
     * Send the message along to the radio.
     */

    private final CommandsInterface mCm;

    private void sendSms(SmsTracker tracker) {
        HashMap map = tracker.mData;

        byte smsc[] = (byte[]) map.get("smsc");
        byte pdu[] = (byte[]) map.get("pdu");

        Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
        
        mCm.sendSMS(SimUtils.bytesToHexString(smsc), SimUtils.bytesToHexString(pdu),
                 reply);
        // sendSMS,, interface CommandsInterface
    }


    --- RIL ↓ -----------------------------------------------------------------------------------

    mCm.sendSMS(...)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
    public void
        sendSMS (String smscPDU, String pdu, Message result)
        {
            RILRequest rr
                    = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);

            rr.mp.writeInt(2);
            rr.mp.writeString(smscPDU);
            rr.mp.writeString(pdu);

            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
            // RILJ 로그는 여기서 프린트 된다. "[...] > SEND_SMS"
            send(rr);
        }


    send(rr)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
    private void
        send(RILRequest rr)
        {
            Message msg;

            msg = mSender.obtainMessage(EVENT_SEND, rr); // 메시지큐에서 메시지 가져오기

            acquireWakeLock(); // Holds a PARTIAL_WAKE_LOCK whenever
                                           (a) There is outstanding RIL request sent to RIL deamon and no
                                                replied
                                           (b) There is a request waiting to be sent out. There is a
                                                WAKE_LOCK_TIMEOUT to release the lock, though
                                                it shouldn't happen often.

            msg.sendToTarget(); // Sends this Message to the Handler specified by getTarget().
                                         // Handler adroid.os.Message.getTarget()
                                         // Retrieve the a handler implementation that will receive this
                                            message. The object must implement
                             Handler.handleMessage().
                                            Each Handler has its own name-space for message codes,
                                            so you do not need to worry about yours conflicting with other
                                            handlers.
        }






    Unsolicited Message


    Vendor RIL 에서 New Message가 왔음을 알린다.

    processUnsolicited (Parcel P)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
    private void
        processUnsolicited (Parcel p)
        {
            int response;
            Object ret;
            
            /**
             * Read an integer value from the parcel at the current dataPosition().
             */
            response = p.readInt();

            try {switch(response) {

            /*
                  cat libs/telephony/ril_unsol_commands.h \
                  | egrep "^ *{RIL_" \
                  | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/'
             */

        ...      
                 /**
                  * Read a string value from the parcel at the current dataPosition().
                  */                                                                ↑ p.readString()  
                case RIL_UNSOL_RESPONSE_NEW_SMS: ret =  responseString(p); break;
                case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret =  responseString(p);
                                                                                                       break;
                case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret =  responseInts(p); break;
        ...
                default:
                    throw new RuntimeException("Unrecognized unsol response: " + response);
                //break; (implied)
            }} catch (Throwable tr) {
                Log.e(LOG_TAG, "Exception processing unsol response: " + response +
                    "Exception:" + tr.toString());
                return;
            }

            switch(response) {
                case RIL_UNSOL_RESPONSE_NEW_SMS: {
                    if (RILJ_LOGD) unsljLog(response);
                                       //  ↑   D/RILJ    (  610): [UNSL]< UNSOL_RESPONSE_NEW_SMS
                                       // 로그 프린트

                    // FIXME this should move up a layer
                    String a[] = new String[2];

                    a[1] = (String)ret;

                    SmsMessage sms;

                    sms = SmsMessage.newFromCMT(a);                
                    if (mSMSRegistrant != null) {  
                        mSMSRegistrant
                            .notifyRegistrant(new AsyncResult(null, sms, null));
                    }
                break;
                }
            }
        }


    SmsMessage.newFromCMT(a)
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
    /**
         * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
         * +CMT unsolicited response (PDU mode, of course)
         *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
         *
         * Only public for debugging
         *
         * {@hide}
         */
    /* package */ 
    public static SmsMessage newFromCMT(String[] lines) {
        try {
            SmsMessage msg = new SmsMessage();
            msg.parsePdu(SimUtils.hexStringToBytes(lines[1]));
            return msg;
        } catch (RuntimeException ex) {
            Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
            return null;
        }
    }


    msg.parsePdu(...)
    /open_src/Frameworks/Base/Telephony/Gsm/SmsMessage.java
    /**
         * TS 27.005 3.1, <pdu> definition "In the case of SMS: 3GPP TS 24.011 [6]
         * SC address followed by 3GPP TS 23.040 [3] TPDU in hexadecimal format:
         * ME/TA converts each octet of TP data unit into two IRA character long
         * hexad number (e.g. octet with integer value 42 is presented to TE as two
         * characters 2A (IRA 50 and 65))" ...in the case of cell broadcast,
         * something else...
         */

    int mti; // TP-Message-Type-Indicator
              // 9.2.3
    String scAddress; /* The address of the SMSC. May be null */
       
    private void parsePdu(byte[] pdu) {
            mPdu = pdu;
            // Log.d(LOG_TAG, "raw sms mesage:");
            // Log.d(LOG_TAG, s);

            PduParser p = new PduParser(pdu);

            scAddress = p.getSCAddress();  
                                      
            /* int android.telephony.gsm.SmsMessage.PduParser.getByte() 에 의해 SCAddress길이를
             *  알수 있고, 이 integer값으로 if문을 통해
             *  PhoneNumberUtils.calledPartyBCDToString(pdu, cur, len) 메소드가 실행되고,
             *  String 타입의 리턴값을 받는다.
             */
            
            if (scAddress != null) {
                if (Config.LOGD) Log.d(LOG_TAG, "SMS SC address: " + scAddress);
            }

            // TODO(mkf) support reply path, user data header indicator

            // TP-Message-Type-Indicator
            // 9.2.3
            int firstByte = p.getByte(); /* return pdu[cur++] & 0xff; */
                                                                      
            /* 위의 PduParser 인스턴스 p 생성시 생성자에 의해 PduParser 클래스의 integer 형 변수
             * cur, mUserDataSeptetPadding 는 0 으로 셋팅된다.
             */

            mti = firstByte & 0x3;
            switch (mti) {
            // TP-Message-Type-Indicator
            // 9.2.3
            case 0:
                parseSmsDeliver(p, firstByte);
                break;
            case 2:
                parseSmsStatusReport(p, firstByte);
                break;
            default:
                // TODO(mkf) the rest of these
                throw new RuntimeException("Unsupported message type");
            }
    }


    parseSmsDeliver(p, firstByte)
    /open_src/Frameworks/Base/Telephony/Gsm/SmsMessage.java

    boolean replyPathPresent = false; // TP-Reply-Path
                                                  // e.g. 23.040 9.2.2.1
    SmsAddress originatingAddress; /* The address of the sender */
    int protocolIdentifier; /* TP-Protocol-Identifier (TP-PID) */
    int dataCodingScheme; // TP-Data-Coding-Scheme
                                    // see TS 23.038
        
    private void parseSmsDeliver(PduParser p, int firstByte) {
            replyPathPresent = (firstByte & 0x80) == 0x80;

            originatingAddress = p.getAddress();

            if (originatingAddress != null) {
                if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
                        + originatingAddress.address);
            }

            // TP-Protocol-Identifier (TP-PID)
            // TS 23.040 9.2.3.9
            protocolIdentifier = p.getByte();

            // TP-Data-Coding-Scheme
            // see TS 23.038
            dataCodingScheme = p.getByte();

            if (Config.LOGV) {
                Log.v(LOG_TAG, "SMS TP-PID:" + protocolIdentifier
                        + " data coding scheme: " + dataCodingScheme);
            }

            scTimeMillis = p.getSCTimestampMillis();
                                              
            // Parses an SC timestamp and returns a currentTimeMillis()-style
            // timestamp

            if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
                                                                    
                                                // D/GSM     (  610): SMS SC timestamp: 1265783527000
                                                // 로그 프린트
            boolean hasUserDataHeader = (firstByte & 0x40) == 0x40;

            parseUserData(p, hasUserDataHeader); //Parses the User Data of an SMS.
        }


    parseUserData(p, hasUserDataHeader)
    /open_src/Frameworks/Base/Telephony/Gsm/SmsMessage.java
    private void parseUserData(PduParser p, boolean hasUserDataHeader) {
            boolean hasMessageClass = false;
            boolean userDataCompressed = false;

            int encodingType = ENCODING_UNKNOWN;

            // Look up the data encoding scheme
            if ((dataCodingScheme & 0x80) == 0) {
                // Bits 7..4 == 0xxx
                automaticDeletion = (0 != (dataCodingScheme & 0x40));
                userDataCompressed = (0 != (dataCodingScheme & 0x20));
                hasMessageClass = (0 != (dataCodingScheme & 0x10));

                if (userDataCompressed) {
                    Log.w(LOG_TAG, "4 - Unsupported SMS data coding scheme "
                            + "(compression) " + (dataCodingScheme & 0xff));
                } else {
                    switch ((dataCodingScheme >> 2) & 0x3) {
                    case 0: // GSM 7 bit default alphabet
                        encodingType = ENCODING_7BIT;
                        break;

                    case 2: // UCS 2 (16bit)
                        encodingType = ENCODING_16BIT;
                        break;

                    case 1: // 8 bit data
                    case 3: // reserved
                        Log.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
                                + (dataCodingScheme & 0xff));
                        encodingType = ENCODING_8BIT;
                        break;
                    }
                }
            } else if ((dataCodingScheme & 0xf0) == 0xf0) {
                automaticDeletion = false;
                hasMessageClass = true;
                userDataCompressed = false;

                if (0 == (dataCodingScheme & 0x04)) {
                    // GSM 7 bit default alphabet
                    encodingType = ENCODING_7BIT;
                } else {
                    // 8 bit data
                    encodingType = ENCODING_8BIT;
                }
            } else if ((dataCodingScheme & 0xF0) == 0xC0
                    || (dataCodingScheme & 0xF0) == 0xD0
                    || (dataCodingScheme & 0xF0) == 0xE0) {
                // 3GPP TS 23.038 V7.0.0 (2006-03) section 4

                // 0xC0 == 7 bit, don't store
                // 0xD0 == 7 bit, store
                // 0xE0 == UCS-2, store

                if ((dataCodingScheme & 0xF0) == 0xE0) {
                    encodingType = ENCODING_16BIT;
                } else {
                    encodingType = ENCODING_7BIT;
                }

                userDataCompressed = false;
                boolean active = ((dataCodingScheme & 0x08) == 0x08);

                // bit 0x04 reserved

                if ((dataCodingScheme & 0x03) == 0x00) {
                    isMwi = true;
                    mwiSense = active;
                    mwiDontStore = ((dataCodingScheme & 0xF0) == 0xC0);
                } else {
                    isMwi = false;

                    Log.w(LOG_TAG, "MWI for fax, email, or other "
                            + (dataCodingScheme & 0xff));
                }
            } else {
                Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
                        + (dataCodingScheme & 0xff));
            }

            // set both the user data and the user data header.
            int count = p.constructUserData(hasUserDataHeader,
                    encodingType == ENCODING_7BIT);
            this.userData = p.getUserData();
            this.userDataHeader = p.getUserDataHeader();

            switch (encodingType) {
            case ENCODING_UNKNOWN:
            case ENCODING_8BIT:
                messageBody = null;
                break;

            case ENCODING_7BIT:
                messageBody = p.getUserDataGSM7Bit(count);
                break;                              
               // Convert a GSM alphabet 7 bit packed string (SMS string) into a java.lang.String.
                   See TS 23.038 6.1.2.1 for SMS Character Packing
            case ENCODING_16BIT:
                messageBody = p.getUserDataUCS2(count);
                break;
            }

            if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");

            if (messageBody != null) {
                parseMessageBody();
            }

            if (!hasMessageClass) {
                messageClass = MessageClass.UNKNOWN;
            } else {
                switch (dataCodingScheme & 0x3) {
                case 0:
                    messageClass = MessageClass.CLASS_0;
                    break;
                case 1:
                    messageClass = MessageClass.CLASS_1;
                    break;
                case 2:
                    messageClass = MessageClass.CLASS_2;
                    break;
                case 3:
                    messageClass = MessageClass.CLASS_3;
                    break;
                }
            }
    }


    parseMessageBody()
    /open_src/Frameworks/Base/Telephony/Gsm/SmsMessage.java
    private void parseMessageBody() {  // return address.length() <= 4;
            if (originatingAddress.couldBeEmailGateway()) {
                extractEmailAddressFromMessageBody();
            }
    }


    extractEmailAddressFromMessageBody();
    /open_src/Frameworks/Base/Telephony/Gsm/SmsMessage.java
    /**
         * Try to parse this message as an email gateway message -> Neither
         * of the standard ways are currently supported: There are two ways
         * specified in TS 23.040 Section 3.8 (not supported via this mechanism) -
         * SMS message "may have its TP-PID set for internet electronic mail - MT
         * SMS format: [<from-address><space>]<message> - "Depending on the
         * nature of the gateway, the destination/origination address is either
         * derived from the content of the SMS TP-OA or TP-DA field, or the
         * TP-OA/TP-DA field contains a generic gateway address and the to/from
         * address is added at the beginning as shown above." - multiple addreses
         * separated by commas, no spaces - subject field delimited by '()' or '##'
         * and '#' Section 9.2.3.24.11
         */
    private void extractEmailAddressFromMessageBody() {

            /*
             * a little guesswork here. I haven't found doc for this.
             * the format could be either
             *
             * 1. [x@y][ ]/[subject][ ]/[body]
             * -or-
             * 2. [x@y][ ]/[body]
             */
            int slash = 0, slash2 = 0, atSymbol = 0;

            try {
                slash = messageBody.indexOf(" /");
                if (slash == -1) {
                    return;
                }

                atSymbol = messageBody.indexOf('@');
                if (atSymbol == -1 || atSymbol > slash) {
                    return;
                }

                emailFrom = messageBody.substring(0, slash);

                slash2 = messageBody.indexOf(" /", slash + 2);

                if (slash2 == -1) {
                    pseudoSubject = null;
                    emailBody = messageBody.substring(slash + 2);
                } else {
                    pseudoSubject = messageBody.substring(slash + 2, slash2);
                    emailBody = messageBody.substring(slash2 + 2);
                }

                isEmail = true;
            } catch (Exception ex) {
                Log.w(LOG_TAG,
                        "extractEmailAddressFromMessageBody: exception slash="
                        + slash + ", atSymbol=" + atSymbol + ", slash2="
                        + slash2, ex);
            }
    }


    여기까지 parse 작업이 완료되면,
    SmsMessage.newFromCMT(a) {} 부분의 return msg 부분이 실행되어
    processUnsolicited (Parcel P) {} 부분의 밑부분의 if문이 실행된다.
    /open_src/frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java
    private void processUnsolicited (Parcel p)
    {
    ...
       
        if (mSMSRegistrant != null) {  
            mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
            
        /* mSMSRegistrant 는 Registrant의 인스턴스, 정의되어있는 곳은 RIL이 상속하고 있는
         * BaseCommands 이다. 인스턴스화된 곳을 찾아 올라가면
         * BaseCommands의 메소드인 setOnNewSMS()에서 생성됨을 알수 있고, setOnNewSMS()를
         * 호출한 곳을 역으로 올라가면,
         * setOnNewSMS()
    SMSDispatcher GSMPhone       *   ⇠ PhoneFactory.makeDefaultPhones() ⇠ PhoneApp.onCreate()  
          
    *    PhoneApp 는 system의 server thread가 생성하였다.
         */
            
    ...
    }


    mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
    /open_src/frameworks/base/Core/Java/Os/Registrant.java
    /**
     * This makes a copy of @param ar
     */

    public void notifyRegistrant(AsyncResult ar)
    {
        internalNotifyRegistrant (ar.result, ar.exception);
    }

        


    internalNotifyRegistrant(ar.result, ar.exception);
    /open_src/frameworks/base/Core/Java/Os/Registrant.java
    /*package*/

    void internalNotifyRegistrant (Object result, Throwable exception)
    {
            Handler h = getHandler();

            if (h == null) {
                clear();
            } else {                         //   Return a new Message instance from the global pool.
                Message msg = Message.obtain();

                msg.what = what;
                
                msg.obj = new AsyncResult(userObj, result, exception);
                
                h.sendMessage(msg); 
           }    
    }


    h.sendMesage(msg)
    /open_src/frameworks/base/Core/Java/Android/Os/Handler.java
    /**
         * Pushes a message onto the end of the message queue after all pending messages
         * before the current time. It will be received in {@link #handleMessage},
         * in the thread attached to this handler.
         *  /

    public final boolean sendMessage(Message msg)
    {
            return sendMessageDelayed(msg, 0);
    }


    sendMessageDelayed(msg, 0)
    /open_src/frameworks/base/Core/Java/Android/Os/Handler.java
    /**
         * Enqueue a message into the message queue after all pending messages
         * before (current time + delayMillis). You will receive it in
         * {@link #handleMessage}, in the thread attached to this handler.
         *  /

    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
            if (delayMillis < 0) {
                delayMillis = 0;
            }
            return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }


    sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    /open_src/frameworks/base/Core/Java/Android/Os/Handler.java
       /**
         * Enqueue a message into the message queue after all pending messages
         * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
         * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
         * You will receive it in {@link #handleMessage}, in the thread attached
         * to this handler.
         */ 

    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
            boolean sent = false;
            MessageQueue queue = mQueue;
            if (queue != null) {
                msg.target = this;
                sent = queue.enqueueMessage(msg, uptimeMillis);
                /* 메시지 전송 delay를 설정해주고, 메시지 큐에 넣는다.
                 * 메시지큐에 메시지가 들어오면 시스템에서 handleMassage()를 실행한다.
                 * handleMessage()는 Handler를 상속한 SMSDiapatcher에서 오버라이딩된
                 * handleMessage()가 실행된다.
                 * delay설정은 시스템의 스케줄링에 도움을 주기 위해서 이다.
            }
            else {
                RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
            }
            return sent;
    }


    handelMessage(msg)
    /open_src/frameworks/Base/Telephony/Java/Com/Android/Internal/Telephony/Gsm/
    SMSDispatcher.java
    /**
         * Handles events coming from the phone stack. Overridden from handler.
         *
         * @param msg the message to handle
         */

        @Override
        public void handleMessage(Message msg) {
            AsyncResult ar;

            switch (msg.what) {
            case EVENT_NEW_SMS:
                // A new SMS has been received by the device
                if (Config.LOGD) {
                    Log.d(TAG, "New SMS Message Received");

                                   //    D/GSM     (  610): New SMS Message Received

                }                 // 로그 프린트

                SmsMessage sms;

                ar = (AsyncResult) msg.obj;

                // FIXME unit test leaves cm == null. this should change
                if (mCm != null) {
                    // FIXME only acknowledge on store
                    mCm.acknowledgeLastIncomingSMS(true, null);
                }

                if (ar.exception != null) {
                    Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception);
                    return;
                }

                sms = (SmsMessage) ar.result;
                dispatchMessage(sms);

                break;

            case EVENT_SEND_SMS_COMPLETE:
                // An outbound SMS has been sucessfully transferred, or failed.
                handleSendComplete((AsyncResult) msg.obj);
                break;

            case EVENT_SEND_RETRY:
                sendSms((SmsTracker) msg.obj);
                break;

            case EVENT_NEW_SMS_STATUS_REPORT:
                handleStatusReport((AsyncResult)msg.obj);
                break;

            case EVENT_SIM_FULL:
                handleSimFull();
                break;

            case EVENT_POST_ALERT:
                handleReachSentLimit((SmsTracker)(msg.obj));
                break;

            case EVENT_ALERT_TIMEOUT:
                ((AlertDialog)(msg.obj)).dismiss();
                msg.obj = null;
                mSTracker = null;
                break;

            case EVENT_SEND_CONFIRMED_SMS:
                if (mSTracker!=null) {
                    if (isMultipartTracker(mSTracker)) {
                        sendMultipartSms(mSTracker);
                    } else {
                        sendSms(mSTracker);
                    }
                    mSTracker = null;
                }
                break;
            }
        }


    dispatchMessage(msg)
    /open_src/frameworks/Base/Telephony/Java/Com/Android/Internal/Telephony/Gsm/
    SMSDispatcher.java
    /**
         * Dispatches an incoming SMS messages.
         *
         * @param sms the incoming message from the phone
         */
       
     /* package */

    void dispatchMessage(SmsMessage sms) {
            // If sms is null, means there was a parsing error.
            // TODO: Should NAK this.
            if (sms == null) {
                return;
            }

            boolean handled = false;

            // Special case the message waiting indicator messages
            if (sms.isMWISetMessage()) {
                mPhone.updateMessageWaitingIndicator(true);

                if (sms.isMwiDontStore()) {
                    handled = true;
                }

                if (Config.LOGD) {
                    Log.d(TAG,
                            "Received voice mail indicator set SMS shouldStore="
                             + !handled);
                }
            } else if (sms.isMWIClearMessage()) {
                mPhone.updateMessageWaitingIndicator(false);

                if (sms.isMwiDontStore()) {
                    handled = true;
                }

                if (Config.LOGD) {
                    Log.d(TAG,
                            "Received voice mail indicator clear SMS shouldStore="
                            + !handled);
                }
            }

            if (handled) {
                return;
            }

            // Parse the headers to see if this is partial, or port addressed
            int referenceNumber = -1;
            int count = 0;
            int sequence = 0;
            int destPort = -1;

            SmsHeader header = sms.getUserDataHeader();
            if (header != null) {
                for (SmsHeader.Element element : header.getElements()) {
                    try {
                        switch (element.getID()) {
                            case SmsHeader.CONCATENATED_8_BIT_REFERENCE: {
                                byte[] data = element.getData();
                                
                                referenceNumber = data[0] & 0xff;
                                count = data[1] & 0xff;
                                sequence = data[2] & 0xff;
                                
                                // Per TS 23.040, 9.2.3.24.1: If the count is zero, sequence
                                // is zero, or sequence > count, ignore the entire element
                                if (count == 0 || sequence == 0 || sequence > count) {
                                    referenceNumber = -1;
                                }
                                break;
                            }
                            
                            case SmsHeader.CONCATENATED_16_BIT_REFERENCE: {
                                byte[] data = element.getData();
                                
                                referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff);
                                count = data[2] & 0xff;
                                sequence = data[3] & 0xff;
                                
                                // Per TS 23.040, 9.2.3.24.8: If the count is zero, sequence
                                // is zero, or sequence > count, ignore the entire element
                                if (count == 0 || sequence == 0 || sequence > count) {
                                    referenceNumber = -1;
                                }
                                break;
                            }
                            
                            case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: {
                                byte[] data = element.getData();
                                
                                destPort = (data[0] & 0xff) << 8;
                                destPort |= (data[1] & 0xff);
                                
                                break;
                            }
                        }
                    } catch (ArrayIndexOutOfBoundsException e) {
                        Log.e(TAG, "Bad element in header", e);
                        return;  // TODO: NACK the message or something, don't just discard.
                    }
                }
            }

            if (referenceNumber == -1) {
                // notify everyone of the message if it isn't partial
                byte[][] pdus = new byte[1][];
                pdus[0] = sms.getPdu();

                if (destPort != -1) {
                    if (destPort == SmsHeader.PORT_WAP_PUSH) {
                        mWapPush.dispatchWapPdu(sms.getUserData());
                    }
                    // The message was sent to a port, so concoct a URI for it
                    dispatchPortAddressedPdus(pdus, destPort);
                } else {
                    // It's a normal message, dispatch it
                    dispatchPdus(pdus);
                }
            } else {
                // Process the message part
                processMessagePart(sms, referenceNumber, sequence, count, destPort);
            }
        }


    dispatchPdus(pdus)
    /open_src/frameworks/Base/Telephony/Java/Com/Android/Internal/Telephony/Gsm/
    SMSDispatcher.java
    /**
         * Dispatches standard PDUs to interested applications
         *
         * @param pdus The raw PDUs making up the message
         */

    private void dispatchPdus(byte[][] pdus) {
            Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
            intent.putExtra("pdus", pdus);
            sendBroadcast(intent, "android.permission.RECEIVE_SMS");
    }


    sendBroadcast(intent, "android.permission.RECEIVE_SMS");
    /open_src/frameworks/Base/Telephony/Java/Com/Android/Internal/Telephony/Gsm/
    SMSDispatcher.java
    private void sendBroadcast(Intent intent, String permission) {
            // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
            // receivers time to take their own wake locks.
            
            mWakeLock.acquire(WAKE_LOCK_TIMEOUT); 
            /* 메소드를 타고 들어가면, delay 주고, 핸들러의 메시지큐에 메시지를 넣는다.
             *  acquire mHandler.postDelayed() ⇠ sendMessageDelayed()                
             *  ⇠ sendMessageAtTime ⇠ enqueueMessage()
             */
            // 메시지큐에 메시지가 왔음으로 handleMessage()가 실행된다.
            mContext.sendBroadcast(intent, permission);
              // BroadcastReceiver 실행된다.
    }


    handleMessage(Message msg)
    /open_src/Packages/Apps/Src/Com/Android/Mms/Transactions/SmsReceiverService.java
    /**
             * Handle incoming transaction requests.
             * The incoming requests are initiated by the MMSC Server or by the
             * MMS Client itself.
             */
            
    @Override
    public void handleMessage(Message msg) {
                if (Log.isLoggable(MmsApp.LOG_TAG, Log.VERBOSE)) {
                    Log.v(TAG, "Handling incoming message: " + msg);
                }
                int serviceId = msg.arg1;
                Intent intent = (Intent)msg.obj;

                String action = intent.getAction();

                if (MESSAGE_SENT_ACTION.equals(intent.getAction())) {
                    handleSmsSent(intent);
                } else if (SMS_RECEIVED_ACTION.equals(action)) {
                    handleSmsReceived(intent);
                } else if (ACTION_BOOT_COMPLETED.equals(action)) {
                    handleBootCompleted();
                } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
                    handleServiceStateChanged(intent);
                }

                // NOTE: We MUST not call stopSelf() directly, since we need to
                // make sure the wake lock acquired by AlertReceiver is released.
                SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId);
    }


    handleSmsReceived(intent)
    /open_src/Packages/Apps/Src/Com/Android/Mms/Transactions/SmsReceiverService.java
    private void handleSmsReceived(Intent intent) {
            SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
            Uri messageUri = insertMessage(this, msgs);

            if (messageUri != null) {
                MessagingNotification.updateNewMessageIndicator(this, true);
            }
    }


    MessagingNotification.updateNewMessageIndicator(this, true)
    Open_src/Package/Apps/Mms/Src/Com/Android/Mms/Transaction/MessagingNotification.java
    /**
         * Checks to see if there are any unread messages or delivery
         * reports.  Shows the most recent notification if there is one.
         *
         * @param context the context to use
         * @param isNew if notify a new message comes, it should be true, otherwise, false.
         */
    public static void updateNewMessageIndicator(Context context, boolean isNew) {
            SortedSet<MmsSmsNotificationInfo> accumulator =
                    new TreeSet<MmsSmsNotificationInfo>(INFO_COMPARATOR);
            Set<Long> threads = new HashSet<Long>(4);
            
            int count = 0;
            count += accumulateNotificationInfo(
                    accumulator, getMmsNewMessageNotificationInfo(context, threads));
            count += accumulateNotificationInfo(
                    accumulator, getSmsNewMessageNotificationInfo(context, threads));

            cancelNotification(context, NOTIFICATION_ID);
            if (!accumulator.isEmpty()) {
                accumulator.first().deliver(context, isNew, count, threads.size());
            }
        }


    accumulator.first().deliver(context, isNew, count, threads.size())
    Open_src/Package/Apps/Mms/Src/Com/Android/Mms/Transaction/MessagingNotification.java
    public void deliver(Context context, boolean isNew, int count, int uniqueThreads) {
                updateNotification(
                        context, mClickIntent, mDescription, mIconResourceId,
                        isNew, mTicker, mTimeMillis, mTitle, count, uniqueThreads);
            }


    updateNotification(...)
    Open_src/Package/Apps/Mms/Src/Com/Android/Mms/Transaction/MessagingNotification.java
    private static void updateNotification(
                Context context,
                Intent clickIntent,
                String description,
                int iconRes,
                boolean isNew,
                CharSequence ticker,
                long timeMillis,
                String title,
                int messageCount,
                int uniqueThreadCount) {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

            if (!sp.getBoolean(
                        MessagingPreferenceActivity.NOTIFICATION_ENABLED, true)) {
                return;
            }

            Notification notification = new Notification(iconRes, ticker, timeMillis);

            // If we have more than one unique thread, change the title (which would
            // normally be the contact who sent the message) to a generic one that
            // makes sense for multiple senders, and change the Intent to take the
            // user to the conversation list instead of the specific thread.
            if (uniqueThreadCount > 1) {
                title = context.getString(R.string.notification_multiple_title);
                clickIntent = getAppIntent();
                clickIntent.setAction(Intent.ACTION_MAIN);
                clickIntent.setType("vnd.android-dir/mms-sms");
            }
            
            // If there is more than one message, change the description (which
            // would normally be a snippet of the individual message text) to
            // a string indicating how many unread messages there are.
            if (messageCount > 1) {
                description = context.getString(R.string.notification_multiple,
                        Integer.toString(messageCount));
            }

            // Make a startActivity() PendingIntent for the notification.
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, clickIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            // Update the notification.
            notification.setLatestEventInfo(context, title, description, pendingIntent);

            if (isNew) {
                boolean vibrate =     
                        sp.getBoolean(MessagingPreferenceActivity.NOTIFICATION_VIBRATE, true);
                if (vibrate) {
                    notification.defaults |= Notification.DEFAULT_VIBRATE;
                }

                String ringtoneStr = sp
                        .getString(MessagingPreferenceActivity.NOTIFICATION_RINGTONE, null);
                notification.sound = TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr);
            }

            notification.flags |= Notification.FLAG_SHOW_LIGHTS;
            notification.ledARGB = 0xff00ff00;
            notification.ledOnMS = 500;
            notification.ledOffMS = 2000;

            NotificationManager nm = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);

            nm.notify(NOTIFICATION_ID, notification);
    }

    Posted by jazzlife
    ,
    1. Core System services
    - Activity manager (manages application lifecycle)
    - Package manager (loads apk files)
    - Window manager (handles applications window manager interaction with surface flinger)
    - Resource manager (handles media resources)
    - Content providers (provides data to application)
    - View system (provides widgets, views, layouts to applications)

    2. Hardware services
    - Provides low-level access to hardware device
    - Location manager
    - Telephony manager
    - Bluetooth service
    - WiFi service
    - USB service
    - Sensor service

    http://www.linuxjournal.com/magazine/java-api-androids-telephony-stack?page=0,4&quicktabs_1=2

    http://sites.google.com/site/io/inside-the-android-application-framework

    http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html

    'old > sms&mms' 카테고리의 다른 글

    Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
    Android SMS call analysis  (0) 2010.07.06
    SMS framework 소스 참고  (0) 2010.05.10
    framework_source 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    Posted by jazzlife
    ,

    'old > sms&mms' 카테고리의 다른 글

    Android SMS call analysis  (0) 2010.07.06
    기본 안드로이드 서비스 구조  (0) 2010.05.12
    framework_source 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    3GPP Technical Specification Documents Download Site  (0) 2010.04.03
    Posted by jazzlife
    ,

    SMS 관련 소스


    packages/apps/IM/src/com/android/im/service/AndroidSmsService.java

    packages/apps/Mms/src/com/android/mms/transaction/SmsReceiverService.java


    frameworks/base/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java

    frameworks/base/telephony/java/android/telephony/gsm/SmsManager.java

    frameworks/base/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java

    frameworks/base/telephony/java/com/android/internal/telephony/gsm/RIL.java + 1076




    frameworks/base/core/java/android/provider/Telephony.java


    Telephony Class

    Sms Class

    Inbox Class

    Sent Class

    Draft Class

    OutBox Class

    Conversations Class

    Intents Class

    Threads Class

    Mms Class

    Inbox Class

    Sent Class

    Draft Class

    Outbox Class

    Addr Class

    Part Class

    Rate Class

    Intents Class

    MmsSms Class

    PendingMessages Class

    Carriers Class

    Intents Class


    Uri.parse

    content://sms

    content://sms/sent

    content://sms/draft

    content://sms/outbox

    content://sms/conversations

    content://mms-sms/threadID

    content://mms

    content://mms/inbox

    content://mms/sent

    content://mms/drafts

    content://mms/outbox

    content://mms-sms/

    content://mms-sms/conversations

    content://mms-sms/messages/byphone

    content://mms-sms/undelivered

    content://mms-sms/draft

    'old > sms&mms' 카테고리의 다른 글

    기본 안드로이드 서비스 구조  (0) 2010.05.12
    SMS framework 소스 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    3GPP Technical Specification Documents Download Site  (0) 2010.04.03
    Network switching subsystem  (0) 2010.03.24
    Posted by jazzlife
    ,

    'old > sms&mms' 카테고리의 다른 글

    SMS framework 소스 참고  (0) 2010.05.10
    framework_source 참고  (0) 2010.05.10
    3GPP Technical Specification Documents Download Site  (0) 2010.04.03
    Network switching subsystem  (0) 2010.03.24
    Definitions  (0) 2010.03.18
    Posted by jazzlife
    ,

    'old > sms&mms' 카테고리의 다른 글

    SMS framework 소스 참고  (0) 2010.05.10
    framework_source 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    Network switching subsystem  (0) 2010.03.24
    Definitions  (0) 2010.03.18
    Posted by jazzlife
    ,

    Network switching subsystem

    From Wikipedia, the free encyclopedia

      (Redirected from Home Location Register)
    Jump to: navigation, search

    Network switching subsystem (NSS) is the component of a GSM system that carries out switching functions and manages the communications between mobile phones and the Public Switched Telephone Network (PSTN). It is owned and deployed by mobile phone operators and allows mobile phones to communicate with each other and telephones in the wider telecommunications network. The architecture closely resembles a telephone exchange, but there are additional functions which are needed because the phones are not fixed in one location. Each of these functions handle different aspects of mobility management and are described in more detail below.

    The Network Switching Subsystem, also referred to as the GSM core network, usually refers to the circuit-switched core network, used for traditional GSM services such as voice calls, SMS, and circuit switched data calls.

    There is also an overlay architecture on the GSM core network to provide packet-switched data services and is known as the GPRS core network. This allows mobile phones to have access to services such as WAP, MMS, and Internet access.

    All mobile phones manufactured today have both circuit and packet based services, so most operators have a GPRS network in addition to the standard GSM core network.

    Contents

    [hide]

    [edit] Mobile switching center (MSC)

    [edit] Description

    The mobile switching center (MSC) is the primary service delivery node for GSM, responsible for routing voice calls and SMS as well as other services (such as conference calls, FAX and circuit switched data). The MSC sets up and releases the end-to-end connection, handles mobility and hand-over requirements during the call and takes care of charging and real time pre-paid account monitoring.

    In the GSM mobile phone system, in contrast with earlier analogue services, fax and data information is sent directly digitally encoded to the MSC. Only at the MSC is this re-coded into an "analogue" signal (although actually this will almost certainly mean sound encoded digitally as PCM signal in a 64-kbit/s timeslot, known as a DS0 in America).

    There are various different names for MSCs in different contexts which reflects their complex role in the network, all of these terms though could refer to the same MSC, but doing different things at different times.

    The gateway MSC (G-MSC) is the MSC that determines which visited MSC the subscriber who is being called is currently located. It also interfaces with the PSTN. All mobile to mobile calls and PSTN to mobile calls are routed through a G-MSC. The term is only valid in the context of one call since any MSC may provide both the gateway function and the Visited MSC function, however, some manufacturers design dedicated high capacity MSCs which do not have any BSSs connected to them. These MSCs will then be the Gateway MSC for many of the calls they handle.

    The visited MSC (V-MSC) is the MSC where a customer is currently located. The VLR associated with this MSC will have the subscriber's data in it.

    The anchor MSC is the MSC from which a handover has been initiated. The target MSC is the MSC toward which a Handover should take place. A mobile switching centre server is a part of the redesigned MSC concept starting from 3GPP Release 5.

    [edit] Mobile switching centre server (MSCS)

    The mobile switching centre server is a soft-switch variant of the mobile switching centre, which provides circuit-switched calling, mobility management, and GSM services to the mobile phones roaming within the area that it serves. MSS functionality enables split between control (signalling) and user plane (bearer in network element called as media gateway/MG), which guarantees more optimal placement of network elements within the network.

    MSS and MGW media gateway makes it possible to cross-connect circuit switched calls switched by using IP, ATM AAL2 as well as TDM. More information is available in 3GPP TS 23.205.

    [edit] Other GSM core network elements connected to the MSC

    The MSC connects to the following elements:

    [edit] Procedures implemented

    Tasks of the MSC include:

    • Delivering calls to subscribers as they arrive based on information from the VLR.
    • Connecting outgoing calls to other mobile subscribers or the PSTN.
    • Delivering SMSs from subscribers to the short message service centre (SMSC) and vice versa.
    • Arranging handovers from BSC to BSC.
    • Carrying out handovers from this MSC to another.
    • Supporting supplementary services such as conference calls or call hold.
    • Generating billing information.

    [edit] Home location register (HLR)

    The home location register (HLR) is a central database that contains details of each mobile phone subscriber that is authorized to use the GSM core network. There can be several logical, and physical, HLRs per public land mobile network (PLMN), though one international mobile subscriber identity (IMSI)/MSISDN pair can be associated with only one logical HLR (which can span several physical nodes) at a time.

    The HLR stores details of every SIM card issued by the mobile phone operator. Each SIM has a unique identifier called an IMSI which is the primary key to each HLR record.

    The next important items of data associated with the SIM are the MSISDNs, which are the telephone numbers used by mobile phones to make and receive calls. The primary MSISDN is the number used for making and receiving voice calls and SMS, but it is possible for a SIM to have other secondary MSISDNs associated with it for fax and data calls. Each MSISDN is also a primary key to the HLR record. The HLR data is stored for as long as a subscriber remains with the mobile phone operator.

    Examples of other data stored in the HLR against an IMSI record is:

    • GSM services that the subscriber has requested or been given.
    • GPRS settings to allow the subscriber to access packet services.
    • Current location of subscriber (VLR and serving GPRS support node/SGSN).
    • Call divert settings applicable for each associated MSISDN.

    The HLR is a system which directly receives and processes MAP transactions and messages from elements in the GSM network, for example, the location update messages received as mobile phones roam around.

    [edit] Other GSM core network elements connected to the HLR

    The HLR connects to the following elements:

    • The G-MSC for handling incoming calls
    • The VLR for handling requests from mobile phones to attach to the network
    • The SMSC for handling incoming SMS
    • The voice mail system for delivering notifications to the mobile phone that a message is waiting
    • The AUC for authentication and ciphering and exchange of data (triplets)

    [edit] Procedures implemented

    The main function of the HLR is to manage the fact that SIMs and phones move around a lot. The following procedures are implemented to deal with this:

    • Manage the mobility of subscribers by means of updating their position in administrative areas called 'location areas', which are identified with a LAC. The action of a user of moving from one LA to another is followed by the HLR with a Location area update procedure.
    • Send the subscriber data to a VLR or SGSN when a subscriber first roams there.
    • Broker between the G-MSC or SMSC and the subscriber's current VLR in order to allow incoming calls or text messages to be delivered.
    • Remove subscriber data from the previous VLR when a subscriber has roamed away from it.

    [edit] Authentication centre (AUC)

    [edit] Description

    The authentication centre (AUC) is a function to authenticate each SIM card that attempts to connect to the GSM core network (typically when the phone is powered on). Once the authentication is successful, the HLR is allowed to manage the SIM and services described above. An encryption key is also generated that is subsequently used to encrypt all wireless communications (voice, SMS, etc.) between the mobile phone and the GSM core network.

    If the authentication fails, then no services are possible from that particular combination of SIM card and mobile phone operator attempted. There is an additional form of identification check performed on the serial number of the mobile phone described in the EIR section below, but this is not relevant to the AUC processing.

    Proper implementation of security in and around the AUC is a key part of an operator's strategy to avoid SIM cloning.

    The AUC does not engage directly in the authentication process, but instead generates data known as triplets for the MSC to use during the procedure. The security of the process depends upon a shared secret between the AUC and the SIM called the Ki. The Ki is securely burned into the SIM during manufacture and is also securely replicated onto the AUC. This Ki is never transmitted between the AUC and SIM, but is combined with the IMSI to produce a challenge/response for identification purposes and an encryption key called Kc for use in over the air communications.

    [edit] Other GSM core network elements connected to the AUC

    The AUC connects to the following elements:

    • the MSC which requests a new batch of triplet data for an IMSI after the previous data have been used. This ensures that same keys and challenge responses are not used twice for a particular mobile.

    [edit] Procedures implemented

    The AUC stores the following data for each IMSI:

    • the Ki
    • Algorithm id. (the standard algorithms are called A3 or A8, but an operator may choose a proprietary one).

    When the MSC asks the AUC for a new set of triplets for a particular IMSI, the AUC first generates a random number known as RAND. This RAND is then combined with the Ki to produce two numbers as follows:

    • The Ki and RAND are fed into the A3 algorithm and the signed response (SRES) is calculated.
    • The Ki and RAND are fed into the A8 algorithm and a session key called Kc is calculated.

    The numbers (RAND, SRES, Kc) form the triplet sent back to the MSC. When a particular IMSI requests access to the GSM core network, the MSC sends the RAND part of the triplet to the SIM. The SIM then feeds this number and the Ki (which is burned onto the SIM) into the A3 algorithm as appropriate and an SRES is calculated and sent back to the MSC. If this SRES matches with the SRES in the triplet (which it should if it is a valid SIM), then the mobile is allowed to attach and proceed with GSM services.

    After successful authentication, the MSC sends the encryption key Kc to the base station controller (BSC) so that all communications can be encrypted and decrypted. Of course, the mobile phone can generate the Kc itself by feeding the same RAND supplied during authentication and the Ki into the A8 algorithm.

    The AUC is usually collocated with the HLR, although this is not necessary. Whilst the procedure is secure for most everyday use, it is by no means crack proof. Therefore a new set of security methods was designed for 3G phones.

    [edit] Visitor location register (VLR)

    [edit] Description

    The visitor location register is a temporary database of the subscribers who have roamed into the particular area which it serves. Each base station in the network is served by exactly one VLR, hence a subscriber cannot be present in more than one VLR at a time.

    The data stored in the VLR has either been received from the HLR, or collected from the MS. In practice, for performance reasons, most vendors integrate the VLR directly to the V-MSC and, where this is not done, the VLR is very tightly linked with the MSC via a proprietary interface.

    Data stored include:

    • IMSI (the subscriber's identity number).
    • Authentication data.
    • MSISDN (the subscriber's phone number).
    • GSM services that the subscriber is allowed to access.
    • access point (GPRS) subscribed.
    • The HLR address of the subscriber.

    [edit] Other GSM core network elements connected to the VLR

    The VLR connects to the following elements:

    • The V-MSC to pass needed data for its procedures; e.g., authentication or call setup.
    • The HLR to request data for mobile phones attached to its serving area.
    • Other VLRs to transfer temporary data concerning the mobile when they roam into new VLR areas. For example, the temporal mobile subscriber identity (TMSI).

    [edit] Procedures implemented

    The primary functions of the VLR are:

    • To inform the HLR that a subscriber has arrived in the particular area covered by the VLR.
    • To track where the subscriber is within the VLR area (location area) when no call is ongoing.
    • To allow or disallow which services the subscriber may use.
    • To allocate roaming numbers during the processing of incoming calls.
    • To purge the subscriber record if a subscriber becomes inactive whilst in the area of a VLR. The VLR deletes the subscriber's data after a fixed time period of inactivity and informs the HLR (e.g., when the phone has been switched off and left off or when the subscriber has moved to an area with no coverage for a long time).
    • To delete the subscriber record when a subscriber explicitly moves to another, as instructed by the HLR.

    [edit] Equipment identity register (EIR)

    The equipment identity register is often integrated to the HLR. The EIR keeps a list of mobile phones (identified by their IMEI) which are to be banned from the network or monitored. This is designed to allow tracking of stolen mobile phones. In theory all data about all stolen mobile phones should be distributed to all EIRs in the world through a Central EIR. It is clear, however, that there are some countries where this is not in operation. The EIR data does not have to change in real time, which means that this function can be less distributed than the function of the HLR. The EIR is a database that contains information about the identity of the mobile equipment that prevents calls from stolen, unauthorized or defective mobile stations. Some EIR also have the capability to log Handset attempts and store it in a log file.

    [edit] Other support functions

    Connected more or less directly to the GSM core network are many other functions.

    [edit] Billing centre (BC)

    The billing centre is responsible for processing the toll tickets generated by the VLRs and HLRs and generating a bill for each subscriber. It is also responsible for generating billing data of roaming subscriber.

    [edit] Short message service centre (SMSC)

    The short message service centre supports the sending and reception of text messages.

    [edit] Multimedia messaging service centre (MMSC)

    The multimedia messaging service centre supports the sending of multimedia messages (e.g., images, audio, video and their combinations) to (or from) MMS-enabled Handsets.

    [edit] Voicemail system (VMS)

    The voicemail system records and stores voicemails.

    [edit] Lawful interception functions

    According to U.S. law, which has also been copied into many other countries, especially in Europe, all telecommunications equipment must provide facilities for monitoring the calls of selected users. There must be some level of support for this built into any of the different elements. The concept of lawful interception is also known, following the relevant U.S. law, as CALEA. Generally Lawful Interception implementation is similar to the implementation of conference call. While A and B is talking with each other, C can join the call and listens silently.

    [edit] See also

    [edit] External links

    'old > sms&mms' 카테고리의 다른 글

    SMS framework 소스 참고  (0) 2010.05.10
    framework_source 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    3GPP Technical Specification Documents Download Site  (0) 2010.04.03
    Definitions  (0) 2010.03.18
    Posted by jazzlife
    ,

    Definitions

    old/sms&mms 2010. 3. 18. 15:53

    For the purposes of the present document, the following terms and definitions apply:

    NOTE 1:   The term "mobile station" (MS) in the present document is synonymous with the term "user equipment" (UE) in UMTS terminology as defined in 3GPP TR 21.905 [29].

    active MS: switched‑on mobile station with a SIM/UICC see 3GPP TS 31.101 [31] module attached

    alert‑SC: service element provided by a GSM/UMTS PLMN to inform an SC which has previously initiated unsuccessful short message delivery attempt(s) to a specific MS, that the MS is now recognized by the PLMN to have recovered operation

    status report: SC informing the originating MS of the outcome of a short message submitted to an SME

    Gateway MSC For Short Message Service (SMS‑GMSC): function of an MSC capable of receiving a short message from an SC, interrogating an HLR for routing information and SMS info, and delivering the short message to the VMSC or the SGSN of the recipient MS

    Interworking MSC For Short Message Service (SMS‑IWMSC): function of an MSC capable of receiving a short message from within the PLMN and submitting it to the recipient SC

    IP-Short-Message-Gateway (IP-SM-GW): function responsible for protocol interworking between the IP-based UE and the SC

    Messages‑Waiting (MW): ervice element that makes a PLMN store information (Messages‑Waiting‑Indication), listing those SCs that have made unsuccessful short message delivery attempts to MSs in that PLMN

    Messages‑Waiting‑Indication (MWI): data to be stored in the HLR and VLR with which an MS is associated, indicating that there is one or more messages waiting in a set of SCs to be delivered to the MS (due to unsuccessful delivery attempt(s))

    Messages‑Waiting‑Data (MWD): part of the MWI to be stored in the HLR. MWD consists of an address list of the SCs which have messages waiting to be delivered to the MS

    Mobile-services Switching Centre (MSC): exchange which performs switching functions for mobile stations located in a geographical area designated as the MSC area

    Mobile‑Station‑Memory‑Capacity‑Exceeded‑Flag (MCEF): part of the MWI to be stored in the HLR

    NOTE 2:   MCEF is a Boolean parameter indicating if the address list of MWD contains one or more entries because an attempt to deliver a short message to an MS has failed with a cause of MS Memory Capacity Exceeded

    Mobile‑Station‑Not‑Reachable‑Flag (MNRF): part of the MWI to be stored in the VLR and the HLR

    NOTE 3:   MNRF is a Boolean parameter indicating if the address list of MWD contains one or more entries because an attempt to deliver a short message to an MS has failed with a cause of Absent Subscriber.

    Mobile‑station‑Not-Reachable-for-GPRS (MNRG): part of the MWI to be stored in the SGSN and the HLR

    NOTE 4:   MNRG is a Boolean parameter indicating if the address list of MWD contains one or more entries because an attempt to deliver a short message to an MS has failed with a cause of Absent Subscriber.

    Mobile‑Station‑Not‑Reachable-via-the-MSC-Reason (MNRR-MSC): part of the MWI in the HLR which stores the reason for an MS being absent when an attempt to deliver a short message to an MS fails at the MSC with a cause of Absent Subscriber

    Mobile‑Station‑Not‑Reachable-via-the-SGSN-Reason (MNRR-SGSN): part of the MWI in the HLR which stores the reason for an MS being absent when an attempt to deliver a short message to an MS fails at the SGSN with a cause of Absent Subscriber

    More‑Messages‑To‑Send (MMS): information element offering an MS receiving a short message from an SC the information whether there are still more messages waiting to be sent from that SC to the MS

    NOTE 5:   The TP‑MMS element (conveyed in the Transfer layer) is copied into the RP‑MMS element (conveyed in the Relay layer). It is possible with Phase 2 and later versions of MAP (3GPP TS 29.002 [15]) for the RP‑MMS element to keep an SM transaction open between the SMS-GMSC and the MS in the case where there are more‑messages‑to‑send. Earlier versions of MAP support the transport of the TP‑MMS element.

    priority: service element enabling the SC or SME to request a short message delivery attempt to an MS irrespective of whether or not the MS has been identified as temporarily absent

    protocol‑identifier: information element by which the originator of a short message (either an SC or an MS) may refer to a higher layer protocol

    receiving MS: the mobile station to which an MT SM is destined.

    reply path procedure: mechanism which allows an SME to request that an SC should be permitted to handle a reply sent in response to a message previously sent from that SME to another SME

    NOTE 6:   This may happen even though the SC may be unknown to the SME which received the initial message.

    report: response from either the network or the recipient upon a short message being sent from either an SC or an MS

    NOTE 7:   A report may be a delivery report, which confirms the delivery of the short message to the recipient, or it may be a failure report, which informs the originator that the short message was never delivered and the reason why.

          When issued by the Service Centre, the delivery report confirms the reception of the Short Message by the SC, and not the delivery of the Short Message to the SME.

          When issued by the Mobile Station, the delivery report confirms the reception of the Short Message by the Mobile Station, and not the delivery of the Short Message to the user.

    replace short message type: range of values in the Protocol Identifier which allows an indication to be sent with a short message (MT or MO) that the short message is of a particular type allowing the receiving MS or the SC to replace an existing message of the same type held in the SC, the ME or on the SIM/UICC, provided it comes:

         in MT cases:                 from the same SC and originating address;

         in MO cases:                 from the same MS.

    sending MS: the mobile station from which an MO SM is sourced.

    Service Centre (SC): function responsible for the relaying and store‑and‑forwarding of a short message between an SME and an MS

    NOTE 8:   The SC is not a part of the GSM/UMTS PLMN, however MSC and SC may be integrated.

    Serving GPRS Support Node (SGSN): exchange which performs packet switching functions for mobile stations located in a geographical area designated as the SGSN area

    short message: information that may be conveyed by means of the Short Message Service

    NOTE 9:   As described in the present document.

    Short Message Entity (SME): entity which may send or receive Short Messages

    NOTE 10: The SME may be located in a fixed network, an MS, or an SC.

    SMS‑STATUS‑REPORT: short message transfer protocol data unit informing the receiving MS of the status of a mobile originated short message previously submitted by the MS, i.e. whether the SC was able to forward the message or not, or whether the message was stored in the SC for later delivery

    SMS‑COMMAND: short message transfer protocol data unit which enables an MS to invoke an operation at the SC

    NOTE 11: An MS may then, for example, delete a short message, cancel a TP-Status-Report-Request, enquire about the status of a short message or request another function to be performed by the SC.

    NOTE 12: The type of operation is indicated by the TP‑Command‑Type and the particular SM to operate on is indicated by the TP‑Message‑Number and the TP‑Destination‑Address. Receipt of an SMS‑COMMAND is confirmed by an RP‑ACK or RP‑ERROR. In the case of certain SMS‑COMMANDs, an SMS‑STATUS‑REPORT may be sent, where the outcome of the SMS‑COMMAND is passed in its TP‑Status field.

    SMS‑DELIVER: short message transfer protocol data unit containing user data (the short message), being sent from an SC to an MS

    SMS‑SUBMIT: short message transfer protocol data unit containing user data (the short message), being sent from an MS to an SC

    Service‑Centre‑Time‑Stamp (SCTS): information element offering the recipient of a short message the information of when the message arrived at the SM‑TL entity of the SC

    NOTE 13: The time of arrival comprises the year, month, day, hour, minute, second and time zone.

    UE‑Not-Reachable-for-IP (UNRI): part of the MWI to be stored in the IP-SM-GW and the HSS/HLR

    NOTE 14: UNRI is a Boolean parameter indicating if the address list of MWD contains one or more entries because an attempt to deliver a short message to an UE has failed with a cause of Absent Subscriber.

    UE‑Not‑Reachable-Reason (UNRR): part of the MWI in the HSS/HLR which stores the reason for an UE being absent when an attempt to deliver a short message to an UE fails at the IP-SM-GW.

    Validity‑Period (VP): information element enabling the originator MS to indicate the time period during which the originator considers the short message to be valid.

    Visitor Location Register (VLR) is a database - part of the GSM mobile phone system - which stores information about all the mobiles that are currently under the jurisdiction of the MSC (Mobile Switching Center) which it serves. Of all the information it stores about each MS (Mobile Station), the most important is the current LAI (Location Area Identity). LAI identifies under which BSC (Base Station Controller) the MS is currently present. This information is vital in the call setup process.

    Whenever an MSC detects a new MS in its network, in addition to creating a new record in the VLR, it also updates the HLR of the mobile subscriber, apprising it of the new location of that MS.


    3rd Generation Partnership Project (3GPP)
    Technical Specification (TS)
    Short Message Service (SMS)
    Public Land Mobile Network (PLMN)
    Operator Determined Barring (ODB)
    Cell Broadcast Service (CBS)
    Service Centre(s) (SC)
    Mobile‑services Switching Centre(s) (MSC)
    Point-to-Point (PP)
    Short Message Service (SMS)
    Data Terminal Equipment ‑ Data Circuit terminating Equipment (DTE ‑ DCE)
    Mobile Application Part (MAP)
    Subscriber Identity Module ‑ Mobile Equipment (SIM‑ ME)
    Universal Multiple‑Octet Coded Character Set (USC)
    Personalisation of Mobile Equipment (ME)
    General Packet Radio Service (GPRS)
    Ir Mobile Communications (IrMC)
    Internet Mail Consortium (IMC)
    Session Initiation Protocol (SIP)
    mobile station" (MS)

    'old > sms&mms' 카테고리의 다른 글

    SMS framework 소스 참고  (0) 2010.05.10
    framework_source 참고  (0) 2010.05.10
    telephony framework architecture  (0) 2010.04.26
    3GPP Technical Specification Documents Download Site  (0) 2010.04.03
    Network switching subsystem  (0) 2010.03.24
    Posted by jazzlife
    ,