Skip to content

Commit af9c8aa

Browse files
cricard13Samuel Ortiz
authored andcommitted
NFC: nci: Add NFCEE discover support
NFCEEs (NFC Execution Environment) have to be explicitly discovered by sending the NCI_OP_NFCEE_DISCOVER_CMD command. The NFCC will respond to this command by telling us how many NFCEEs are connected to it. Then the NFCC sends a notification command for each and every NFCEE connected. Here we implement support for sending NCI_OP_NFCEE_DISCOVER_CMD command, receiving the response and the potential notifications. Signed-off-by: Christophe Ricard <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
1 parent 8277f69 commit af9c8aa

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

include/net/nfc/nci_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ struct nci_conn_info {
100100
struct sk_buff *rx_skb;
101101
};
102102

103+
#define NCI_INVALID_CONN_ID 0x80
104+
103105
/* NCI Core structures */
104106
struct nci_dev {
105107
struct nfc_dev *nfc_dev;
@@ -182,6 +184,8 @@ void nci_unregister_device(struct nci_dev *ndev);
182184
int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
183185
int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val);
184186

187+
int nci_nfcee_discover(struct nci_dev *ndev, u8 action);
188+
185189
static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
186190
unsigned int len,
187191
gfp_t how)

net/nfc/nci/core.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,23 @@ int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val)
469469
}
470470
EXPORT_SYMBOL(nci_set_config);
471471

472+
static void nci_nfcee_discover_req(struct nci_dev *ndev, unsigned long opt)
473+
{
474+
struct nci_nfcee_discover_cmd cmd;
475+
__u8 action = opt;
476+
477+
cmd.discovery_action = action;
478+
479+
nci_send_cmd(ndev, NCI_OP_NFCEE_DISCOVER_CMD, 1, &cmd);
480+
}
481+
482+
int nci_nfcee_discover(struct nci_dev *ndev, u8 action)
483+
{
484+
return nci_request(ndev, nci_nfcee_discover_req, action,
485+
msecs_to_jiffies(NCI_CMD_TIMEOUT));
486+
}
487+
EXPORT_SYMBOL(nci_nfcee_discover);
488+
472489
static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
473490
{
474491
struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);

net/nfc/nci/ntf.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,33 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
713713
nci_req_complete(ndev, NCI_STATUS_OK);
714714
}
715715

716+
static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev,
717+
struct sk_buff *skb)
718+
{
719+
u8 status = NCI_STATUS_OK;
720+
struct nci_conn_info *conn_info;
721+
struct nci_nfcee_discover_ntf *nfcee_ntf =
722+
(struct nci_nfcee_discover_ntf *)skb->data;
723+
724+
pr_debug("\n");
725+
726+
conn_info = devm_kzalloc(&ndev->nfc_dev->dev,
727+
sizeof(struct nci_conn_info), GFP_KERNEL);
728+
if (!conn_info) {
729+
status = NCI_STATUS_REJECTED;
730+
goto exit;
731+
}
732+
733+
conn_info->id = nfcee_ntf->nfcee_id;
734+
conn_info->conn_id = NCI_INVALID_CONN_ID;
735+
736+
INIT_LIST_HEAD(&conn_info->list);
737+
list_add(&conn_info->list, &ndev->conn_info_list);
738+
739+
exit:
740+
nci_req_complete(ndev, status);
741+
}
742+
716743
void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
717744
{
718745
__u16 ntf_opcode = nci_opcode(skb->data);
@@ -751,6 +778,9 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
751778
nci_rf_deactivate_ntf_packet(ndev, skb);
752779
break;
753780

781+
case NCI_OP_NFCEE_DISCOVER_NTF:
782+
nci_nfcee_discover_ntf_packet(ndev, skb);
783+
break;
754784
default:
755785
pr_err("unknown ntf opcode 0x%x\n", ntf_opcode);
756786
break;

net/nfc/nci/rsp.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,23 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
196196
}
197197
}
198198

199+
static void nci_nfcee_discover_rsp_packet(struct nci_dev *ndev,
200+
struct sk_buff *skb)
201+
{
202+
struct nci_nfcee_discover_rsp *discover_rsp;
203+
204+
if (skb->len != 2) {
205+
nci_req_complete(ndev, NCI_STATUS_NFCEE_PROTOCOL_ERROR);
206+
return;
207+
}
208+
209+
discover_rsp = (struct nci_nfcee_discover_rsp *)skb->data;
210+
211+
if (discover_rsp->status != NCI_STATUS_OK ||
212+
discover_rsp->num_nfcee == 0)
213+
nci_req_complete(ndev, discover_rsp->status);
214+
}
215+
199216
void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
200217
{
201218
__u16 rsp_opcode = nci_opcode(skb->data);
@@ -241,6 +258,10 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
241258
nci_rf_deactivate_rsp_packet(ndev, skb);
242259
break;
243260

261+
case NCI_OP_NFCEE_DISCOVER_RSP:
262+
nci_nfcee_discover_rsp_packet(ndev, skb);
263+
break;
264+
244265
default:
245266
pr_err("unknown rsp opcode 0x%x\n", rsp_opcode);
246267
break;

0 commit comments

Comments
 (0)