Hi Pekka,

On 11/16/2010 11:05 AM, pekka.pe...@nokia.com wrote:
> From: Pekka Pessi <pekka.pe...@nokia.com>
> 
> Report early incoming calls as waiting or incoming, depending on the
> state of other calls.
> 
> Report MT_RELEASED or MO_RELEASED via ofono_voicecall_notify(),
> TERMINATED calls via ofono_voicecall_disconnected().
> ---
>  drivers/isimodem/voicecall.c |  401 
> +++++++++++++++++++++---------------------
>  1 files changed, 203 insertions(+), 198 deletions(-)
> 
> diff --git a/drivers/isimodem/voicecall.c b/drivers/isimodem/voicecall.c
> index c3365f6..c450f12 100644
> --- a/drivers/isimodem/voicecall.c
> +++ b/drivers/isimodem/voicecall.c
> @@ -62,13 +62,6 @@ struct isi_voicecall {
>  
>  /* ------------------------------------------------------------------------- 
> */
>  
> -static void isi_call_notify(struct ofono_voicecall *ovc,
> -                             struct isi_call *call);
> -static void isi_call_release(struct ofono_voicecall *, struct isi_call *);
> -static struct ofono_call isi_call_as_ofono_call(struct isi_call const *);
> -static int isi_call_status_to_clcc(struct isi_call const *call);
> -static struct isi_call *isi_call_set_idle(struct isi_call *call);
> -
>  typedef void GIsiIndication(GIsiClient *client,
>               const void *restrict data, size_t len,
>               uint16_t object, void *opaque);
> @@ -80,9 +73,6 @@ typedef gboolean GIsiResponse(GIsiClient *client,
>                               void const *restrict data, size_t len,
>                               uint16_t object, void *opaque);
>  
> -static GIsiVerify isi_call_verify_cb;
> -static gboolean isi_call_register(gpointer);
> -
>  enum {
>       ISI_CALL_TIMEOUT = 1000,
>  };
> @@ -205,6 +195,174 @@ static gboolean isi_ctx_return_success(struct 
> isi_call_req_context *irc)
>  }
>  
>  /* ------------------------------------------------------------------------- 
> */
> +/* Notify */
> +
> +enum clcc_status {
> +     CLCC_STATUS_ACTIVE = 0,
> +     CLCC_STATUS_HOLD = 1,
> +     CLCC_STATUS_DIALING = 2,
> +     CLCC_STATUS_ALERTING = 3,
> +     CLCC_STATUS_INCOMING = 4,
> +     CLCC_STATUS_WAITING = 5,
> +     CLCC_STATUS_DISCONNECTED = 6, /* Nonstandard */
> +};

Please follow M11 completely here, particularly the tabs before the values.

> +
> +static int isi_call_waiting_or_incoming(struct isi_voicecall const *ivc)
> +{
> +     int id;
> +
> +     for (id = 1; id <= 7; id++) {
> +             switch (ivc->calls[id].status) {
> +             case CALL_STATUS_ANSWERED:
> +             case CALL_STATUS_ACTIVE:
> +             case CALL_STATUS_HOLD_INITIATED:
> +             case CALL_STATUS_HOLD:
> +             case CALL_STATUS_RETRIEVE_INITIATED:
> +             case CALL_STATUS_RECONNECT_PENDING:
> +             case CALL_STATUS_SWAP_INITIATED:
> +                     return CLCC_STATUS_WAITING;
> +             }
> +     }
> +
> +     return CLCC_STATUS_INCOMING;
> +}
> +
> +/** Get +CLCC status */
> +static int isi_call_status_to_clcc(struct isi_voicecall const *ivc,
> +                                     struct isi_call const *call)
> +{
> +     switch (call->status) {
> +     case CALL_STATUS_CREATE:
> +             return CLCC_STATUS_DIALING;
> +
> +     case CALL_STATUS_COMING:
> +             return isi_call_waiting_or_incoming(ivc);
> +
> +     case CALL_STATUS_PROCEEDING:
> +             if ((call->mode_info & CALL_MODE_ORIGINATOR))
> +                     return isi_call_waiting_or_incoming(ivc); /* MT */
> +             else
> +                     return CLCC_STATUS_DIALING; /* MO */
> +
> +     case CALL_STATUS_MO_ALERTING:
> +             return CLCC_STATUS_ALERTING;
> +
> +     case CALL_STATUS_MT_ALERTING:
> +             return CLCC_STATUS_INCOMING;
> +
> +     case CALL_STATUS_WAITING:
> +             return CLCC_STATUS_WAITING;
> +
> +     case CALL_STATUS_ANSWERED:
> +     case CALL_STATUS_ACTIVE:
> +     case CALL_STATUS_HOLD_INITIATED:
> +     case CALL_STATUS_RECONNECT_PENDING:
> +     case CALL_STATUS_SWAP_INITIATED:
> +             return CLCC_STATUS_ACTIVE;
> +
> +     case CALL_STATUS_HOLD:
> +     case CALL_STATUS_RETRIEVE_INITIATED:
> +             return CLCC_STATUS_HOLD;
> +
> +     case CALL_STATUS_MO_RELEASE:
> +     case CALL_STATUS_MT_RELEASE:
> +     case CALL_STATUS_TERMINATED:
> +     case CALL_STATUS_IDLE:
> +             return CLCC_STATUS_DISCONNECTED;
> +     }
> +
> +     return CLCC_STATUS_ACTIVE;
> +}
> +
> +static struct ofono_call isi_call_as_ofono_call(struct isi_voicecall const 
> *ivc,
> +                                             struct isi_call const *call)
> +{
> +     struct ofono_call ocall = { call->id };
> +     struct ofono_phone_number *number = &ocall.phone_number;
> +
> +     ocall.type = 0; /* Voice call */
> +     ocall.direction = call->mode_info & CALL_MODE_ORIGINATOR;
> +     ocall.status = isi_call_status_to_clcc(ivc, call);
> +     memcpy(number->number, call->address, sizeof number->number);

Please watch out for the sizeof usage.

> +     number->type = 0x80 | call->addr_type;
> +     ocall.clip_validity = call->presentation & 3;
> +
> +     if (ocall.clip_validity == 0 && strlen(number->number) == 0)
> +             ocall.clip_validity = 2;
> +
> +     return ocall;
> +}
> +
> +static struct isi_call *isi_call_set_idle(struct isi_call *call)
> +{
> +     uint8_t id;
> +
> +     id = call->id;
> +     memset(call, 0, sizeof *call);

sizeof use again

> +     call->id = id;
> +
> +     return call;
> +}
> +
> +static void isi_call_disconnected(struct ofono_voicecall *ovc,
> +                                     struct isi_call *call)
> +{
> +     struct ofono_error error = { OFONO_ERROR_TYPE_NO_ERROR, 0 };
> +     enum ofono_disconnect_reason reason = call->reason;
> +
> +     if (!reason)
> +             reason = OFONO_DISCONNECT_REASON_ERROR;
> +
> +     DBG("disconnected id=%u reason=%u", call->id, reason);
> +     ofono_voicecall_disconnected(ovc, call->id, reason, &error);
> +     isi_call_set_idle(call);
> +}
> +
> +static void isi_call_notify(struct ofono_voicecall *ovc,
> +                             struct isi_call *call)
> +{
> +     struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
> +     struct isi_call_req_context *irc, **queue;
> +     struct ofono_call ocall;
> +
> +     DBG("called with status=%s (0x%02X)",
> +             call_status_name(call->status), call->status);
> +
> +     for (queue = &ivc->queue; (irc = *queue);) {
> +             irc->step(irc, call->status);
> +
> +             if (*queue == irc)
> +                     queue = &irc->next;
> +     }
> +
> +     ocall = isi_call_as_ofono_call(ivc, call);
> +
> +     DBG("id=%u,\"%s\",%u,\"%s\",%u,%u",
> +             ocall.id,
> +             ocall.direction ? "mt" : "mo",
> +             ocall.status,
> +             ocall.phone_number.number,
> +             ocall.phone_number.type,
> +             ocall.clip_validity);
> +
> +     ofono_voicecall_notify(ovc, &ocall);
> +
> +     switch (call->status) {
> +     case CALL_STATUS_MO_RELEASE:
> +             call->reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
> +             break;
> +
> +     case CALL_STATUS_MT_RELEASE:
> +             call->reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
> +             break;
> +
> +     case CALL_STATUS_IDLE:
> +     case CALL_STATUS_TERMINATED:
> +             isi_call_disconnected(ovc, call);

Is the break statement missing here?

> +     }
> +}
> +
> +/* ------------------------------------------------------------------------- 
> */
>  /* Decoding subblocks */
>  
>  static void isi_call_any_address_sb_proc(struct isi_voicecall *ivc,
> @@ -491,16 +649,8 @@ static void isi_call_status_ind_cb(GIsiClient *client,
>               }
>       }
>  
> -     if (old != call->status) {
> -             if (call->status == CALL_STATUS_IDLE) {
> -                     call->status = CALL_STATUS_TERMINATED;
> -                     isi_call_notify(ovc, call);
> -                     isi_call_set_idle(call);
> -                     return;
> -             }
> -     }
> -
> -     isi_call_notify(ovc, call);
> +     if (old != call->status)
> +             isi_call_notify(ovc, call);
>  }
>  
>  static struct isi_call_req_context *
> @@ -801,150 +951,6 @@ static gboolean isi_call_dtmf_send_resp(GIsiClient 
> *client,
>               return isi_ctx_return_failure(irc);
>  }
>  
> -
> -/* ------------------------------------------------------------------------- 
> */
> -/* Notify */
> -
> -static void isi_call_notify(struct ofono_voicecall *ovc,
> -                             struct isi_call *call)
> -{
> -     struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
> -     struct isi_call_req_context *irc, **queue;
> -     struct ofono_call ocall;
> -
> -     DBG("called with status=%s (0x%02X)",
> -             call_status_name(call->status), call->status);
> -
> -     for (queue = &ivc->queue; (irc = *queue);) {
> -             irc->step(irc, call->status);
> -             if (*queue == irc)
> -                     queue = &irc->next;
> -     }
> -
> -     switch (call->status) {
> -     case CALL_STATUS_IDLE:
> -     case CALL_STATUS_MO_RELEASE:
> -     case CALL_STATUS_MT_RELEASE:
> -     case CALL_STATUS_TERMINATED:
> -             isi_call_release(ovc, call);
> -             return;
> -     }
> -
> -     ocall = isi_call_as_ofono_call(call);
> -
> -     DBG("id=%u,%s,%u,\"%s\",%u,%u",
> -             ocall.id,
> -             ocall.direction ? "terminated" : "originated",
> -             ocall.status,
> -             ocall.phone_number.number,
> -             ocall.phone_number.type,
> -             ocall.clip_validity);
> -
> -     ofono_voicecall_notify(ovc, &ocall);
> -}
> -
> -static void isi_call_release(struct ofono_voicecall *ovc,
> -                             struct isi_call *call)
> -{
> -     struct ofono_error error = { OFONO_ERROR_TYPE_NO_ERROR, 0 };
> -     enum ofono_disconnect_reason reason;
> -
> -     switch (call->status) {
> -     case CALL_STATUS_IDLE:
> -             reason = OFONO_DISCONNECT_REASON_UNKNOWN;
> -             break;
> -     case CALL_STATUS_MO_RELEASE:
> -             reason = OFONO_DISCONNECT_REASON_LOCAL_HANGUP;
> -             break;
> -     case CALL_STATUS_MT_RELEASE:
> -             reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP;
> -             break;
> -     case CALL_STATUS_TERMINATED:
> -     default:
> -             reason = OFONO_DISCONNECT_REASON_ERROR;
> -             break;
> -     }
> -
> -     if (!call->reason) {
> -             call->reason = reason;
> -             DBG("disconnected id=%u reason=%u", call->id, reason);
> -             ofono_voicecall_disconnected(ovc, call->id, reason, &error);
> -     }
> -
> -     if (!reason)
> -             isi_call_set_idle(call);
> -}
> -
> -static struct ofono_call isi_call_as_ofono_call(struct isi_call const *call)
> -{
> -     struct ofono_call ocall = { call->id };
> -     struct ofono_phone_number *number = &ocall.phone_number;
> -
> -     ocall.type = 0; /* Voice call */
> -     ocall.direction = call->mode_info & CALL_MODE_ORIGINATOR;
> -     ocall.status = isi_call_status_to_clcc(call);
> -     memcpy(number->number, call->address, sizeof number->number);
> -     number->type = 0x80 | call->addr_type;
> -     ocall.clip_validity = call->presentation & 3;
> -     if (ocall.clip_validity == 0 && strlen(number->number) == 0)
> -             ocall.clip_validity = 2;
> -
> -     return ocall;
> -}
> -
> -/** Get +CLCC status */
> -static int isi_call_status_to_clcc(struct isi_call const *call)
> -{
> -     switch (call->status) {
> -     case CALL_STATUS_CREATE:
> -             return 2;
> -     case CALL_STATUS_COMING:
> -             return 4;
> -     case CALL_STATUS_PROCEEDING:
> -             if ((call->mode_info & CALL_MODE_ORIGINATOR))
> -                     return 4; /* MT */
> -             else
> -                     return 2; /* MO */
> -     case CALL_STATUS_MO_ALERTING:
> -             return 3;
> -     case CALL_STATUS_MT_ALERTING:
> -             return 4;
> -     case CALL_STATUS_WAITING:
> -             return 5;
> -
> -     case CALL_STATUS_ANSWERED:
> -     case CALL_STATUS_ACTIVE:
> -     case CALL_STATUS_MO_RELEASE:
> -     case CALL_STATUS_MT_RELEASE:
> -     case CALL_STATUS_HOLD_INITIATED:
> -             return 0;
> -
> -     case CALL_STATUS_HOLD:
> -     case CALL_STATUS_RETRIEVE_INITIATED:
> -             return 1;
> -
> -     case CALL_STATUS_RECONNECT_PENDING:
> -     case CALL_STATUS_TERMINATED:
> -     case CALL_STATUS_SWAP_INITIATED:
> -             return 0;
> -     }
> -
> -     return 0;
> -}
> -
> -static struct isi_call *isi_call_set_idle(struct isi_call *call)
> -{
> -     uint8_t id;
> -
> -     if (call) {
> -             id = call->id;
> -             memset(call, 0, sizeof *call);
> -             call->id = id;
> -     }
> -
> -     return call;
> -}
> -
>  /* ---------------------------------------------------------------------- */
>  
>  static void isi_dial(struct ofono_voicecall *ovc,
> @@ -1244,31 +1250,27 @@ static void isi_send_tones(struct ofono_voicecall 
> *ovc, const char *tones,
>       isi_call_dtmf_send_req(ovc, CALL_ID_ALL, tones, cb, data);;
>  }
>  
> -static int isi_voicecall_probe(struct ofono_voicecall *ovc,
> -                             unsigned int vendor, void *user)
> +static gboolean isi_call_register(gpointer _ovc)
>  {
> -     GIsiModem *idx = user;
> -     struct isi_voicecall *ivc = g_try_new0(struct isi_voicecall, 1);
> -     int id;
> -
> -     if (!ivc)
> -             return -ENOMEM;
> +     struct ofono_voicecall *ovc = _ovc;
> +     struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
> +     const char *debug = getenv("OFONO_ISI_DEBUG");
>  
> -     for (id = 0; id <= 7; id++)
> -             ivc->calls[id].id = id;
> +     if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "call") == 0))
> +             g_isi_client_set_debug(ivc->client, call_debug, NULL);
>  
> -     ivc->client = g_isi_client_create(idx, PN_CALL);
> -     if (!ivc->client) {
> -             g_free(ivc);
> -             return -ENOMEM;
> -     }
> +     g_isi_subscribe(ivc->client,
> +                     CALL_STATUS_IND, isi_call_status_ind_cb,
> +                     ovc);
>  
> -     ofono_voicecall_set_data(ovc, ivc);
> +     if (!isi_call_status_req(ovc, CALL_ID_ALL,
> +                                     CALL_STATUS_MODE_ADDR_AND_ORIGIN,
> +                                     NULL, NULL))
> +             DBG("Failed to request call status");
>  
> -     if (!g_isi_verify(ivc->client, isi_call_verify_cb, ovc))
> -             DBG("Unable to verify reachability");
> +     ofono_voicecall_register(ovc);
>  
> -     return 0;
> +     return FALSE;
>  }
>  
>  static void isi_call_verify_cb(GIsiClient *client,
> @@ -1287,28 +1289,31 @@ static void isi_call_verify_cb(GIsiClient *client,
>       g_idle_add(isi_call_register, ovc);
>  }
>  
> -static gboolean isi_call_register(gpointer _ovc)
> +static int isi_voicecall_probe(struct ofono_voicecall *ovc,
> +                             unsigned int vendor, void *user)
>  {
> -     struct ofono_voicecall *ovc = _ovc;
> -     struct isi_voicecall *ivc = ofono_voicecall_get_data(ovc);
> +     GIsiModem *idx = user;
> +     struct isi_voicecall *ivc = g_try_new0(struct isi_voicecall, 1);
> +     int id;
>  
> -     const char *debug = getenv("OFONO_ISI_DEBUG");
> +     if (!ivc)
> +             return -ENOMEM;
>  
> -     if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "call") == 0))
> -             g_isi_client_set_debug(ivc->client, call_debug, NULL);
> +     for (id = 1; id <= 7; id++)
> +             ivc->calls[id].id = id;
>  
> -     g_isi_subscribe(ivc->client,
> -                     CALL_STATUS_IND, isi_call_status_ind_cb,
> -                     ovc);
> +     ivc->client = g_isi_client_create(idx, PN_CALL);
> +     if (!ivc->client) {
> +             g_free(ivc);
> +             return -ENOMEM;
> +     }
>  
> -     if (!isi_call_status_req(ovc, CALL_ID_ALL,
> -                                     CALL_STATUS_MODE_ADDR_AND_ORIGIN,
> -                                     NULL, NULL))
> -             DBG("Failed to request call status");
> +     ofono_voicecall_set_data(ovc, ivc);
>  
> -     ofono_voicecall_register(ovc);
> +     if (!g_isi_verify(ivc->client, isi_call_verify_cb, ovc))
> +             DBG("Unable to verify reachability");
>  
> -     return FALSE;
> +     return 0;
>  }
>  
>  static void isi_voicecall_remove(struct ofono_voicecall *call)

Regards,
-Denis
_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to