3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "gatserver.h"
37 #define RING_TIMEOUT 3
39 struct ofono_emulator {
40 struct ofono_atom *atom;
41 enum ofono_emulator_type type;
49 unsigned char cmee_mode;
51 guint callsetup_source;
67 static void emulator_debug(const char *str, void *data)
69 ofono_info("%s: %s\n", (char *)data, str);
72 static void emulator_disconnect(gpointer user_data)
74 struct ofono_emulator *em = user_data;
78 ofono_emulator_remove(em);
81 static void ppp_connect(const char *iface, const char *local,
83 const char *dns1, const char *dns2,
86 DBG("Network Device: %s\n", iface);
87 DBG("IP Address: %s\n", local);
88 DBG("Remote IP Address: %s\n", remote);
89 DBG("Primary DNS Server: %s\n", dns1);
90 DBG("Secondary DNS Server: %s\n", dns2);
93 static void cleanup_ppp(struct ofono_emulator *em)
97 g_at_ppp_unref(em->ppp);
100 __ofono_private_network_release(em->pns_id);
103 if (em->server == NULL)
106 g_at_server_resume(em->server);
107 g_at_server_send_final(em->server, G_AT_SERVER_RESULT_NO_CARRIER);
110 static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
112 struct ofono_emulator *em = user_data;
117 static void ppp_suspend(gpointer user_data)
119 struct ofono_emulator *em = user_data;
123 g_at_server_resume(em->server);
126 static void suspend_server(gpointer user_data)
128 struct ofono_emulator *em = user_data;
129 GAtIO *io = g_at_server_get_io(em->server);
131 g_at_server_suspend(em->server);
133 if (g_at_ppp_listen(em->ppp, io) == FALSE)
137 static void request_private_network_cb(
138 const struct ofono_private_network_settings *pns,
141 struct ofono_emulator *em = data;
142 GAtIO *io = g_at_server_get_io(em->server);
147 em->ppp = g_at_ppp_server_new_full(pns->server_ip, pns->fd);
148 if (em->ppp == NULL) {
153 g_at_ppp_set_server_info(em->ppp, pns->peer_ip,
154 pns->primary_dns, pns->secondary_dns);
156 g_at_ppp_set_acfc_enabled(em->ppp, TRUE);
157 g_at_ppp_set_pfc_enabled(em->ppp, TRUE);
159 g_at_ppp_set_credentials(em->ppp, "", "");
160 g_at_ppp_set_debug(em->ppp, emulator_debug, "PPP");
162 g_at_ppp_set_connect_function(em->ppp, ppp_connect, em);
163 g_at_ppp_set_disconnect_function(em->ppp, ppp_disconnect, em);
164 g_at_ppp_set_suspend_function(em->ppp, ppp_suspend, em);
166 g_at_server_send_intermediate(em->server, "CONNECT");
167 g_at_io_set_write_done(io, suspend_server, em);
172 __ofono_private_network_release(em->pns_id);
176 g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
179 static gboolean dial_call(struct ofono_emulator *em, const char *dial_str)
183 DBG("dial call %s", dial_str);
185 if (c == '*' || c == '#' || c == 'T' || c == 't') {
186 if (__ofono_private_network_request(request_private_network_cb,
187 &em->pns_id, em) == FALSE)
194 static void dial_cb(GAtServer *server, GAtServerRequestType type,
195 GAtResult *result, gpointer user_data)
197 struct ofono_emulator *em = user_data;
199 const char *dial_str;
203 if (type != G_AT_SERVER_REQUEST_TYPE_SET)
206 g_at_result_iter_init(&iter, result);
208 if (!g_at_result_iter_next(&iter, ""))
211 dial_str = g_at_result_iter_raw_line(&iter);
218 if (!dial_call(em, dial_str))
224 g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
227 static void dun_ath_cb(GAtServer *server, GAtServerRequestType type,
228 GAtResult *result, gpointer user_data)
230 struct ofono_emulator *em = user_data;
237 case G_AT_SERVER_REQUEST_TYPE_SET:
238 g_at_result_iter_init(&iter, result);
239 g_at_result_iter_next(&iter, "");
241 if (g_at_result_iter_next_number(&iter, &val) == FALSE)
249 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
253 g_at_ppp_unref(em->ppp);
256 __ofono_private_network_release(em->pns_id);
259 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
264 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
269 static void resume_ppp(gpointer user_data)
271 struct ofono_emulator *em = user_data;
273 g_at_server_suspend(em->server);
274 g_at_ppp_resume(em->ppp);
277 static void dun_ato_cb(GAtServer *server, GAtServerRequestType type,
278 GAtResult *result, gpointer user_data)
280 struct ofono_emulator *em = user_data;
281 GAtIO *io = g_at_server_get_io(em->server);
288 case G_AT_SERVER_REQUEST_TYPE_SET:
289 g_at_result_iter_init(&iter, result);
290 g_at_result_iter_next(&iter, "");
292 if (g_at_result_iter_next_number(&iter, &val) == FALSE)
299 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
303 g_at_server_send_intermediate(em->server, "CONNECT");
304 g_at_io_set_write_done(io, resume_ppp, em);
309 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
314 static struct indicator *find_indicator(struct ofono_emulator *em,
315 const char *name, int *index)
320 for (i = 1, l = em->indicators; l; l = l->next, i++) {
321 struct indicator *ind = l->data;
323 if (g_str_equal(ind->name, name) == FALSE)
335 static struct ofono_call *find_call_with_status(struct ofono_emulator *em,
338 struct ofono_modem *modem = __ofono_atom_get_modem(em->atom);
339 struct ofono_voicecall *vc;
341 vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem);
345 return __ofono_voicecall_find_call_with_status(vc, status);
348 static void notify_deferred_indicators(GAtServer *server, void *user_data)
350 struct ofono_emulator *em = user_data;
354 struct indicator *ind;
356 for (i = 1, l = em->indicators; l; l = l->next, i++) {
362 if (em->events_mode == 3 && em->events_ind && em->slc &&
364 sprintf(buf, "+CIEV: %d,%d", i, ind->value);
365 g_at_server_send_unsolicited(em->server, buf);
368 ind->deferred = FALSE;
372 static gboolean notify_ccwa(void *user_data)
374 struct ofono_emulator *em = user_data;
375 struct ofono_call *c;
378 * '+CCWA: "+",' + phone number + phone type on 3 digits max
381 char str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1];
383 if ((em->type == OFONO_EMULATOR_TYPE_HFP && em->slc == FALSE) ||
387 c = find_call_with_status(em, CALL_STATUS_WAITING);
389 if (c && c->clip_validity == CLIP_VALIDITY_VALID) {
390 phone = phone_number_to_string(&c->phone_number);
391 sprintf(str, "+CCWA: \"%s\",%d", phone, c->phone_number.type);
393 g_at_server_send_unsolicited(em->server, str);
395 g_at_server_send_unsolicited(em->server, "+CCWA: \"\",128");
398 em->callsetup_source = 0;
403 static gboolean notify_ring(void *user_data)
405 struct ofono_emulator *em = user_data;
406 struct ofono_call *c;
409 * '+CLIP: "+",' + phone number + phone type on 3 digits max
412 char str[OFONO_MAX_PHONE_NUMBER_LENGTH + 14 + 1];
414 if (em->type == OFONO_EMULATOR_TYPE_HFP && em->slc == FALSE)
417 g_at_server_send_unsolicited(em->server, "RING");
422 c = find_call_with_status(em, CALL_STATUS_INCOMING);
427 switch (c->clip_validity) {
428 case CLIP_VALIDITY_VALID:
429 phone = phone_number_to_string(&c->phone_number);
430 sprintf(str, "+CLIP: \"%s\",%d", phone, c->phone_number.type);
431 g_at_server_send_unsolicited(em->server, str);
434 case CLIP_VALIDITY_WITHHELD:
435 g_at_server_send_unsolicited(em->server, "+CLIP: \"\",128");
442 static void brsf_cb(GAtServer *server, GAtServerRequestType type,
443 GAtResult *result, gpointer user_data)
445 struct ofono_emulator *em = user_data;
451 case G_AT_SERVER_REQUEST_TYPE_SET:
452 g_at_result_iter_init(&iter, result);
453 g_at_result_iter_next(&iter, "");
455 if (g_at_result_iter_next_number(&iter, &val) == FALSE)
458 if (val < 0 || val > 127)
461 em->r_features = val;
463 sprintf(buf, "+BRSF: %d", em->l_features);
464 g_at_server_send_info(em->server, buf, TRUE);
465 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
470 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
475 static void cind_cb(GAtServer *server, GAtServerRequestType type,
476 GAtResult *result, gpointer user_data)
478 struct ofono_emulator *em = user_data;
480 struct indicator *ind;
487 case G_AT_SERVER_REQUEST_TYPE_QUERY:
489 * "+CIND: " + terminating null + number of indicators *
490 * (max of 3 digits in the value + separator)
492 size = 7 + 1 + (g_slist_length(em->indicators) * 4);
493 buf = g_try_malloc0(size);
497 len = sprintf(buf, "+CIND: ");
500 for (l = em->indicators; l; l = l->next) {
502 len = sprintf(tmp, "%s%d",
503 l == em->indicators ? "" : ",",
508 g_at_server_send_info(em->server, buf, TRUE);
510 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
513 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
515 * '+CIND: ' + terminating null + number of indicators *
516 * ( indicator name + '("",(000,000))' + separator)
520 for (l = em->indicators; l; l = l->next) {
522 size += strlen(ind->name) + 15;
525 buf = g_try_malloc0(size);
529 len = sprintf(buf, "+CIND: ");
532 for (l = em->indicators; l; l = l->next) {
534 len = sprintf(tmp, "%s(\"%s\",(%d%c%d))",
535 l == em->indicators ? "" : ",",
537 (ind->max - ind->min) == 1 ? ',' : '-',
542 g_at_server_send_info(server, buf, TRUE);
544 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
549 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
554 static void cmer_cb(GAtServer *server, GAtServerRequestType type,
555 GAtResult *result, gpointer user_data)
557 struct ofono_emulator *em = user_data;
561 case G_AT_SERVER_REQUEST_TYPE_QUERY:
562 sprintf(buf, "+CMER: %d,0,0,%d,0", em->events_mode,
564 g_at_server_send_info(em->server, buf, TRUE);
565 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
568 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
569 sprintf(buf, "+CMER: (0,3),(0),(0),(0,1),(0)");
570 g_at_server_send_info(em->server, buf, TRUE);
571 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
574 case G_AT_SERVER_REQUEST_TYPE_SET:
577 int mode = em->events_mode;
578 int ind = em->events_ind;
581 g_at_result_iter_init(&iter, result);
582 g_at_result_iter_next(&iter, "");
585 if (!g_at_result_iter_next_number_default(&iter, mode, &mode))
588 if (mode != 0 && mode != 3)
592 if (!g_at_result_iter_next_number_default(&iter, 0, &val)) {
593 if (!g_at_result_iter_skip_next(&iter))
602 if (!g_at_result_iter_next_number_default(&iter, 0, &val)) {
603 if (!g_at_result_iter_skip_next(&iter))
612 if (!g_at_result_iter_next_number_default(&iter, ind, &ind)) {
613 if (!g_at_result_iter_skip_next(&iter))
618 if (ind != 0 && ind != 1)
622 if (!g_at_result_iter_next_number_default(&iter, 0, &val)) {
623 if (!g_at_result_iter_skip_next(&iter))
631 /* check that bfr is last parameter */
632 if (g_at_result_iter_skip_next(&iter))
636 em->events_mode = mode;
637 em->events_ind = ind;
639 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
647 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
652 static void clip_cb(GAtServer *server, GAtServerRequestType type,
653 GAtResult *result, gpointer user_data)
655 struct ofono_emulator *em = user_data;
659 if (em->slc == FALSE)
663 case G_AT_SERVER_REQUEST_TYPE_SET:
664 g_at_result_iter_init(&iter, result);
665 g_at_result_iter_next(&iter, "");
667 if (!g_at_result_iter_next_number(&iter, &val))
670 if (val != 0 && val != 1)
673 /* check this is last parameter */
674 if (g_at_result_iter_skip_next(&iter))
679 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
684 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
688 static void ccwa_cb(GAtServer *server, GAtServerRequestType type,
689 GAtResult *result, gpointer user_data)
691 struct ofono_emulator *em = user_data;
694 struct indicator *call_ind;
695 struct indicator *cs_ind;
697 if (em->slc == FALSE)
701 case G_AT_SERVER_REQUEST_TYPE_SET:
702 g_at_result_iter_init(&iter, result);
703 g_at_result_iter_next(&iter, "");
705 if (!g_at_result_iter_next_number(&iter, &val))
708 if (val != 0 && val != 1)
711 /* check this is last parameter */
712 if (g_at_result_iter_skip_next(&iter))
715 call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
716 cs_ind = find_indicator(em, OFONO_EMULATOR_IND_CALLSETUP, NULL);
718 if (cs_ind->value == OFONO_EMULATOR_CALLSETUP_INCOMING &&
719 call_ind->value == OFONO_EMULATOR_CALL_ACTIVE &&
720 em->ccwa == FALSE && val == 1)
721 em->callsetup_source = g_timeout_add_seconds(0,
726 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
731 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
735 static void cmee_cb(GAtServer *server, GAtServerRequestType type,
736 GAtResult *result, gpointer user_data)
738 struct ofono_emulator *em = user_data;
744 case G_AT_SERVER_REQUEST_TYPE_SET:
745 g_at_result_iter_init(&iter, result);
746 g_at_result_iter_next(&iter, "");
748 if (g_at_result_iter_next_number(&iter, &val) == FALSE)
751 if (val != 0 && val != 1)
756 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
759 case G_AT_SERVER_REQUEST_TYPE_QUERY:
760 sprintf(buf, "+CMEE: %d", em->cmee_mode);
761 g_at_server_send_info(em->server, buf, TRUE);
762 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
765 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
766 /* HFP only support 0 and 1 */
767 sprintf(buf, "+CMEE: (0,1)");
768 g_at_server_send_info(em->server, buf, TRUE);
769 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
774 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
779 static void bia_cb(GAtServer *server, GAtServerRequestType type,
780 GAtResult *result, gpointer user_data)
782 struct ofono_emulator *em = user_data;
785 case G_AT_SERVER_REQUEST_TYPE_SET:
791 g_at_result_iter_init(&iter, result);
792 g_at_result_iter_next(&iter, "");
794 /* check validity of the request */
795 while (g_at_result_iter_next_number_default(&iter, 0, &val))
796 if (val != 0 && val != 1)
799 /* Check that we have no non-numbers in the stream */
800 if (g_at_result_iter_skip_next(&iter) == TRUE)
803 /* request is valid, update the indicator activation status */
804 g_at_result_iter_init(&iter, result);
805 g_at_result_iter_next(&iter, "");
807 for (l = em->indicators; l; l = l->next) {
808 struct indicator *ind = l->data;
810 if (g_at_result_iter_next_number_default(&iter,
811 ind->active, &val) == FALSE)
814 if (ind->mandatory == TRUE)
820 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
826 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
831 static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
832 int min, int max, int dflt,
835 struct indicator *ind;
837 ind = g_try_new0(struct indicator, 1);
839 ofono_error("Unable to allocate indicator structure");
843 ind->name = g_strdup(name);
848 ind->mandatory = mandatory;
850 em->indicators = g_slist_append(em->indicators, ind);
853 static void emulator_unregister(struct ofono_atom *atom)
855 struct ofono_emulator *em = __ofono_atom_get_data(atom);
860 if (em->callsetup_source) {
861 g_source_remove(em->callsetup_source);
862 em->callsetup_source = 0;
865 for (l = em->indicators; l; l = l->next) {
866 struct indicator *ind = l->data;
872 g_slist_free(em->indicators);
873 em->indicators = NULL;
875 g_at_ppp_unref(em->ppp);
878 if (em->pns_id > 0) {
879 __ofono_private_network_release(em->pns_id);
883 g_at_server_unref(em->server);
887 void ofono_emulator_register(struct ofono_emulator *em, int fd)
891 DBG("%p, %d", em, fd);
896 io = g_io_channel_unix_new(fd);
898 em->server = g_at_server_new(io);
899 if (em->server == NULL)
902 g_io_channel_unref(io);
904 g_at_server_set_debug(em->server, emulator_debug, "Server");
905 g_at_server_set_disconnect_function(em->server,
906 emulator_disconnect, em);
907 g_at_server_set_finish_callback(em->server, notify_deferred_indicators,
910 if (em->type == OFONO_EMULATOR_TYPE_HFP) {
911 emulator_add_indicator(em, OFONO_EMULATOR_IND_SERVICE, 0, 1, 0,
913 emulator_add_indicator(em, OFONO_EMULATOR_IND_CALL, 0, 1, 0,
915 emulator_add_indicator(em, OFONO_EMULATOR_IND_CALLSETUP, 0, 3,
917 emulator_add_indicator(em, OFONO_EMULATOR_IND_CALLHELD, 0, 2,
919 emulator_add_indicator(em, OFONO_EMULATOR_IND_SIGNAL, 0, 5, 0,
921 emulator_add_indicator(em, OFONO_EMULATOR_IND_ROAMING, 0, 1, 0,
923 emulator_add_indicator(em, OFONO_EMULATOR_IND_BATTERY, 0, 5, 5,
926 g_at_server_register(em->server, "+BRSF", brsf_cb, em, NULL);
927 g_at_server_register(em->server, "+CIND", cind_cb, em, NULL);
928 g_at_server_register(em->server, "+CMER", cmer_cb, em, NULL);
929 g_at_server_register(em->server, "+CLIP", clip_cb, em, NULL);
930 g_at_server_register(em->server, "+CCWA", ccwa_cb, em, NULL);
931 g_at_server_register(em->server, "+CMEE", cmee_cb, em, NULL);
932 g_at_server_register(em->server, "+BIA", bia_cb, em, NULL);
935 __ofono_atom_register(em->atom, emulator_unregister);
938 case OFONO_EMULATOR_TYPE_DUN:
939 g_at_server_register(em->server, "D", dial_cb, em, NULL);
940 g_at_server_register(em->server, "H", dun_ath_cb, em, NULL);
941 g_at_server_register(em->server, "O", dun_ato_cb, em, NULL);
943 case OFONO_EMULATOR_TYPE_HFP:
944 g_at_server_set_echo(em->server, FALSE);
951 static void emulator_remove(struct ofono_atom *atom)
953 struct ofono_emulator *em = __ofono_atom_get_data(atom);
955 DBG("atom: %p", atom);
960 struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
961 enum ofono_emulator_type type)
963 struct ofono_emulator *em;
964 enum ofono_atom_type atom_t;
966 DBG("modem: %p, type: %d", modem, type);
968 if (type == OFONO_EMULATOR_TYPE_DUN)
969 atom_t = OFONO_ATOM_TYPE_EMULATOR_DUN;
970 else if (type == OFONO_EMULATOR_TYPE_HFP)
971 atom_t = OFONO_ATOM_TYPE_EMULATOR_HFP;
975 em = g_try_new0(struct ofono_emulator, 1);
981 em->l_features |= HFP_AG_FEATURE_3WAY;
982 em->l_features |= HFP_AG_FEATURE_REJECT_CALL;
983 em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_STATUS;
984 em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_CONTROL;
985 em->l_features |= HFP_AG_FEATURE_EXTENDED_RES_CODE;
986 em->events_mode = 3; /* default mode is forwarding events */
987 em->cmee_mode = 0; /* CME ERROR disabled by default */
989 em->atom = __ofono_modem_add_atom_offline(modem, atom_t,
990 emulator_remove, em);
995 void ofono_emulator_remove(struct ofono_emulator *em)
997 __ofono_atom_free(em->atom);
1000 void ofono_emulator_send_final(struct ofono_emulator *em,
1001 const struct ofono_error *final)
1006 * TODO: Handle various CMEE modes and report error strings from
1009 switch (final->type) {
1010 case OFONO_ERROR_TYPE_CMS:
1011 sprintf(buf, "+CMS ERROR: %d", final->error);
1012 g_at_server_send_ext_final(em->server, buf);
1015 case OFONO_ERROR_TYPE_CME:
1016 switch (em->cmee_mode) {
1018 sprintf(buf, "+CME ERROR: %d", final->error);
1022 sprintf(buf, "+CME ERROR: %s",
1023 telephony_error_to_str(final));
1030 g_at_server_send_ext_final(em->server, buf);
1033 case OFONO_ERROR_TYPE_NO_ERROR:
1034 g_at_server_send_final(em->server, G_AT_SERVER_RESULT_OK);
1037 case OFONO_ERROR_TYPE_CEER:
1038 case OFONO_ERROR_TYPE_SIM:
1039 case OFONO_ERROR_TYPE_FAILURE:
1041 g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
1046 void ofono_emulator_send_unsolicited(struct ofono_emulator *em,
1049 g_at_server_send_unsolicited(em->server, result);
1052 void ofono_emulator_send_intermediate(struct ofono_emulator *em,
1055 g_at_server_send_intermediate(em->server, result);
1058 void ofono_emulator_send_info(struct ofono_emulator *em, const char *line,
1061 g_at_server_send_info(em->server, line, last);
1065 ofono_emulator_request_cb_t cb;
1067 ofono_destroy_func destroy;
1068 struct ofono_emulator *em;
1071 struct ofono_emulator_request {
1073 enum ofono_emulator_request_type type;
1076 static void handler_proxy(GAtServer *server, GAtServerRequestType type,
1077 GAtResult *result, gpointer userdata)
1079 struct handler *h = userdata;
1080 struct ofono_emulator_request req;
1082 if (h->em->type == OFONO_EMULATOR_TYPE_HFP && h->em->slc == FALSE) {
1083 g_at_server_send_final(h->em->server, G_AT_SERVER_RESULT_ERROR);
1088 case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
1089 req.type = OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY;
1091 case G_AT_SERVER_REQUEST_TYPE_SET:
1092 req.type = OFONO_EMULATOR_REQUEST_TYPE_SET;
1094 case G_AT_SERVER_REQUEST_TYPE_QUERY:
1095 req.type = OFONO_EMULATOR_REQUEST_TYPE_QUERY;
1097 case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
1098 req.type = OFONO_EMULATOR_REQUEST_TYPE_SUPPORT;
1101 g_at_result_iter_init(&req.iter, result);
1102 g_at_result_iter_next(&req.iter, "");
1104 h->cb(h->em, &req, h->data);
1107 static void handler_destroy(gpointer userdata)
1109 struct handler *h = userdata;
1112 h->destroy(h->data);
1117 ofono_bool_t ofono_emulator_add_handler(struct ofono_emulator *em,
1119 ofono_emulator_request_cb_t cb,
1120 void *data, ofono_destroy_func destroy)
1124 h = g_new0(struct handler, 1);
1127 h->destroy = destroy;
1130 if (g_at_server_register(em->server, prefix, handler_proxy, h,
1131 handler_destroy) == TRUE)
1139 ofono_bool_t ofono_emulator_remove_handler(struct ofono_emulator *em,
1142 return g_at_server_unregister(em->server, prefix);
1145 ofono_bool_t ofono_emulator_request_next_string(
1146 struct ofono_emulator_request *req,
1149 return g_at_result_iter_next_string(&req->iter, str);
1152 ofono_bool_t ofono_emulator_request_next_number(
1153 struct ofono_emulator_request *req,
1156 return g_at_result_iter_next_number(&req->iter, number);
1159 const char *ofono_emulator_request_get_raw(struct ofono_emulator_request *req)
1161 return g_at_result_iter_raw_line(&req->iter);
1164 enum ofono_emulator_request_type ofono_emulator_request_get_type(
1165 struct ofono_emulator_request *req)
1170 void ofono_emulator_set_indicator(struct ofono_emulator *em,
1171 const char *name, int value)
1175 struct indicator *ind;
1176 struct indicator *call_ind;
1177 struct indicator *cs_ind;
1182 ind = find_indicator(em, name, &i);
1184 if (ind == NULL || ind->value == value || value < ind->min
1185 || value > ind->max)
1190 call_ind = find_indicator(em, OFONO_EMULATOR_IND_CALL, NULL);
1191 cs_ind = find_indicator(em, OFONO_EMULATOR_IND_CALLSETUP, NULL);
1193 call = ind == call_ind;
1194 callsetup = ind == cs_ind;
1197 * When callsetup indicator goes to Incoming and there is an active
1198 * call a +CCWA should be sent before +CIEV
1200 waiting = (callsetup && value == OFONO_EMULATOR_CALLSETUP_INCOMING &&
1201 call_ind->value == OFONO_EMULATOR_CALL_ACTIVE);
1206 if (em->events_mode == 3 && em->events_ind && em->slc && ind->active) {
1207 if (!g_at_server_command_pending(em->server)) {
1208 sprintf(buf, "+CIEV: %d,%d", i, ind->value);
1209 g_at_server_send_unsolicited(em->server, buf);
1211 ind->deferred = TRUE;
1215 * Ring timer should be started when:
1216 * - callsetup indicator is set to Incoming and there is no active call
1217 * (not a waiting call)
1218 * - or call indicator is set to inactive while callsetup is already
1220 * In those cases, a first RING should be sent just after the +CIEV
1221 * Ring timer should be stopped for all other values of callsetup
1226 /* Call state went from active/held + waiting -> incoming */
1227 if (call && value == OFONO_EMULATOR_CALL_INACTIVE &&
1228 cs_ind->value == OFONO_EMULATOR_CALLSETUP_INCOMING)
1234 if (value != OFONO_EMULATOR_CALLSETUP_INCOMING) {
1235 if (em->callsetup_source > 0) {
1236 g_source_remove(em->callsetup_source);
1237 em->callsetup_source = 0;
1245 em->callsetup_source = g_timeout_add_seconds(RING_TIMEOUT,
1249 void __ofono_emulator_set_indicator_forced(struct ofono_emulator *em,
1250 const char *name, int value)
1253 struct indicator *ind;
1256 ind = find_indicator(em, name, &i);
1258 if (ind == NULL || value < ind->min || value > ind->max)
1263 if (em->events_mode == 3 && em->events_ind && em->slc && ind->active) {
1264 if (!g_at_server_command_pending(em->server)) {
1265 sprintf(buf, "+CIEV: %d,%d", i, ind->value);
1266 g_at_server_send_unsolicited(em->server, buf);
1268 ind->deferred = TRUE;