int wl_cfgnan_sub_handler(struct net_device *ndev, struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data) { wl_nan_ioc_t *nanioc = NULL; struct bcm_tlvbuf *tbuf = NULL; wl_nan_disc_params_t params; s32 ret = BCME_OK; u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE; /* * proceed only if mandatory arguments are present - subscriber id, * service hash */ if ((!cmd_data->sub_id) || (!cmd_data->svc_hash.data) || (!cmd_data->svc_hash.dlen)) { WL_ERR((" mandatory arguments are not present \n")); return -EINVAL; } nanioc = kzalloc(nanioc_size, kflags); if (!nanioc) { WL_ERR((" memory allocation failed \n")); return -ENOMEM; } tbuf = bcm_xtlv_buf_alloc(NULL, BCM_XTLV_HDR_SIZE + sizeof(params)); if (!tbuf) { WL_ERR((" memory allocation failed \n")); ret = -ENOMEM; goto fail; } /* * command to test * * wl: wl nan subscribe 10 NAN123 * * wpa_cli: DRIVER NAN_SUBSCRIBE SUB_ID=10 SVC_HASH=NAN123 */ /* nan subscribe */ params.period = 1; params.ttl = WL_NAN_TTL_UNTIL_CANCEL; params.flags = 0; params.instance_id = (wl_nan_instance_id_t)cmd_data->sub_id; memcpy((char *)params.svc_hash, cmd_data->svc_hash.data, cmd_data->svc_hash.dlen); bcm_xtlv_put_data(tbuf, WL_NAN_XTLV_SVC_PARAMS, ¶ms, sizeof(params)); nanioc->version = htod16(WL_NAN_IOCTL_VERSION); nanioc->id = htod16(WL_NAN_CMD_SUBSCRIBE); nanioc->len = htod16(bcm_xtlv_buf_len(tbuf)); bcopy(bcm_xtlv_head(tbuf), nanioc->data, bcm_xtlv_buf_len(tbuf)); nanioc_size = sizeof(wl_nan_ioc_t) + bcm_xtlv_buf_len(tbuf); ret = wldev_iovar_setbuf(ndev, "nan", nanioc, nanioc_size, cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL); if (unlikely(ret)) { WL_ERR((" nan subscribe failed, error = %d \n", ret)); goto fail; } else { WL_DBG((" nan subscribe successful \n")); } fail: if (tbuf) { bcm_xtlv_buf_free(NULL, tbuf); } if (nanioc) { kfree(nanioc); } return ret; }
int wl_cfgnan_cancel_sub_handler(struct net_device *ndev, struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data) { wl_nan_ioc_t *nanioc = NULL; struct bcm_tlvbuf *tbuf = NULL; wl_nan_disc_params_t params; s32 ret = BCME_OK; u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE; /* proceed only if mandatory argument is present - subscriber id */ if (!cmd_data->sub_id) { WL_ERR((" mandatory argument is not present \n")); return -EINVAL; } nanioc = kzalloc(nanioc_size, kflags); if (!nanioc) { WL_ERR((" memory allocation failed \n")); return -ENOMEM; } tbuf = bcm_xtlv_buf_alloc(NULL, BCM_XTLV_HDR_SIZE + sizeof(params)); if (!tbuf) { WL_ERR((" memory allocation failed \n")); ret = -ENOMEM; goto fail; } /* * command to test * * wl: wl nan cancel_subscribe 10 * * wpa_cli: DRIVER NAN_CANCEL_SUBSCRIBE PUB_ID=10 */ bcm_xtlv_put_data(tbuf, WL_NAN_XTLV_INSTANCE_ID, &cmd_data->sub_id, sizeof(wl_nan_instance_id_t)); /* nan cancel subscribe */ nanioc->version = htod16(WL_NAN_IOCTL_VERSION); nanioc->id = htod16(WL_NAN_CMD_CANCEL_SUBSCRIBE); nanioc->len = htod16(bcm_xtlv_buf_len(tbuf)); bcopy(bcm_xtlv_head(tbuf), nanioc->data, bcm_xtlv_buf_len(tbuf)); nanioc_size = sizeof(wl_nan_ioc_t) + bcm_xtlv_buf_len(tbuf); ret = wldev_iovar_setbuf(ndev, "nan", nanioc, nanioc_size, cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL); if (unlikely(ret)) { WL_ERR((" nan cancel subscribe failed, error = %d \n", ret)); goto fail; } else { WL_DBG((" nan cancel subscribe successful \n")); } fail: if (tbuf) { bcm_xtlv_buf_free(NULL, tbuf); } if (nanioc) { kfree(nanioc); } return ret; }
uint16 bcm_xtlv_buf_rlen(struct bcm_tlvbuf *tbuf) { if (tbuf == NULL) return 0; return tbuf->size - bcm_xtlv_buf_len(tbuf); }