Skip to content

Commit 5dd3036

Browse files
lylezhu2012kartben
authored andcommitted
Bluetooth: HFP_HF: Query subscriber number
Add function `bt_hfp_hf_query_subscriber` to query the AG subscriber number. Add callback `subscriber_number` to notify the result of the query of the subscriber number information. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 1e4c740 commit 5dd3036

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

include/zephyr/bluetooth/classic/hfp_hf.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,39 @@ struct bt_hfp_hf_cb {
383383
* @param number Value of `<Phone number>`.
384384
*/
385385
void (*request_phone_number)(struct bt_hfp_hf *hf, const char *number);
386+
387+
/** Query subscriber number callback
388+
*
389+
* If this callback is provided it will be called whenever the
390+
* result code `+CUNM: [<alpha>],<number>, <type>,[<speed> ,<service>]`
391+
* is received from AG.
392+
* `<alpha>`: This optional field is not supported, and shall be left
393+
* blank.
394+
* `<number>`: Quoted string containing the phone number in the format
395+
* specified by `<type>`.
396+
* `<type>` field specifies the format of the phone number provided,
397+
* and can be one of the following values:
398+
* - values 128-143: The phone number format may be a national or
399+
* international format, and may contain prefix and/or escape digits.
400+
* No changes on the number presentation are required.
401+
* - values 144-159: The phone number format is an international
402+
* number, including the country code prefix. If the plus sign ("+")
403+
* is not included as part of the number and shall be added by the AG
404+
* as needed.
405+
* - values 160-175: National number. No prefix nor escape digits
406+
* included.
407+
* `<speed>`: This optional field is not supported, and shall be left
408+
* blank.
409+
* `<service>`: Indicates which service this phone number relates to.
410+
* Shall be either 4 (voice) or 5 (fax).
411+
*
412+
* @param hf HFP HF object.
413+
* @param number Value of `<number>` without quotes.
414+
* @param type Value of `<type>`.
415+
* @param service Value of `<service>`.
416+
*/
417+
void (*subscriber_number)(struct bt_hfp_hf *hf, const char *number, uint8_t type,
418+
uint8_t service);
386419
};
387420

388421
/** @brief Register HFP HF profile
@@ -805,6 +838,16 @@ int bt_hfp_hf_request_phone_number(struct bt_hfp_hf *hf);
805838
*/
806839
int bt_hfp_hf_transmit_dtmf_code(struct bt_hfp_hf_call *call, char code);
807840

841+
/** @brief Handsfree HF Query Subscriber Number Information
842+
*
843+
* It allows HF to query the AG subscriber number by sending `AT+CNUM`.
844+
*
845+
* @param hf HFP HF object.
846+
*
847+
* @return 0 in case of success or negative value in case of error.
848+
*/
849+
int bt_hfp_hf_query_subscriber(struct bt_hfp_hf *hf);
850+
808851
#ifdef __cplusplus
809852
}
810853
#endif

subsys/bluetooth/host/classic/hfp_hf.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,45 @@ int chld_handle(struct at_client *hf_at)
16031603
}
16041604
#endif /* CONFIG_BT_HFP_HF_3WAY_CALL */
16051605

1606+
static int cnum_handle(struct at_client *hf_at)
1607+
{
1608+
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
1609+
int err;
1610+
char *alpha;
1611+
char *number;
1612+
uint32_t type;
1613+
char *speed;
1614+
uint32_t service = 4;
1615+
1616+
alpha = at_get_raw_string(hf_at, NULL);
1617+
number = at_get_string(hf_at);
1618+
if (!number) {
1619+
LOG_INF("Cannot get number");
1620+
return -EINVAL;
1621+
}
1622+
1623+
err = at_get_number(hf_at, &type);
1624+
if (err) {
1625+
LOG_INF("Cannot get type");
1626+
return -EINVAL;
1627+
}
1628+
1629+
speed = at_get_raw_string(hf_at, NULL);
1630+
1631+
err = at_get_number(hf_at, &service);
1632+
if (err) {
1633+
LOG_INF("Cannot get service");
1634+
}
1635+
1636+
if (bt_hf->subscriber_number) {
1637+
bt_hf->subscriber_number(hf, number, (uint8_t)type, (uint8_t)service);
1638+
}
1639+
1640+
LOG_DBG("CNUM number %s type %d service %d", number, type, service);
1641+
1642+
return 0;
1643+
}
1644+
16061645
static const struct unsolicited {
16071646
const char *cmd;
16081647
enum at_cmd_type type;
@@ -1632,6 +1671,7 @@ static const struct unsolicited {
16321671
#if defined(CONFIG_BT_HFP_HF_VOICE_RECG)
16331672
{ "BVRA", AT_CMD_TYPE_UNSOLICITED, bvra_handle },
16341673
#endif /* CONFIG_BT_HFP_HF_VOICE_RECG */
1674+
{ "CNUM", AT_CMD_TYPE_UNSOLICITED, cnum_handle },
16351675
};
16361676

16371677
static const struct unsolicited *hfp_hf_unsol_lookup(struct at_client *hf_at)
@@ -2387,6 +2427,40 @@ int bt_hfp_hf_transmit_dtmf_code(struct bt_hfp_hf_call *call, char code)
23872427
return err;
23882428
}
23892429

2430+
static int cnum_finish(struct at_client *hf_at, enum at_result result,
2431+
enum at_cme cme_err)
2432+
{
2433+
struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
2434+
2435+
LOG_DBG("AT+CNUM (result %d) on %p", result, hf);
2436+
2437+
return 0;
2438+
}
2439+
2440+
int bt_hfp_hf_query_subscriber(struct bt_hfp_hf *hf)
2441+
{
2442+
int err;
2443+
2444+
LOG_DBG("");
2445+
2446+
if (!hf) {
2447+
LOG_ERR("No HF connection found");
2448+
return -ENOTCONN;
2449+
}
2450+
2451+
if (!atomic_test_bit(hf->flags, BT_HFP_HF_FLAG_CONNECTED)) {
2452+
LOG_ERR("SLC is not established on %p", hf);
2453+
return -ENOTCONN;
2454+
}
2455+
2456+
err = hfp_hf_send_cmd(hf, NULL, cnum_finish, "AT+CNUM");
2457+
if (err < 0) {
2458+
LOG_ERR("Fail to query subscriber number information on %p", hf);
2459+
}
2460+
2461+
return err;
2462+
}
2463+
23902464
static int ata_finish(struct at_client *hf_at, enum at_result result,
23912465
enum at_cme cme_err)
23922466
{

0 commit comments

Comments
 (0)