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 contains four tabs: twelvekeydialer and recentcallslistactivity.Activity-aliasDialtactscontactsentryactivity and dialtactsfavoritesentryactivity indicate contacts and add tabs respectively. However, contactslistactivity is responsible for the list of genuine contacts and favorites. 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. The actual intert. action_call_privileged string is Android. Intent. Action. call_privileged. You can find out the androidmanifest. XML in packegs/phone.Activity-aliasIntent-filter is set, 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 ); |