Hi Denis,

On Fri, Apr 26, 2013 at 9:39 AM, Denis Kenzior <denkenz@gmail.com> wrote:
Hi Paulo,


On 04/26/2013 12:53 PM, Paulo Borges wrote:
Hi Denis,

On Thu, Apr 25, 2013 at 2:58 PM, Denis Kenzior <denkenz@gmail.com
<mailto:denkenz@gmail.com>> wrote:

    Hi Paulo,


    On 04/25/2013 02:09 PM, Paulo Borges wrote:

        ---
           src/emulator.c |   31 ++++++++++++++++++++++++++++++__-

           1 file changed, 30 insertions(+), 1 deletion(-)

        diff --git a/src/emulator.c b/src/emulator.c
        index 8ac79d5..5027b02 100644
        --- a/src/emulator.c
        +++ b/src/emulator.c
        @@ -45,6 +45,8 @@

           #define RING_TIMEOUT 3

        +#define HFP_16_AG_DRIVER "hfp16-ag-driver"
        +
           struct ofono_emulator {
                 struct ofono_atom *atom;
                 enum ofono_emulator_type type;
        @@ -1007,6 +1009,32 @@ struct ofono_emulator
        *ofono_emulator_create(struct ofono_modem *modem,
                 return em;
           }

        +static int hfp16_card_probe(struct ofono_handsfree_card *card,
        +                                       unsigned int vendor,
        void *data)
        +{
        +       DBG("HFP 1.6 AG card driver probe");
        +
        +       return 0;
        +}
        +
        +static void hfp16_card_remove(struct ofono_handsfree_card *card)
        +{
        +       DBG("HFP 1.6 AG card driver remove");
        +}
        +
        +static void hfp16_card_connect(struct ofono_handsfree_card *card,
        +                       ofono_handsfree_card_connect___cb_t cb,

        void *data)
        +{
        +       DBG("HFP 1.6 AG card driver connect");
        +}
        +
        +static struct ofono_handsfree_card_driver hfp16_ag_driver = {
        +       .name           = HFP_16_AG_DRIVER,
        +       .probe          = hfp16_card_probe,
        +       .remove         = hfp16_card_remove,
        +       .connect        = hfp16_card_connect,
        +};
        +


    So why do we need this exactly?  There is already a default
    implementation inside handsfree_audio_card if the driver is NULL.
      How is this going to be different from the default implementation?


           static int card_set_local_remote(struct ofono_handsfree_card
        *card, int fd)
           {
                 struct sockaddr_rc saddr;
        @@ -1338,9 +1366,10 @@ void
        __ofono_emulator_set___indicator_forced(struct ofono_emulator *em,


           int __ofono_emulator_init(void)
           {
        -       return 0;
        +       return
        ofono_handsfree_card_driver___register(&hfp16_ag_driver);
           }

           void __ofono_emulator_cleanup(void)
           {
        +       ofono_handsfree_card_driver___unregister(&hfp16_ag_driver);

           }


    Regards,
    -Denis


When both roles support codec negotiation feature AG must first send an
unsolicited +BCS and only call the default implementation after HF
respond with AT+BCS [1].

[1] HFP 1.6 spec page 31: 4.11.3 "Codec Connection Setup".


This is where the spec is a bit fuzzy.  There is some room for interpretation on the timing of the codec negotiation exchange.

Can we do the codec negotiation before hand, not as part of the .connect implementation?  e.g. can we negotiate the codec right after SLC establishment and from then on simply establish the SCO link, or must we always perform codec negotiation right before the SCO link establishment?

Regards,
-Denis

Yes, we can negotiate the codec after an incoming AT+BAC command from HF. This way, we can ensure that the chosen codec is valid and we don't need to use a card driver.

I'll change this and send a new version.

--
Cheers,
Paulo.