Skip to content

Commit 736bb95

Browse files
cricard13Samuel Ortiz
authored andcommitted
NFC: nci: Support logical connections management
In order to communicate with an NFCEE, we need to open a logical connection to it, by sending the NCI_OP_CORE_CONN_CREATE_CMD command to the NFCC. It's left up to the drivers to decide when to close an already opened logical connection. Signed-off-by: Christophe Ricard <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
1 parent f7f793f commit 736bb95

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

include/net/nfc/nci.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,26 @@ struct nci_core_set_config_cmd {
243243
struct set_config_param param; /* support 1 param per cmd is enough */
244244
} __packed;
245245

246+
#define NCI_OP_CORE_CONN_CREATE_CMD nci_opcode_pack(NCI_GID_CORE, 0x04)
247+
struct dest_spec_params {
248+
__u8 id;
249+
__u8 protocol;
250+
} __packed;
251+
252+
struct core_conn_create_dest_spec_params {
253+
__u8 type;
254+
__u8 length;
255+
struct dest_spec_params value;
256+
} __packed;
257+
258+
struct nci_core_conn_create_cmd {
259+
__u8 destination_type;
260+
__u8 number_destination_params;
261+
struct core_conn_create_dest_spec_params params;
262+
} __packed;
263+
264+
#define NCI_OP_CORE_CONN_CLOSE_CMD nci_opcode_pack(NCI_GID_CORE, 0x05)
265+
246266
#define NCI_OP_RF_DISCOVER_MAP_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
247267
struct disc_map_config {
248268
__u8 rf_protocol;
@@ -327,6 +347,16 @@ struct nci_core_set_config_rsp {
327347
__u8 params_id[0]; /* variable size array */
328348
} __packed;
329349

350+
#define NCI_OP_CORE_CONN_CREATE_RSP nci_opcode_pack(NCI_GID_CORE, 0x04)
351+
struct nci_core_conn_create_rsp {
352+
__u8 status;
353+
__u8 max_ctrl_pkt_payload_len;
354+
__u8 credits;
355+
__u8 conn_id;
356+
} __packed;
357+
358+
#define NCI_OP_CORE_CONN_CLOSE_RSP nci_opcode_pack(NCI_GID_CORE, 0x05)
359+
330360
#define NCI_OP_RF_DISCOVER_MAP_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
331361

332362
#define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)

include/net/nfc/nci_core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val);
186186

187187
int nci_nfcee_discover(struct nci_dev *ndev, u8 action);
188188
int nci_nfcee_mode_set(struct nci_dev *ndev, u8 nfcee_id, u8 nfcee_mode);
189+
int nci_core_conn_create(struct nci_dev *ndev,
190+
struct core_conn_create_dest_spec_params *params);
191+
int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id);
189192

190193
static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
191194
unsigned int len,

net/nfc/nci/core.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,44 @@ int nci_nfcee_mode_set(struct nci_dev *ndev, u8 nfcee_id, u8 nfcee_mode)
507507
}
508508
EXPORT_SYMBOL(nci_nfcee_mode_set);
509509

510+
static void nci_core_conn_create_req(struct nci_dev *ndev, unsigned long opt)
511+
{
512+
struct nci_core_conn_create_cmd cmd;
513+
struct core_conn_create_dest_spec_params *params =
514+
(struct core_conn_create_dest_spec_params *)opt;
515+
516+
cmd.destination_type = NCI_DESTINATION_NFCEE;
517+
cmd.number_destination_params = 1;
518+
memcpy(&cmd.params.type, params,
519+
sizeof(struct core_conn_create_dest_spec_params));
520+
nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD,
521+
sizeof(struct nci_core_conn_create_cmd), &cmd);
522+
}
523+
524+
int nci_core_conn_create(struct nci_dev *ndev,
525+
struct core_conn_create_dest_spec_params *params)
526+
{
527+
ndev->cur_id = params->value.id;
528+
return nci_request(ndev, nci_core_conn_create_req,
529+
(unsigned long)params,
530+
msecs_to_jiffies(NCI_CMD_TIMEOUT));
531+
}
532+
EXPORT_SYMBOL(nci_core_conn_create);
533+
534+
static void nci_core_conn_close_req(struct nci_dev *ndev, unsigned long opt)
535+
{
536+
__u8 conn_id = opt;
537+
538+
nci_send_cmd(ndev, NCI_OP_CORE_CONN_CLOSE_CMD, 1, &conn_id);
539+
}
540+
541+
int nci_core_conn_close(struct nci_dev *ndev, u8 conn_id)
542+
{
543+
return nci_request(ndev, nci_core_conn_close_req, conn_id,
544+
msecs_to_jiffies(NCI_CMD_TIMEOUT));
545+
}
546+
EXPORT_SYMBOL(nci_core_conn_close);
547+
510548
static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
511549
{
512550
struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);

net/nfc/nci/rsp.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,45 @@ static void nci_nfcee_mode_set_rsp_packet(struct nci_dev *ndev,
222222
nci_req_complete(ndev, status);
223223
}
224224

225+
static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev,
226+
struct sk_buff *skb)
227+
{
228+
__u8 status = skb->data[0];
229+
struct nci_conn_info *conn_info;
230+
struct nci_core_conn_create_rsp *rsp;
231+
232+
pr_debug("status 0x%x\n", status);
233+
234+
if (status == NCI_STATUS_OK) {
235+
rsp = (struct nci_core_conn_create_rsp *)skb->data;
236+
list_for_each_entry(conn_info, &ndev->conn_info_list, list) {
237+
if (conn_info->id == ndev->cur_id)
238+
break;
239+
}
240+
241+
if (!conn_info || conn_info->id != ndev->cur_id) {
242+
status = NCI_STATUS_REJECTED;
243+
goto exit;
244+
}
245+
246+
conn_info->conn_id = rsp->conn_id;
247+
conn_info->max_pkt_payload_len = rsp->max_ctrl_pkt_payload_len;
248+
atomic_set(&conn_info->credits_cnt, rsp->credits);
249+
}
250+
251+
exit:
252+
nci_req_complete(ndev, status);
253+
}
254+
255+
static void nci_core_conn_close_rsp_packet(struct nci_dev *ndev,
256+
struct sk_buff *skb)
257+
{
258+
__u8 status = skb->data[0];
259+
260+
pr_debug("status 0x%x\n", status);
261+
nci_req_complete(ndev, status);
262+
}
263+
225264
void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
226265
{
227266
__u16 rsp_opcode = nci_opcode(skb->data);
@@ -251,6 +290,14 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
251290
nci_core_set_config_rsp_packet(ndev, skb);
252291
break;
253292

293+
case NCI_OP_CORE_CONN_CREATE_RSP:
294+
nci_core_conn_create_rsp_packet(ndev, skb);
295+
break;
296+
297+
case NCI_OP_CORE_CONN_CLOSE_RSP:
298+
nci_core_conn_close_rsp_packet(ndev, skb);
299+
break;
300+
254301
case NCI_OP_RF_DISCOVER_MAP_RSP:
255302
nci_rf_disc_map_rsp_packet(ndev, skb);
256303
break;

0 commit comments

Comments
 (0)