Address: http://lisaguo.iteye.com/blog/920065
Andriod phone module (Overview)
1. process the AT command sent from Java.
2. the unsolicited message is reported to Java from the modem.
3. monitoring and notification mechanisms for various statuses related to cats.
4. How call-related icons change.
5. Principle of GPRS dial-up access.
6. Call-related voice path Switching Principle and vibration interface.
7. Call-related notification service.
8. Various server related to calls.
Andriod phone module (1)
Part 1: Process of sending AT commands from Java.
Outbound call process:
1. Android: Process = "android. process. acore" in androidmanifest. xml of contacts indicates that the application is running in the acore process.
The action attribute of intent-filter of dialtactsactivity is set to main, and the catelog attribute is set to launcher. Therefore, this activity can appear in the main menu and is the first interface to click this application. Dialtactsactivity consists of four tabs: twelvekeydialer and recentcallslistactivity. Two activities-alias dialtactscontactsentryactivity and dialtactsfavoritesentryactivity indicate contacts and favorites respectively.
Tab, but the real contact list and favorites are the responsibility of contactslistactivity.
2. Enter The onclick method in twelvekeydialer, press and hold the button ID to R. Id. dialbutton, and execute the placecall () method:
Intent intent = new intent (intent. action_call_privileged, Uri. fromparts ("tel", number, null ));
Intent. setflags (intent. flag_activity_new_task );
Startactivity (intent );
3. intert. the actual action_call_privileged string is Android. intent. action. call_privileged: Find the androidmanifest in packegs/phone. in XML, privilegedoutgoingcallbroadcaster activity-alias sets intent-filter, so you need to find its targetactivity as outgoingcallbroadcaster. So go to oncreate () of outgoingcallbroadcaster:
String action = intent. getaction ();
String number = phonenumberutils. getnumberfromintent (intent, this );
If (number! = NULL ){
Number = phonenumberutils. convertkeypadletterstodigits (number );
Number = phonenumberutils. stripseparators (number );
}
Final Boolean emergencynumber =
(Number! = NULL) & phonenumberutils. isemergencynumber (number );
Obtain the action and number, and determine the action and number type.
// If callnow = true, the incall interface is started:
Intent. setclass (this, incallscreen. Class );
Startactivity (intent );
And send the broadcast to outgoingcallreceiver:
Intent broadcastintent = new intent (intent. action_new_outgoing_call );
If (number! = NULL) broadcastintent. putextra (intent. extra_phone_number, number );
Broadcastintent. putextra (extra_already_called, callnow );
Broadcastintent. putextra (extra_original_uri, intent. getdata (). tostring ());
Sendorderedbroadcast (broadcastintent, permission,
New outgoingcallreceiver (), null, activity. result_ OK, number, null );
4. Intent. action_new_outgoing_call the actual string Android. Intent. Action. new_outgoing_call. You can find the androidmanifest. XML in packegs/phone to receive the intent message. Find the internal class outgoingcallreceiver in the outgoingcallbroadcaster class and execute the onreceive () function:
Execute doreceive (context, intent); method:
Obtain the sent number and obtain the phonetype according to the phoneapp instance. Finally, start the incall interface:
Intent newintent = new intent (intent. action_call, Uri );
Newintent. putextra (intent. extra_phone_number, number );
Newintent. setclass (context, incallscreen. Class );
Newintent. addflags (intent. flag_activity_new_task );
5. Java part of the request dialing process
6. Part of the C/C ++ request dialing process
6.1 initialize the event loop, start the serial port listener, and register the socket listener.
Rild. C-> main ()
(1) ril_starteventloop
// Create an event loop thread
Ret = pthread_create (& s_tid_dispatch, & ATTR, eventloop, null );
// Register the process to wake up Event Callback
Ril_event_set (& s_wakeupfd_event, s_fdwakeupread, true,
Processwakeupcallback, null );
Rileventaddwakeup (& s_wakeupfd_event );
// Create an event Loop
Ril_event_loop
For (;;){
...
N = select (NFDs, & rfds, null, null, PTV );
// Check for timeouts
Processtimeouts ();
// Check for read-ready
Processreadreadies (& rfds, N );
// Fire away
Firepending ();
}
(2), funcs = rilinit (& s_rilenv, argc, rilargv); // It is actually to execute ril_init in the reference-ril.c by dynamically loading the dynamic library
// Start a separate thread to read serial data
Ret = pthread_create (& s_tid_mainloop, & ATTR, mainloop, null );
FD = open (s_device_path, o_rdwr );
Ret = at_open (FD, onunsolicited );
Ret = pthread_create (& s_tid_reader, & ATTR, readerloop, & ATTR );
Ril_requesttimedcallback (initializecallback, null, & timeval_0 );
The Program executed in initializecallback:
Setradiostate (radio_state_off );
At_handshake ();
/* Note: We don't check errors here. Everything important will
Be handled in onattimeout and onatreaderclosed */
/* Atchannel is tolerant of ECHO but it must */
/* Have verbose result codes */
At_send_command ("ate0q0v1", null );
/* No auto-answer */
At_send_command ("ats0 = 0", null );
...
// Register the rild socket port event to listen to the event Loop
(3), ril_register (funcs );
S_fdlisten = android_get_control_socket (socket_name_ril );
Ret = listen (s_fdlisten, 4 );
Ril_event_set (& s_listen_event, s_fdlisten, false,
Listencallback, null); // Add this port to the event select queue
Rileventaddwakeup (& s_listen_event );
If there is data on the rild socket port, the listencallback function will be executed.
Listencallback
// Create a new listening handle for the client connection. s_fdlisten continues to listen for connections from other clients.
S_fdcommand = accept (s_fdlisten, (sockaddr *) & peeraddr, & socklen );
Ril_event_set (& s_commands_event, s_fdcommand, 1,
Processcommandscallback, p_rs); // Add this port to the event select queue
Rileventaddwakeup (& s_commands_event );
6.2 socket listening, receive the socket request of dial
Processcommandscallback
// Read data to p_record
Ret = record_stream_get_next (p_rs, & p_record, & recordlen );
Processcommandbuffer (p_record, recordlen );
P. setdata (uint8_t *) buffer, buflen );
// Status checked at end
Status = P. readint32 (& request );
Status = P. readint32 (& token); // the serial number in the Request queue
PRI = (requestinfo *) calloc (1, sizeof (requestinfo ));
Pri-> token = token;
/*
Contains the # include "ril_commands.h" statement. The struct is as follows:
Typedef struct {
Int requestnumber;
Void (* dispatchfunction) (parcel & P, struct requestinfo * Pri );
INT (* responsefunction) (parcel & P, void * response, size_t responselen );
} Commandinfo;
*/
Pri-> PCI = & (s_commands [request]);
Pri-> p_next = s_pendingrequests;
S_pendingrequests = PRI;
Pri-> PCI-> dispatchfunction (p, PRI );
// Assume that the dial command is received. pri-> PCI-> dispatchfunction (p, PRI) calls dispatchdial (p, PRI)
Dispatchdial (p, PRI)
S_callbacks.onrequest (PRI-> PCI-> requestnumber, & dial, sizeof (Dial), PRI );
In reference-ril.c onrequest ()
...
Switch (request ){
Case ril_request_dial:
Requestdial (data, datalen, t );
Asprintf (& cmd, "ATD % S % s;", p_dial-> address, clir );
Ret = at_send_command (CMD, null );
Err = at_send_command_full (command, no_result, null, null, 0, pp_outresponse );
Err = at_send_command_full_nolock (command, type, responseprefix, smspdu, timeoutmsec, sponse );
Err = writeline (command );
// Wait until a successful or failed response is received, such as OK, connect, and error CME.
Err = pthread_cond_wait (& s_commandcond, & s_commandmutex );
Waiting ....
Waiting ....
/* Success or failure is ignored by the upper layer here.
It will call get_current_cils and determine success that way */
Ril_onrequestcomplete (T, ril_e_success, null, 0 );
P. writeint32 (response_solicited );
P. writeint32 (PRI-> token );
Erroffset = P. dataposition ();
P. writeint32 (E );
If (E = ril_e_success ){
/* Process response on Success */
Ret = pri-> PCI-> responsefunction (p, response, responselen );
If (Ret! = 0 ){
P. setdataposition (erroroffset );
P. writeint32 (RET );
}
}
Sendresponse (P );
Sendresponseraw (P. Data (), P. datasize ());
Blockingwrite (FD, (void *) & header, sizeof (header ));
Blockingwrite (FD, Data, datasize );
6.4 The serial port listener receives the ATD command response "OK" or "No carrier", etc.
Readerloop ()
Line = Readline ();
Processline (line );
Handlefinalresponse (line );
Pthread_cond_signal (& s_commandcond); // at this point, the previous wait ends, and then execute the ril_onrequestcomplete Function
6.5. processing after the Java layer receives the response, taking dial as an example.
RIL. Java-> rilreceiver. Run ()
For (;;)
{
...
Length = readrilmessage (is, buffer );
P = parcel. Obtain ();
P. unmarshall (buffer, 0, length );
P. setdataposition (0 );
Processresponse (P );
Type = P. readint ();
If (type = response_solicited ){
Processsolicited (P );
Serial = P. readint ();
RR = findandremoverequestfromlist (Serial );
Rr. mresult. sendtotarget ();
......
}
Calltracker. Java-> handlemessage (Message MSG)
Switch (msg. What ){
Case event_operation_complete:
AR = (asyncresult) msg. OBJ;
Operationcomplete ();
Cm. getcurrentcils (lastrelevantpoll );
Andriod phone module (2)
Part 2: the process of reporting unsolicited messages to Java from modem.
C ++:
Readerloop ()
Line = Readline ();
Processline (line );
Handleunsolicited (line );
If (s_unsolhandler! = NULL ){
S_unsolhandler (line1, line2); // The Void onunsolicited (const char * s, const char * sms_pdu) is actually executed)
If (strstartswith (S, "+ cring:") | strstartswith (S, "ring ")
| Strstartswith (S, "no carrier") | strstartswith (S, "+ ccwa "))
Ril_onunsolicitedresponse (ril_unsol_response_call_state_changed, null, 0 );
P. writeint32 (response_unsolicited );
P. writeint32 (unsolresponse );
Ret = s_unsolresponses [unsolresponseindex]. responsefunction (p, Data, datalen );
Ret = sendresponse (P );
Sendresponseraw (P. Data (), P. datasize ());
Ret = blockingwrite (FD, (void *) & header, sizeof (header ));
Blockingwrite (FD, Data, datasize );
Java:
RIL. Java-> rilreceiver. Run ()
For (;;)
{
...
Length = readrilmessage (is, buffer );
P = parcel. Obtain ();
P. unmarshall (buffer, 0, length );
P. setdataposition (0 );
Processresponse (P );
Processunsolicited (P );
Response = P. readint ();
Switch (response ){
...
Case ril_unsol_response_call_state_changed: ret = responsevoid (p); break;
...
}
Switch (response ){
Case ril_unsol_response_call_state_changed:
If (rilj_logd) unsljlog (response );
Mcallstateregistrants
. Notifyregistrants (New asyncresult (null, null, null ));
...
}
Andriod phone module (3 and 4)
Part 3: monitoring and notification mechanisms for various statuses related to cats
Part 4: How call-related icons change.
A. register the listener
B. Event Notification Section
Note: All status change notifications are handled in telephonyregistry. For details, see the source code of this type.
Mobile phone SIM card function analysis
SIM card is a symbol of the unique user identity of a GSM mobile phone.
What are the functions and principles of SIM card? The following is a brief description.
SIM card, as a symbol of user identity, mainly contains the following two types of information: imsi number, authentication, and encryption algorithm.
Imsi is called the International Mobile Station user identification number. It is completely different from the IMEI international mobile device identification number. The imsi number is the number that is fixed on the internal storage chip of the SIM card. When the customer applies to access the network, the telecommunications business staff will bring a brand new SIM card, the 15-digit imsi number marked on the card, corresponding to the number selected by the user, enter the computer to create a file. This is a convenient and quick way to access the GSM system.
The IMEI number is an inherent number in the body of a mobile phone, reflecting a series of information such as the factory location and manufacturer of the mobile phone.
The difference between the two numbers reflects the principle of separate GSM system machines and numbers.
The GSM system has good confidentiality and is also reflected in the SIM card. When a user calls online, the imsi number needs to be transmitted in the air for authentication. Imsi numbers are transmitted in the air after authentication and encryption in the SIM card. After these complex operations, deciphering is basically impossible. This is also a major embodiment that the GSM system is better than the etacs system.
In terms of appearance, SIM cards can be divided into big cards and small cards, which are designed to meet the needs of different sizes of mobile phones. However, as the mobile phone market is becoming increasingly small and light, more and more manufacturers have eliminated large card models and small cards have become increasingly popular.
Observe the SIM card and you can see that each card has 8 metal pins. They have the following functions, as shown in figure 1.
Figure 1 SIM card pin
There are two types of SIM card Power Supply: 5 V and 3 V. Early SIM cards generally provide 5 V power. With the increasing demand for battery time, manufacturers have adopted various methods to reduce the power consumption of mobile phones, including reducing the CPU power from about 5 V to about 3 V, as a result, the power supply of the entire mobile phone body is basically reduced to about 3 V, so that the power supply voltage of the SIM card is reduced. Currently, many SIM cards are compatible with two types of voltage supply to meet the needs of the transitional period.
In addition, the SIM card capacity varies depending on the memory size of the internal storage chip of the SIM card. The capacity of the card is reflected in how many records can be stored on the SIM card when the user uses the phone book function.
During daily use, "SIM card not accepted", "Please insert SIM card", and other abnormal phenomena may occur. At this time, we can take the SIM card from the machine and use an eraser to gently wipe the card surface. Do not scratch the card surface with sharp things, so as to avoid poor contact and even damage the SIM card. If it still cannot be used normally after wiping, the mobile phone card should be sent to a professional repair site for repair personnel to check.