2 * This file is part of hayes-ril.
4 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
6 * Parts of this code are based on htcgeneric-ril, reference-ril:
7 * Copyright 2006-2011, htcgeneric-ril contributors
8 * Copyright 2006, The Android Open Source Project
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
23 #define LOG_TAG "RIL-CALL"
24 #include <utils/Log.h>
25 #include <telephony/ril.h>
27 #include <hayes-ril.h>
33 RIL_CallState at2ril_call_state(int state)
37 return RIL_CALL_ACTIVE;
39 return RIL_CALL_HOLDING;
41 return RIL_CALL_DIALING;
43 return RIL_CALL_ALERTING;
45 return RIL_CALL_INCOMING;
47 return RIL_CALL_WAITING;
53 void at2ril_call_list(RIL_Call *call, char *data)
55 struct at_response_data **response_data = NULL;
56 int response_data_count = 0;
61 response_data_count = at_response_data_process(&response_data, data, strlen(data));
62 if(response_data_count < 7)
65 // 1,0,2,0,0,"0557514206",129
67 if(response_data[0]->type != AT_RESPONSE_DATA_NUMERIC)
69 call->index = response_data[0]->value.n;
71 if(response_data[1]->type != AT_RESPONSE_DATA_NUMERIC)
73 call->isMT = response_data[1]->value.n;
75 if(response_data[2]->type != AT_RESPONSE_DATA_NUMERIC)
77 state = response_data[2]->value.n;
78 call->state = at2ril_call_state(state);
80 if(response_data[3]->type != AT_RESPONSE_DATA_NUMERIC)
82 mode = response_data[3]->value.n;
83 call->isVoice = (mode == 0);
85 if(response_data[4]->type != AT_RESPONSE_DATA_NUMERIC)
87 call->isMpty = response_data[4]->value.n;
89 if(response_data[5]->type != AT_RESPONSE_DATA_STRING)
91 number = strdup(response_data[5]->value.s);
92 if(number != NULL && strspn(number, "+0123456789") == 0)
94 call->number = number;
96 if(response_data[6]->type != AT_RESPONSE_DATA_NUMERIC)
98 call->toa = response_data[6]->value.n;
100 at_response_data_free(response_data, response_data_count);
105 LOGE("Error while parsing call list!");
106 at_response_data_free(response_data, response_data_count);
109 int at_clcc_expect(struct at_response *response, void *data, RIL_Token t)
111 RIL_Call **calls = NULL;
116 struct timeval poll_interval = {0, 500000};
118 if(response->status == AT_STATUS_UNDEF)
119 return AT_RESPONSE_UNHANDELD_REASON_STATUS;
121 LOGE("Caught valid AT+CLCC unsol!");
123 if(at_status_error(response->status)) {
124 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
127 calls_count = response->data_count;
128 if(calls_count > 0) {
129 calls = calloc(1, sizeof(RIL_Call *) * calls_count);
131 LOGD("Got %d call(s) ingoing!", calls_count);
133 for(i=0 ; i < calls_count ; i++) {
134 calls[i] = calloc(1, sizeof(RIL_Call));
135 at2ril_call_list(calls[i], response->data[i]);
137 if(calls[i]->state != RIL_CALL_ACTIVE && calls[i]->state != RIL_CALL_HOLDING)
141 RIL_requestTimedCallback(ril_call_state_changed, NULL, &poll_interval);
144 RIL_onRequestComplete(t, RIL_E_SUCCESS, calls, sizeof(RIL_Call *) * calls_count);
146 for(i=0 ; i < calls_count ; i++) {
147 if(calls[i] != NULL) {
148 if(calls[i]->number != NULL)
149 free(calls[i]->number);
157 return AT_RESPONSE_HANDLED_OK;
160 void ril_request_get_current_calls(RIL_Token t, void *data, size_t length)
162 if(ril_globals.radio_state == RADIO_STATE_OFF) {
163 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
166 at_send_expect_to_func("AT+CLCC", NULL, NULL, t, at_clcc_expect);
169 void ril_call_state_changed(void *data)
171 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
174 void at_cring(struct at_response *response)
176 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
179 void ril_request_anwswer(RIL_Token t, void *data, size_t length)
183 status = at_send_expect_status("ATA", NULL);
185 if(at_status_error(status))
186 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
188 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
195 void ril_request_dial(RIL_Token t, void *data, size_t length)
198 char *command = NULL;
200 int status = AT_STATUS_UNDEF;
202 dial = (RIL_Dial *) data;
205 case 1: clir = "I"; break; // invocation
206 case 2: clir = "i"; break; // suppression
208 case 0: clir = ""; break; // subscription default
211 asprintf(&command, "ATD%s%s;", dial->address, clir);
213 status = at_send_expect_status(command, NULL);
217 if(at_status_error(status))
218 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
220 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
223 void no_carrier_unexpect(struct at_response *response)
225 // This comes to notify call end
226 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
229 void ril_request_hangup(RIL_Token t, void *data, size_t length)
231 char *command = NULL;
233 int status = AT_STATUS_UNDEF;
235 index = *((int *) data);
237 asprintf(&command, "AT+CHLD=1%d", index);
239 status = at_send_expect_status(command, NULL);
243 if(at_status_error(status))
244 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
246 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
249 void at_chld_request(RIL_Token t, char *data)
253 status = at_send_expect_status("AT+CHLD", data);
255 if(at_status_error(status))
256 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
258 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
261 void ril_request_hangup_waiting_or_background(RIL_Token t, void *data, size_t length)
263 at_chld_request(t, "0");
266 void ril_request_hangup_foreground_resume_background(RIL_Token t, void *data, size_t length)
268 at_chld_request(t, "1");
271 void ril_request_switch_waiting_or_holding_and_active(RIL_Token t, void *data, size_t length)
273 at_chld_request(t, "2");