1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #ifndef CLD80211_LIB_H 31 #define CLD80211_LIB_H 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 #include <netlink/genl/genl.h> 37 #include <stdbool.h> 38 39 #ifndef UNUSED 40 #define UNUSED(x) (void)(x) 41 #endif 42 43 struct cld80211_ctx { 44 struct nl_sock *sock; 45 int netlink_familyid; 46 /* socket pair used to exit from blocking poll*/ 47 int exit_sockets[2]; 48 int sock_buf_size; 49 int nlctrl_familyid; 50 }; 51 52 /** 53 * enum cld80211_attr - Driver/Application embeds the data in nlmsg with the 54 * help of below attributes 55 * CLD80211_ATTR_VENDOR_DATA: Embed all other attributes in this nested 56 * attribute. 57 * CLD80211_ATTR_DATA: Embed driver/application data in this attribute 58 * CLD80211_ATTR_META_DATA: Embed meta data for above data. This will help 59 * wlan driver to peek into request message packet without opening up definition 60 * of complete request message. 61 * @CLD80211_ATTR_CMD: cld80211 vendor subcommand in this attribute 62 * @CLD80211_ATTR_CMD_TAG_DATA: cld80211 vendor subcommand data is present in 63 * this attribute. It is a nested attribute with sub attributes of specified 64 * vendor sub command. 65 * 66 * Any new message in future can be added as another attribute 67 */ 68 enum cld80211_attr { 69 CLD80211_ATTR_VENDOR_DATA = 1, 70 CLD80211_ATTR_DATA, 71 CLD80211_ATTR_META_DATA, 72 CLD80211_ATTR_CMD, 73 CLD80211_ATTR_CMD_TAG_DATA, 74 75 __CLD80211_ATTR_AFTER_LAST, 76 CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1 77 }; 78 79 /** 80 * Create socket of type NETLINK_GENERIC 81 * Retuns valid sock only if socket creation is succesful and cld80211 82 * family is present, returns NULL otherwise 83 */ 84 struct cld80211_ctx *cld80211_init(void); 85 86 /** 87 * free the socket created in cld80211_init() 88 */ 89 void cld80211_deinit(struct cld80211_ctx *ctx); 90 91 /** 92 * Allocate nl_msg and populate family and genl header details 93 */ 94 struct nl_msg *cld80211_msg_alloc(struct cld80211_ctx *ctx, int cmd, 95 struct nlattr **nla_data, int pid); 96 97 /** 98 * Send nlmsg to driver and return; It doesn't wait for response 99 */ 100 int cld80211_send_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg); 101 102 /** 103 * Send nlmsg to driver and get response, if any 104 */ 105 int cld80211_send_recv_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg, 106 int (*valid_handler)(struct nl_msg *, void *), 107 void *valid_data); 108 109 /** 110 * Add membership for multicast group "mcgroup" to receive the messages 111 * sent to this group from driver 112 */ 113 int cld80211_add_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup); 114 115 /** 116 * Remove membership of multicast group "mcgroup" to stop receiving messages 117 * sent to this group from driver 118 */ 119 int cld80211_remove_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup); 120 121 /** 122 * Receive messages from driver on cld80211 family. Client can do 123 * a select()/poll() on the socket before calling this API. 124 * sock: nl_sock created for communication 125 * cb: nl callback context provided by client 126 * Returns corresponding errno when a failure happens while receiving nl msg 127 */ 128 int cld80211_recv_msg(struct nl_sock *sock, struct nl_cb *cb); 129 130 /** 131 * Receive messages from driver on cld80211 family from the 132 * multicast groups subscribed 133 * timeout: Timeout in milliseconds for poll(); -1 is for infinite timeout. 134 * recv_multi_msg: Boolean flag to be sent false/true from client to indicate 135 * whether it wants to receive only one message or multiple 136 * messages from timeoutblock. 137 * false: Receive only one message and return 138 * true: Continue in the loop to receive multiple message till 139 * client explicitly sends exit via exit_cld80211_recv(). 140 * cbctx: Context provided by client, which is to be used when an 141 * nlmsg is received 142 * Returns corresponding errno when a failure happens while receiving nl msg 143 */ 144 int cld80211_recv(struct cld80211_ctx *ctx, int timeout, bool recv_multi_msg, 145 int (*valid_handler)(struct nl_msg *, void *), 146 void *cbctx); 147 148 /** 149 * poll() is a blocking call on sock. Client has to unblock the poll() 150 * first to exit gracefully. 151 */ 152 void exit_cld80211_recv(struct cld80211_ctx *ctx); 153 #ifdef __cplusplus 154 } 155 #endif 156 157 #endif 158