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 // TODO: ifdef poll with flags (not all devices need this)
117 struct timeval poll_interval = {0, 750000};
119 if(response->status == AT_STATUS_UNDEF)
120 return AT_RESPONSE_UNHANDELD_REASON_STATUS;
122 LOGE("Caught valid AT+CLCC unsol!");
124 if(at_status_error(response->status)) {
125 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
128 calls_count = response->data_count;
129 if(calls_count > 0) {
130 calls = calloc(1, sizeof(RIL_Call *) * calls_count);
132 LOGD("Got %d call(s) ingoing!", calls_count);
134 for(i=0 ; i < calls_count ; i++) {
135 calls[i] = calloc(1, sizeof(RIL_Call));
136 at2ril_call_list(calls[i], response->data[i]);
138 if(calls[i]->state != RIL_CALL_ACTIVE && calls[i]->state != RIL_CALL_HOLDING)
142 RIL_requestTimedCallback(ril_call_state_changed, NULL, &poll_interval);
145 RIL_onRequestComplete(t, RIL_E_SUCCESS, calls, sizeof(RIL_Call *) * calls_count);
147 for(i=0 ; i < calls_count ; i++) {
148 if(calls[i] != NULL) {
149 if(calls[i]->number != NULL)
150 free(calls[i]->number);
158 return AT_RESPONSE_HANDLED_OK;
161 void ril_request_get_current_calls(RIL_Token t, void *data, size_t length)
163 if(ril_globals.radio_state == RADIO_STATE_OFF) {
164 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
167 at_send_expect_to_func("AT+CLCC", NULL, NULL, t, at_clcc_expect);
170 void ril_call_state_changed(void *data)
172 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
175 void at_cring(struct at_response *response)
177 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
180 void ril_request_anwswer(RIL_Token t, void *data, size_t length)
184 status = at_send_expect_status("ATA", NULL);
186 if(at_status_error(status))
187 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
189 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
196 void ril_request_dial(RIL_Token t, void *data, size_t length)
199 char *command = NULL;
201 int status = AT_STATUS_UNDEF;
203 dial = (RIL_Dial *) data;
206 case 1: clir = "I"; break; // invocation
207 case 2: clir = "i"; break; // suppression
209 case 0: clir = ""; break; // subscription default
212 asprintf(&command, "ATD%s%s;", dial->address, clir);
214 status = at_send_expect_status(command, NULL);
218 if(at_status_error(status))
219 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
221 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
224 void no_carrier_unexpect(struct at_response *response)
226 // This comes to notify call end
227 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
230 void ril_request_hangup(RIL_Token t, void *data, size_t length)
232 char *command = NULL;
234 int status = AT_STATUS_UNDEF;
236 index = *((int *) data);
238 asprintf(&command, "AT+CHLD=1%d", index);
240 status = at_send_expect_status(command, NULL);
244 if(at_status_error(status))
245 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
247 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
250 void at_chld_request(RIL_Token t, char *data)
254 status = at_send_expect_status("AT+CHLD", data);
256 if(at_status_error(status))
257 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
259 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
262 void ril_request_hangup_waiting_or_background(RIL_Token t, void *data, size_t length)
264 at_chld_request(t, "0");
267 void ril_request_hangup_foreground_resume_background(RIL_Token t, void *data, size_t length)
269 at_chld_request(t, "1");
272 void ril_request_switch_waiting_or_holding_and_active(RIL_Token t, void *data, size_t length)
274 at_chld_request(t, "2");