NFC: Initial SNL support
SNL (Service Name Lookup) allows for LLCP peers to map service names with SAPs. This is mandatory for connection less support as peers need to get the right SAPs without sending the CONNECT frame. Here we only support the Rx part of SNL. The Tx one will be implemented when supporting connection less LLCP sockets. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
c43bb03d5a
commit
19cfe5843e
|
@ -1043,6 +1043,66 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nfc_llcp_recv_snl(struct nfc_llcp_local *local,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct nfc_llcp_sock *llcp_sock;
|
||||||
|
u8 dsap, ssap, *tlv, type, length, tid, sap;
|
||||||
|
u16 tlv_len, offset;
|
||||||
|
char *service_name;
|
||||||
|
size_t service_name_len;
|
||||||
|
|
||||||
|
dsap = nfc_llcp_dsap(skb);
|
||||||
|
ssap = nfc_llcp_ssap(skb);
|
||||||
|
|
||||||
|
pr_debug("%d %d\n", dsap, ssap);
|
||||||
|
|
||||||
|
if (dsap != LLCP_SAP_SDP || ssap != LLCP_SAP_SDP) {
|
||||||
|
pr_err("Wrong SNL SAP\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlv = &skb->data[LLCP_HEADER_SIZE];
|
||||||
|
tlv_len = skb->len - LLCP_HEADER_SIZE;
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
while(offset < tlv_len) {
|
||||||
|
type = tlv[0];
|
||||||
|
length = tlv[1];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case LLCP_TLV_SDREQ:
|
||||||
|
tid = tlv[2];
|
||||||
|
service_name = (char *) &tlv[3];
|
||||||
|
service_name_len = length - 1;
|
||||||
|
|
||||||
|
pr_debug("Looking for %s\n", service_name);
|
||||||
|
|
||||||
|
if (service_name_len == strlen("urn:nfc:sn:sdp") &&
|
||||||
|
!strncmp(service_name, "urn:nfc:sn:sdp",
|
||||||
|
service_name_len)) {
|
||||||
|
sap = 1;
|
||||||
|
} else {
|
||||||
|
llcp_sock =
|
||||||
|
nfc_llcp_sock_from_sn(local,
|
||||||
|
service_name,
|
||||||
|
service_name_len);
|
||||||
|
sap = llcp_sock ? llcp_sock->ssap : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfc_llcp_send_snl(local, tid, sap);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pr_err("Invalid SNL tlv value 0x%x\n", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += length + 2;
|
||||||
|
tlv += length + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void nfc_llcp_rx_work(struct work_struct *work)
|
static void nfc_llcp_rx_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
|
struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
|
||||||
|
@ -1093,6 +1153,11 @@ static void nfc_llcp_rx_work(struct work_struct *work)
|
||||||
nfc_llcp_recv_dm(local, skb);
|
nfc_llcp_recv_dm(local, skb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LLCP_PDU_SNL:
|
||||||
|
pr_debug("SNL\n");
|
||||||
|
nfc_llcp_recv_snl(local, skb);
|
||||||
|
break;
|
||||||
|
|
||||||
case LLCP_PDU_I:
|
case LLCP_PDU_I:
|
||||||
case LLCP_PDU_RR:
|
case LLCP_PDU_RR:
|
||||||
case LLCP_PDU_RNR:
|
case LLCP_PDU_RNR:
|
||||||
|
|
Loading…
Reference in New Issue