Hi! Droid 4 has ... something similar to AT commands, but not quite. For voice calls, I modified atmodem... but I guess there are so many changes that creating separate motorolamodem/voicecall.c might be an option? (send_clcc() changes make sense as a cleanup, and were sent in separate mail.)
Any ideas?
Best regards,
Pavel
diff --git a/drivers/atmodem/voicecall.c b/drivers/atmodem/voicecall.c
index d55cf00..e22d412 100644
--- a/drivers/atmodem/voicecall.c
+++ b/drivers/atmodem/voicecall.c
@@ -1,4 +1,4 @@
-/*
+/* -*- linux-c -*-
*
* oFono - Open Source Telephony
*
@@ -264,14 +264,18 @@ poll_again:
poll_clcc, vc);
}
+static void send_clcc(struct voicecall_data *vd, struct ofono_voicecall *vc)
+{
+ if (vd->vendor != OFONO_VENDOR_MOTMDM)
+ g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix, clcc_poll_cb, vc,
NULL);
+}
+
static gboolean poll_clcc(gpointer user_data)
{
struct ofono_voicecall *vc = user_data;
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, vc, NULL);
-
+ send_clcc(vd, vc);
vd->clcc_source = 0;
return FALSE;
@@ -297,8 +301,7 @@ static void generic_cb(gboolean ok, GAtResult *result,
gpointer user_data)
}
}
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, req->vc, NULL);
+ send_clcc(vd, req->vc);
/* We have to callback after we schedule a poll if required */
req->cb(&error, req->data);
@@ -316,8 +319,7 @@ static void release_id_cb(gboolean ok, GAtResult *result,
if (ok)
vd->local_release = 1 << req->id;
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, req->vc, NULL);
+ send_clcc(vd, req->vc);
/* We have to callback after we schedule a poll if required */
req->cb(&error, req->data);
@@ -408,16 +410,17 @@ static void at_dial(struct ofono_voicecall *vc,
switch (clir) {
case OFONO_CLIR_OPTION_INVOCATION:
- strcat(buf, "I");
+ strcat(buf, (vd->vendor != OFONO_VENDOR_MOTMDM) ? "I" : ",0");
break;
case OFONO_CLIR_OPTION_SUPPRESSION:
- strcat(buf, "i");
+ strcat(buf, (vd->vendor != OFONO_VENDOR_MOTMDM) ? "i" : ",1");
break;
default:
break;
}
- strcat(buf, ";");
+ if (vd->vendor != OFONO_VENDOR_MOTMDM)
+ strcat(buf, ";");
if (g_at_chat_send(vd->chat, buf, atd_prefix,
atd_cb, cbd, g_free) > 0)
@@ -462,8 +465,13 @@ static void at_answer(struct ofono_voicecall *vc,
static void at_hangup(struct ofono_voicecall *vc,
ofono_voicecall_cb_t cb, void *data)
{
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+
/* Hangup active call */
- at_template("AT+CHUP", vc, generic_cb, 0x3f, cb, data);
+ if (vd->vendor != OFONO_VENDOR_MOTMDM)
+ at_template("AT+CHUP", vc, generic_cb, 0x3f, cb, data);
+ else
+ at_template("ATH", vc, generic_cb, 0x3f, cb, data);
}
static void clcc_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -745,6 +753,8 @@ static void clip_notify(GAtResult *result, gpointer
user_data)
GSList *l;
struct ofono_call *call;
+ printf("got clip, searching for incoming calls\n");
+
l = g_slist_find_custom(vd->calls,
GINT_TO_POINTER(CALL_STATUS_INCOMING),
at_util_call_compare_by_status);
@@ -759,7 +769,10 @@ static void clip_notify(GAtResult *result, gpointer
user_data)
g_at_result_iter_init(&iter, result);
- if (!g_at_result_iter_next(&iter, "+CLIP:"))
+ printf("Got clip...\n");
+
+ if (/* !g_at_result_iter_next(&iter, "+CLIP:") && */
+ !g_at_result_iter_next(&iter, "~+CLIP="))
return;
if (!g_at_result_iter_next_string(&iter, &num))
@@ -962,8 +975,7 @@ static void no_carrier_notify(GAtResult *result, gpointer
user_data)
struct ofono_voicecall *vc = user_data;
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, vc, NULL);
+ send_clcc(vd, vc);
}
static void no_answer_notify(GAtResult *result, gpointer user_data)
@@ -971,8 +983,7 @@ static void no_answer_notify(GAtResult *result, gpointer
user_data)
struct ofono_voicecall *vc = user_data;
struct voicecall_data *vd = ofono_voicecall_get_data(vc);
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, vc, NULL);
+ send_clcc(vd, vc);
}
static void busy_notify(GAtResult *result, gpointer user_data)
@@ -984,8 +995,7 @@ static void busy_notify(GAtResult *result, gpointer
user_data)
* or UDUB on the other side
* TODO: Handle UDUB or other conditions somehow
*/
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix,
- clcc_poll_cb, vc, NULL);
+ send_clcc(vd, vc);
}
static void cssi_notify(GAtResult *result, gpointer user_data)
@@ -1063,6 +1073,61 @@ static void vtd_query_cb(gboolean ok, GAtResult *result,
gpointer user_data)
vd->tone_duration = duration * 100;
}
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_voicecall *vc = user_data;
+ struct voicecall_data *vd = ofono_voicecall_get_data(vc);
+ int strength, ind;
+ GAtResultIter iter;
+ struct ofono_call *call;
+ enum ofono_disconnect_reason reason;
+
+ g_at_result_iter_init(&iter, result);
+
+ printf("Got ciev...\n");
+ if (!g_at_result_iter_next(&iter, "~+CIEV="))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &ind))
+ return;
+
+ if (ind != 1)
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &strength))
+ return;
+
+ printf("Got ciev 1,%d...: \n", strength);
+
+ switch (strength) {
+ case 7: /* outgoing call starts */
+ printf("Outgoing notification, but ATD should have created it
for us\n");
+ break;
+ case 4: /* call incoming ringing */
+ printf("Call ringing\n");
+ call = create_call(vc, 9, 1, CALL_STATUS_INCOMING, NULL, 128,
2);
+ if (call == NULL) {
+ ofono_error("Couldn't create call, call management is
fubar!");
+ return;
+ }
+ call->type = 0;
+ vd->flags = FLAG_NEED_CLIP;
+ /* FIXME: we should really do that at +CLIP callback .. when
that works */
+ //ofono_voicecall_notify(vc, call);
+ break;
+ case 0: /* call ends */
+ call = vd->calls->data;
+
+ reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
+ if (!call->type)
+ ofono_voicecall_disconnected(vc, call->id, reason,
NULL);
+
+ printf("Call ends\n"); break;
+ }
+}
+
+
static void at_voicecall_initialized(gboolean ok, GAtResult *result,
gpointer user_data)
{
@@ -1074,6 +1139,9 @@ static void at_voicecall_initialized(gboolean ok,
GAtResult *result,
g_at_chat_register(vd->chat, "RING", ring_notify, FALSE, vc, NULL);
g_at_chat_register(vd->chat, "+CRING:", cring_notify, FALSE, vc, NULL);
g_at_chat_register(vd->chat, "+CLIP:", clip_notify, FALSE, vc, NULL);
+ g_at_chat_register(vd->chat, "~+CLIP=", clip_notify, FALSE, vc, NULL);
+ g_at_chat_register(vd->chat, "~+CIEV=", ciev_notify, FALSE, vc, NULL);
+
g_at_chat_register(vd->chat, "+CDIP:", cdip_notify, FALSE, vc, NULL);
g_at_chat_register(vd->chat, "+CNAP:", cnap_notify, FALSE, vc, NULL);
g_at_chat_register(vd->chat, "+CCWA:", ccwa_notify, FALSE, vc, NULL);
@@ -1093,7 +1161,8 @@ static void at_voicecall_initialized(gboolean ok,
GAtResult *result,
ofono_voicecall_register(vc);
/* Populate the call list */
- g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix, clcc_cb, vc, NULL);
+ if (vd->vendor != OFONO_VENDOR_MOTMDM)
+ g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix, clcc_cb, vc,
NULL);
}
static int at_voicecall_probe(struct ofono_voicecall *vc, unsigned int vendor,
@@ -1112,12 +1181,18 @@ static int at_voicecall_probe(struct ofono_voicecall
*vc, unsigned int vendor,
ofono_voicecall_set_data(vc, vd);
- g_at_chat_send(vd->chat, "AT+CRC=1", NULL, NULL, NULL, NULL);
+ if (vd->vendor != OFONO_VENDOR_MOTMDM) {
+ g_at_chat_send(vd->chat, "AT+CRC=1", NULL, NULL, NULL, NULL);
+ }
g_at_chat_send(vd->chat, "AT+CLIP=1", NULL, NULL, NULL, NULL);
- g_at_chat_send(vd->chat, "AT+CDIP=1", NULL, NULL, NULL, NULL);
- g_at_chat_send(vd->chat, "AT+CNAP=1", NULL, NULL, NULL, NULL);
+ if (vd->vendor != OFONO_VENDOR_MOTMDM) {
+ g_at_chat_send(vd->chat, "AT+CDIP=1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(vd->chat, "AT+CNAP=1", NULL, NULL, NULL, NULL);
+ }
switch (vd->vendor) {
+ case OFONO_VENDOR_MOTMDM:
+ break;
case OFONO_VENDOR_QUALCOMM_MSM:
case OFONO_VENDOR_SIMCOM:
g_at_chat_send(vd->chat, "AT+COLP=0", NULL, NULL, NULL, NULL);
@@ -1127,9 +1202,11 @@ static int at_voicecall_probe(struct ofono_voicecall
*vc, unsigned int vendor,
break;
}
- g_at_chat_send(vd->chat, "AT+CSSN=1,1", NULL, NULL, NULL, NULL);
- g_at_chat_send(vd->chat, "AT+VTD?", NULL,
- vtd_query_cb, vc, NULL);
+ if (vd->vendor != OFONO_VENDOR_MOTMDM) {
+ g_at_chat_send(vd->chat, "AT+CSSN=1,1", NULL, NULL, NULL, NULL);
+ g_at_chat_send(vd->chat, "AT+VTD?", NULL,
+ vtd_query_cb, vc, NULL);
+ }
g_at_chat_send(vd->chat, "AT+CCWA=1", NULL,
at_voicecall_initialized, vc, NULL);
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures)
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
signature.asc
Description: Digital signature
_______________________________________________ ofono mailing list [email protected] https://lists.ofono.org/mailman/listinfo/ofono
